IndexedDB 是一个事务型数据库系统,具体IndexedDB是什么,IndexedDB特点信息请阅读HTML5 IndexedDB。


![]() | IndexedDB API 是强大的,但对于简单的情况可能看起来太复杂。如果你更喜欢一个简单的 API,请尝试 localForage、dexie.js、PouchDB、idb、idb-keyval、JsStore 或者 lovefield 之类的库,这些库使 IndexedDB 对开发者来说更加友好。 |
使用 IndexedDB 的第一步是打开叫"testDB"数据库,没有的话则新建。使用indexedDB.open()方法。
var request = window.indexedDB.open("testDB", version);version指定数据库版本,当你想要更改数据库格式(比如增加对象存储,非增加记录),必须指定更高版本,通过 versionchange 来更改
indexedDB.open()方法返回一个 IDBRequest 对象。这个对象通过三种事件error、success、upgradeneeded,处理打开数据库的操作结果。
当试图打开一个尚未被创建的数据库,或者如果指定的版本号,大于数据库的实际版本号,就会发生数据库升级事件upgradeneeded。这时通过事件对象的target.result属性,拿到数据库实例。
request.onupgradeneeded = function(event){
//upgradeneeded 事件
};error事件表示打开数据库失败。
request.onerror = function(event){
console.log("打开DB失败", event);
};success事件表示成功打开数据库。
request.onsuccess = function(event){
console.log("成功打开DB");
db = event.target.result;
};这时,通过request对象的result属性拿到数据库对象。
后续的操作主要在upgradeneeded事件的监听函数里面完成,因为这时版本从无到有,所以会触发这个事件。
request.onupgradeneeded = function(event){
console.log("Upgrading",event);
db = event.target.result;
var objectStore = db.createObjectStore("students", { keyPath : "rollNo"});
};主键(key)是默认建立索引的属性。比如,数据记录是{ id: 1, name: '张三' },那么id属性可以作为主键。主键也可以指定为下一层对象的属性,比如{ foo: { bar: 'baz' } }的foo.bar也可以指定为主键。
如果数据记录里面没有合适作为主键的属性,那么可以让 IndexedDB 自动生成主键(自增长)。
var objectStore = db.createObjectStore("students", { autoIncrement: true });新增数据指的是向对象仓库写入数据记录。这需要通过事务完成。可通过监听连接对象的success事件和error事件,了解是否写入成功
document.querySelector("#list .student .add").onclick = () => {
transaction = db.transaction("students","readwrite");
objectStore = transaction.objectStore("students");
const sid = document.querySelector("#list .student .id").value;
const str = document.querySelector("#list .student .str").value;
if(sid !== "" && str !== "") {
objectStore.add({rollNo: sid,value:str});
} else {
confirm("主键和str不能为空")
}
//oncomplete能触发
transaction.oncomplete = function(event) {
confirm("添加成功")
};
transaction.onerror = function(event) {
confirm("添加失败")
};
}![]() | 异步事务使用数据库中的事件对象属性。所有的读取和写入数据均在事务中完成。由IDBDatabase发起事务,通过IDBTransaction 来设置事务的模式(例如:是否只读readonly或读写readwrite),以及通过IDBObjectStore来发起一个请求。同时你也可以使用它来中止事务。 Transactions 可使用以下三种模式:1、"readonly"允许读取数据,不改变。2、"readwrite"允许读取和写入现有数据存储,数据被改变。3、"versionchange"允许执行任何操作,包括删除和创建对象存储和索引。此模式是用于开始使用IDBDatabase (en-US) 的 setVersion() (en-US)方法更新版本号事务。这种模式的事务无法与其他事务并发运行。这种模式下的事务被称为“升级事务”。 |
IDBObjectStore.delete()方法用于删除记录。
document.querySelector("#list .student .romove").onclick = () => {
transaction = db.transaction("students","readwrite");
objectStore = transaction.objectStore("students");
const sid = document.querySelector("#list .student .id").value;
if(sid !== "") {
objectStore.delete(sid);
} else {
confirm("主键不能为空")
}
transaction.oncomplete = function(event) {
confirm("删除成功")
};
transaction.onerror = function(event) {
confirm("删除失败")
};
}![]() | 删除数据和查找不存在的数据时时不会报错的,可自行写代码处理,可参考查找数据的方法。 |
修改数据要使用IDBObject.put()方法。
document.querySelector("#list .student .update").onclick = () => {
transaction = db.transaction("students","readwrite");
objectStore = transaction.objectStore("students");
const sid = document.querySelector("#list .student .id").value;
const str = document.querySelector("#list .student .str").value;
if(sid !== "") {
var request = objectStore.put({rollNo: sid,value:str});
request.onsuccess = function(event) {
confirm("修改成功");
};
request.onerror = function(event) {
confirm("修改发生错误");
};
} else {
confirm("主键不能为空")
}
transaction.oncomplete = function(event) {
console.log("事务成功");
};
transaction.onerror = function(event) {
console.log("事务失败");
};
}![]() | put()方法在修改不存在的数据时候会新增数据 |
查找数据要使用objectStore.get()方法。
document.querySelector("#list .student .search").onclick = () => {
transaction = db.transaction("students","readwrite");
objectStore = transaction.objectStore("students");
const sid = document.querySelector("#list .student .id").value;
if(sid !== "") {
var request = objectStore.get(sid);
request.onsuccess = function(event) {
if (request.result==undefined) {
confirm("查询不到数据!");
}else{
confirm("查询到的数据为:"+request.result.value);
}
};
request.onerror = function(event) {
confirm("查询发生错误");
};
} else {
confirm("主键不能为空")
}
transaction.oncomplete = function(event) {
console.log("事务成功");
};
transaction.onerror = function(event) {
console.log("事务失败");
};
}![]() | 本身indexedDB的delete()和get()方法在处理不存在的数据时时不会报错的,可自行处理。 |
deleteObjectStore()方法是要在upgradeneeded事件下处理的。删除表前要执行close()方法。
document.querySelector("#list .student .delete").onclick = () => {
console.log('删除表开始');
version=version+1;
db.close();
request = window.indexedDB.open("testDB",version);
request.onerror = (event) => {
console.error(event.target.error)
};
request.onsuccess = (event) => {
db = event.target.result;
console.log('delet success')
}
request.onupgradeneeded = (event) => {
db = event.target.result;
db.deleteObjectStore("students");
// db.close();
//删除之后不需要再关闭,否则会报错 DOMException: The connection was closed
objectStore = db.createObjectStore("students", { keyPath : "rollNo"});
confirm("删除表成功");
};
}indexedDB.deleteDatabase()方法用于删除一个数据库,参数为数据库的名字。它会立刻返回一个IDBOpenDBRequest对象,然后对数据库执行异步删除。删除操作的结果会通过事件通知,IDBOpenDBRequest对象可以监听以下事件。
success:删除成功
error:删除报错
document.querySelector("#deleteBase_ss").onclick = () => {
const DBDeleteRequest = window.indexedDB.deleteDatabase('testDB');
db.close();
DBDeleteRequest.onsuccess = (event) => {
confirm("删除数据库成功");
};
DBDeleteRequest.onerror = (event) => {
confirm("删除数据库失败");
};
}更多案例请下载