前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >IndexedDB

IndexedDB

作者头像
jinghong
发布2020-05-12 13:05:15
8670
发布2020-05-12 13:05:15
举报
文章被收录于专栏:前端开发0202

IndexedDB

参考链接:阮一峰 网道API MDN

基本概念

IndexedDB 是一个比较复杂的 API,涉及不少概念。它把不同的实体,抽象成一个个对象接口。学习这个 API,就是学习它的各种对象接口。

  • 数据库:IDBDatabase 对象
  • 对象仓库:IDBObjectStore 对象
  • 索引: IDBIndex 对象
  • 事务: IDBTransaction 对象
  • 操作请求:IDBRequest 对象
  • 指针: IDBCursor 对象
  • 主键集合:IDBKeyRange 对象

open database

代码语言:javascript
复制
var request = window.indexedDB.open(databaseName, version) // databaseName: 数据库名  version: 版本
// 如果指定的数据库不存在,将会创建,版本默认为1
// return IDBRequest 对象。这个对象有三种事件error、success、upgradeneeded,用于打开数据库后的操作。
request.onerror = function (event) {
    console.log('error')
}

request.onsuccess = function (event) {
    let db = request.result
    console.log('success')
}

request.onupgradeneeded = function (event) {
    let db = event.target.result
    console.log('update 当指定版本大于版本,就会触发升级事件 第一次打开数据库时,会先触发upgradeneeded事件,然后触发success事件。') 
}
//成功后,即可通过request.result 访问IDBdatabse对象

IDBDatabase 对象有以下属性。

  • IDBDatabase.name:字符串,数据库名称。
  • IDBDatabase.version:整数,数据库版本。数据库第一次创建时,该属性为空字符串。
  • IDBDatabase.objectStoreNames:DOMStringList 对象(字符串的集合),包含当前数据的所有 object store 的名字。
  • IDBDatabase.onabort:指定 abort 事件(事务中止)的监听函数。
  • IDBDatabase.onclose:指定 close 事件(数据库意外关闭)的监听函数。
  • IDBDatabase.onerror:指定 error 事件(访问数据库失败)的监听函数。
  • IDBDatabase.onversionchange:数据库版本变化时触发(发生upgradeneeded事件,或调用indexedDB.deleteDatabase())。

IDBTransaction 对象

IDBTransaction 对象用来异步操作数据库事务,所有的读写操作都要通过这个对象进行,IDBDatabase.transaction()方法返回的就是一个 IDBTransaction 对象。

  • IDBTransaction.db:返回当前事务所在的数据库对象 IDBDatabase。
  • IDBTransaction.error:返回当前事务的错误。如果事务没有结束,或者事务成功结束,或者被手动终止,该方法返回null
  • IDBTransaction.mode:返回当前事务的模式,默认是readonly(只读),另一个值是readwrite
  • IDBTransaction.objectStoreNames:返回一个类似数组的对象 DOMStringList,成员是当前事务涉及的对象仓库的名字。
  • IDBTransaction.onabort:指定abort事件(事务中断)的监听函数。
  • IDBTransaction.oncomplete:指定complete事件(事务成功)的监听函数。
  • IDBTransaction.onerror:指定error事件(事务失败)的监听函数。

IDBTransaction 对象有以下方法。

  • IDBTransaction.abort():终止当前事务,回滚所有已经进行的变更。
  • IDBTransaction.objectStore(name):返回指定名称的对象仓库 IDBObjectStore。

IDBIndex 对象 IDBObjectStore.index()方法可以获取 IDBIndex 对象。

  • IDBIndex.name:字符串,索引的名称。
  • IDBIndex.objectStore:索引所在的对象仓库。
  • IDBIndex.keyPath:索引的主键。
  • IDBIndex.multiEntry:布尔值,针对keyPath为数组的情况,如果设为true,创建数组时,每个数组成员都会有一个条目,否则每个数组都只有一个条目。
  • IDBIndex.unique:布尔值,表示创建索引时是否允许相同的主键。

IDBIndex 对象有以下方法,它们都是异步的,立即返回的都是一个 IDBRequest 对象。

  • IDBIndex.count():用来获取记录的数量。它可以接受主键或 IDBKeyRange 对象作为参数,这时只返回符合主键的记录数量,否则返回所有记录的数量。
  • IDBIndex.get(key):用来获取符合指定主键的数据记录。
  • IDBIndex.getKey(key):用来获取指定的主键。
  • IDBIndex.getAll():用来获取所有的数据记录。它可以接受两个参数,都是可选的,第一个参数用来指定主键,第二个参数用来指定返回记录的数量。如果省略这两个参数,则返回所有记录。由于获取成功时,浏览器必须生成所有对象,所以对性能有影响。如果数据集比较大,建议使用 IDBCursor 对象。
  • IDBIndex.getAllKeys():该方法与IDBIndex.getAll()方法相似,区别是获取所有主键。
  • IDBIndex.openCursor():用来获取一个 IDBCursor 对象,用来遍历索引里面的所有条目。
  • IDBIndex.openKeyCursor():该方法与IDBIndex.openCursor()方法相似,区别是遍历所有条目的主键。

