美文网首页
indexDB数据库初学之一

indexDB数据库初学之一

作者: 焚心123 | 来源:发表于2023-11-08 15:45 被阅读0次
    • indexDB就是浏览器内置的前端数据库,跟localStorage等一样可进行存储,不过indexDB可以存储250~300MB,当然又优点也会有缺点,选择适合项目的就可以,下面简单的介绍下如何使用
    • 连接数据库
    const data = reactive({
                    db: null,
                    storeName: 'test', //当前的数据库名
                    version: 1, //版本号
                    obj: {
                        name: 4,
                        id: 4,
                        age: 66,
                        list: [1, 2, 3]
                    }
                })
    function init(data) {
            const request = (window.indexedDB || window.webkitIndexedDB).open(data.storeName, data
                .version)
            request.onsuccess = e => {
                console.log('数据库打开成功', e.target.result);
                data.db = e.target.result
            }
            request.onerror = e => {
                console.log('数据库启动报错', e);
                throw Error('数据库报错啦:' + e.target.result)
            }
            //数据库创建或者升级的时候都会触发
            request.onupgradeneeded = e => {
                data.db = e.target.result
                let objectStore = null
                if (!data.db.objectStoreNames.contains(data.storeName)) {
                    //在数据库中创建表group,设置主键为id,属性中必须要有id的字段
                    objectStore = data.db.createObjectStore(data.storeName, {
                        keyPath: 'id'
                    })
                    //创建索引indexName指向表中的name字段且设为唯一值,不能重复,属性中可以没有name属性,但是id必须要有
                    objectStore.createIndex('indexName', 'name', {
                        unique: true
                    }) // 创建索引 可以让你搜索任意字段
    
                }
            }
        }
    
    
    • 上面的代码中使用了id作为主键,在添加的属性中必须要有id这个字段,storeName是数据库的名字,可以有多个数据库

    • 添加数据

     //添加数据
        const addData = (db, storeName, obj) => {
            //readwrite 读写操作的权限
            const request = db.transaction([storeName], 'readwrite').objectStore(storeName).add(obj)
            request.onsuccess = e => {
                console.log('写入成功', e.target.result);
                //这里可以做一些操作,添加第一次之后数据还是相同的就要进行阻止或者清空,否则报错
                //readyState为done是添加完毕
            }
            request.onerror = e => {
                console.log('写入失败:', e);
                throw Error('写入失败:' + e.target.result)
            }
        }
    

    这里是使用vue进行练习的,如果你的添加数据使用的是响应式的,那么就需要转为原始的数据才可以添加成功,reactive转为toRaw

    • 获取数据
    // 获取某一条数据
        const getData = (db, storeName, key) => {
            // transaction 第二个参数不写,默认是只读,key是当前属性的id值
            const request = db.transaction([storeName]).objectStore(storeName).get(key)
            request.onsuccess = e => {
                console.log('读取成功', e.target.result);
    
            }
            request.onerror = e => {
                console.log('读取失败:', e);
                throw Error('读取失败:' + e.target.result)
            }
        }
    
    • 获取当前数据库下当前表下的全部数据
     const getAllData = (db, storeName) => {
            // transaction 第二个参数不写,默认是只读
            const request = db.transaction([storeName]).objectStore(storeName).getAll()
            request.onsuccess = e => {
                console.log('读取全部成功', e.target.result);
    
            }
            request.onerror = e => {
                console.log('读取全部失败:', e);
                throw Error('读取全部失败:' + e.target.result)
            }
        }
    
    • 通过索引值进行查询数据
     // 通过索引name获取数据
        const getNameData = (db, storeName, name) => {
            // transaction 第二个参数不写,默认是只读
            const request = db.transaction([storeName]).objectStore(storeName).index('indexName').get(name)
            request.onsuccess = e => {
                console.log('读取索引成功', e.target.result);
    
            }
            request.onerror = e => {
                console.log('读取索引失败:', e);
                throw Error('读取索引失败:' + e.target.result)
            }
        }
    
    • 更新某一条数据
     // 更新某一条数据
        const upData = (db, storeName, data) => {
            // data 是当前的某一条数据更新的对象
            const request = db.transaction([storeName], 'readwrite').objectStore(storeName).put(data)
            request.onsuccess = e => { //readyState为done是更新完毕,或者result会返回当前的id值可进行判断
                console.log(e.target.result, e.target);
                console.log('更新成功', e.target.result);
    
            }
            request.onerror = e => {
                console.log('更新失败:', e);
                throw Error('更新失败:' + e.target.result)
            }
        }
    
    • 删除某一条数据
      // 删除某一条数据
        const deleteData = (db, storeName, key) => {
            const request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(key); //key---id值
            request.onsuccess = e => { //readyState为done是更新完毕
                console.log(e.target.result, e.target);
                console.log('删除成功', e.target.result);
    
            }
            request.onerror = e => {
                console.log('删除失败:', e);
                throw Error('删除失败:' + e.target.result)
            }
        }
    
    • 遍历当前表下的所有数据,第二个方法可做分页的操作
     // 使用指针遍历所有值使用id
        const fORData = (db, storeName) => {
            const request = db.transaction([storeName], 'readwrite').objectStore(storeName)
            request.openCursor().onsuccess = e => { //readyState为done是更新完毕
                var cursor = event.target.result;
                if (cursor) {
                    console.log("当前的id值: " + cursor.key + " 和age值 " + cursor.value.age);
                    cursor.continue();
                } else {
                    console.log("结束遍历");
                }
    
            }
            request.onerror = e => {
                console.log('遍历所有值失败:', e);
                throw Error('遍历所有值失败:' + e.target.result)
            }
        }
        // 使用指针遍历所有值,使用name索引
        const fORData1 = (db, storeName) => {
            const objectStore = db.transaction([storeName]).objectStore(storeName)
            var index = objectStore.index("indexName");
            const range = IDBKeyRange.bound(1, 10); //遍历id从1到10的数据
            index.openCursor(range).onsuccess = function (event) {
                var cursor = event.target.result;
                if (cursor) {
                    console.log("当前的name值: " + cursor.key + " 和age值 " + cursor.value.id);
                    cursor.continue();
                } else {
                    console.log("结束遍历");
                }
            };
    
            index.openCursor(range).onerror = e => {
                console.log('遍历所有值失败:', e);
                throw Error('遍历所有值失败:' + e.target.result)
            }
        }
    
    • 最后整体的代码如下
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    </head>
    
    <body>
        <div id="app">
            <button @click="startDB">启动数据库</button>
            <button @click="addBase">添加数据</button>
            <button @click="getBase">读取数据</button>
            <button @click="getNameBase">读取索引数据</button>
            <button @click="getAllBase">读取全部数据</button>
            <button @click="upBase">更新数据</button>
            <button @click="deleteBase">删除数据</button>
            <button @click="forBase">指针遍历</button>
        </div>
    </body>
    
    </html>
    <script>
        const {
            createApp,
            reactive,
            toRefs,
            toRaw
        } = Vue
    
        createApp({
            setup() {
                const data = reactive({
                    db: null,
                    storeName: 'test', //当前的数据库名
                    version: 1, //版本号
    
                    obj: {
                        name: 44,
                        id: 44,
                        age: 66,
                        list: [1, 2, 3]
                    }
    
                })
                // 启动数据库
                const startDB = () => {
                    init(data)
                }
                //添加数据
    
                const addBase = () => {
                    //使用reactive会将数据变为响应式,添加会报错,将响应式数据转为原始对象(不是响应式的就可以存储)
                    addData(data.db, data.storeName, toRaw(data.obj))
                }
    
                // 获取数据
    
                const getBase = () => {
                    getData(data.db, data.storeName, 7) //根据id进行读取
                }
                // 更新某一项
                const upBase = () => {
                    upData(data.db, data.storeName, {
                        id: 6,
                        age: 222,
                        list: 333
                    }) //根据id进行读取
                }
                // 删除某一项
                const deleteBase = () => {
                    deleteData(data.db, data.storeName, 5) //根据id进行读取
                }
                // 读取全部的数据
                const getAllBase = () => {
                    getAllData(data.db, data.storeName)
                }
                // 读取索引的数据
                const getNameBase = () => {
                    getNameData(data.db, data.storeName, 6)
                }
                const forBase = () => {
                    fORData(data.db, data.storeName) //遍历有id值
                    fORData1(data.db, data.storeName) //遍历通过name索引
    
    
                }
                return {
                    startDB,
                    addBase,
                    getBase,
                    upBase,
                    deleteBase,
                    getAllBase,
                    getNameBase,
                    forBase,
                    ...toRefs(data)
                }
            }
        }).mount('#app')
    
        function init(data) {
            const request = (window.indexedDB || window.webkitIndexedDB).open(data.storeName, data
                .version)
            request.onsuccess = e => {
                console.log('数据库打开成功', e.target.result);
                data.db = e.target.result
            }
            request.onerror = e => {
                console.log('数据库启动报错', e);
                throw Error('数据库报错啦:' + e.target.result)
            }
            //数据库创建或者升级的时候都会触发
            request.onupgradeneeded = e => {
                data.db = e.target.result
                let objectStore = null
                if (!data.db.objectStoreNames.contains(data.storeName)) {
                    //在数据库中创建表group,设置主键为id,属性中必须要有id的字段
                    objectStore = data.db.createObjectStore(data.storeName, {
                        keyPath: 'id'
                    })
                    //创建索引indexName指向表中的name字段且设为唯一值,不能重复,属性中可以没有name属性,但是id必须要有
                    objectStore.createIndex('indexName', 'name', {
                        unique: true
                    }) // 创建索引 可以让你搜索任意字段
    
                }
            }
        }
    
        //添加数据
        const addData = (db, storeName, obj) => {
            //读写操作
            const request = db.transaction([storeName], 'readwrite').objectStore(storeName).add(obj)
            request.onsuccess = e => {
                console.log('写入成功', e.target.result);
    
            }
            request.onerror = e => {
                console.log('写入失败:', e);
                throw Error('写入失败:' + e.target.result)
            }
        }
        // 获取数据
        const getData = (db, storeName, key) => {
            // transaction 第二个参数不写,默认是只读
            const request = db.transaction([storeName]).objectStore(storeName).get(key)
            request.onsuccess = e => {
                console.log('读取成功', e.target.result);
    
            }
            request.onerror = e => {
                console.log('读取失败:', e);
                throw Error('读取失败:' + e.target.result)
            }
        }
        // 通过索引name获取数据
        const getNameData = (db, storeName, name) => {
            // transaction 第二个参数不写,默认是只读
            const request = db.transaction([storeName]).objectStore(storeName).index('indexName').get(name)
            request.onsuccess = e => {
                console.log('读取索引成功', e.target.result);
    
            }
            request.onerror = e => {
                console.log('读取索引失败:', e);
                throw Error('读取索引失败:' + e.target.result)
            }
        }
        // 获取数据
        const getAllData = (db, storeName) => {
            // transaction 第二个参数不写,默认是只读
            const request = db.transaction([storeName]).objectStore(storeName).getAll()
            request.onsuccess = e => {
                console.log('读取全部成功', e.target.result);
    
            }
            request.onerror = e => {
                console.log('读取全部失败:', e);
                throw Error('读取全部失败:' + e.target.result)
            }
        }
        // 更新某一条数据
        const upData = (db, storeName, data) => {
            const request = db.transaction([storeName], 'readwrite').objectStore(storeName).put(data)
            request.onsuccess = e => { //readyState为done是更新完毕,或者result会返回当前的id值可进行判断
                console.log(e.target.result, e.target);
                console.log('更新成功', e.target.result);
    
            }
            request.onerror = e => {
                console.log('更新失败:', e);
                throw Error('更新失败:' + e.target.result)
            }
        }
        // 删除某一条数据
        const deleteData = (db, storeName, key) => {
            const request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(key); //key---id值
            request.onsuccess = e => { //readyState为done是更新完毕
                console.log(e.target.result, e.target);
                console.log('删除成功', e.target.result);
    
            }
            request.onerror = e => {
                console.log('删除失败:', e);
                throw Error('删除失败:' + e.target.result)
            }
        }
        // 使用指针遍历所有值使用id
        const fORData = (db, storeName) => {
            const request = db.transaction([storeName], 'readwrite').objectStore(storeName)
            request.openCursor().onsuccess = e => { //readyState为done是更新完毕
                var cursor = event.target.result;
                if (cursor) {
                    console.log("当前的id值: " + cursor.key + " 和age值 " + cursor.value.age);
                    cursor.continue();
                } else {
                    console.log("结束遍历");
                }
    
            }
            request.onerror = e => {
                console.log('遍历所有值失败:', e);
                throw Error('遍历所有值失败:' + e.target.result)
            }
        }
        // 使用指针遍历所有值,使用name索引
        const fORData1 = (db, storeName) => {
            const objectStore = db.transaction([storeName]).objectStore(storeName)
            var index = objectStore.index("indexName");
            const range = IDBKeyRange.bound(1, 10); //遍历id从1到10的数据
            index.openCursor(range).onsuccess = function (event) {
                var cursor = event.target.result;
                if (cursor) {
                    console.log("当前的name值: " + cursor.key + " 和age值 " + cursor.value.id);
                    cursor.continue();
                } else {
                    console.log("结束遍历");
                }
            };
    
            index.openCursor(range).onerror = e => {
                console.log('遍历所有值失败:', e);
                throw Error('遍历所有值失败:' + e.target.result)
            }
        }
    </script>
    
    • 代码中的onsuccess和onerror函数可以封装一个公共的或者你有更好的方式

    相关文章

      网友评论

          本文标题:indexDB数据库初学之一

          本文链接:https://www.haomeiwen.com/subject/ppuqwdtx.html