javascript基础学习系列三百九十:IndexedDB数据库

IndexedDB 是类似于 MySQL 或 Web SQL Database 的数据库。与传统数据库最大的区别在于, IndexedDB 使用对象存储而不是表格保存数据。IndexedDB 数据库就是在一个公共命名空间下的一组对 象存储,类似于 NoSQL 风格的实现。
使用 IndexedDB 数据库的第一步是调用 indexedDB.open()方法,并给它传入一个要打开的数据 库名称。如果给定名称的数据库已存在,则会发送一个打开它的请求;如果不存在,则会发送创建并打 开这个数据库的请求。这个方法会返回 IDBRequest 的实例,可以在这个实例上添加 onerror 和 onsuccess 事件处理程序。举例如下:

let db,
        request,
version = 1;
    request = indexedDB.open("admin", version);
    request.onerror = (event) =>
      alert(`Failed to open: ${event.target.errorCode}`);
    request.onsuccess = (event) => {
db = event.target.result;
};

以前,IndexedDB 使用 setVersion()方法指定版本号。这个方法目前已废弃。如前面代码所示, 要在打开数据库的时候指定版本。这个版本号会被转换为一个 unsigned long long 数值,因此不要 使用小数,而要使用整数。
在两个事件处理程序中,event.target 都指向 request,因此使用哪个都可以。如果 onsuccess 事件处理程序被调用,说明可以通过 event.target.result 访问数据库(IDBDatabase)实例了, 这个实例会保存到 db 变量中。之后,所有与数据库相关的操作都要通过 db 对象本身来进行。如果打 开数据库期间发生错误,event.target.errorCode 中就会存储表示问题的错误码。


let user = { 26 username: "007",
firstName: "James",
lastName: "Bond",

注意 以前,出错时会使用IDBDatabaseException表示IndexedDB发生的错误。目前 它已被标准的 DOMExceptions 取代。
建立了数据库连接之后,下一步就是使用对象存储。如果数据库版本与期待的不一致,那可能需要 创建对象存储。不过,在创建对象存储前,有必要想一想要存储什么类型的数据。
假设要存储包含用户名、密码等内容的用户记录。可以用如下对象来表示一条记录:

password: "foo"
};

观察这个对象,可以很容易看出最适合作为对象存储键的 username 属性。用户名必须全局唯一, 它也是大多数情况下访问数据的凭据。这个键很重要,因为创建对象存储时必须指定一个键。

客户端存储

数据库的版本决定了数据库模式,包括数据库中的对象存储和这些对象存储的结构。如果数据库还 不存在,open()操作会创建一个新数据库,然后触发 upgradeneeded 事件。可以为这个事件设置处 理程序,并在处理程序中创建数据库模式。如果数据库存在,而你指定了一个升级版的版本号,则会立 即触发 upgradeneeded 事件,因而可以在事件处理程序中更新数据库模式。
下面的代码演示了为存储上述用户信息如何创建对象存储:

request.onupgradeneeded = (event) => {
      const db = event.target.result;
// 如果存在则删除当前objectStore。测试的时候可以这样做 // 但这样会在每次执行事件处理程序时删除已有数据
if (db.objectStoreNames.contains("users")) {
        db.deleteObjectStore("users");
      }
      db.createObjectStore("users", { keyPath: "username" });
    };

这里第二个参数的 keyPath 属性表示应该用作键的存储对象的属性名。 25.3.3 事务
创建了对象存储之后,剩下的所有操作都是通过事务完成的。事务要通过调用数据库对象的 transaction()方法创建。任何时候,只要想要读取或修改数据,都要通过事务把所有修改操作组织 起来。最简单的情况下,可以像下面这样创建事务:

   let transaction = db.transaction();

如果不指定参数,则对数据库中所有的对象存储有只读权限。更具体的方式是指定一个或多个要访 问的对象存储的名称:

   let transaction = db.transaction("users");

这样可以确保在事务期间只加载 users 对象存储的信息。如果想要访问多个对象存储,可以给第 一个参数传入一个字符串数组:

let transaction = db.transaction(["users", "anotherStore"]);

如前所述,每个事务都以只读方式访问数据。要修改访问模式,可以传入第二个参数。这个参数应 该是下列三个字符串之一:“readonly”、“readwrite"或"versionchange”。比如:

  let transaction = db.transaction("users", "readwrite");

这样事务就可以对 users 对象存储读写了。
有了事务的引用,就可以使用 objectStore()方法并传入对象存储的名称以访问特定的对象存储。 然后,可以使用 add()和 put()方法添加和更新对象,使用 get()取得对象,使用 delete()删除对象, 使用 clear()删除所有对象。其中,get()和 delete()方法都接收对象键作为参数,这 5 个方法都创 建新的请求对象。来看下面的例子:

   const transaction = db.transaction("users"),
        store = transaction.objectStore("users"),
        request = store.get("007");
request.onerror = (event) => alert("Did not get the object!"); request.onsuccess = (event) => alert(event.target.result.firstName);

因为一个事务可以完成任意多个请求,所以事务对象本身也有事件处理程序:onerror 和 oncomplete。 15 这两个事件可以用来获取事务级的状态信息:

transaction.onerror = (event) => { // 整个事务被取消

注意,不能通过 oncomplete 事件处理程序的 event 对象访问 get()请求返回的任何数据。因此, 17
};


transaction.oncomplete = (event) => {
// 整个事务成功完成 };

仍然需要通过这些请求的 onsuccess 事件处理程序来获取数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值