前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >javascript 操作浏览器数据库IndexedDB

javascript 操作浏览器数据库IndexedDB

原创
作者头像
iwhao
发布2024-07-03 23:34:15
1190
发布2024-07-03 23:34:15

前言

Indexed Database API 简称 IndexedDB,是浏览器中存储结构化数据的一个方案。IndexedDB 用于代

替目前已废弃的 Web SQL Database API。IndexedDB 背后的思想是创造一套 API,方便 JavaScript 对象的

存储和获取,同时也支持查询和搜索。

IndexedDB 的设计几乎完全是异步的。为此,大多数操作以请求的形式执行,这些请求会异步执行,

产生成功的结果或错误。绝大多数 IndexedDB 操作要求添加 onerror 和 onsuccess 事件处理程序来确

定输出。

2017 年,新发布的主流浏览器(Chrome、Firefox、Opera、Safari)完全支持 IndexedDB。IE10/11

和 Edge 浏览器部分支持 IndexedDB。

特点

  • 1 键值对储存。 IndexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以"键值对"的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,不能有重复,否则会抛出一个错误。
  • 2 异步。 IndexedDB 操作时不会锁死浏览器,用户依然可以进行其他操作,这与 LocalStorage 形成对比,后者的操作是同步的。异步设计是为了防止大量数据的读写,拖慢网页的表现。
  • 3 支持事务。 IndexedDB 支持事务(transaction),这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。
  • 4 同源限制 IndexedDB 受到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。
  • 5 储存空间大 IndexedDB 的储存空间比 LocalStorage 大得多,一般来说不少于 250MB,甚至没有上限。
  • 6 支持二进制储存。 IndexedDB 不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。

数据库

IndexedDB 是类似于 MySQL 或 Web SQL Database 的数据库。与传统数据库最大的区别在于,

IndexedDB 使用对象存储而不是表格保存数据。IndexedDB 数据库就是在一个公共命名空间下的一组对

象存储,类似于 NoSQL 风格的实现。

使用 IndexedDB 数据库的第一步是调用 indexedDB.open()方法,并给它传入一个要打开的数据

库名称。如果给定名称的数据库已存在,则会发送一个打开它的请求;如果不存在,则会发送创建并打

开这个数据库的请求。这个方法会返回 IDBRequest 的实例,可以在这个实例上添加 onerror 和

onsuccess 事件处理程序

代码语言:js
复制
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;
}; 

在两个事件处理程序中,event.target 都指向 request,因此使用哪个都可以。如果 onsuccess

事件处理程序被调用,说明可以通过 event.target.result 访问数据库(IDBDatabase)实例了,

这个实例会保存到 db 变量中。之后,所有与数据库相关的操作都要通过 db 对象本身来进行。如果打

开数据库期间发生错误,event.target.errorCode 中就会存储表示问题的错误码。

对象存储

建立了数据库连接之后,下一步就是使用对象存储。如果数据库版本与期待的不一致,那可能需要

创建对象存储。不过,在创建对象存储前,有必要想一想要存储什么类型的数据。

假设要存储包含用户名、密码等内容的用户记录。可以用如下对象来表示一条记录:

代码语言:js
复制
let user = {
 username: "007",
 firstName: "James",
 lastName: "Bond",
 password: "foo"
}; 

观察这个对象,可以很容易看出最适合作为对象存储键的 username 属性。用户名必须全局唯一,

它也是大多数情况下访问数据的凭据。这个键很重要,因为创建对象存储时必须指定一个键。

数据库的版本决定了数据库模式,包括数据库中的对象存储和这些对象存储的结构。如果数据库还

不存在,open()操作会创建一个新数据库,然后触发 upgradeneeded 事件。可以为这个事件设置处

理程序,并在处理程序中创建数据库模式。如果数据库存在,而你指定了一个升级版的版本号,则会立

即触发 upgradeneeded 事件,因而可以在事件处理程序中更新数据库模式。

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

这里第二个参数的 keyPath 属性表示应该用作键的存储对象的属性名。

事务

创建了对象存储之后,剩下的所有操作都是通过事务完成的。事务要通过调用数据库对象的

transaction()方法创建。任何时候,只要想要读取或修改数据,都要通过事务把所有修改操作组织

起来,

