indexedDB 資料庫主鍵

admin發表於2019-07-15

如果將一個indexedDB資料庫比作地球,那麼其中的每一個物件倉庫就是一個國家。

物件倉庫中的一條資料就是一個國家的公民,而公民又有一個唯一標識其身份的標識。

indexedDB資料庫物件倉庫中的主鍵則扮演著資料唯一身份標識的身份。

首先看一段程式碼例項:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<script>
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', { keyPath: 'email' });
  }
}

request.onsuccess = (ev) => {
  let db = ev.target.result;
  let transaction = db.transaction(['website'], 'readwrite');

  transaction.oncomplete = function (event) {
    console.log('事務完成');
  };
  transaction.onerror = function (event) {
    console.log('事務錯誤資訊: ' + transaction.error);
  };

  let objectStore = transaction.objectStore('website');
  let objectStoreRequest = objectStore.add({webName:"百度",age:15,email:"baidu@163.com"});

  objectStoreRequest.onsuccess = function (event) {
    console.log('資料新增成功');
  };
}
</script>
</head>
<body>
  <p>物件倉庫的主鍵為email</p>
</body>
</html>

通過上面程式碼建立或者開啟名為"antzone"的資料庫,進而建立物件倉庫與新增資料。

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

a:3:{s:3:\"pic\";s:43:\"portal/201907/15/124534t4kir57e44iia74u.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

對於主鍵分析如下:

(1).通過createObjectStore()方法第二個物件引數keyPath屬性規定主鍵。

(2).keyPath由key與path的組成,顧名思義,它用來規定鍵的路徑。

(3).keyPath的屬性值是新增資料的一個屬性,也就是說鍵的路徑指向某一個物件屬性。

(4).主鍵必須是唯一的,否則會報錯。

關於createObjectStore()方法的基本用法可以參閱createObjectStore() 建立物件倉庫一章節。

主鍵也可以是自增長的,沒必要是新增資料的屬性,程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<script>
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});
  }
}
request.onsuccess = (ev) => {
  let db = ev.target.result;
  let transaction = db.transaction(['website'], 'readwrite');

  transaction.oncomplete = function (event) {
    console.log('事務完成');
  };
  transaction.onerror = function (event) {
    console.log('事務錯誤資訊: ' + transaction.error);
  };

  let objectStore = transaction.objectStore('website');
  let objectStoreRequest = objectStore.add({webName:"百度",age:15,email:"baidu@163.com"});

  objectStoreRequest.onsuccess = function (event) {
    console.log('資料新增成功');
  };
}
</script>
</head>
<body>
  <p>物件倉庫的主鍵為email</p>
</body>
</html>

和前面程式碼唯一的區別是,修改了createObjectStore()方法的第二個引數。

[JavaScript] 純文字檢視 複製程式碼
let objectStore = db.createObjectStore('website', { keyPath: 'email' });
let objectStore = db.createObjectStore('website',{autoIncrement:true});

會以遞增1的方式自動為資料新增主鍵,autoIncrement的預設值是false。

通常情況下,keyPath與autoIncrement屬性一個存在就能滿足需求,當然兩個也可以同時存在:

[JavaScript] 純文字檢視 複製程式碼
let objectStore = db.createObjectStore('website',{
  keyPath: 'email',
  autoIncrement:true
}

如果新增資料中具有指定的屬性,則不自動生成鍵值,如果不存在,則自動生成遞增鍵值,填充keyPath指定屬性。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<script>
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',{
      keyPath: 'email',
      autoIncrement:true
    });
  }
}
request.onsuccess = (ev) => {
  let db = ev.target.result;
  let transaction = db.transaction(['website'], 'readwrite');

  transaction.oncomplete = function (event) {
    console.log('事務完成');
  };
  transaction.onerror = function (event) {
    console.log('事務錯誤資訊: ' + transaction.error);
  };

  let objectStore = transaction.objectStore('website');
  let objectStoreRequest = objectStore.add({webName:"百度",age:15});

  objectStoreRequest.onsuccess = function (event) {
    console.log('資料新增成功');
  };
}
</script>
</head>
<body>
  <p>物件倉庫的主鍵為email</p>
</body>
</html>

上述程式碼中,我們依次新增如下資料:

[JavaScript] 純文字檢視 複製程式碼
let objectStoreRequest = objectStore.add({webName:"螞蟻部落",age:5,email:"ant@163.com"});
let objectStoreRequest = objectStore.add({webName:"百度",age:15});

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

a:3:{s:3:\"pic\";s:43:\"portal/201907/15/124716uwzfpmq1pg5wwpgg.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

執行結果證明了對於兩個屬性都規定的闡述。

createObjectStore()方法可以不指定第二個引數,此時在新增資料的時候,必須在add中指定。

看如下程式碼例項:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<script>
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');
  }
}
request.onsuccess = (ev) => {
  let db = ev.target.result;
  let transaction = db.transaction(['website'], 'readwrite');

  transaction.oncomplete = function (event) {
    console.log('事務完成');
  };
  transaction.onerror = function (event) {
    console.log('事務錯誤資訊: ' + transaction.error);
  };

  let objectStore = transaction.objectStore('website');
  let objectStoreRequest = objectStore.add({webName:"螞蟻部落",age:5,email:"ant@163.com"},"softwhy");

  objectStoreRequest.onsuccess = function (event) {
    console.log('資料新增成功');
  };
}
</script>
</head>
<body>
  <p>物件倉庫的主鍵為"softwhy"</p>
</body>
</html>

add()方法第二個引數用於規定主鍵值,程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201907/15/124817pblgxgdepl0afm88.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

上面演示的都是儲存物件,物件倉庫也可以儲存其他資料型別,程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<script>
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});
  }
}
request.onsuccess = (ev) => {
  let db = ev.target.result;
  let transaction = db.transaction(['website'], 'readwrite');

  transaction.oncomplete = function (event) {
    console.log('事務完成');
  };
  transaction.onerror = function (event) {
    console.log('事務錯誤資訊: ' + transaction.error);
  };

  let objectStore = transaction.objectStore('website');
  let objectStoreRequest = objectStore.add("螞蟻部落");

  objectStoreRequest.onsuccess = function (event) {
    console.log('資料新增成功');
  };
}
</script>
</head>
<body>
  <p>為物件倉庫新增字串</p>
</body>
</html>

上述程式碼為物件倉庫新增了一個字串"螞蟻部落"。

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

a:3:{s:3:\"pic\";s:43:\"portal/201907/15/124931zbsscfw6q6n5593c.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

主鍵採用自增長方式,估計很多朋友會認為,由於新增的是值型別,就無法設定keyPath。

事實這是錯誤的,字串可以臨時包裝成物件,所以可以設定字串所具有的屬性,比如length作為主鍵。

與主鍵比較類似的是索引,具體可以參閱indexedDB資料庫索引一章節。

相關文章