一.使用指导
1.indexedDB 数据库类似于 NoSQL key-value 的风格实现,原生支持储存 JS 的对象,数据库能干的事它都能干。
2.储存量理论上没有上限 Chrome 对 IndexedDB 储存空间限制的定义是:硬盘可用空间的三分之一。
3.所有操作都是异步的,相比 LocalStorage 同步操作性能更高,尤其是数据量较大时,为此,大多数操作以请求的形式执行,这些请求会异步执行,产生成功的结果或错误,绝大多数 IndexedDB 操作要求添加 onerror 和 onsuccess 事件处理程序来确定输出。
4.支持事务。 IndexedDB 支持事务(transaction),这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。
5.同源限制 IndexedDB 数据库是与页面源(协议、域和端口)绑定的,因此信息不能跨域共享。这意味着 www.wrox.com 和 p2p.wrox.com 会对应不同的数据存储。
6.支持二进制储存。 IndexedDB 不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)
7.浏览器兼容 2017 年及之后发布的主流浏览器(Chrome、Firefox、Opera、Safari)完全支持 IndexedDB,IE10/11和 Edge 浏览器部分支持 IndexedDB。
二.连接数据库
使用 IndexedDB 数据库的第一步是调用 indexedDB.open()方法,并给它传入一个要打开的数据库名称。如果给定名称的数据库已存在,则会发送一个打开它的请求;如果不存在,则会发送创建并打开这个数据库的请求。这个方法会返回 IDBRequest 的实例,可以在这个实例上添加 onerror 和onsuccess 事件处理程序。举例如下:
const dbName = "test_DB"; //数据库名称
var db;
var request = indexedDB.open(dbName, 1); //打开数据库 参数 open(名称,版本号)
request.onerror = function (event) {
// 初始加载错误
console.log('加载错误 !', event);
};
// 创建存储空间 (新建和版本号变动触发的事件),添加索引是为了加速数据的检索
request.onupgradeneeded = function (event) {
db = event.target.result;
if (!db.objectStoreNames.contains('user_list')) { //查看表是否存在,不存在就创建
// createObjectStore 创建数据库,参数 user_list 是创建仓库名称,keyPath:将 "id" 作为主键,要保证他的唯一性, autoIncrement 是自动递增
var objectStore = db.createObjectStore("user_list", { keyPath: 'id', autoIncrement: true });
// 创建一个索引来通过 name 进行搜索,unique 表示是否允许数据的重复
objectStore.createIndex("name", "name", { unique: false });
// 手机是不允许重复的所以启用 unique: true
objectStore.createIndex("phone", "phone", { unique: true });
}
};
request.onsuccess = function (e) {
console.log("Success!");
db = e.target.result; //回去db操作对象
}
request.onerror = function (e) {
console.log("Error", e);
}
1.新增数据
// 创建事务,参数 transaction(
user_list 创建仓库名称:可以是单个也可以是数组的多个 ['user_list','info_list'],
readwrite 要修改访问模式:"readonly"、"readwrite"或"versionchange"
)
var tx = db.transaction('user_list', 'readwrite');
var store = tx.objectStore('user_list'); //拿到对象的操作方法
var req = store.add({name:xxx,age:xx}); //保存
req.onsuccess = function (evt) {
//添加成功
};
req.onerror = function () {
console.error("add error");
};
2.获取数据列表
var tx = db.transaction('user_list', 'readonly');
var store = tx.objectStore('user_list');
//store.get(1); 根据主键获取单个数据(看删除示例)
//store.index('phone').get('13726783748'); //使用手机号索引查询数据 (看更新示例)
//注:store.index('name') 这种多条索引数据的需要用到游标遍历
var req = store.count(); //获取当前总数集合
req = store.openCursor(); //通过游标查询,遍历数据表格的所有记录 openCursor(注:游标里还可以指定过滤条件,用到自己查询太多了)
req.onerror = function (evt) {
console.error("add error");
};
req.onsuccess = function (evt) { //多次触发,相当于循环列表
var cursor = evt.target.result; //拿到的是单次循环对象
if (cursor) {
console.log('da=>', cursor);
cursor.continue(); //游标指向下一个
}
}
3.删除
var tx = db.transaction('user_list', 'readwrite');
var store = tx.objectStore('user_list');
var req = store.get(1); //搜索主键 id 是否存在
req.onsuccess = function (evt) {
var record = evt.target.result;
if (typeof record != 'undefined') { //是否搜到值,没搜到就是 undefined
req = store.delete(1); //存在就删除
}
};
req.onerror = function (evt) {
console.error("delete:", evt.target.errorCode); //显示错误码
};
4.更新数据
var tx = db.transaction('user_list', 'readwrite');
var store = tx.objectStore('user_list');
var req = store.index('phone').get('13726783748'); //使用手机号索引
req.onsuccess = function (evt) {
var record = evt.target.result; //得到数据对象 类似:{id:1,name:'小红',age:11}
if (typeof record != 'undefined') {
record.name='小明';
record.age=12;
store.put(record); //更新整个数据
//store.update({name:"小明",age:12}) //更新部分数据
}
};
5.删除仓库数据
var tx = db.transaction('user_list', 'readwrite');
var store = tx.objectStore('user_list');
store.clear(); //清空仓库
6.删除整个仓库,需要在 onupgradeneeded 里面使用
request.onupgradeneeded = function (event) {
db = event.target.result;
if(db.objectStoreNames.contains('user_list')){
db.deleteObjectStore('user_list'); //删除整个仓库
}
}
备注:查询还可以多表查询,关联查询,关联添加等,因为需要和设计表结构及索引等相互配合就没写,有需要的自行查询。
网友评论