IndexedDB基本操作学习总结

前言

        最近在做一个脱机的项目,数据需要保存到前端,前端页面的操作大部分也是基于IndexdDB的,而该项目之前用的也是IndexedDB,在这里和大家分享下学习到的IndexdDB基本操作和学习时的遇到的一些坑。

                                                                                                ------ 学习,分享

大纲


一,IndexedDB简要 

二,判断浏览器是否支持IndexedDB

三,如何创建一个对象仓库(创建表)

四,实现IndexedDB的增加/修改

五,实现IndexedDB的删除

六,实现IndexedDB的查询(着重分享)

七,关于IndexedDB的回调使用问题

八,总结

文档链接:(注意,有的api需要网页语言选择英文才有)

https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API

一,IndexdDB简要 (官方概述)

        IndexedDB 是一个事务型数据库系统,类似于基于 SQL 的 RDBMS。 然而,不像 RDBMS 使用固定列表,IndexedDB 是一个基于 JavaScript 的面向对象数据库。IndexedDB 允许您存储和检索用索引的对象;可以存储结构化克隆算法支持的任何对象。您只需要指定数据库模式,打开与数据库的连接,然后检索和更新。

(IndexedDB 的数据结构类似于redis,是以key&value的形式存储)

二,判断浏览器是否支持IndexedDB

var indexedDB =
        window.indexedDB ||
        window.webkitIndexedDB ||
        window.mozIndexedDB ||
        window.msIndexedDB;  //获取IDBFactory接口实例

    if (!indexedDB) {
        console.log('你的浏览器不支持IndexedDB');
    }

三, 如何创建一个对象仓库(创建表)

①打开库

    //此处version代表的版本,具体看文档,这里不做讲解
    var request = indexedDB.open(databaseName, version);

    request.onerror = function (event) {
        console.log('indexeddb打开失败');
    };

    request.onsuccess = function (event) {
        var db = event.target.result;
        console.log('indexeddb打开成功');
    };

②创建表(此篇以student表为例),创建索引

//upgradeneeded 事件的事件处理器,会在当一个数据库的版本比已经存在的版本还高的时候触发。
request.onupgradeneeded = function (event) {
        db = event.target.result;
        console.log('indexeddb更新成功');
        var objectStore;
        //新增对象仓库
        if (!db.objectStoreNames.contains('student')) {//如果该表不存在,创建表
            //使用student的id属性作为主键,也可以使用默认的自增主键
            //objectStore = db.createObjectStore('student', { autoIncrement: true });
            objectStore = db.createObjectStore('student', { keyPath: 'id' });
            //创建索引,其三个属性分别是,索引名称,索引所代表属性,是否唯一
            objectStore.createIndex('name', ['name'], { unique: true });
        }
}

四,实现IndexedDB的增加/修改 

①新增数据

//IndexdDB都是通过事务操作的,此处开启一个事务,赋予读写的权限
var transaction= db.transaction(["student"], "readwrite")
//获取表的实例,得到objectStore 就可以开始操作了
var objectStore = .objectStore("student");
//此处添加一个student对象
var request = objectStore.add(this.student);
//每一个操作都会有成功和是失败的回调
request.onerror = (event) => {
    console.log("添加成功");
};
request.onsuccess= (event) => {
    console.log("添加成功");
};

当然,你也可以用 objectStore.put(this.student)来新增,前提是表里面没有相同的数据

②修改数据 (相同部分省略)

//put后的2个参数,name代表被修改对象的属性(同时必须是主键!)
var putRequest = objectStore.put(this.student,this.student.id);
putRequest .onerror = (event) => {
    console.log("修改失败");
};
putRequest .onsuccess= (event) => {
    console.log("修改成功");
};

五,实现IndexedDB的删除

此处只介绍通过key删除(相同部分省略),通过范围删除,详见文档KeyRange

//delete()可通过主键和主键范围删除 例如:var request = objectStore.delete(KeyRange);
var deRequest = objectStore.delete(this.student.id);
deRequest .onerror = (event) => {
    console.log("删除失败");
};
deRequest .onsuccess= (event) => {
    console.log("删除成功");
};

六,实现IndexdDB的查询(重点来了)

①objectStore.getAll()查询全部

