教你怎么玩indexedDB浏览器数据库,执行流程以及常见错误等等
(小编最近在研究indexedDB数据库,在网上看的文档都有些不好理解,像小编这个接触过mySql,Oracle,SQL Server的人看了都是云里雾里的,所以决定自己写一篇关于indexedDB是数据库的博文出来帮助小白更直白的了解,转载请注明出处,谢谢)
那么先给大家上一张图让大家看看数据表的结构
为什么要使用indexedDB浏览器数据库?
随着浏览器的功能不断增强,越来越多的网站开始考虑,将大量数据储存在客户端,这样可以减少从服务器获取数据,直接从本地获取数据。现有的浏览器数据储存方案,都不适合储存大量数据:Cookie 的大小不超过4KB,且每次请求都会发送回服务器;LocalStorage 在 2.5MB 到 10MB 之间(各家浏览器不同),而且不提供搜索功能,不能建立自定义的索引。
通俗地说**,IndexedDB 就是浏览器提供的本地数据库**,它可以被网页脚本创建和操作。IndexedDB 允许储存大量数据,提供查找接口,还能建立索引。这些都是 LocalStorage 所不具备的。就数据库类型而言,IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库。IndexedDB 具有以下特点。
(1)键值对储存。 IndexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以"键值对"的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,不能有重复,否则会抛出一个错误。(2)异步。 IndexedDB 操作时不会锁死浏览器,用户依然可以进行其他操作,这与 LocalStorage 形成对比,后者的操作是同步的。异步设计是为了防止大量数据的读写,拖慢网页的表现。
(3)支持事务。 IndexedDB 支持事务(transaction),这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。
(4)同源限制 IndexedDB 受到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。
(5)储存空间大 IndexedDB 的储存空间比 LocalStorage 大得多,一般来说不少于 250MB,甚至没有上限。
(6)支持二进制储存。 IndexedDB 不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。
接下来我们就来看看这个高大上nb带闪电的玩意怎么玩
如何使用?
首先,创建打开数据库// indexedDB浏览器数据库是挂载在window上的,在其数据库对象上有一个open方法 /*** open方法接收两个参数,第一个参数字符数是数据库名,第二个参数为数据库版本号* open方法可以用来打开数据库也可以用来创建数据库,只传一个数据库名的时候,如果数据库名已存在默认打开当前版本数据库,如果不存在则会新建一个* 数据库,第二个参数是版本号,不传的时候打开默认是当前版本,创建默认是1* 返回一个当前数据库的IDBOpenDBRequest对象(小编理解就是当前数据库的一个对象实例),这个实例自带了一些事件* 常用的有* error =》数据库打开失败* onsuccess =》数据库打开成功(就可以通过其result属性拿到数据库对象了)* upgradeneeded =》数据库升级事件,如果指定的版本号大于当前数据库版本号就会发生数据库升级事件,这个时候则需要使用事件对象的event.taget.result拿到数据库实例** 如果是新建数据库,由于数据库的从无到有属于版本升级,所以会先触发request的onupgradeneeded事件然后再触发其onsuccess事件**/ var request=window.indexedDB.open("dataNames"); //如果要删除数据库:indexDB.deleteDatabase('数据库名');
这样我们就在window上创建了一个浏览器数据库了,库名叫做“dataNames”,既然创建了数据库,那么就要建表了,这个window.indexedDB.open(“dataNames”);方法创建数据库的时候会返回一个对象,这个对象上有三个事件
数据库打开成功和失败事件大家都好理解,那么这个数据库版本升级事件是个什么鬼?这个事件就是我们创建数据表的地方了,数据库版本升级是啥意思呢?我们使用 var request=window.indexedDB.open(“dataNames”);方法时如果第二个参数也就是版本号参数大于当前数据版本号就会发生数据库版本升级事件,否则就只会触发数据库打开成功或者失败事件而不会触发版本升级事件
那么,直接上创建表的代码// 数据库版本升级事件 request.onupgradeneeded=function (ev) {//拿到数据库实例对象,其中包含了对数据库表的的创建编辑等功能db=ev.target.result;var objectStore;//判断我们要创建的person表是否已经存在,数据库实例的objectStoreNames中放的是我们的所有表的集合//contain方法查看数据库表集合中是否存在某种表if (!db.objectStoreNames.contains('person1')) {//使用数据库实例的createObjectStore方法创建对象仓库(其实就是数据表),第一个参数字符串就是数据表名,第二个表示//设置这个表中的id为主键(主键是唯一的,方便迅速索引查找)objectStore = db.createObjectStore('person1', { keyPath: 'id' });//使用createIndex为这个数据表添加索引(其实就是列名),三个参数分别是:列名,列名所在属性,配置对象(是否包含重复的值)objectStore.createIndex('name', 'name', { unique: false });objectStore.createIndex('email', 'email', { unique: true });} };
这就创建出来一张名为person1的表了,设置了这个表的id列为主键列,为其增加了一个name列和一个email列
那么有了表了接下来就为给表添加数据了,window.indexedDB.open(“dataNames”);方法创建数据库的时候会先触发onupgradeneeded事件然后触发onsuccess数据库打开成功事件// 数据库打开(已有就打开,没有就创建后打开)成功事件 request.onsuccess=function (ev) {//拿到数据库实例对象,其中包含了对数据库表的的创建编辑等功能db=ev.target.result;console.log(db);//调用add方法向我们创建的数据库表中添加数add(); };// add方法用来项数据库中存入数据 function add() {//indexedDB数据库的读写都是通过事务来完成的,// 通过数据库对象实例.transaction(['表名'],‘只读或读写’)来创建一个指定表的事务// 只读:read,不能修改数据库数据,可以并发执行// 读写:readwrite,可以进行读写操作// 版本变更:verionchangeconsole.log(db);var request = db.transaction(['person1'], 'readwrite');//通过创建的表事务的pbjectStore(‘表名’)拿到我们要的数据库指定表对象request=request.objectStore('person1');//通过表对象的add方法向数据库中写入数据返回一个IDBRequest对象,对手上的onsuccess事件是数据写入成功事件,onerror是数据写入失败事件console.log(request);request =request.add({ id: 1, name: '王阔', age: 24, email: 'wangkuo@example.com' });//数据写入成功request.onsuccess = function (event) {console.log('数据写入成功');};console.log(request);//数据写入失败request.onerror = function (event) {console.log('数据写入失败');} }
这样我们就向数据库的person1表中添加了一条数据了,也可以添加多条,
那么添加完数据就要在其他同域的页面上获取数据了,首先还是打开数据库//数据库打开(已有就打开,没有就创建后打开)成功事件 request.onsuccess=function (ev) {//拿到数据库实例对象,其中包含了对数据库表的的创建编辑等功能db=ev.target.result;console.log('数据库打开成功');//调用read方法向我们创建的数据库表中拿取数据read(); };
read方法就是我们获取数据的方法
//从indexedDB数据库中读取数据 function read() {//创建一个指定表的事务对象var transaction = db.transaction(['person1']);//获取指定表的实例var objectStore = transaction.objectStore('person1');//通过get(索引)拿取数据var request=objectStore.get(1);//获取全部数据 var request = objectStore.getAll();//获取数据总数 var request = objectStore.count();// 数据拿取失败request.onerror = function(event) {reject();console.log('事务失败');};//数据拿取成功request.onsuccess = function(event) {//这里数据拿取成功的话,传入的事件对象中的target的result就是我们拿取到的数据了//如果上面是用objectStore.get(1);拿取的那就是单个数据//使用objectStore.getAll();拿取的就是全部数据//不管拿取的那种数据都会被存到事件对象的target.result中去if (request.result) {console.log('Name: ' + request.result.name);console.log('Age: ' + request.result.age);console.log('Email: ' + request.result.email);} else {console.log('未获得数据记录');}}; }
这里需要注意的是开启数据库是异步操作,而拿取数据也是异步操作,也就是说我们如果在表对象的onsuccess方法之外获取数据是获取不到的
总结一下小编研究之中犯过的错误:
1.数据库版本号更新的时候创建之前版本已经存在的表,这个不会报错,但是如果监测会发现进入onerror事件中去了
2.导致数据写入失败的原因:我们添加列的时候第三个参数如果是true那就是不允许重复,添加的数据不允许重复列如果重复了会导致数据写入失败,写入得数据主键列有重复也回导致数据写入失败,还有一些其他的数据格式原因等
这些就是小编整理的学习indexedDB浏览器数据库的笔记,后续还会出一些深层一点的笔记,随后附上indexedDB对象图和完整代码
小编用来两个文件,一个添加数据一个获取数据添加数据
// indexedDB浏览器数据库是挂载在window上的,在其数据库对象上有一个open方法/*** open方法接收两个参数,第一个参数字符数是数据库名,第二个参数为数据库版本号* open方法可以用来打开数据库也可以用来创建数据库,只传一个数据库名的时候,如果数据库名已存在默认打开当前版本数据库,如果不存在则会新建一个* 数据库,第二个参数是版本号,不传的时候打开默认是当前版本,创建默认是1* 返回一个当前数据库的IDBOpenDBRequest对象(小编理解就是当前数据库的一个对象实例),这个实例自带了一些事件* 常用的有* error =》数据库打开失败* onsuccess =》数据库打开成功(就可以通过其result属性拿到数据库对象了)* upgradeneeded =》数据库升级事件,如果指定的版本号大于当前数据库版本号就会发生数据库升级事件,这个时候则需要使用事件对象的event.taget.result拿到数据库实例** 如果是新建数据库,由于数据库的从无到有属于版本升级,所以会先触发request的onupgradeneeded事件然后再触发其onsuccess事件** indexDB主要对象介绍:* IDBFactory:打开数据库的工厂对象,用于打开数据库,并管理数据库版本。* IDBOpenDBRequest:请求对象,对数据库的访问、操作都是基于请求的,通过请求对象获取其他DOM对象。* IDBDatabase:数据库对象,封装了对数据库表的创建、编辑等功能。* IDBObjectStore:类似于数据库的数据表。* IDBIndex:数据库索引对象,用于创建数据表的索引。* IDBTransaction:数据库事物控制对象。* IDBCursor:数据库访问游标,用于访问数据。*/var request=window.indexedDB.open("dataNames",3);//如果要删除数据库:indexDB.deleteDatabase('数据库名');var db;// 数据库打开(已有就打开,没有就创建后打开)成功事件request.onsuccess=function (ev) {//拿到数据库实例对象,其中包含了对数据库表的的创建编辑等功能db=ev.target.result;//调用add方法向我们创建的数据库表中添加数add();};// 数据库版本升级事件request.onupgradeneeded=function (ev) {//拿到数据库实例对象,其中包含了对数据库表的的创建编辑等功能db=ev.target.result;var objectStore;//判断我们要创建的person表是否已经存在,数据库实例的objectStoreNames中放的是我们的所有表的集合//contain方法查看数据库表集合中是否存在某种表if (!db.objectStoreNames.contains('person1')) {//使用数据库实例的createObjectStore方法创建对象仓库(其实就是数据表),第一个参数字符串就是数据表名,第二个表示//设置这个表中的id为主键(主键是唯一的,方便迅速索引查找)objectStore = db.createObjectStore('person1', { keyPath: 'id' });console.log(objectStore);//使用createIndex为这个数据表添加索引(其实就是列名),三个参数分别是:列名,列名所在属性,配置对象(是否包含重复的值)objectStore.createIndex('name', 'name', { unique: false });objectStore.createIndex('email', 'email', { unique: true });}};// 数据库打开失败事件request.onerror=function (e) {console.log("数据库启动失败")}// add方法用来项数据库中存入数据function add() {//indexedDB数据库的读写都是通过事务来完成的,// 通过数据库对象实例.transaction(['表名'],‘只读或读写’)来创建一个指定表的事务// 只读:read,不能修改数据库数据,可以并发执行// 读写:readwrite,可以进行读写操作// 版本变更:verionchangevar request = db.transaction(['person1'], 'readwrite');//通过创建的表事务的pbjectStore(‘表名’)拿到我们要的数据库指定表对象request=request.objectStore('person1');//通过表对象的add方法向数据库中写入数据返回一个IDBRequest对象,对手上的onsuccess事件是数据写入成功事件,onerror是数据写入失败事件console.log(request);request =request.add({ id: 4, name: '王阔', age: 24, email: 'wangkuo@example.com' });//数据写入成功request.onsuccess = function (event) {console.log('数据写入成功');};console.log(request);//数据写入失败request.onerror = function (event) {console.log('数据写入失败');}}//删除指定id的数据function deleteInif() {var request = db.transaction(['person1'], 'readwrite');request=request.objectStore('person1');request.delete(5);}//清空表记录function clearInif() {var request = db.transaction(['person1'], 'readwrite');request=request.objectStore('person1');request.clear();}
- 获取数据
var request=window.indexedDB.open("dataNames");var db;//数据库打开(已有就打开,没有就创建后打开)成功事件request.onsuccess=function (ev) {//拿到数据库实例对象,其中包含了对数据库表的的创建编辑等功能db=ev.target.result;console.log('数据库打开成功');//调用read方法向我们创建的数据库表中拿取数据read();};//从indexedDB数据库中读取数据function read() {//创建一个指定表的事务对象var transaction = db.transaction(['person1']);//获取指定表的实例var objectStore = transaction.objectStore('person1');//通过get(索引)拿取数据var request=objectStore.get(1);//获取全部数据 var request = objectStore.getAll();//获取数据总数 var request = objectStore.count();// 数据拿取失败request.onerror = function(event) {console.log('事务失败');};//数据拿取成功request.onsuccess = function(event) {//这里数据拿取成功的话,传入的事件对象中的target的result就是我们拿取到的数据了//如果上面是用objectStore.get(1);拿取的那就是单个数据//使用objectStore.getAll();拿取的就是全部数据//不管拿取的那种数据都会被存到事件对象的target.result中去console.log(event.target.result);if (request.result) {console.log('Name: ' + request.result.name);console.log('Age: ' + request.result.age);console.log('Email: ' + request.result.email);} else {console.log('未获得数据记录');}};}
教你怎么玩indexedDB浏览器数据库,执行流程以及常见错误等等相关推荐
- 前端三种本地存储方式+indexedDB浏览器数据库存储
1.cookie存储: 特征:1.不同的浏览器存放的cookie位置不一样,也是不能通用的.2.cookie的存储是以域名形式进行区分的,不同的域下存储的cookie是独立的.3.我们可以设置cook ...
- firebird数据库安装连接的一些常见错误及解决方法
firebird数据库安装连接的一些常见错误及解决方法 最近有一个需求是把数据库里面的数据提取出来,这个数据库的后缀是.fdb,查阅资料可知应该是firebird数据库的文件,可是firebird数据 ...
- postgres数据库执行脚本时,错误ERROR: unterminated quoted string at or near处理
远程连接postgres数据库,通过psql执行执行SQL脚本 命令如下: psql -h 10.201.83.202 -p 15432 -U postgres -d fruit_tp -a -f f ...
- imp-00017: 由于 oracle 错误 6550,数据库IMP导入时常见错误说明-转自百度空间-三生有约...
问题一: IMP-00003: 遇到 ORACLE 错误 1119 ORA-01119: 创建数据库文件 'E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\ALARM01. ...
- java之struts2的执行流程讲解(1)
1.struts2的执行流程 请求--->Tomcat(判读项目是否存在)--->项目的web.xml--->struts2的核心过滤器 --->判读请求的资源(hello.a ...
- 一行代码,搞定浏览器数据库 IndexedDB
作者 | 星尘starx 来源 | https://juejin.cn/post/6918705632757415950 前言 2021 年,如果你的前端应用,需要在浏览器上保存数据,有三个主流方案可 ...
- indexed true mysql_一行代码,搞定浏览器数据库 IndexedDB
前言 2021 年,如果你的前端应用,需要在浏览器上保存数据,有三个主流方案可以选择: Cookie:上古时代就已存在,但能应用的业务场景非常有限 LocalStorage:使用简单灵活,但是容量只有 ...
- 浏览器数据库 IndexedDB
浏览器数据库 IndexedDB 随着浏览器的功能不断增强,越来越多的网站开始考虑,将大量数据储存在客户端,这样可以减少从服务器获取数据,直接从本地获取数据. 现有的浏览器数据储存方案,都不适合储存大 ...
- 浏览器数据库IndexedDB
概述 随着浏览器的功能不断增强,越来越多的网站开始考虑,将大量数据储存在客户端,这样可以减少从服务器获取数据,直接从本地获取数据. Cookie 的大小不超过4KB,且每次请求都会发送回服务器: Lo ...
最新文章
- Kali Linux 2020.1b发布了
- 菜鸟也学DW做ASP
- mysql插入数据返回主键值_Mysql千万级别数据批量插入只需简单三步!
- Codeforces 889C Maximum Element(DP + 计数)
- php 检测数组内是否有空值,PHP判断数组是否为空的常用方法
- RemoveError: ‘setuptools‘ is a dependency of conda
- 3d建模电脑配置要求_建模你会一个软zbrush够吃一辈子,你学会了吗?
- .Net/C# 实现真正的只读的 Hashtable 类型的属性 (ReadOnly Hashtable Property)
- 五个部署Hyper-v的常见错误.
- Atitit 多语言互相调用总结mltlan invk现在我们开发项目往往会采用多种语言,各取所长 组合使用。。常常需要互相调用为什么会调用多种语言?1.开发效率与可读性 ,一种情况是实现同
- 计算机毕业设计 SSM+Vue音乐播放网站系统 云音乐播放系统 付费音乐播放系统Java Vue MySQL数据库 远程调试 代码讲解
- 计算机word图表布布局在哪,word中的页面布局在哪里
- python局域网文件互传
- 编程实践精华总结集锦系列1: SpringBoot/Maven/IDEA/Java/Kotlin/Redis等等
- python使用126发邮件代码
- java编写猜词游戏
- 数据结构 --- 图的遍历 DFS、BFS
- 一个简易版的新闻应用(同时兼容手机和平板)
- 下载、安装Ctex及编译自动化学报模板时错误的解决
- 视频号如何上热门的几个指标:国仁楠哥