浏览器本地mysql_IndexedDB:浏览器里的本地数据库
IndexedDB 是什么
在現(xiàn)代瀏覽器的本地存儲方案中,indexedDB 是一項重要的能力組成, 它是可以在瀏覽器端使用的本地數(shù)據(jù)庫,可以存儲大量數(shù)據(jù),提供接口來查詢,還可以建立索引,這些都是其他存儲方案 Cookie 或者 LocalStorage 無法提供的能力。單從數(shù)據(jù)庫類型來看,IndexedDB 是一個非關(guān)系型數(shù)據(jù)庫(不支持通過 SQL 語句操作)。
IndexedDB 的主要概念
IndexedDB 是一個比較復(fù)雜的 API 組合,學(xué)習(xí)它的過程就相當(dāng)于學(xué)習(xí)它的各個對象 API 接口,包括以下這些( IDB 指當(dāng)前操作的數(shù)據(jù)庫實例 ):
數(shù)據(jù)庫:IDBDatabase 對象
倉庫對象: IDBObjectStore 對象
索引:IDBIndex 對象
事務(wù):IDBTransaction 對象
操作請求:IDBRequest 對象
指針:IDBCursor 對象
主鍵:IDBKeyRange 對象
在這些 API 中包含一些主要概念:
數(shù)據(jù)庫:數(shù)據(jù)庫是所有相關(guān)數(shù)據(jù)的基本容器。在同源策略( 協(xié)議 + 域名 + 端口 )的前提下,每個域名下可以新建任意多的數(shù)據(jù)庫。IndexedDB 中有版本概念,這就規(guī)定了同一時刻下只有一個版本的數(shù)據(jù)庫存在。
對象倉庫:對象倉庫 ObjectStore 在 IndexedDB 中對應(yīng)的是 MYSQL 中的表 Table。
數(shù)據(jù):對象倉庫中記錄的是若干條數(shù)據(jù),數(shù)據(jù)只有主鍵和數(shù)據(jù)體兩個部分,主鍵不能重復(fù),可以為自增的整數(shù)編號或者數(shù)據(jù)中指定的一個屬性。數(shù)據(jù)體可以是任意數(shù)據(jù)類型,不限于對象。
索引:為不同的屬性建立索引可以加快數(shù)據(jù)的檢索。
事務(wù):數(shù)據(jù)的 CURD (增刪查改) 都要通過事務(wù)來完成。
通過簡單的對比圖來理解 IndexedDB 的概念:
快速起步 IndexedDB
在介紹了 IndexedDB 的主要概念之后,可以通過一個簡單實用的 CURD 例子來學(xué)習(xí)在日常開發(fā)中我們是怎么使用 IndexedDB 的,各個 API 細(xì)節(jié)日后可以慢慢深入學(xué)習(xí)。
必不可少的瀏覽器支持檢查:
if(!('indexedDB' in window)){
console.log('當(dāng)前瀏覽器支持 IndexedDB');
return;
} else {
console.log('您的瀏覽器不支持 IndexedDB')
// todo 建議升級或者更換其他瀏覽器
}
連接數(shù)據(jù)庫
// 數(shù)據(jù)庫實例
let db;
// 數(shù)據(jù)庫打開操作,第一個參數(shù)是數(shù)據(jù)庫名稱, 第二個參數(shù)是數(shù)據(jù)庫版本
let DBRequestLink = window.indexedDB.open('dataBaseName', 1)
DBRequestLink.onsuccess = function(event) {
// 獲取數(shù)據(jù)庫實例
db = DBRequestLink.result;
// 其他操作
};
// 這個監(jiān)聽回調(diào)觸發(fā)于數(shù)據(jù)庫首次新建、open數(shù)據(jù)庫時傳遞新版本(只能比之前傳遞的版本高)
DBRequestLink.onupgradeneeded = function(event) {};
創(chuàng)建數(shù)據(jù)庫的主鍵和字段
DBOpenRequest.onupgradeneeded = function(event) {
let db = event.target.result;
// 創(chuàng)建一個數(shù)據(jù)庫存儲對象,并指定主鍵
let objectStore = db.createObjectStore('person', {
keyPath: 'id',
autoIncrement: true
});
/* 定義存儲對象的數(shù)據(jù)項
* 第一個參數(shù)是創(chuàng)建的索引名稱,可以為空
* 第二個參數(shù)是索引使用的關(guān)鍵名稱,可以為空
* 第三個參數(shù)是可選配置參數(shù),可以不傳,常用參數(shù)之一就是 unique ,表示該字段是否唯一,不能重復(fù)
*/
objectStore.createIndex('id', 'id', {
unique: true
});
objectStore.createIndex('name', 'name');
objectStore.createIndex('age', 'age');
objectStore.createIndex('sex', 'sex');
};
在上述操作中,我們先定義了上文中提到的 IDBObjectStore 對象,并指定主鍵為 id ,隨后又通過 createIndex 來創(chuàng)建字段。值得注意的是雖然創(chuàng)建了四個字段,但在 IndexedDb 中數(shù)據(jù)還是分為主鍵 id 和數(shù)據(jù)主體兩個部分,并不會像 MYSQL 中在 Table 中呈現(xiàn)四列。
向數(shù)據(jù)庫中添加數(shù)據(jù)
// 這里的 db 就是第二步中的 db 對象,
// transaction api 的第一個參數(shù)是數(shù)據(jù)庫名稱,第二個參數(shù)是操作類型
let newItem = {
id: 1,
name: '徐嘻嘻',
age: 3,
sex: 'female'
};
let transaction = db.transaction('dataBaseName', "readwrite");
// 找到對應(yīng)的存儲對象
let objectStore = transaction.objectStore('person');
// 添加到數(shù)據(jù)對象中, 傳入JavaScript對象
objectStore.add(newItem);
新建操作是在新建了一個 事務(wù)( IDBTransaction 對象)的前提下完成的,傳入的數(shù)據(jù)不需要做任何轉(zhuǎn)換,可以無縫傳入?JavaScript?對象。
修改數(shù)據(jù)庫中的數(shù)據(jù)
// 這里的 db 就是第二步中的 db 對象,
// 新建事務(wù)
let transaction = db.transaction('dataBaseName', "readwrite");
// 新數(shù)據(jù)主體
let newRecord = {
id: 1,
name: '徐嘎嘎',
age: 5,
sex: 'male'
};
// 打開已經(jīng)存儲的數(shù)據(jù)對象
let objectStore = transaction.objectStore('person');
// 獲取存儲的對應(yīng)鍵的存儲對象, 傳入主鍵 id,值為 1
let objectStoreRequest = objectStore.get(1);
// 獲取成功后替換當(dāng)前數(shù)據(jù)
objectStoreRequest.onsuccess = function(event) {
// 數(shù)據(jù)
var record = objectStoreRequest.result;
// 遍歷替換
for (let key in newRecord) {
if (typeof record[key] != 'undefined' || key !== 'id') {
record[key] = newRecord[key];
}
}
// 更新數(shù)據(jù)庫存儲數(shù)據(jù)
objectStore.put(record);
};
基本思路是創(chuàng)建一個事務(wù),先找到想要修改的數(shù)據(jù)主體,然后在更新該數(shù)據(jù)主體內(nèi)容。 事務(wù)創(chuàng)建邏輯相同,并在創(chuàng)建之后調(diào)用事務(wù)的 get 和 put 操作。
刪除數(shù)據(jù)庫中的數(shù)據(jù)
// 這里的 db 就是第二步中的 db 對象,
// 新建事務(wù)
let transaction = db.transaction('dataBaseName', "readwrite");
// 打開已經(jīng)存儲的數(shù)據(jù)對象
let objectStore = transaction.objectStore('person');
// 獲取存儲的對應(yīng)鍵的存儲對象, 傳入主鍵 id,值為 1
let objectStoreRequest = objectStore.delete(1);
調(diào)用 delete 接口,傳入指定的 id 即可。
佛山vi設(shè)計https://www.houdianzi.com/fsvi/ 豌豆資源搜索大全https://55wd.com
可以提效的類庫
? 從上面的例子中可以看出,每一次操作需要至少三行代碼才能完成,而且需要一直維護(hù) DB 的對象引用,避免它被回收,這樣子開發(fā)代碼膨脹得太厲害,所以我們在業(yè)務(wù)中引入其他類庫來減少代碼量
LocalForage
可以指定數(shù)據(jù)存儲方案,默認(rèn)依次為 IndexedDB、WebSQL、LocalStorage,意味著當(dāng)前 IndexedDB 失效可以有兜底措施。
API 簡化為 CRUD ( getItem、removeItem、setItem、clear )
庫大小為 475b
Pouchdb
API 簡化為 put、get、remove,基于 promise 來檢查回收錯誤
有較好的錯誤日志機(jī)制, 如失敗,沖突等等,方便調(diào)試
庫大小為 255b
這兩個類庫比較符合我們的開發(fā)要求,我們當(dāng)前使用的是 LocalForage。
結(jié)束語
在業(yè)務(wù)開發(fā)中,我們都會碰到或多或少的本地存儲需求,本文介紹了其中一種存儲方案 IndexedDB 的簡單實踐。就我們的應(yīng)用場景來看,IndexedDB 的適用面還是很廣的。考慮到 IE10 也可以支持,把它實踐在實際項目中應(yīng)該是沒有問題的。
總結(jié)
以上是生活随笔為你收集整理的浏览器本地mysql_IndexedDB:浏览器里的本地数据库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql show full proc
- 下一篇: mysql sycho_Java面试题