indexDB学习记录

为什么学习indexDB,它虽然是在浏览器上,但是实际存储是跟本地的磁盘相关,所以当存储大文件时数据,尤其在离线存储和大数据量处理方面。,就可以使用indexDB了

 了解indexDB

indexDB是浏览器提供的非线性数据库,由仓库-表-索引组成,表之间是无法关联,因为是非线性。

indexDB基础使用

来自b站学习

方法 

function openDB(dbName, version = 1) {
    return new Promise((resolve, reject) => {
        // 兼容浏览器
        const indexDB = window.indexedDB || window.mozIndexDB || window.webkitIndexDB || window.msIndexDB;
        let db;
        // 打开数据库,没有就创建
        const request = indexDB.open(dbName, version);
        // 数据打开并回调
        request.onsuccess = function (event) {
            db = event.target.result; // 数据对象
            console.log('打开成功')
            resolve(db)
        };
        // 数据库打开失败回调
        request.onerror = function (event) {
            console.log('数据库打开失败');
            reject('数据库打开失败')
        }

        // 数据库有更新时就回调,创建表时,要版本更新
        request.onupgradeneeded = function (event) {
            // 创建或升级时会触发
            console.log('upgradeneeded')
            db = event.target.result; // 数据对象
            var objectStore; // 仓库
            // 在dbName数据库,创建一个表
            objectStore = db.createObjectStore('bao', {
                keyPath: 'squencdId', // 这是主键
                // autoIncrement:true //实现自增1,2,3这种
            })
            // 创建索引,在后面查询数据的时候可以根据索引查   也可以理解为建表的结构
            //  objectStore.createIndex(库中某个字段,键的名字,对象[unique:是否唯一])
            objectStore.createIndex('link', 'link', { unique: false });
            objectStore.createIndex('squencdId', "squencdId", { unique: true });
            objectStore.createIndex('messageType', "messageType", { unique: false });
        }
    })
}

// 插入数据
function addData(db, storeName, data) {
    // 事务对象 指定表格名称和操作模式(只读或读写)  // 仓库对象
    var request = db.transaction([storeName], "readwrite").objectStore(storeName).add(data);
    request.onsuccess = function (event) {
        console.log('数据写入成功')
    }
    request.onerror = function (event) {
        console.log('数据读写失败')
    }
}

// indexDB查询只能通过主键、游标、索引查询

// 通过主键查询,这里的主键是的squencdId所对应的值    数据库对象,表名,主键的值
function getDataKey(db, storeName, keyValue) {
    return new Promise((resolve, reject) => {
        const transaction = db.transaction([storeName]); // 事务
        const objectStore = transaction.objectStore(storeName); // 仓库对象 
        const request = objectStore.get(keyValue);

        request.onerror = function (event) {
            console.log('事务失败')
        }

        request.onsuccess = function (event) {
            console.log('查询结果', event.target.result);
            resolve(event.target.result)
        }
    })
}


// 游标查询数据  逐行读取数据,存入数组,最终得到整个仓库的所以数据。
function cursorGetData(db, storeName) {
    return new Promise((resolve, reject) => {
        let list = [];
        var store = db.transaction(storeName, 'readwrite').objectStore(storeName);
        var request = store.openCursor(); // 开启游标对象
        // 游标对象开启成功
        request.onsuccess = function (e) {
            var cursor = e.target.result;
            // console.log('cursor',cursor)
            // 必须判断,有值才cursor.continue(); 
            if (cursor) {
                list.push(cursor.value);
                cursor.continue(); // 遍历了存储对象中所有内容
            } else {
                console.log('游标读取数据', list)
                resolve(list)
            }
        }
    })

}


// 索引查询
function getDataByIndex(db, storeName, indexName, indexValue) {
    return new Promise((resolve, reject) => {
        var store = db.transaction(storeName, 'readwrite').objectStore(storeName);
        var request = store.index(indexName).get(indexValue);
        request.onerror = function () {
            console.log('事务失败')
        }
        request.onsuccess = function (e) {
            const result = e.target.result;
            console.log('索引查询结果', result);
            resolve(result)
        }
    })
}

// 通过索引和游标一起查询
function cursorGetDataByIndex(db, storeName, indexName, indexValue) {
    return new Promise((resolve, reject) => {
        let list = [];
        var store = db.transaction(storeName, 'readwrite').objectStore(storeName);
        var request = store.index(indexName).openCursor(IDBKeyRange.only(indexValue));
        request.onerror = function () {
            console.log('事务失败')
        }
        request.onsuccess = function (e) {
            const cursor = e.target.result;
            if (cursor) {
                list.push(cursor.value);
                cursor.continue(); // 遍历了存储对象中所有内容
            } else {
                console.log('游标索引查询结果', list)
                resolve(list)
            }
        }
    })
}

