浏览器 IndexedDB 简明教程 ( 七 ) - 数据库 ( IDBDatabase ) 方法

yufei       6 年, 9 月 前       1325

经过一夜长眠后,早上起来突然间想明白了 浏览器 IndexedDB 简明教程 ( 六 ) - IDBFactory 和删除数据库 中的 deleteDatabase 为什么会在 window.indexedDB

因为按照 IndexedDB 这种异步打开数据库的方式,如果要先创建一个数据库实例然后再调用相关方法来删除显得多余且复杂化了,还不如直接简单的提供一个静态的方法来删除

前面几章节中我们把创建数据库、升级数据库版本和删除数据库的操作讲完了,本章节我们就来了解下这个数据库对象 IDBDatabase

怎么得到 IDBDatabase 对象的实例

从前面的章节中,我们知道 IDBRequest 的回调函数 successonupgradeneeded 的参数 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( ) 当数据库结构发生变化时触发

范例

  1. 输出当前连接的数据库的名称、版本和存储对象列表

    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}
    

    因为我们没有创建任何数据库存储对象,所以存储对象列表是空的

  2. 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'});
    }
    
  3. 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});
    }
    
  4. 关闭数据库

    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 回调中数据库就是关闭了

    这两个回调事件用的是同一个数据库实例,也就是说,前面章节中,我们说的是可能是错的...

    在这里,我道歉,真的...抱歉误导了大家

  5. 删除存储对象

    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('删除存储对象成功');
    }
    

    输出结果如下

    升级成功
    删除存储对象成功
    打开数据库成功
    
  6. 如果指定的存储对象不存在,那么会引发删除失败,如果是在 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
    打开数据库失败
    

结束语

其实不止删除不存在的存储对象会报错,当存储对象存在时再执行一次创建动作也会失败,我们会再下一章节中说明

然后还剩下一个事务的方法我们没深入了解,这个等放到下下一章节吧

目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.