IDBCursor 对象 IDBCursor 对象代表指针对象,用来遍历数据仓库(IDBObjectStore)或索引(IDBIndex)的记录。

IDBCursor 对象一般通过IDBObjectStore.openCursor()方法获得。

  • IDBCursor.source:返回正在遍历的对象仓库或索引。
  • IDBCursor.direction:字符串,表示指针遍历的方向。共有四个可能的值:next(从头开始向后遍历)、nextunique(从头开始向后遍历,重复的值只遍历一次)、prev(从尾部开始向前遍历)、prevunique(从尾部开始向前遍历,重复的值只遍历一次)。该属性通过IDBObjectStore.openCursor()方法的第二个参数指定,一旦指定就不能改变了。
  • IDBCursor.key:返回当前记录的主键。
  • IDBCursor.value:返回当前记录的数据值。
  • IDBCursor.primaryKey:返回当前记录的主键。对于数据仓库(objectStore)来说,这个属性等同于 IDBCursor.key;对于索引,IDBCursor.key 返回索引的位置值,该属性返回数据记录的主键。

IDBCursor 对象有如下方法。

  • IDBCursor.advance(n):指针向前移动 n 个位置。
  • IDBCursor.continue():指针向前移动一个位置。它可以接受一个主键作为参数,这时会跳转到这个主键。
  • IDBCursor.continuePrimaryKey():该方法需要两个参数,第一个是key,第二个是primaryKey,将指针移到符合这两个参数的位置。
  • IDBCursor.delete():用来删除当前位置的记录,返回一个 IDBRequest 对象。该方法不会改变指针的位置。
  • IDBCursor.update():用来更新当前位置的记录,返回一个 IDBRequest 对象。它的参数是要写入数据库的新的值。

IDBKeyRange 对象 IDBKeyRange 对象代表数据仓库(object store)里面的一组主键。根据这组主键,可以获取数据仓库或索引里面的一组记录。

IDBKeyRange 可以只包含一个值,也可以指定上限和下限。它有四个静态方法,用来指定主键的范围。

  • IDBKeyRange.lowerBound():指定下限。
  • IDBKeyRange.upperBound():指定上限。
  • IDBKeyRange.bound():同时指定上下限。
  • IDBKeyRange.only():指定只包含一个值。

下面是一些代码实例。

代码语言:javascript
复制
// All keys ≤ x
var r1 = IDBKeyRange.upperBound(x);

// All keys < x
var r2 = IDBKeyRange.upperBound(x, true);

// All keys ≥ y
var r3 = IDBKeyRange.lowerBound(y);

// All keys > y
var r4 = IDBKeyRange.lowerBound(y, true);

// All keys ≥ x && ≤ y
var r5 = IDBKeyRange.bound(x, y);

// All keys > x &&< y
var r6 = IDBKeyRange.bound(x, y, true, true);

// All keys > x && ≤ y
var r7 = IDBKeyRange.bound(x, y, true, false);

// All keys ≥ x &&< y
var r8 = IDBKeyRange.bound(x, y, false, true);

// The key = z
var r9 = IDBKeyRange.only(z);

IDBKeyRange.lowerBound()IDBKeyRange.upperBound()IDBKeyRange.bound()这三个方法默认包括端点值,可以传入一个布尔值,修改这个属性。

与之对应,IDBKeyRange 对象有四个只读属性。

  • IDBKeyRange.lower:返回下限
  • IDBKeyRange.lowerOpen:布尔值,表示下限是否为开区间(即下限是否排除在范围之外)
  • IDBKeyRange.upper:返回上限
  • IDBKeyRange.upperOpen:布尔值,表示上限是否为开区间(即上限是否排除在范围之外)

IDBKeyRange 实例对象生成以后,将它作为参数输入 IDBObjectStore 或 IDBIndex 对象的openCursor()方法,就可以在所设定的范围内读取数据。

代码语言:javascript
复制
var t = db.transaction(['people'], 'readonly');
var store = t.objectStore('people');
var index = store.index('name');

var range = IDBKeyRange.bound('B', 'D');

index.openCursor(range).onsuccess = function (e) {
  var cursor = e.target.result;
  if (cursor) {
    console.log(cursor.key + ':');

    for (var field in cursor.value) {
      console.log(cursor.value[field]);
    }
    cursor.continue();
  }
}

