JavaScript - IndexedDB:客戶端數據存儲的入口

你好,有抱負的開發者們!今天,我們將踏上一段令人興奮的旅程,進入IndexedDB的世界。作為你們友好的鄰居計算機科學老師,我將指導你們了解這項強大的技術,這項技術可能會徹底改變你們對網頁應用程序的看法。所以,拿起你們最喜歡的飲料,坐在最舒適的椅子上,讓我們一起深入探討吧!

JavaScript - IndexedDB

IndexedDB是什麼?

IndexedDB就像一個迷你數據庫,直接存在你的網頁瀏覽器中。想像一下,你有一個數字文件櫃,你可以在裡面存儲各種信息,從簡單的文本到複雜的對象、圖像,甚至文件。這就是IndexedDB!

但這裡有個酷炫的部分:與遠方服務器上的傳統數據庫不同,IndexedDB托管在用戶的設備上。這意味著你的網頁應用程序即使在没有網絡連接的情況下也能處理數據。是不是很棒?

IndexedDB的主要特點

  1. 異步性質:在處理數據時不會凍結你的應用程序。
  2. 面向對象:直接存儲JavaScript對象,無需複雜的轉換。
  3. 大量數據容量:比其他客戶端存儲選項存儲更多數據。

為什麼使用IndexedDB?

現在你可能會想,“既然我有像localStorage這樣的其他選項,為什麼還要麻煩使用IndexedDB?”這個問題問得好!讓我通過一個小故事來解釋。

想像你正在構建一個記筆記的應用程序。使用localStorage,你只能存儲簡單的字符串。這就像試圖組織一個圖書館,每本書只能包含一句話。這並不是很有用,對吧?

另一方面,IndexedDB就像擁有一個神奇的圖書館,每本書可以包含整本小說、圖片,甚至視頻。你可以超快速地搜索這個圖書館,而且它可以保存遠遠超過普通書架的信息。

以下是一些使用IndexedDB的有力理由:

  1. 離線功能:即使在沒有網絡連接的情況下也能讓應用程序正常運作。
  2. 性能:有效地處理大量結構化數據。
  3. 複杂数據結構:輕鬆存儲和檢索JavaScript對象。
  4. 事務數據庫模型:即使在出錯的情況下也能保證數據完整性。

CRUD操作

現在,讓我們來動手寫一些代碼!在數據庫的世界中,我們經常會談到CRUD操作。不,這不是關於清理污垢(儘管它在你的數據中可以起到這個作用)。CRUD代表創建(Create)、讀取(Read)、更新(Update)和刪除(Delete)。這是你將在IndexedDB中執行的基本操作。

讓我們通過一些例子來分解這些操作:

1. 創建(添加數據)

let db;
const request = indexedDB.open("MyNotes", 1);

request.onupgradeneeded = (event) => {
db = event.target.result;
const objectStore = db.createObjectStore("notes", { keyPath: "id", autoIncrement: true });
};

request.onsuccess = (event) => {
db = event.target.result;

const transaction = db.transaction(["notes"], "readwrite");
const objectStore = transaction.objectStore("notes");

const note = { title: "我的第一個筆記", content: "你好,IndexedDB!" };
const request = objectStore.add(note);

request.onsuccess = () => {
console.log("筆記添加成功");
};
};

在這個例子中,我們創建了一個名為"MyNotes"的數據庫並在其中添加了一個筆記。這就像在日記中寫下新的條目。

2. 讀取(檢索數據)

const transaction = db.transaction(["notes"]);
const objectStore = transaction.objectStore("notes");
const request = objectStore.get(1);

request.onsuccess = (event) => {
if (request.result) {
console.log("筆記:", request.result);
} else {
console.log("未找到id為1的筆記");
}
};

在這裡,我們檢索id為1的筆記。這就像翻到日記中的特定頁面來閱讀你寫下的內容。

3. 更新(修改數據)

const transaction = db.transaction(["notes"], "readwrite");
const objectStore = transaction.objectStore("notes");
const request = objectStore.get(1);

