IndexedDB的使用

更新日期: 2019-07-16阅读: 1.6k标签: IndexedDB

1、简介

随着浏览器功能增强,许多网站开始将大量数据保存在客户端,从而减少从服务器获取数据的操作,提高了响应速度。
cookie 由于大小不超过 4kb,肯定不合适。
LocalStorage 大小在 2.5 - 10 M间(不同浏览器不同,比如Chrome为 5M),且不提供索引、查找慢,也不合适。
IndexedDB 就比较合适了,是浏览器提供的本地数据库,它可以被网页脚本创建和操作。IndexedDB 允许储存大量数据,提供查找接口,还能建立索引提高查询效率。


2、特点

(1)采用键值对存储。
  IndexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以"键值对"的形式保存。

(2)异步处理。
  IndexedDB 操作时采用异步处理,用户可以进行其它操作。

(3)支持事务。
  IndexedDB 支持事务,即要么完成、要么失败,不会出现完成一半的状态。

(4)存储空间大、且支持二进制存储。


3、相关概念

(1)数据库(IDBDatabase 对象)
  管理、存储数据的仓库。IndexedDB 数据库有版本的概念。同一个时刻,只能有一个版本的数据库存在。如果要修改数据库结构(新增或删除表、索引或者主键),只能通过升级数据库版本完成。

(2)对象仓库(IDBObjectStore 对象)
  每个数据库都包含若干对象仓库。可以理解为一个个数据表。

(3)数据记录  
  对象仓库中存储的即为数据记录,采用键值对保存。其中键唯一,值可以为任意类型。

(4)索引(IDBIndex 对象)
  为了提高查询效率,可以根据数据记录的主键建立索引。

(5)事务(IDBTransaction 对象)
  数据记录的读写和删改,都要通过事务完成。事务对象提供error、abort和complete三个事件,用来监听操作结果。

(6)操作请求(IDBRequest 对象)

(7)指针( IDBCursor 对象)
  可用于遍历数据。

(8)主键集合(IDBKeyRange 对象)


4、vue使用indexedDB快速入门实例

此处,我将创建一个 “test” 数据库, 其中有一个 “person” 表(对象仓库)

【main.js】
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')



【App.vue】
<template>
    <div>
        <small>添加前请先打开数据库(如数据库不存在则执行创建过程)</small><br /><br />
        <button @click="openDB">打开数据库</button>
        <button @click="deleteDB">删除数据库</button><br /><br />
        <button @click="closeDB">关闭数据库</button><br /><br />
        姓名:<input type="text" id="name" v-model="name"><br />
        年龄:<input type="number" id="age" min=1 v-model="age"><br />
        性别:
        男:<input type="radio" id="man" name="sex" value="male" v-model="sex">
        女:<input type="radio" id="woman" name="sex" value="female" v-model="sex"><br />

        <button @click="add">添加数据</button>
        <button @click="get">获取数据</button><br /> 
        <button @click="foreach">遍历数据</button><br /> 
        <button @click="update">更新数据</button><br /> 
        <button @click="remove">删除数据</button><br /> 
        <button @click="searchFromIndex">根据索引查数据</button><br /> 
    </div>
    <!--App -->
</template>

<script>
    import indexedDB from './indexedDB.js'
    export default {
        data () {
            return {
                name: 'tom',
                age: '12',
                sex: 'male'
            }
        },
        methods: {
            openDB() {
                indexedDB.openDB('test', 'person', 1)
            },

            deleteDB() {
                indexedDB.deleteDB('test')
            },
            
            closeDB() {
                indexedDB.closeDB('test')
            },
            
            add() {
                indexedDB.add('person', {name: this.name, age: this.age, sex: this.sex})
            },
            
            get() {
                indexedDB.get('person')
            },
            
            foreach() {
                indexedDB.foreach('person')
            },
            
            update() {
                indexedDB.update('person', {id: 4, name: this.name, age: this.age, sex: this.sex})
            },
            
            remove() {
                indexedDB.remove('person', 4)
            },
            
            searchFromIndex() {
                indexedDB.searchFromIndex('person', 'name', 'tom')
            }
        }
    }
</script>

<style>

</style>