IDBKeyRange 有一个实例方法includes(key),返回一个布尔值,表示某个主键是否包含在当前这个主键组之内。

代码语言:javascript
复制
var keyRangeValue = IDBKeyRange.bound('A', 'K', false, false);

keyRangeValue.includes('F') // true
keyRangeValue.includes('W') // false

createDatabase

代码语言:javascript
复制
request.onupgradeneeded = function (event) {
    let db = event.target.result
    if (!db.objectStoreNames.contains('persion')) let objcetStore = db.createObjectStore('persion', {keyPath: 'id'}) 
    // db.createObjectStore(databaseName, options) options: keyPath 主键 或 autoIncrement 设置为true,两者只能存在一个 
}

createIndex

代码语言:javascript
复制
objcetStore.createIndex()//方法用于新建当前数据库的一个索引。该方法只能在VersionChange监听函数里面调用,只有存在数据库后才能使用。

objectStore.createIndex(indexName, keyPath, objectParameters)
该方法可以接受三个参数。
indexName:索引名
keyPath:主键
objectParameters:配置对象(可选)
第三个参数可以配置以下属性。

unique:如果设为true,将不允许重复的值
multiEntry:如果设为true,对于有多个值的主键数组,每个值将在索引里面新建一个条目,否则主键数组对应一个条目。

add

代码语言:javascript
复制
function add() {
  var request = db.transaction(['person'], 'readwrite')
    .objectStore('person')
    .add({ id: 1, name: '张三', age: 24, email: '[email protected]' });

  request.onsuccess = function (event) {
    console.log('数据写入成功');
  };

  request.onerror = function (event) {
    console.log('数据写入失败');
  }
}

add();

上面代码中,写入数据需要新建一个事务。新建时必须指定表格名称和操作模式(“只读”或“读写”)。新建事务以后,通过IDBTransaction.objectStore(name)方法,拿到 IDBObjectStore 对象,再通过表格对象的add()方法,向表格写入一条记录。

写入操作是一个异步操作,通过监听连接对象的success事件和error事件,了解是否写入成功。

read

代码语言:javascript
复制
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('Name: ' + request.result.name);
        console.log('Age: ' + request.result.age);
        console.log('Email: ' + request.result.email);
      } else {
        console.log('未获得数据记录');
      }
   };
}

read();

上面代码中,objectStore.get()方法用于读取数据,参数是主键的值

map

遍历数据表格的所有记录,要使用指针对象 IDBCursor。

代码语言:javascript
复制
function readAll() {
  var objectStore = db.transaction('person').objectStore('person');

   objectStore.openCursor().onsuccess = function (event) {
     var cursor = event.target.result;

     if (cursor) {
       console.log('Id: ' + cursor.key);
       console.log('Name: ' + cursor.value.name);
       console.log('Age: ' + cursor.value.age);
       console.log('Email: ' + cursor.value.email);
       cursor.continue();
    } else {
      console.log('没有更多数据了!');
    }
  };
}

readAll();

上面代码中,新建指针对象的openCursor()方法是一个异步操作,所以要监听success事件。

update

更新数据要使用IDBObject.put()方法。

代码语言:javascript
复制
function update() {
  var request = db.transaction(['person'], 'readwrite')
    .objectStore('person')
    .put({ id: 1, name: '李四', age: 35, email: '[email protected]' });

  request.onsuccess = function (event) {
    console.log('数据更新成功');
  };

  request.onerror = function (event) {
    console.log('数据更新失败');
  }
}

update();

上面代码中,put()方法自动更新了主键为1的记录。

delete

IDBObjectStore.delete()方法用于删除记录。

代码语言:javascript
复制
function remove() {
  var request = db.transaction(['person'], 'readwrite')
    .objectStore('person')
    .delete(1);

  request.onsuccess = function (event) {
    console.log('数据删除成功');
  };
}

remove();

use Index

索引的意义在于,可以让你搜索任意字段,也就是说从任意字段拿到数据记录。如果不建立索引,默认只能搜索主键(即从主键取值)。

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

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

现在,就可以从name找到对应的数据记录了。

代码语言:javascript
复制
var transaction = db.transaction(['person'], 'readonly');
var store = transaction.objectStore('person');
var index = store.index('name');
var request = index.get('李四');

request.onsuccess = function (e) {
  var result = e.target.result;
  if (result) {
    // ...
  } else {
    // ...
  }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • IndexedDB
    • 基本概念
      • open database
        • createDatabase
          • createIndex
            • add
              • read
                • map
                  • update
                    • delete
                      • use Index
                      相关产品与服务
                      数据库
                      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档