//objectStore.getAll(query, count)其实有2个参数,query是代表需要查询的key或者KeyRange
//count代表在IDBKeyRange下查询到多个对象时,指定返回的数量
//此处不加参,默认查询所有
var getAll = objectStore.getAll();
getAll.onerror = (event) => {
    console.log("查询失败");
};
getAll.onsuccess= (event) => {
    //list就是查询到的所有数据
    var list = getAll.result
    console.log("查询成功");
};

②objectStore.openCursor()查询全部,此处的openCursor()是一个游标,详见文档IDBCursor

它和上面的方法不一样,在成功回调的函数里面,相当于是一个循环,list.continue()就相当于是接

着循环的意思,必不可少。

var _this = this;
var cursor = objectStore.openCursor();
cursor.onerror = (event) => {
    console.log("查询失败");
};
cursor.onsuccess= (event) => {
    //此处与上面不同
    var list = event.target.result;
    if(list)
        //此回调中list.continue()必不可少,详见文档
        //此处以data[]接受数据为例
        _this.data.push(list);
        list.continue();
    }
    console.log("查询成功");
};

③objectStore.index()通过索引,使用游标返回按该索引排序的一系列记录,相当于条件查询,返回符合当前条件的条目。

var _this = this
var transaction = db.transaction(["student"],"readonly")
var objectStore = objectStore("student");
//此处选择我们的之前所创建的索引名称
var myIndex  = objectStore.index('name');//拿到实例
//IDBKeyRange.only创建一个包含单个值的范围
var keyRange = IDBKeyRange.only('张三');//定义查询条件为张三
myIndex.openCursor(keyRange).onerror = (event) => {
    console.log('查询失败')
};
myIndex.openCursor(keyRange).onsuccess= (event) => {
    //此处相当于是查询到所有name='张三'的数据
    if(list)
        _this.data.push(list);
        list.continue();
    }
    console.log('查询成功')
};

(如果是要通过条件查询到某一唯一值,可将对象的主键或者唯一字段创建索引,用法一样。)

关键字查询

//相当于上面2的查询所有的方法
var keyword = this.keyword//关键字
var transaction = _db.transaction(["sutdent"]);
var objectStore = transaction.objectStore("sutdent");
var c = objectStore.openCursor();
c.onsuccess = function(e) {
    var cursor = e.target.result;
    if (cursor) {
        var stu = cursor.value;//得到当前对象
        //判断当前对象中的name属性是否有我要检索的关键字
        if (stu.name.indexOf(keyword) >= 0) {
             _this.data.push(stu);
        }
          cursor.continue();
    } 
};

⑤通过objectStore.get(key)主键查询

//通过主键查询,此主键可以是默认自增,但是这样你就不好操作,建议将对象的主键
//类似id这样的设为主键,这样在修改时,可以通过其id做修改
var getOne = objectStore.get(key);
getOne.onerror = (event) => {
    console.log("查询失败");
};
getOne.onsuccess= (event) => {
    //通过key查询到的数据
    var list = getAll.result
    console.log("查询成功");
};

(查询这一块,只知道这么些,其它没有深入了解,总的来说,IndexdDB在查询这一块局限性太大,不比不知道,才发现原来sql很强大。)

七,关于IndexedDB的回调使用问题

        1.注意使用IndexedDB事务操作赋值时,在成功的回调里面进行赋值,如果在成功的回调外面赋值,数据是拿不到的。因为IndexedDB是过度异步的。

        2.因为赋值是在成功的回调里面的,所以后续如果有其他的IndexedDB的操作,可以在一个回调里面嵌套其他事务,然后就是一个回调嵌套下一个回调,然后嵌套下一个回调.......

        3.大家也看到了,上面代码中this的使用,在回调外面定义var _this = this ,这是因为回调里面的this就不是你所熟悉的那个this了,当前指定对象不同。

八,总结

       IndexedDB的数据结构是类似于redis的key&value形式存储,它是一个浏览器数据库,允许储存大量数据。

        emmm,总的来说,我个人接触IndexedDB也不多,在csdn中搜到的相关也很少,所以大家在使用的时候,还是多看看文档。

        IndexdDB个人使用完后,只觉得要不是需求需要,我才不会去用IndexedDB,相比我们常用的sql,这个用起来简直太繁琐和麻烦了。(主要是接任务时一开始还不会这个鬼东西~~)

        本人新手一枚,第一次发博,如果文中有写错或者说错的地方,还望大家指出,也欢迎大家一起探讨,一起学习,一起分享!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值