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');
  objectStore.add({webName:"螞蟻部落",age:5,email:"ant@163.com"});
  objectStore.add({webName:"百度",age:15});
}
</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;}

程式碼分析如下:

(1).程式碼規定主鍵既可以是email,也可以是自增長數字。

(2).第一個物件直接量,具有email屬性,於是將ant@163.com設定為主鍵。

(3).第二個物件直接量,不具有email屬性,使用自增長數字作為主鍵,所以設定為1。

(4).注意的是,第二個物件直接量被新增了一個email屬性,其值是1。

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資料庫索引一章節。

相關文章