【indexedDB.js】
// 定义一个全局变量,用于保存数据库连接(开发中应该不会这么写,此处只是帮助理解)
let db = null;  
export default {
    // indexedDB兼容
    indexedDB: window.indexedDB || window.webkitindexedDB || window.msIndexedDB || mozIndexedDB,

    // 打开数据库
    // dbname指的是 数据库名, version 指的是 版本号
    openDB(dbname, objectStoreName, version) {
        // 获取当前数据库版本号
        var version = version || 1

        // 获取数据库连接,若数据库不存在,会创建数据库(异步处理,根据情况自动触发下面三个事件)
        var request = this.indexedDB.open(dbname, version)

        // 获取数据库连接失败
        request.onerror = function(event) {
            console.log('IndexedDB数据库打开错误')
        }

        // 获取数据库连接成功 
        request.onsuccess = function(event, callback) {
            db = event.target.result;
            if (callback && (typeof callback === 'function')) {
                callback(db)
            }
            if (db != null) {
                console.log('数据库打开成功')
            }
        }

        // 创建新的储存空间(当第一次创建数据库、或者数据库版本号变化时会触发)
        request.onupgradeneeded = function(event) {
            console.log('数据库版本变化')
            console.log('创建数据库' + dbname)
            // 拿到数据库连接的结果对象
            db = event.target.result;

            // 判断当前数据库中表(对象仓库)是否存在(注意此处是数据库的表名,不是数据库名)
            if (!db.objectStoreNames.contains(objectStoreName)) {
                // 创建对象仓库,并设置主键自增
                var objectStore = db.createObjectStore(objectStoreName, {
                    keyPath: 'id',
                    autoIncrement: true
                })

                // 创建索引(根据需要创建)
                objectStore.createIndex('name', 'name', {
                    unique: false
                })

                objectStore.createIndex('age', 'age', {
                    unique: false
                })

                objectStore.createIndex('sex', 'sex', {
                    unique: false
                })
            }
        }

    },

    // 删除数据库
    deleteDB: function(dbname, callback) {
        // 删除数据库
        var deleteQuest = this.indexedDB.deleteDatabase(dbname);
        
        // 成功删除
        deleteQuest.onerror = function() {
            console.log('删除数据库出错' + event.target.message)
        }

        // 删除失败 
        deleteQuest.onsuccess = function() {
            if (callback && (typeof callback === 'function')) {
                callback()
            }
            console.log('删除数据库成功')
        }
    },

    // 关闭数据库 
    closeDB: function() {
        if (db != null) {
            db.close()
            db = null
            console.log("数据库关闭")
        }
    },

    // 添加数据
    // 对象仓库(表名),传入的参数
    add: function(objectStoreName, argument) {
        if (db != null) {
            console.log(db)
            
            // 执行事务,添加数据到对象仓库(表)
            var request = db.transaction([objectStoreName], 'readwrite')
                .objectStore(objectStoreName)
                .add(argument);

            request.onsuccess = function(event) {
                console.log('数据写入成功');
            };

            request.onerror = function(event) {
                console.log('数据写入失败');
            }
        }
    },

    // 获取数据
    // 对象仓库(表名)
    get: function(objectStoreName) {
        if (db != null){
            console.log(db)
            
            // 执行事务,从对象仓库(表)中获取所有数据
            var request = db.transaction([objectStoreName], 'readwrite')
                .objectStore(objectStoreName).getAll()
            
            // 数据获取失败
            request.onerror = function(event) {
                console.log('事务失败')
            }
            
            //数据获取成功
            request.onsuccess = function(event) {
                if (request.result) {
                    // 打印所有数据
                    console.log(request.result)
                } else {
                    console.log('未获得数据记录')
                }
            };
        }
    },
    
    // 遍历数据
    // 对象仓库(表名)
    foreach: function(objectStoreName) {
        if (db != null){
            console.log(db)
            
            // 执行事务,从对象仓库(表)中获取所有数据
            var request = db.transaction([objectStoreName], 'readwrite')
                .objectStore(objectStoreName).openCursor()
            
            // 数据获取失败
            request.onerror = function(event) {
                console.log('事务失败')
            }
            
            //数据获取成功
            request.onsuccess = function(event) {
                let cursor = request.result
                if (cursor) {
                    // 遍历打印所有数据
                    console.log(cursor)
                    console.log(cursor.key)
                    console.log(cursor.value.name)
                    console.log(cursor.value.age)
                    console.log(cursor.value.sex)
                    cursor.continue()
                } else {
                    console.log('未获得数据记录')
                }
            };
        }
    },
    
    // 更新数据(若数据存在,则覆盖之前的数据,若数据不存在,则新增一个值)
    // 对象仓库(表名)
    update: function(objectStoreName, argument) {
        if (db != null) {
            console.log(db)
            
            // 执行事务,添加数据到对象仓库(表)
            var request = db.transaction([objectStoreName], 'readwrite')
                .objectStore(objectStoreName)
                .put(argument);

            request.onsuccess = function(event) {
                console.log('数据更新成功');
            };

            request.onerror = function(event) {
                console.log('数据更新失败');
            }
        }
    },
    
    // 删除数据(若数据不存在,则不会执行删除操作)
    // 对象仓库(表名)
    remove: function(objectStoreName, index) {
        if (db != null){
            console.log(db)
            
            // 执行事务,从对象仓库(表)中获取所有数据
            var request = db.transaction([objectStoreName], 'readwrite')
                .objectStore(objectStoreName).delete(index)
            
            // 数据获取失败
            request.onerror = function(event) {
                console.log('事务失败')
            }
            
            //数据获取成功
            request.onsuccess = function(event) {
                if (request.result) {
                    // 遍历打印所有数据
                    console.log(request.result)
                } else {
                    console.log('未获得数据记录')
                }
            };
        }
    },
    
    // 根据索引查值(若数据不存在,返回一个[]数组)
    // 对象仓库(表名)
    searchFromIndex: function(objectStoreName, index, data) {
        if (db != null){
            console.log(db)
            
            // 执行事务,从对象仓库(表)中获取所有数据
            var request = db.transaction([objectStoreName], 'readonly')
                .objectStore(objectStoreName).index(index).getAll(data)
            
            // 数据获取失败
            request.onerror = function(event) {
                console.log('事务失败')
            }
            
            //数据获取成功
            request.onsuccess = function(event) {
                if (request.result) {
                    // 遍历打印所有数据
                    console.log(request.result)
                } else {
                    console.log('未获得数据记录')
                }
            };
        }
    }
}


