前端indexDB數(shù)據(jù)庫(kù)的使用

一、indexDB中的對(duì)象

數(shù)據(jù)庫(kù):IDBDatabase 對(duì)象

對(duì)象倉(cāng)庫(kù):IDBObjectStore 對(duì)象

索引: IDBIndex 對(duì)象

事務(wù): IDBTransaction 對(duì)象

操作請(qǐng)求:IDBRequest 對(duì)象

指針: IDBCursor 對(duì)象

主鍵集合:IDBKeyRange 對(duì)象

二、操作數(shù)據(jù)庫(kù)

  1. 打開數(shù)據(jù)庫(kù)

如果存在就打開,不存在就創(chuàng)建一個(gè)indexDB數(shù)據(jù)庫(kù)

window.indexedDB.open(databaseName, version)  // 數(shù)據(jù)庫(kù)名稱,版本號(hào)
  1. 創(chuàng)建表(創(chuàng)建對(duì)象倉(cāng)庫(kù))

要在onupgradeneeded中創(chuàng)建表和索引,onupgradeneeded函數(shù)只有在數(shù)據(jù)庫(kù)創(chuàng)建和數(shù)據(jù)庫(kù)版本升級(jí)才會(huì)觸發(fā)

const req = window.indexedDB.open('utm_db_product', 1) // 打開/創(chuàng)建數(shù)據(jù)庫(kù)
req.onsuccess = function (event) { // 監(jiān)聽數(shù)據(jù)庫(kù)創(chuàng)建成功事件
    let db = event.target.result // 數(shù)據(jù)庫(kù)對(duì)象
    console.log('數(shù)據(jù)庫(kù)打開成功')
}
req.onerror = function (error) {
    console.log('數(shù)據(jù)庫(kù)打開報(bào)錯(cuò)')
}
req.onupgradeneeded = function (event) {
    // 數(shù)據(jù)庫(kù)創(chuàng)建或升級(jí)的時(shí)候會(huì)觸發(fā)
    db = event.target.result
    let storeName = 'product' // 表名
    if (!db.objectStoreNames.contains(storeName)) { // 判斷表是否存在
        let objectStore = db.createObjectStore(storeName, { keyPath: 'pro_id',autoIncrement: true })
    }
}

db.createObjectStore可以創(chuàng)建一張表,param1 表名,param2 配置對(duì)象,keyPath為主鍵,autoIncrement是自動(dòng)生成一個(gè)自增主鍵,一般keyPath和autoIncrement只需要一個(gè),兩個(gè)都存在的話,自動(dòng)生成一個(gè)自增主鍵,并且keyPath設(shè)置的字段必須要存在

  1. 創(chuàng)建索引

索引可以用來(lái)搜索,主鍵是默認(rèn)的索引

req.onupgradeneeded = function (event) {
    // 數(shù)據(jù)庫(kù)創(chuàng)建或升級(jí)的時(shí)候會(huì)觸發(fā)
    db = event.target.result
    let storeName = 'product' // 表名
    if (!db.objectStoreNames.contains(storeName)) { // 判斷表是否存在
        let objectStore = db.createObjectStore(storeName, { keyPath: 'pro_id',autoIncrement: true })
        objectStore.createIndex('name', 'name', { unique: false }) // 創(chuàng)建索引 可以讓你搜索任意字段
    }
}

給對(duì)象倉(cāng)庫(kù)(數(shù)據(jù)庫(kù)表)創(chuàng)建索引,需要使用對(duì)象倉(cāng)庫(kù)的createIndex()函數(shù),param1 索引名稱,param2 索引所在屬性,param3 配置對(duì)象 配置該屬性是否是唯一的

param3 配置對(duì)象可配置屬性

  • unique 唯一

  • multiEntry 對(duì)于有多個(gè)值的主鍵數(shù)組,每個(gè)值將在索引里面新建一個(gè)條目,否則主鍵數(shù)組對(duì)應(yīng)一個(gè)條目

  1. 使用promise封裝 open方法
/**
 * 打開/創(chuàng)建數(shù)據(jù)庫(kù)
 * @param {object} dbName 數(shù)據(jù)庫(kù)的名字
 * @param {string} storeName 倉(cāng)庫(kù)名稱
 * @param {string} version 數(shù)據(jù)庫(kù)的版本
 * @param {Array} index 索引數(shù)組
 * @return {object} 該函數(shù)會(huì)返回一個(gè)數(shù)據(jù)庫(kù)實(shí)例
*/
const openDB = function (dbName, version, storeName, keyPath, index) {
    return new Promise((resolve, reject) => {
        //  兼容瀏覽器
        let indexedDB =
            window.indexedDB ||
            window.mozIndexedDB ||
            window.webkitIndexedDB ||
            window.msIndexedDB
        let db = null
        const req = indexedDB.open(dbName, version)
        // 操作成功
        req.success = function () {
            db = event.target.result // 數(shù)據(jù)庫(kù)對(duì)象
            resolve({code: 0, success: true, data: db, msg: '數(shù)據(jù)庫(kù)打開成功!'})
        }
        // 操作失敗
        request.onerror = function (event) {
            resolve({code: -1, success: false, data: null, msg: '數(shù)據(jù)庫(kù)打開失敗!'})
        }
        // 創(chuàng)建表和索引
        request.onupgradeneeded = function (event) {
            // 數(shù)據(jù)庫(kù)創(chuàng)建或升級(jí)的時(shí)候會(huì)觸發(fā)
            db = event.target.result // 數(shù)據(jù)庫(kù)對(duì)象
            let objectStore
            if (!db.objectStoreNames.contains(storeName)) {
                objectStore = db.createObjectStore(storeName, { keyPath: keyPath || 'id',autoIncrement: true }) // 創(chuàng)建表
                index.forEach(item => {
                    objectStore.createIndex(item, item, { unique: false }) // 創(chuàng)建索引
                })
            }
        }
    })
}
  1. 添加數(shù)據(jù)

