IndexedDB學習筆記

DrMoon發表於2018-03-19

連線資料庫

const request = IndexedDB.open('dbName', version)
複製程式碼

連線資料庫,dbName是資料庫名,version是資料庫版本號,版本號必須為整數。返回的是一個IDBOpenDBRquest物件,代表一個請求連線資料庫的請求物件,可以對物件的onsuccess和onerror事件監聽來定義連線成功或失敗後執行的方法。

const request = IndexedDB.open('test', 1)
request.onsuccess = (e) => {
  console.log('連線資料庫成功!')
}
複製程式碼

連線資料庫成功後執行的事件。

const request = IndexedDB.open('test', 1)
request.onerror = (e) => {
  console.log('連線資料庫失敗!')
}
複製程式碼

連線資料庫失敗後執行的事件。

const request = IndexedDB.open('test', 2)
request.onupgradeneeded = (e) => {
  console.log('資料庫當前版本為:' + e.newVersion)
}
複製程式碼

資料庫更新後執行的事件。在對indexedDB的物件倉庫本身進行操作的時候,需要在資料庫版本號更新時才會建立的ongradeneeded事件中進行操作。

建立物件倉庫

const request = IndexedDB.open('test', 3)
request.onupgradeneeded = (e) => {
  const db = e.target.result
  const store = db.createObjectStore('User', {
    keyPath: 'userId',
    autoIncrement: false,
  })
  const idx = store.createIndex('userNameIndex', 'userName', {
    unique: false
  })
  console.log('建立物件倉庫成功!')
}
複製程式碼

createObjectStore方法建立一個物件倉庫,類似於關係型資料庫的一個表,該方法接收兩個引數:

  • 第一個引數是該物件倉庫的名字;
  • 第二個引數是一個物件,其中keyPath是該物件倉庫的主鍵,autoIncrement為是否要求該主鍵自增,false即為不允許主鍵自增,需要建立資料時自己傳入。

createIndex方法接收三個引數:

  • 第一個引數為索引名;
  • 第二個為資料物件的某個屬性,這裡使用userName屬性來建立索引;
  • 第三個引數為可選引數,值為一個物件。物件中的unique屬性為true,代表索引值不可以相同,即兩條資料的userName不可以相同,為false表示可以相同。

操作物件倉庫中的資料

操作物件倉庫中資料的方法:

  • add():新增資料的方法,接受要新增的物件資料作為引數若引數物件的主鍵在物件倉庫中已存在,會新增失敗。

  • put():新增或更新資料的方法,接受要新增的物件資料作為引數,若引數物件的主鍵在物件倉庫中已存在,會變為更新對應的資料物件。

  • get():獲取資料的方法,接受要查詢資料的主鍵作為引數。

  • delete():刪除資料的方法,接受要查詢資料的主鍵作為引數。

    const request = indexedDB.open('test', 3) request.onsuccess = (e) => { console.log('連線資料庫成功!') const db = e.target.result const tx = db.transaction('User','readwrite') const store = tx.objectStore('User') const value = { 'userId': 1, 'userName': 'Luke', 'age': 18 } const req1 = store.put(value) const req2 = store.get(1) req2.onsuccess = function () { console.log(this.result) } const req3 = store.delete(1) req3.onsuccess = function () => { console.log('資料刪除成功!') } }

transaction方法接收兩個引數:

  • 第一個引數是字串或陣列,是字串時該引數是一個物件倉庫的名字,是陣列時該引數是由物件倉庫名組成的陣列,transaction可以對引數中任何一個物件倉庫進行操作;
  • 第二個引數為物件倉庫的事務模式,傳入readonly表示只能對物件倉庫進行讀操作,無法進行寫操作。傳入readwrite時表示可以進行讀寫操作。

使用索引值查詢資料

const index = store.index('userNameIndex')
index.get('DrMoon').onsuccess = function () {
  console.log(this.result)
}
複製程式碼

使用建立物件倉庫時定義的索引來獲取資料物件:

  • 首先要使用index方法定義一個索引查詢物件,該方法接收一個索引項作為引數,這個索引項需是之前建立物件索引時採用的索引名,即createIndex方法的第一個引數;
  • 然後就可以使用剛才定義的索引查詢物件的get方法來查詢資料物件。

使用遊標來查詢資料

使用get方法獲取資料需要知道資料的主鍵值,且只能獲取單個主鍵值的資料,若想查詢範圍數值內的主鍵值的資料,可以使用物件倉庫的openCursor方法,該方法接收兩個引數:

  • 第一個引數定義要查詢的目標資料物件的主鍵值範圍,首先需要使用IDBKeyRange物件的方法來定義查詢的主鍵值範圍:

    • IDBKeyRange.bound(1, 10, false, false)bound方法可以定義查詢的主鍵值範圍,該方法接收四個引數:

      • 第一個引數為要查詢的主鍵值範圍的最小值;
      • 第二個引數為要查詢的主鍵值範圍的最大值;
      • 第三個參數列示範圍是否包含範圍的最小值,即要查詢的主鍵值範圍是否包含第一個引數,為true表示不包含,false表示包含,預設為false
      • 第四個參數列示範圍是否包含範圍的最大值,即要查詢的主鍵值範圍是否包含第二個引數,為true表示不包含,false表示包含,預設為false
    • IDBKeyRange.only(1)only方法可以定義只包含單個主鍵值的範圍,該方法接收一個引數:

      • 該引數即為要查詢的主鍵值
    • IDBKeyRange.lowerBound(1, false)lowerBound方法可以定義小於某個主鍵值的主鍵值範圍,該方法接收兩個引數:

      • 第一個引數定義主鍵值的最小值,要查詢的主鍵值都要大於這個主鍵值;
      • 第二個引數定義主鍵值範圍是否包含範圍的最小值,即要查詢的主鍵值範圍是否包含第一個引數,為true表示不包含,false表示包含,預設為false
    • IDBKeyRange.upperBound(10, false)upperBound方法可以定義小於某個主鍵值的主鍵值範圍,該方法接收兩個引數:

      • 第一個引數定義主鍵值的最大值,要查詢的主鍵值都要小於這個主鍵值;
      • 第二個引數定義主鍵值範圍是否包含範圍的最大值,即要查詢的主鍵值範圍是否包含第一個引數,為true表示不包含,false表示包含,預設為false
  • 第二個引數時查詢資料物件時遊標的讀取方向:

    • next:遊標讀取的資料按主鍵值升序排列,主鍵值相等的資料都被讀取。引數預設為該值。

    • **nextunique **:遊標讀取的資料按主鍵值升序排列,主鍵值相等的資料只讀取第一條。

    • prev:遊標讀取的資料按主鍵值降序排列,主鍵值相等的資料都被讀取。

    • prevunique:遊標讀取的資料按主鍵值降序排列,主鍵值相等的資料只讀取第一條。

      const range = IDBKeyRange.bound(1, 10) let data = [] let req = store.openCursor(range, 'next') req.onsuccess = function (e) { let cursor = this.result if (cursor) { data.push(cursor.value) cursor.continue() } else { console.log(data) } }

openCursor方法根據接收的引數對物件倉庫進行查詢,每查詢到一條資料回將該條資料的結果推入data陣列,然後使用continue方法進行下一次查詢,直到查詢結束後將data陣列列印出來。這樣便完成了對要求的主鍵值範圍內的資料物件的查詢。

openCursor方法接收到的第一個引數為空或者null,該方法會將物件倉庫中的所有資料查詢出來。