indexDB数据库初学之一

  • 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函数可以封装一个公共的或者你有更好的方式
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。