indexedDB 修改索引

admin發表於2019-07-17

關於如何建立索引可以參閱IDBObjectStore.createIndex() 索引一章節。

本章節通過程式碼例項介紹一下indexedDB資料庫如何修改物件倉庫的索引。

一.周邊知識:

物件倉庫用於儲存資料,可以給物件倉庫設定名稱、主鍵或者索引等資訊。

它的名稱和主鍵一旦設定,在後期是無法被修改的,但是我們可以修改它的索引資訊。

二.修改索引:

當然我們可以確定索引是可以後期修改的,首先看一段程式碼例項:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<script>
let students=[
  { 
    id:1001, 
    name:"張三", 
    age:21,
    sex:"男"
  },{ 
    id:1002, 
    name:"李四", 
    age:20,
    sex:"女"
  },{ 
    id:1003, 
    name:"王五", 
    age:19,
    sex:"女"
  }
];
let request = window.indexedDB.open("antzone", 1);
request.onupgradeneeded = (ev) => {
  let db = ev.target.result;
  if (!db.objectStoreNames.contains('website')) {
    let objectStore = db.createObjectStore('website',{autoIncrement:true});
    objectStore.createIndex("xingbie","sex",{ unique: false });
    objectStore.createIndex("xingming","name",{ unique: true });
  }
}
request.onsuccess = (ev) => {
  let db = ev.target.result;
  let transaction = db.transaction(['website'], 'readwrite');
  let objectStore = transaction.objectStore('website');
  for(let i=0;i<students.length;i++){
    objectStore.add(students[i]);
  }
}
</script>
</head>
<body>
  <p>為物件建立索引,並新增資料</p>
</body>
</html>

上述程式碼建立了一個名為"antzone"的資料庫,新增物件倉庫的同時設定其主鍵與索引。

最後通過迴圈方式新增了一些關於學生的資訊,程式碼執行效果截圖如下:

aid[3387]

以上面的例子為基礎對已有的索引進行修改,程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<script>
let students=[
  { 
    id:1001, 
    name:"張三", 
    age:21,
    sex:"男"
  },{ 
    id:1002, 
    name:"李四", 
    age:20,
    sex:"女"
  },{ 
    id:1003, 
    name:"王五", 
    age:19,
    sex:"女"
  }
];
let request = window.indexedDB.open("antzone", 2);
request.onupgradeneeded = (ev) => {
  let db = ev.target.result;
  if (!db.objectStoreNames.contains('website')) {
    let objectStore = db.createObjectStore('website',{autoIncrement:true});
    objectStore.createIndex("xingbie","sex",{ unique: false });
    objectStore.createIndex("xingming","name",{ unique: true });
  }

  let objectStore = ev.target.transaction.objectStore('website')
  let indexNames = objectStore.indexNames
  if (indexNames.contains('xingbie')) {
    objectStore.deleteIndex('xingbie')
  }
  objectStore.createIndex('nannv', 'sex', {unique: false})
}
request.onsuccess = (ev) => {
  let db = ev.target.result;
  let transaction = db.transaction(['website'], 'readwrite');
  let objectStore = transaction.objectStore('website');
  for(let i=0;i<students.length;i++){
    objectStore.add(students[i]);
  }
}
</script>
</head>
<body>
  <p>修改物件倉庫的索引</p>
</body>
</html>

程式碼執行效果截圖如下:

aid[3388]

可以看到,通過上述程式碼,將索引xingbie修改為nannv,方式比較簡單首先刪除然後再重建。

程式碼分析如下:

(1).索引的刪除與建立需要在upgradeneeded事件處理函式中進行。

(2).所以為了觸發upgradeneeded事件,將資料庫的版本由1修改為2。

(3).對於資料的讀寫、物件倉庫的刪除建立或者索引的刪除新增都會在一個事務中進行。

(4).此時可能有朋友會問,為什麼在第一段建立物件倉庫的程式碼中,並沒有事務的應用。

(5).事實上這只是一種假象,upgradeneeded事件觸發會自動建立一個模式為"versionchange"的事務。

(6).非"讀操作"事務不能衝突,所以不能在upgradeneeded中再新建一個事務,要使用當前執行的事務。

核心程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
let objectStore = ev.target.transaction.objectStore('website')
  let indexNames = objectStore.indexNames
  if (indexNames.contains('nannv')) {
    objectStore.deleteIndex('nannv')
  }
  objectStore.createIndex('xingbie', 'sex', {unique: false})

上面是核心程式碼,分析如下:

(1).ev.target.transaction獲取當前正在執行的事務。

(2).ev.target.transaction.objectStore('website')獲取指定名稱物件倉庫。

(3).objectStore.indexNames獲取物件倉庫中所有索引的名稱。

(4).然後再判斷是否已經存在對應的索引,如果存在著刪除,然後再建立給定名稱的索引。

相關文章