// 通过索引和游标的分页查询
function cursorGetDataByIndexAndPage(db, storeName, indexName, indexValue, page, pageSize) {

    return new Promise((resolve, reject) => {
        cursorGetDataByIndex(db, storeName, indexName, indexValue).then(res => {
            const total = res.length;
            const totalPage =  Math.ceil(total / pageSize);

            if( totalPage < page){
                resolve({
                    data: [],
                    total: total,
                    totalPage: totalPage,
                    current: page,
                    size: pageSize
                })
                return
            }

            let list = [];
            let counter = 0; // 计数器
            let advanced = true; // 是否跳过查询
            var store = db.transaction(storeName, 'readwrite').objectStore(storeName);
            var request = store.index(indexName).openCursor(IDBKeyRange.only(indexValue));
            request.onerror = function () {
                console.log('事务失败')
            }

            request.onsuccess = function (e) {
                let cursor = e.target.result;
                if (page > 1 && advanced) {
                    advanced = false;
                    cursor.advance((page - 1) * pageSize);  // 跳过多少条
                    return
                }

                if (cursor) {
                    list.push(cursor.value);
                    counter++;
                    if (counter < pageSize) {
                        cursor.continue(); // 遍历了存储对象中所有内容
                    } else {
                        console.log('游标索引分页查询结果', list)
                        cursor = null;
                        resolve({
                            data: list,
                            total: total,
                            totalPage: totalPage,
                            current: page,
                            size: pageSize
                        });
                    }
                } else {
                    console.log('游标索引分页查询结果', list)
                    resolve({
                        data: list,
                        total: total,
                        totalPage: totalPage,
                        current: page,
                        size: pageSize
                    });
                }
            }
        })
    })

}

// 更新数据 主键值存在就更新,不存在就添加
function updataDB(db,storeName,data){
    return new Promise((resolve, reject) => {
        var request = db.transaction(storeName, 'readwrite').objectStore(storeName).put(data);
        
        request.onerror = function () {
            console.log('数据更新失败')
            reject()
        }
        request.onsuccess = function (e) {
            console.log('数据更新成功')
            resolve()
        }
    })
}


// 通过主键值,删除数据
function deleteDB(db,storeName,id){
    return new Promise((resolve, reject) => {
        var request = db.transaction(storeName, 'readwrite').objectStore(storeName).delete(id);
        
        request.onerror = function () {
            console.log('删除失败')
            reject()
        }
        request.onsuccess = function (e) {
            console.log('删除成功')
            resolve()
        }
    })
}

// 通过索引和游标,删除数据
function cursorDelete(db,storeName,indexName,indexValue){
    return new Promise((resolve, reject) => {
        var store = db.transaction(storeName, 'readwrite').objectStore(storeName)
        var request = store.index(indexName).openCursor(IDBKeyRange.only(indexValue));
        
        request.onerror = function () {
            console.log('删除失败')
            reject()
        }
        request.onsuccess = function (e) {
            var cursor = e.target.result;
            var deleteRequest;
            if(cursor){
                deleteRequest = cursor.delete();
                deleteRequest.onerror = function(){
                    console.log('游标删除数据失败')
                    reject();
                };
                deleteRequest.onsuccess = function(){
                    console.log('游标删除数据成功')
                    resolve();
                }
                cursor.continue();
            }
            resolve()
        }
    })
}

function closeDB(db){
    db.close();
    console.log('数据库已关闭')
}

 使用

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="./indexDB.js"></script>
  <title>Document</title>
</head>

<body>

  <button id="dbBtn">打开数据库</button>

  <script>
    const dbBtnDom = document.getElementById('dbBtn');
    var hasOpen = false;
    var db;
    // 创建数据库
    const openTheDB = async () => {
      db = await openDB('test', 1);
      // 插入数据
      const data = {
        link: '1',
        squencdId: Math.floor(Math.random() * 100),
        messageType: Math.floor(Math.random() * 100)
      }

      // addData(db, 'bao', data)

      // 通过主键查询
      getDataKey(db, 'bao', 15).then(res => {
        // console.log('查询结果',res)
      })

      // 游标查询
      cursorGetData(db, 'bao');

      // 索引查询  若是值有重复,只返回查询索引值的第一个
      getDataByIndex(db, 'bao', 'link', '1');

      // 通过索引和游标一起查询,只要link='1'都返回
      cursorGetDataByIndex(db, 'bao', 'link', '1')

      // 通过索引和游标的分页查询
      cursorGetDataByIndexAndPage(db, 'bao', 'link', '1', 1, 5).then(res => {
        console.log('通过索引和游标的分页查询', res);
      });

      // 更新数据
      updataDB(db, 'bao', { link: '1', squencdId: 7, messageType: 12 });

      // 删除数据
      // deleteDB(db,'bao',7);

      // 通过索引和游标,删除数据
      cursorDelete(db, 'bao', 'messageType', 35)
    }


    dbBtnDom.onclick = () => {
      if (hasOpen) {
        dbBtnDom.innerHTML = '打开数据库'
        hasOpen = false;
        closeDB(db);
        db = null;
      } else {
        hasOpen = true;
        dbBtnDom.innerHTML = '关闭数据库';
        openTheDB();
      }
    }

    window.addEventListener('beforeunload', function (e) {
      e.preventDefault();
      closeDB(db);
    });

  </script>
</body>

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值