操作全是异步

开启数据库

indexedDB.open()为开启的API,还可以为开启的数据库设置版本号

// 打开数据库
let request, database;

request = indexedDB.open('test');

request.onerror = function (event) {
    console.log(event);
}

request.onsuccess = function (event) {
    console.log(event);

    database = event.target.result;

    // 设置版本号
    if (database.version != '1.0') {
        request = database.setVersion('1.0');

        request.onerror = function (event) {
        console.log(`错误码${event.target.errorCode}`);
        }

        request.onsuccess = function (event) {
            console.log(`已经设置数据库${database.name}的版本为${database.version}`);
        }
    } else {
        console.log(`数据库${database.name}的版本号为${database.version}`);
    }
}

数据库第一次开启后,关闭浏览器再次打开调用open,则相当于连接该数据库。

数据库“建表”,插入store

插入indexedDB中的对象,类似于MySQL中的建表操作,需要建立好数据库才能调用,API为database.createObjectStore("books", {keyPath: "isbn"}),注意,该方法只能在open的回调中的onupgradeneeded的方法中使用

一个版本建立多个存储空间

一个版本创建多个存储空间,只能在一次数据库更新或者创建的时候,在onupgradeneeded中一次性创建多个。

// 来自w3c的例子
// 这里用createIndex来创建不同的keypath的存储空间
const request = indexedDB.open("library");
let db;

request.onupgradeneeded = function() {
  // The database did not previously exist, so create object stores and indexes.
  const db = request.result;
  const store = db.createObjectStore("books", {keyPath: "isbn"});
  const titleIndex = store.createIndex("by_title", "title", {unique: true});
  const authorIndex = store.createIndex("by_author", "author");

  // Populate with initial data.
  store.put({title: "Quarry Memories", author: "Fred", isbn: 123456});
  store.put({title: "Water Buffaloes", author: "Fred", isbn: 234567});
  store.put({title: "Bedrock Nights", author: "Barney", isbn: 345678});
};

request.onsuccess = function() {
  db = request.result;
};

更新数据库

indexedDB.open(database, version)的第二个参数去升级数据库版本,注意version只能大于等于最新版本,等于时触发onsuccess,大于时依次触发onupgradeneededonsuccess方法,另外需要注意的时,version不能是浮点数,否则2.4 => 2不会触发onupgradeneeded方法

事务

indexedDB.transactionopen中的回调onsuccessonupgradeneeded中都可以使用,都用来增删改查数据库中存储空间的数据

对数据的操作
let db = request.result;
let transaction = db.transaction('books2', 'readwrite');
let store = transaction.objectStore('books2');

//let addRequest1 = store.add({
//    author: 'lalala2',
//    title: '测试用的2',
//    isbn: 324552
//});

//addRequest1.onerror = function(e){
//    console.log('失败', e);
//}
//addRequest1.onsuccess = function(e){
//    console.log('成功', e);
//}
let addRequest = store.add({
    author: 'lalala',
    title: '测试用的1',
    isbn: 334552
});
let addRequest = store.add({
    author: 'lalala',
    title: '测试用的1',
    isbn: 334552
});

addRequest.onerror = function(e){
    console.log(e);
}
addRequest.onsuccess = function(e){
    let getAdd = store.get(e.target.result);
    getAdd.onsuccess = function(e){
        console.log(e);
    }
    getAdd.onerror = function(e){
        console.log(e);
    }
}
//let addRequest2 = store.add({
//    author: 'lalala1',
//    title: '测试用的1',
//    isbn: 314552
//});

//addRequest2.onerror = function(e){
//    console.log('失败', e);
//}
//addRequest2.onsuccess = function(e){
//    console.log('成功', e);
//}
let deleteData = store.delete(234567);
deleteData.onsuccess = function(e){
    console.log('删除', e);
}
  1. 事务是异步的
  2. 修改、删除、增加的数据在控制台不会即时刷新,但是可以获取到
  3. 如果在同一个事务中,增删改查的操作有一个失败了,那么其后的操作都会失败,例如上述的代码,如果先添加数据,再添加注释的数据,则后面的注释数据则会添加失败。
  4. get获取数据后,可以在其中修改,再put,例子可以看mdn上

游标

可以理解为Object.keys()这个方法,只不过openCursor接受的两个参数让遍历整个存储空间更方便。

  1. 第一个参数IDKeyRange
  2. 第二个参数nextprevnextuniqueprevunique(后面两个用于游标查询的数据可能不止一条情况,只会返回键值最小的,但是在IDKeyRange用创建存储空间的keypath时,基本不会出现一个键值索引到多条数据的情况)用于遍历顺序
// 这里是选取不同keypath的存储空间,可以配合IDKeyRange来指定唯一键值
const tx = db.transaction("books", "readonly");
const store = tx.objectStore("books");
const index = store.index("by_author");

let keyRange = IDBKeyRange.bound("Barney", "Fred", false, true);

index.openCursor(keyRange, 'next').onsuccess = function(e){
    console.log(e);
    let cursor = e.target.result;
    if(cursor){
        console.log('存在游标', `name: ${cursor.value.author},title: ${cursor.value.title}`);
        cursor.continue();
    } else {
        console.log('游标失败');
    }
};

另外,各种IDKeyRange的API可以去mdn查询


远远的飞梦
53 声望12 粉丝

人的意志可以创造梦想