需要通過(guò)事務(wù)對(duì)象IDBTransaction 來(lái)獲取到對(duì)象倉(cāng)庫(kù)(表),然后通過(guò)對(duì)象倉(cāng)庫(kù)的add()方法向表中添加數(shù)據(jù)

// 1. 打開數(shù)據(jù)庫(kù)
const db = window.indexedDB.open('utm_db_product', 1)
// 2. 創(chuàng)建事務(wù)對(duì)象
const t = db.transaction(['product'], 'readwrite') // params1 表名, param2 讀寫模式
// 3. 拿到對(duì)象倉(cāng)庫(kù)
const objectStore = t.objectStore('product') // params 表名
// 4. 添加數(shù)據(jù)
const req = objectStore.add({pro_id: 123456, pro_name: '大白菜'}) // params 添加的數(shù)據(jù)
// 5. 操作成功
req.success = function (e) {}
// 6. 操作失敗
req.success = function (e) {}

// 注:1234 可使用點(diǎn)操作符連寫
const req =  window.indexedDB.open('utm_db_product', 1)
                           .transaction(['product'], 'readwrite')
                           .objectStore('product')
                           .add({pro_id: 123456, pro_name: '大白菜'})
  1. 使用promise封裝 add方法
/**
 * 新增數(shù)據(jù)
 * @param {object} db 數(shù)據(jù)庫(kù)實(shí)例
 * @param {string} storeName 倉(cāng)庫(kù)名稱
 * @param {string} data 數(shù)據(jù)
 **/
const addData = function (db, storeName, data) {
  return new Promise((resolve, reject) => {
    let req = db
        .transaction([storeName], 'readwrite')
        .objectStore(storeName) // 倉(cāng)庫(kù)對(duì)象
        .add(data)
      // 操作成功
    req.onsuccess = function (event) {
        console.log('數(shù)據(jù)寫入成功')
        resolve({code: 0, success: true, data: null, msg: '數(shù)據(jù)寫入成功!'})
    }
    // 操作失敗
    req.onerror = function (event) {
        console.log('數(shù)據(jù)寫入失敗')
        let data = {code: -1, success: false, data: null, msg: '數(shù)據(jù)寫入失敗!'}
        resolve(data)
    }
  })
}
  1. 修改數(shù)據(jù)

使用對(duì)象倉(cāng)庫(kù)的put方法,修改表中數(shù)據(jù)

objectStore.put({id: 1, pro_id: 123456, pro_name: '胡蘿卜'}) // param1 數(shù)據(jù) param2 主鍵,可選

該方法自動(dòng)更新了主鍵id為1的數(shù)據(jù)

  1. 使用promise封裝 put方法
/**
* 更新數(shù)據(jù)
* @param {object} db 數(shù)據(jù)庫(kù)實(shí)例
* @param {string} storeName 倉(cāng)庫(kù)名稱
* @param {object} data 數(shù)據(jù)
*/
const updateData = function (db, storeName, data) {
    return new Promise((resolve, reject) => {
        const req = db
                    .transaction([storeName], 'readwrite')
                    .objectStore(storeName)
                    .put(data)
        // 操作成功
        req.onsuccess = function (event) {
            console.log('數(shù)據(jù)更新成功')
            resolve({code: 0, success: true, data: null, msg: '數(shù)據(jù)更新成功!'})
        }
        // 操作失敗
        req.onerror = function (event) {
            console.log('數(shù)據(jù)更新失敗')
            let data = {code: -1, success: false, data: null, msg: '數(shù)據(jù)更新失敗!'}
            resolve(data)
        }
    })
}
  1. 刪除數(shù)據(jù)

使用對(duì)象倉(cāng)庫(kù)的delete方法,刪除表中數(shù)據(jù)

objectStore.delete(1) // param 主鍵的值

該方法會(huì)刪除主鍵為1的數(shù)據(jù)

  1. 獲取數(shù)據(jù)

使用對(duì)象倉(cāng)庫(kù)的get方法,獲取對(duì)應(yīng)主鍵的數(shù)據(jù)

objectStore.get(1) // param 主鍵的值

該方法會(huì)獲取主鍵為1的數(shù)據(jù)

  1. 使用指針對(duì)象遍歷所有數(shù)據(jù)

使用指針對(duì)象IDBCursor遍歷數(shù)據(jù)

objectStore.openCursor().onsuccess = function () {
   const cursor = e.target.result
   if (cursor) {
       console.log(cursor.key) // 當(dāng)前遍歷數(shù)據(jù)的主鍵
       console.log(cursor.value) // 當(dāng)前遍歷的數(shù)據(jù)
       cursor.continue() // 繼續(xù)下一個(gè)
   }
}

本文轉(zhuǎn)自辰漪博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容