request.onsuccess = (event) => {
const data = event.target.result;
data.content = "更新後的內容!";
const updateRequest = objectStore.put(data);

updateRequest.onsuccess = () => {
console.log("筆記更新成功");
};
};

這段代碼更新了現有的筆記。這就像在日記中划掉一些內容並寫下新的版本。

4. 刪除(移除數據)

const request = db.transaction(["notes"], "readwrite")
.objectStore("notes")
.delete(1);

request.onsuccess = () => {
console.log("筆記刪除成功");
};

在這裡,我們刪除了一個筆記。這就像從日記中撕下一頁(但在现实生活中不要這樣做,孩子们!)

實作範例:一個簡單的記筆記應用程序

現在,讓我們將所有這些組合起來,構建一個更完整的例子。我們將創建一個簡單的記筆記應用程序,演示所有的CRUD操作。

<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IndexedDB 筆記應用程序</title>
</head>
<body>
<h1>我的筆記</h1>
<input type="text" id="noteTitle" placeholder="筆記標題">
<textarea id="noteContent" placeholder="筆記內容"></textarea>
<button id="addNote">添加筆記</button>
<div id="notesList"></div>

<script>
let db;
const dbName = "NotesDB";

const request = indexedDB.open(dbName, 1);

request.onerror = (event) => {
console.error("數據庫錯誤: " + event.target.error);
};

request.onsuccess = (event) => {
db = event.target.result;
displayNotes();
};

request.onupgradeneeded = (event) => {
db = event.target.result;
const objectStore = db.createObjectStore("notes", { keyPath: "id", autoIncrement: true });
};

function addNote() {
const title = document.getElementById("noteTitle").value;
const content = document.getElementById("noteContent").value;

const transaction = db.transaction(["notes"], "readwrite");
const objectStore = transaction.objectStore("notes");
const note = { title: title, content: content };
const request = objectStore.add(note);

request.onsuccess = () => {
document.getElementById("noteTitle").value = "";
document.getElementById("noteContent").value = "";
displayNotes();
};
}

function displayNotes() {
const notesList = document.getElementById("notesList");
notesList.innerHTML = "";

const objectStore = db.transaction("notes").objectStore("notes");
objectStore.openCursor().onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
const noteElement = document.createElement("div");
noteElement.innerHTML = `
<h3>${cursor.value.title}</h3>
<p>${cursor.value.content}</p>
<button onclick="deleteNote(${cursor.value.id})">刪除</button>
`;
notesList.appendChild(noteElement);
cursor.continue();
}
};
}

function deleteNote(id) {
const request = db.transaction(["notes"], "readwrite")
.objectStore("notes")
.delete(id);

request.onsuccess = () => {
displayNotes();
};
}

document.getElementById("addNote").onclick = addNote;
</script>
</body>
</html>

這個例子創建了一個簡單的網頁,你可以在上面添加、查看和刪除筆記。它是一個基本的但功能完整的筆記應用程序,展示了IndexedDB的強大功能。

結論

就是这样,各位!我們一起穿越了IndexedDB的土地,從了解其基礎知識到實現真實世界的範例。記住,像任何強大的工具一樣,掌握IndexedDB需要練習。如果一开始觉得有点難以掌握,不要氣餒。继續實驗,繼續編程,很快你就能夠构建出令人驚艷的離線功能網頁應用程序!

在我們結束之前,讓我們總結一下我們所涵蓋的IndexedDB關鍵方法:

方法 描述
indexedDB.open() 打開數據庫連接
createObjectStore() 創建新的對象存儲
transaction() 開始新的事務
add() 向對象存儲添加新記錄
put() 更新對象存儲中的現有記錄
get() 從對象存儲中檢索記錄
delete() 從對象存儲中刪除記錄
openCursor() 打開游標以迭代記錄

將這些方法放在手邊,你很快就會成為IndexedDB的專家!

記住,千里之行,始於足下。或者在我們的例子中,成為一個網頁開發大師的旅程,從理解IndexedDB開始。祝你好運,願你的數據庫永遠保持索引!

Credits: Image by storyset