IndexedDBを使ってみる
今作っているアプリの保存機能をどうしようか考えていて、 前から気になっていたIndexedDBを使うことにしました。 その際、調べたので基本的な使い方をまとめます!
用語や概要の説明はしません。簡単な使い方のみ説明します。 用語や概要はIndexedDB API - Web API | MDNを見てください。
扱うデータは以下の通りです。
- DB名: myDatabase
- objectStore名: myObjectStore
id | firstName | lastName | age |
---|---|---|---|
1 | 一郎 | 山田 | 30 |
2 | 次郎 | 山田 | 27 |
3 | 一郎 | 田中 | 27 |
DB, objectStoreを作成
// 指定したDBへ接続(ない場合は作成) const request = indexedDB.open('myDatabase') // 作成 or バージョンを更新した場合 request.onupgradeneeded = event => { // dbを取得 const db = event.target.result // objectStoreを作成 const objectStore = db.createObjectStore("myObjectStore", { keyPath: "id" }) // keyPathは、一意となるプロパティ名を指定(Primary Keyみたいな感じ) // index作成(lastName) ... lastNameは重複を許可してるので、unique: falseを指定 objectStore.createIndex("lastName", "lastName", { unique: false }) // index作成(age) .... ageも重複を許可してるので、unique: falseを指定 objectStore.createIndex("age", "age", { unique: false }) } // 成功の場合 request.onsuccess = event => { // 接続成功時の処理 } // 失敗の場合 request.onerror = event => { // 接続失敗時の処理 }
データを追加
const request = indexedDB.open('myDatabase') request.onsuccess = event => { // dbを取得 const db = event.target.result // transactionを取得 const transaction = db.transaction(["myObjectStore"], "readwrite") // 追加するので"readwrite"を指定 transaction.oncomplete = e => { console.log("success!!") } transaction.onerror = e => { console.error("error: ", e) } // objectStoreを取得 const objectStore = transaction.objectStore("myObjectStore") objectStore.add({ id: 1, firstName: "一郎", lastName: "山田", age: 30 }) objectStore.add({ id: 2, firstName: "次郎", lastName: "山田", age: 27 }) objectStore.add({ id: 3, firstName: "一郎", lastName: "田中", age: 27 }) }
データを取得
keyPathを使用してデータを取得
const request = indexedDB.open('myDatabase') request.onsuccess = event => { // dbを取得 const db = event.target.result // transactionを取得 const transaction = db.transaction(["myObjectStore"]) // objectStoreを取得 const objectStore = transaction. objectStore("myObjectStore") // requestを取得 const req = objectStore.get(1) req.onsuccess = e => { console.log("success: ", e.target.result) } // { id: 1, firstName: "一郎", lastName: "山田", age: 30 } } req.onerror = e => { console.error("error: ", e) } }
cursorを使用してデータを取得
keyPath知らない場合、objectStoreを昇順(keyPath)に検索
(indexがあるので、あまり使わない方法かも...)
const request = indexedDB.open('myDatabase') request.onsuccess = event => { // dbを取得 const db = event.target.result // transactionを取得 const transaction = db.transaction(["myObjectStore"]) // objectStoreを取得 const objectStore = transaction. objectStore("myObjectStore") // requestを取得 const req = objectStore.openCursor() req.onsuccess = e => { // cursorを取得 const cursor = e.target.result if (cursor) { console.log("cursor: ", cursor, " value: ", cursor.value) cursor.continue(); // cursorを移動させてる } } req.onerror = e => { console.error("error: ", e) } }
indexを使用してデータを取得
const request = indexedDB.open('myDatabase') request.onsuccess = event => { // dbを取得 const db = event.target.result // transactionを取得 const transaction = db.transaction(["myObjectStore"]) // objectStoreを取得 const objectStore = transaction. objectStore("myObjectStore") // indexを取得 const index = objectStore.index("age"); // 一番最初のvalueを取得 index.get("一郎").onsuccess = e => { console.log("success: ", e.target.result) // { id: 1, firstName: "一郎", lastName: "山田", age: 30 } } // indexの全てのvalueを取得 index.openCursor().onsuccess = e => { const cursor = e.target.result if (cursor) { console.log("cursor: ", cursor, " value: ", cursor.value) cursor.continue(); // cursorを移動させてる } } // indexの全てのkeyPathを取得 index.openKeyCursor().onsuccess = e => { const cursor = e.target.result if (cursor) { console.log("cursor: ", cursor, " keyPath: ", cursor.value) cursor.continue(); // cursorを移動させてる } } }
データを更新
const request = indexedDB.open('myDatabase') request.onsuccess = event => { // dbを取得 const db = event.target.result // transactionを取得 const transaction = db.transaction(["myObjectStore"], "readwrite") // 追加するので"readwrite"を指定 // objectStoreを取得 const objectStore = transaction. objectStore("myObjectStore") // requestを取得 const req = objectStore.get(1) req.onsuccess = e => { const data = e.target.result // データを変更 data.age = 33 // 変更リクエストを取得 const updateRequest = objectStore.put(data) updateRequest.onsuccess = e => { console.log("success: ", e) } updateRequest.onerror = e => { console.error("error: ", e) } } req.onerror = e => { console.error("error: ", e) } }
データを削除
const request = indexedDB.open('myDatabase') request.onsuccess = event => { // dbを取得 const db = event.target.result // transactionを取得 const transaction = db.transaction(["myObjectStore"], "readwrite") // 追加するので"readwrite"を指定 // objectStoreを取得 const objectStore = transaction. objectStore("myObjectStore") // requestを取得 const req = objectStore.delete(1) req.onsuccess = e => { console.log("success: ", e) } // 削除完了 req.onerror = e => { console.error("error: ", e) } }
以上です。
indexedDBのラッパークラス作って、Promise返すメソッド作れば使いやすくなるかもって思ってます。有名なライブラリがあるけど、簡単なライブラリでも作ってみようかな....