注意request.onsuccess和 request.onupgradeneeded 都是异步得,所以下方得增删改查 都需要 在异步里操作,不然回报找不到 db.transaction

代码语言:js
复制
  let db;
  var request = indexedDB.open('users');
  request.onerror = function (event) {
    console.log('数据库打开报错');
  };
  request.onsuccess = function (event) {
    db = event.target.result;
  };
  request.onupgradeneeded = function(event) {
    db = event.target.result;
    var objectStore;
    if (!db.objectStoreNames.contains('person')) {
      objectStore = db.createObjectStore('person', { keyPath: 'id' });
    }else{
      objectStore = db.createObjectStore('person', { keyPath: 'id' }); 
    }
    objectStore.createIndex('name', 'name', { unique: false }); 
    objectStore.createIndex('age', 'age', { unique: false }); 
  };

写操作

代码语言:js
复制
 function addData() {
    console.log(db)
    var request = db.transaction(['person'], 'readwrite') //readwrite表示有读写权限
      .objectStore('person')
      .add({ id: 1, name: 'iwhao', age: 18}); //新增数据
    request.onsuccess = function (event) {
      console.log('数据写入成功');
    };
    request.onerror = function (event) {
      console.log('数据写入失败');
    }
  }

读取操作

代码语言:js
复制
function read() {
   var transaction = db.transaction(['person']);
   var objectStore = transaction.objectStore('person');
   var request = objectStore.get(1);
   request.onerror = function(event) {
     console.log('事务失败');
   };
   request.onsuccess = function( event) {
      if (request.result) {
        console.log(request.result);
      } else {
        console.log('未获得数据记录');
      }
   };
}

更新

代码语言:js
复制
  function upData() {
    console.log(db)
    var request = db.transaction(['person'], 'readwrite') //readwrite表示有读写权限
      .objectStore('person')
      .put({ id: 1, name: 'whao', age: 20}); //更新数据
    request.onsuccess = function (event) {
      console.log('数据写入成功');
    };
    request.onerror = function (event) {
      console.log('数据写入失败');
    }
  }

删除

代码语言:js
复制
function del(){
    var request = db.transaction(['person'], 'readwrite')
      .objectStore('person')
      .delete(1);
    request.onsuccess = function (event) {
      console.log('数据删除成功');
    };
}

索引

对某些数据集,可能需要为对象存储指定多个键。例如,如果同时记录了用户 ID 和用户名,那可能

需要通过任何一种方式来获取用户数据。为此,可以考虑将用户 ID 作为主键,然后在用户名上创建索引。

假定新建表格的时候,对name字段建立了索引。

代码语言:js
复制
objectStore.createIndex('name', 'name', { unique: false });

createIndex()的第一个参数是索引的名称,第二个参数是索引属性的名称,第三个参数是包含

键 unique 的 options 对象。这个选项中的 unique 应该必须指定,表示这个键是否在所有记录中唯

一。因为 username 可能不会重复,所以这个键是唯一的。

索引查询

代码语言:js
复制
function getIndexes() {
    const transaction = db.transaction(['person']);
    const store = transaction.objectStore('person');
    const index = store.index("name")
    const request = index.get("iwhao");
    request.onerror = function(event) {
      console.log('事务失败');
    };
    request.onsuccess = function( event) {
      if (request.result) {
        console.log(request.result);
      } else {
        console.log('未获得数据记录');
      }
    };
  }

限制

IndexedDB 的很多限制实际上与 Web Storage 一样。首先,IndexedDB 数据库是与页面源(协议、域

和端口)绑定的,因此信息不能跨域共享。这意味着 www.wrox.com 和 p2p.wrox.com 会对应不同的数据

存储。

其次,每个源都有可以存储的空间限制。当前 Firefox 的限制是每个源 50MB,而 Chrome 是 5MB。

移动版 Firefox 有 5MB 限制,如果用度超出配额则会请求用户许可。

Firefox 还有一个限制——本地文本不能访问 IndexedDB 数据库。Chrome 没有这个限制。因此在本

地运行本书示例时,要使用 Chrome。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 特点
  • 数据库
  • 对象存储
  • 事务
    • 写操作
      • 读取操作
        • 更新
          • 删除
          • 索引
          • 限制
          相关产品与服务
          数据库
          云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档