经过一夜长眠后,早上起来突然间想明白了 浏览器 IndexedDB 简明教程 ( 六 ) - IDBFactory 和删除数据库 中的 deleteDatabase
为什么会在 window.indexedDB
上
因为按照 IndexedDB 这种异步打开数据库的方式,如果要先创建一个数据库实例然后再调用相关方法来删除显得多余且复杂化了,还不如直接简单的提供一个静态的方法来删除
前面几章节中我们把创建数据库、升级数据库版本和删除数据库的操作讲完了,本章节我们就来了解下这个数据库对象 IDBDatabase
怎么得到 IDBDatabase
对象的实例
从前面的章节中,我们知道 IDBRequest
的回调函数 success
和 onupgradeneeded
的参数 event.target.result
就是一个 IDBDatabase
对象的实例
let db; //先删除 window.indexedDB.deleteDatabase('demo') const req = window.indexedDB.open('demo'); req.onerror = function (event) { console.log('打开数据库失败'); }; req.onsuccess = function (event) { db = event.target.result; console.log('打开数据库成功'); }; req.onupgradeneeded = function (event) { console.log(event.target.result); console.log('升级成功'); }
获取 Indexed 数据库实例的方法只有这两个,而且,非常重要的,千万不要认为 onupgradeneeded
中的 event.target.result
这个数据库实例是打开的,人家只是表示升级了的而已,虽然结果一样,但语意不一样
IDBDatabase 方法、属性和事件
通过展开上面代码的输出结果,我们可以发现 IDBDatabase
有着以下的方法、属性和回调事件
IDBDatabase 提供的方法
方法 | 说明 |
---|---|
IDBDatabase.close() | 关闭数据库 |
IDBDatabase.createObjectStore(name, [parameters]) | 创建一个新的存储对象 parameters 是个可选对象,有以下两个属性: {keyPath: "id"} 设置一个keyPath 键,被存储在存储对象空间中的所有对象都必须存在 id 。{autoIncrement: true} 自动生成数字键 |
IDBDatabase.deleteObjectStore("toDoList") | 删除指定 name 的存储对象 |
IDBDatabase.transaction(storeName, [mode]) | 立即返回一个 IDBTransaction 对象,然后在一个独立线程内开启一个事务。第一个参数是事务希望跨越的对象存储空间的列表( storeName 为字符串数组,如果你只需要访问一个对象存储空间,可以用一个字符串作为storeName) 。如果你希望事务能够跨越所有的对象存储空间你可以传入一个空数组。第二个参数定义了事务的访问类型: readonly ( 默认 ) 或者 readwrite |
IDBDatabase 提供的属性
属性 | 说明 |
---|---|
IDBDatabase.name | 只读,数据库的名称 |
IDBDatabase.version | 只读,数据库的版本号 |
IDBDatabase.objectStoreNames | 只读,当前连接的数据库中的存储对象名称的列表 |
IDBDatabase 提供的回调事件
事件 | 说明 |
---|---|
IDBDatabase.onabort = function( ) | 当数据库访问被中止时触发 |
IDBDatabase.onerror = function( ) | 访问数据库失败触发 |
IDBDatabase.onversionchange = function( ) | 当数据库结构发生变化时触发 |
范例
-
输出当前连接的数据库的名称、版本和存储对象列表
let db; //先删除 window.indexedDB.deleteDatabase('demo') const req = window.indexedDB.open('demo'); req.onerror = function (event) { console.log('打开数据库失败'); }; req.onsuccess = function (event) { console.log('打开数据库成功'); db = event.target.result; //输出当前连接的数据库名称、版本和存储对象列表 console.log('数据库名称:', db.name); console.log('数据库版本:', db.version); console.log('数据库存储对象列表:',db.objectStoreNames); }; req.onupgradeneeded = function (event) { console.log('升级成功'); }
运行以上代码,输出结果如下
升级成功 打开数据库成功 数据库名称: demo 数据库版本: 1 数据库存储对象列表: DOMStringList {length: 0}
因为我们没有创建任何数据库存储对象,所以存储对象列表是空的
-
createObjectStore()
创建一个存储对象city
并且指定数据中的属性city_id
为主键创建和删除存储对象一般都在
onupgradeneeded
事件回调中完成,好像放在onsuccess
中会报错,let db; //先删除 window.indexedDB.deleteDatabase('demo') const req = window.indexedDB.open('demo'); req.onerror = function (event) { console.log('打开数据库失败'); }; req.onsuccess = function (event) { console.log('打开数据库成功'); db = event.target.result; }; req.onupgradeneeded = function (event) { console.log('升级成功'); let db2 = event.target.result; // 创建存储对象 `city` 并指定 `city_id` 为主键 db2.createObjectStore('city',{keyPath:'city_id'}); }
-
createObjectStore()
创建一个存储对象user
并使用自增数字作为主键let db; //先删除 window.indexedDB.deleteDatabase('demo') const req = window.indexedDB.open('demo'); req.onerror = function (event) { console.log('打开数据库失败'); }; req.onsuccess = function (event) { console.log('打开数据库成功'); db = event.target.result; }; req.onupgradeneeded = function (event) { console.log('升级成功'); let db2 = event.target.result; // 创建存储对象 `user` 并指定自增数字为主键 db2.createObjectStore('city',{autoIncrement: true}); }
-
关闭数据库
let db; //先删除 window.indexedDB.deleteDatabase('demo') const req = window.indexedDB.open('demo'); req.onerror = function (event) { console.log('打开数据库失败'); }; req.onsuccess = function (event) { console.log('打开数据库成功'); db = event.target.result; db.close(); }; req.onupgradeneeded = function (event) { console.log('升级成功'); let db2 = event.target.result; // 创建存储对象 `user` 并指定自增数字为主键 db2.createObjectStore('city',{autoIncrement: true}); db2.close(); }
运行结果如下
升级成功 打开数据库失败
nnd,说明什么,也就是说明在
onupgradeneeded
事件中,数据库就是已经打开的了,如果我们关闭了,那么在onsuccess
回调中数据库就是关闭了这两个回调事件用的是同一个数据库实例,也就是说,前面章节中,我们说的是可能是错的...
在这里,我道歉,真的...抱歉误导了大家
-
删除存储对象
let db; //先删除 window.indexedDB.deleteDatabase('demo') const req = window.indexedDB.open('demo'); req.onerror = function (event) { console.log('打开数据库失败'); }; req.onsuccess = function (event) { console.log('打开数据库成功'); db = event.target.result; }; req.onupgradeneeded = function (event) { console.log('升级成功'); let db2 = event.target.result; // 创建存储对象 `user` 并指定自增数字为主键 db2.createObjectStore('city',{autoIncrement: true}); // 删除之前创建的存储对象 `city` db2.deleteObjectStore('city'); console.log('删除存储对象成功'); }
输出结果如下
升级成功 删除存储对象成功 打开数据库成功
-
如果指定的存储对象不存在,那么会引发删除失败,如果是在
onupgradeneeded
事件中删除,那么会引发打开数据库失败let db; //先删除 window.indexedDB.deleteDatabase('demo') const req = window.indexedDB.open('demo'); req.onerror = function (event) { console.log('打开数据库失败'); }; req.onsuccess = function (event) { console.log('打开数据库成功'); db = event.target.result; }; req.onupgradeneeded = function (event) { console.log('升级成功'); let db2 = event.target.result; // 因为没创建,所以删除存储对象 `city` 失败 db2.deleteObjectStore('city'); console.log('删除存储对象成功'); }
运行结果如下
升级成功 Uncaught DOMException: Failed to execute 'deleteObjectStore' on 'IDBDatabase': The specified object store was not found 打开数据库失败
结束语
其实不止删除不存在的存储对象会报错,当存储对象存在时再执行一次创建动作也会失败,我们会再下一章节中说明
然后还剩下一个事务的方法我们没深入了解,这个等放到下下一章节吧