indexDB项目demo

1,567 阅读4分钟

indexedDB就是一个非关系型数据库,它不需要你去写一些特定的sql语句来对数据库进行操作,因为它是nosql的,数据形式使用的是json

出现的意义

IndexedDB很适合存储大量数据,它的API是异步调用的。IndexedDB使用索引存储数据,各种数据库操作放在事务中执行。IndexedDB甚至还支持简单的数据类型。IndexedDB比localstorage强大得多,但它的API也相对复杂。对于简单的数据,你应该继续使用localstorage,但当你希望存储大量数据时,IndexedDB会明显的更适合,IndexedDB能提供你更为复杂的查询数据的方式。

indexedDB的特性

  1. 有了数据库后我们自然希望创建一个表用来存储数据,但indexedDB中没有表的概念,而是objectStore,一个数据库中可以包含多个objectStore,objectStore是一个灵活的数据结构,可以存放多种类型数据。也就是说一个objectStore相当于一张表,里面存储的每条数据和一个键相关联。我们可以使用每条记录中的某个指定字段作为键值(keyPath),也可以使用自动生成的递增数字作为键值(keyGenerator),也可以不指定。选择键的类型不同,objectStore可以存储的数据结构也有差异。
键类型存储数据
不使用任意值,但是没添加一条数据的时候需要指定键参数
keyPath任意值,但是没添加一条数据的时候需要指定键参数
keyGenerator任意值
都使用Javascript对象,如果对象中有keyPath指定的属性则不生成新的键值,如果没有自动生成递增键值,填充keyPath指定属性
  1. 事务性

在indexedDB中,每一个对数据库操作是在一个事务的上下文中执行的。事务范围一次影响一个或多个object stores,你通过传入一个object store名字的数组到创建事务范围的函数来定义。例如:db.transaction(storeName, 'readwrite'),创建事务的第二个参数是事务模式。当请求一个事务时,必须决定是按照只读还是读写模式请求访问。

  1. 基于请求

对indexedDB数据库的每次操作,描述为通过一个请求打开数据库,访问一个object store,再继续。IndexedDB API天生是基于请求的,这也是API异步本性指示。对于你在数据库执行的每次操作,你必须首先为这个操作创建一个请求。当请求完成,你可以响应由请求结果产生的事件和错误。

  1. 异步

在IndexedDB大部分操作并不是我们常用的调用方法,返回结果的模式,而是请求—响应的模式,所谓异步API是指并不是这条指令执行完毕,我们就可以使用request.result来获取indexedDB对象了,就像使用ajax一样,语句执行完并不代表已经获取到了对象,所以我们一般在其回调函数中处理。

代码示例

项目实战

