
IndexedDBとは
IndexedDBは、ブラウザ内で利用可能なキーバリューストア型の非同期データベースです。
JavaScriptで大容量のデータを保存・管理でき、リッチなWebアプリケーションを構築する際に使用されます。
Web Storage API (sessionStorage or localStorage) は各ブラウザ対応を考慮した場合、最大5MBしか保存できませんが、IndexedDBなら1GBは保存できるので、データ量が多い場合は必然的にIndexedDBを使用します。
IndexedDBの使い方
最初にアクセスするデータベースの名前を指定して、データベース内の「オブジェクトストア」の名前を指定します。
次に指定した名前のデータベースに接続するためのリクエストを作成します。
request.onsuccessでデータベース名などが取得できていれば接続成功です。
const DB_NAME = 'UserDatabase'
const STORE_NAME = 'users'
const request = indexedDB.open(DB_NAME)
request.onsuccess = (event) => {
const db = event.target.result
console.log(db.name)
// UserDatabase
}
データベースを取得および追加したいコードは以下のようになります。
初回のみrequest.onupgradeneededでオブジェクトストアを作成します。
db.transaction() でデータベース内で操作を行うためのトランザクションを作成して、transaction.objectStore()でトランザクション内で操作する対象のオブジェクトストア(データが格納されている場所)を取得します。(今回の例ではusers)
あとはstore.get() で取得、store.add()で追加ができます。
今回のサンプルには追加していませんが、store.put() で更新、store.delete() で削除ができます。
詳細はMdNのIDBObjectStoreのインスタンスメソッドを参照してください。
const DB_NAME = 'UserDatabase'
const STORE_NAME = 'users'
const request = indexedDB.open(DB_NAME)
request.onsuccess = (event) => {
const db = event.target.result
const transaction = db.transaction(STORE_NAME, 'readonly')
const store = transaction.objectStore(STORE_NAME)
const countRequest = store.count()
countRequest.onsuccess = () => {
const userName = document.getElementById('userName')
const addUserBtn = document.getElementById('addUserBtn')
const userId = document.getElementById('userId')
const userIdBtn = document.getElementById('userIdBtn')
const result = document.getElementById('result')
let id = countRequest.result
addUserBtn.addEventListener('click', () => {
if (!userName.value) return
addUser(db, { id: ++id, name: userName.value })
userName.value = ''
})
userIdBtn.addEventListener('click', () => {
if (!userId.value) return
getUser(db, parseInt(userId.value))
})
}
}
request.onupgradeneeded = (event) => {
const db = event.target.result
if (!db.objectStoreNames.contains(STORE_NAME)) {
const objectStore = db.createObjectStore(STORE_NAME, { keyPath: 'id' })
objectStore.createIndex('name', 'name', { unique: false })
objectStore.createIndex('age', 'age', { unique: false })
console.log('オブジェクトストアが作成されました')
}
}
function addUser(db, user) {
const transaction = db.transaction(STORE_NAME, 'readwrite')
const store = transaction.objectStore(STORE_NAME)
const getRequest = store.get(user.id)
getRequest.onsuccess = () => {
if (getRequest.result) {
console.log('同じIDのユーザーがすでに存在します:', getRequest.result)
} else {
const addRequest = store.add(user)
addRequest.onsuccess = () => {
console.log('ユーザーが追加されました:', user)
}
}
}
}
function getUser(db, id) {
const transaction = db.transaction(STORE_NAME, 'readonly')
const store = transaction.objectStore(STORE_NAME)
const request = store.get(id)
const result = document.getElementById('result')
request.onsuccess = () => {
result.textContent = request.result?.name ?? `id: ${id} のユーザーは存在しません`
}
}
IndexedDBのget(), add(), count()のサンプル