链接: https://www.fly63.com/article/detial/5950

indexedDB 数据库_html5中Web离线数据库的使用

HTML5的本地存储中有一种叫 indexedDB 的数据库,该数据库是一种存储在客户端本地的 NoSQL 数据库,它可以存储大量的数据。这篇文章讲解indexedDB 如何存储数据?

使用IndexedDB做前端日志持久化

页面如果表现不符合预期,前端工程师在没有 javascript 日志的情况下,很难 debug。所以就需要针对必要的步骤记录日志,并上传。但是每记录一条日志就上传并不是一个合适的选择

前端数据库:WebSQL和IndexedDB

WebSQL是前端的一个独立模块,是web存储方式的一种,我们调试的时候会经常看到,只是一般很少使用。兼容性:当前只有谷歌支持,ie和火狐均不支持。

IndexedDB:浏览器里的本地数据库

在现代浏览器的本地存储方案中,indexedDB 是一项重要的能力组成, 它是可以在浏览器端使用的本地数据库,可以存储大量数据,提供接口来查询,还可以建立索引,这些都是其他存储方案 Cookie 或者 LocalStorage 无法提供的能力

浏览器数据库 indexedDB

indexedDB用于在浏览器端存储大量的结构化数据。对比于其他的浏览器存储技术(cookie,localStorage),indexedDB具有以下优点:另外,indexedDB还具备以下特点:

使用indexedDB,降低环境搭建成本

学习前端新框架、新技术。如果需要做一些数据库的操作来增加demo的体验(CURD流程可以让演示的体验根据丝滑),最开始的时候一个演示程序我们会调用后台,这样其实有一点弊端,就是增加了开发和维护成本,简单的一个demo不应该劳师动众

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!