// 创建/更新一个数据库
    let creatUpdateStore = function (name, verson = 1) {
        console.log('creatUpdateStore');
        // 打开数据库
        let request = window.indexedDB.open(name, verson);

        request.onsuccess = function (event) {
            console.log('open success');
        };

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

        request.onupgradeneeded = function (event) {
            let db = event.target.result;
            if (!db.objectStoreNames.contains(name)) {
                // 创建仓库对象(创建表格)
                // 这里我将主键设置为id
                let objectStore = db.createObjectStore(name, {
                    keyPath: 'id',
                    autoIncrement: true
                });
            }
        };
    };

    // 往数据库中加数据
    let addDataStore = function (storeName, data, verson) {
        console.log('addDataStore');
        return new Promise((resolve, reject) => {
            let databaseName = storeName;
            let databaseVersion = verson || 1;
            let db;
            let request = indexedDB.open(databaseName, databaseVersion);
            request.onsuccess = function (event) {
                db = event.target.result;
                db = event.target.result;
                // 将数据保存到新建的对象仓库
                let objectStore = db
                    .transaction(databaseName, 'readwrite')
                    .objectStore(databaseName);
                if (uf.utils.typeof(data, 'array')) {
                    data.forEach(function (dataItem) {
                        // 添加一条数据
                        objectStore.add(dataItem);
                    });
                    resolve();
                } else {
                    // 添加一条数据
                    objectStore.add(data);
                    resolve();
                }
            };
            request.error = function () {
                reject();
            };
            request.onupgradeneeded = function (event) {
                let db = event.target.result;
                if (!db.objectStoreNames.contains(storeName)) {
                    // 创建仓库对象(创建表格)
                    // 这里我将主键设置为id
                    let objectStore = db.createObjectStore(storeName, {
                        keyPath: 'id',
                        autoIncrement: true
                    });
                }
            };
        });
    };

    // 获取数据
    let getStoreData = function (name, key = 1) {
        console.log('getStoreData');
        return new Promise((resolve, reject) => {
            let request = indexedDB.open(name);
            request.onsuccess = function (event) {
                let db = event.target.result;
                let req;
                try {
                    req = db
                        .transaction(name, 'readwrite')
                        .objectStore(name)
                        .get(key); // 这里的“1”也是主键的键值
                } catch (e) {
                    reject('用户失败');
                }
                if (!req) {
                    return;
                }
                req.onsuccess = function () {
                    resolve(req.result)
                };
                req.onerror = function () {
                    reject('获取失败');
                };
            };
            request.onupgradeneeded = function (event) {
                let db = event.target.result;
                if (!db.objectStoreNames.contains(name)) {
                    // 创建仓库对象(创建表格)
                    // 这里我将主键设置为id
                    let objectStore = db.createObjectStore(name, {
                        keyPath: 'id',
                        autoIncrement: true
                    });
                }
            };
        });
    };
    // 删除数据
    let delectStoreData = function (name, key) {
        console.log('delectStoreData');
        return new Promise((resolve, reject) => {
            let databaseName = name;
            let db;
            let request = window.indexedDB.open(databaseName);
            request.onsuccess = function (event) {
                db = event.target.result;
                let req = db
                    .transaction(databaseName, 'readwrite')
                    .objectStore(databaseName)
                    .delete(key); // 这里指定的是主键的键值

                req.onsuccess = function () {
                    resolve('删除成功');
                };

                req.onerror = function () {
                    reject('删除失败');
                };
            };
        });
    };
    // 更新
    let updateStoreData = function (storeName, newData, key) {
        console.log('updateStoreData');
        return new Promise((resolve, reject) => {
            let request = window.indexedDB.open(storeName);
            let db;
            request.onsuccess = function (event) {
                db = event.target.result;
                let transaction = db.transaction(storeName, 'readwrite');
                let store = transaction.objectStore(storeName);
                let storeData = store.get(key);

                storeData.onsuccess = function (e) {
                    let data = e.target.result || {};
                    for (a in newData) {
                        data[a] = newData[a];
                    }
                    store.put(data);
                    resolve();
                };
            };
            request.onupgradeneeded = function (event) {
                let db = event.target.result;
                if (!db.objectStoreNames.contains(storeName)) {
                    // 创建仓库对象(创建表格)
                    // 这里我将主键设置为id
                    let objectStore = db.createObjectStore(storeName, {
                        keyPath: 'id',
                        autoIncrement: true
                    });
                }
            };
        });
    };
    // 遍历获取
    let storeDataList = function (storeName) {
        console.log('storeDataList');
        return new Promise((resolve, reject) => {
            let request = window.indexedDB.open(storeName);
            let db;
            request.onsuccess = function (event) {
                db = event.target.result;
                let transaction = db.transaction(storeName);
                let store = transaction.objectStore(storeName);
                let cursor = store.openCursor();//打开游标
                let dataList = new Array();
                cursor.onsuccess = function (e) {
                    var cursorVal = e.target.result;
                    if (cursorVal) {
                        dataList.push(cursorVal.value);
                        cursorVal.continue();
                    } else {
                        // 遍历结束
                        resolve(dataList);
                    }
                };
            };
            request.onupgradeneeded = function (event) {
                let db = event.target.result;
                if (!db.objectStoreNames.contains(storeName)) {
                    // 创建仓库对象(创建表格)
                    // 这里我将主键设置为id
                    let objectStore = db.createObjectStore(storeName, {
                        keyPath: 'id',
                        autoIncrement: true
                    });
                }
            };
        });
    };


    // 批量删除
    function batchDelete(storeName, keys) {
        console.log('batchDelete');
        let allKeys = keys.map(item => {
            item = +item;
            return delectStoreData(storeName, item);
        });
        return allKeys;
        /* Promise.all(allKeys).then(data => {
             console.log(data);
             resolve(data);
         });*/
    }