indexedDB 使用小結

由於項目用到了indexedDB存一些數據,就補了一下這方便的資料。踩一下「坑」。若是你還不瞭解什麼是indexedDB,能夠先看看這三篇文章入個門。javascript


1.不能動態添加表

indexedDB 中 createObjectStore(相似新增表)和deleteObjectStore(相似刪除表)方法只有在onupgradeneeded 中調用。而表有時候又是動態的,因此作了一下的封裝。html

/**
 * 根據數據庫中是否包含表名會自動升級數據庫
 * @param dbName         數據庫名稱
 * @param storeNames     表名-arrays
 * @param version        數據庫版本號
 */
export async function openDatabase(dbName, storeNames = [], version = undefined) {
    return new Promise((resolve, reject) => {
        const request = window.indexedDB.open(dbName, version)
        request.onsuccess = (event) => {
            const db = event.target.result

            let isNeedUpdate = false
            for (let i = 0; i < storeNames.length; i++) {
                if (!db.objectStoreNames.contains(storeNames[i])) {
                    isNeedUpdate = true
                    break
                }
            }

            function callback(db) {
                if (db) {
                    resolve(db)
                } else {
                    reject(`can't open ${dbName}`)
                }
            }

            if (isNeedUpdate) {
                const version = db.version + 1
                db.close()
                openDatabase(dbName, storeNames, version).then((db) => {
                    callback(db)
                })
            } else {
                callback(db)
            }
        }
        request.onerror = (e) => {
            reject(e)
        }
        request.onblocked = () => {
            reject(`${dbName} is blocked.`)
        }
        request.onupgradeneeded = (event) => {
            const db = event.target.result
            for (const storeName of storeNames) {
                if (!db.objectStoreNames.contains(storeName)) {
                    db.createObjectStore(storeName, {
                        keyPath: "key"
                        // autoIncrement: true
                    })
                }
            }
        }
    })
}

2.主鍵不能更新

個人需求是把一個文件列表存入數據庫。以前是把文件完整路徑做爲了主鍵。可是當遇到修改文件名或移動文件,文件路徑就會發生變動的這種狀況,就須要更新主鍵。然而並無找到這樣的方法。前端

IDBObjectStore.put(item, key)方法用於更新某個主鍵對應的數據記錄,若是對應的鍵值不存在,則插入一條新的記錄。該方法返回一個 IDBRequest 對象。
該方法接受兩個參數,第一個參數爲新數據,第二個參數爲主鍵,該參數可選,且只在自動遞增時纔有必要提供,由於那時主鍵不包含在數據值裏面。

因此,我能想到的方案html5

  1. 先刪除記錄,再添加。不過就不能算是更新了。
  2. 建立表時,不要使用數據字段爲主鍵,除非你肯定之後不會改。使用自增主鍵。還有修改對應的獲取數據的方法。 該方法放棄,若是使用自增字段作主鍵,而後經過索引字段能夠獲取數據。可是卻拿得不到對應的主鍵(經過IDBCursor能夠獲取,可是感受方法很笨)。拿不到主鍵仍是更新不了數據...卒
相關文章
相關標籤/搜索