indexedDB的简单使用

今天想写一篇关于indexedDB的文章,由于最近项目需要前端存储数据,但是localStorage存储空间有限,最后综合考虑采用indexedDB来存储。本文将简单介绍一下indexedDB的使用场景,以及简单的封装。IndexedDB是一个基于JavaScript的面向对象数据库,他是一个事务型数据库系统,事务型数据库与关系型数据库的区别呢,这里就不多做介绍了。直接切入正文吧。

1、indexedDB的优点:

1. 键值对存储,方便。

2. 异步操作,不会导致主流程卡顿,影响用户体验。

3. 支持存储对象,字符串,二进制数据。

2、主要流程:

打开数据库( indexedDB.open() )>创建数据仓库( db.createObjectStore() )>创建一个事务,链接数据仓库( db.transaction([storeName]).objectStore(storeName) )>对数据增删改查( stroe.add()、store.put()、store.delete()、store.get() )>关闭数据库( db.close() )。

数据的获取方式有三种:

1、使用getAll()获取所有数据。

2、使用get(key)获取单条数据,这里的key是要获取数据的主键的值。

3、使用openCursor(),这是indexedDB的指针对象,他也是异步的所以监听success方法,然后使用cursor.contiune()移动指针。

3、封装:

interface MsgProps {
  type: string,
  message: string | object
}
export default class DB {
  dbName: string
  db: any
  constructor(name: string) {
    this.dbName = name
  }

  open(storeName: string, keyPath: string, indexs?: Array<string>) {
    if(!window.indexedDB) {
      return alert('您的浏览器不支持该app,为了更好的体验,请使用新版chrome浏览器')
    }
    const request = window.indexedDB.open(this.dbName, new Date().getTime())
    return new Promise((resolve, rej) => {
      request.onerror = (e: any) => {
        this.onmessage({type: '数据库连接失败', message: e})
        rej()
      }
      request.onsuccess = (e: any) => {
        this.db = e.target.result
        this.onmessage({type: '数据库连接成功', message: ''})
        resolve()
      }
      request.onupgradeneeded = (e: any) => {
        const db = e.target.result
        if(!db.objectStoreNames.contains(storeName)) {
          const store = db.createObjectStore(storeName, {autoIncrement: true, keyPath})
          if(indexs && indexs.length) {
            indexs.map((v) => {
              store.createIndex(v, v, { unique: false })
            })
          }
          store.transaction.oncomplete = (ev: any) => {
            this.onmessage({type: '创建对象仓库成功', message: ''})
          }
        }
      }
    })
    
  }

  onmessage(msg: MsgProps) {
    console.log(msg.type, msg.message)
  }

  update(storeName: string, data: object) {
    const store = this.db.transaction([storeName], 'readwrite').objectStore(storeName)
    return new Promise((resolve, rej) => {
      const request = store.put({
        ...data,
        lastModify: new Date().getTime()
      })
      request.onsuccess = (e: any) => {
        this.onmessage({
          type: '更新成功',
          message: data
        })
        resolve()
      }
      request.onerror = (e: any) => {
        this.onmessage({
          type: '更新失败',
          message: data
        })
        rej()
      }
    })
  }

  getList(storeName: string) {
    const store = this.db.transaction([storeName]).objectStore(storeName)
    return new Promise((resolve, rej) => {
      store.getAll().onsuccess = (e: any) => {
        const res = e.target.result
        this.onmessage({
          type: '获取列表成功',
          message: res
        })
        resolve(res)
      }
    })
  }

  getItem(storeName: string, key: string) {
    const store = this.db.transaction(storeName).objectStore(storeName)
    return new Promise((resolve, rej) => {
      const request = store.get(key)
      request.onsuccess = (e: any) => {
        resolve(e.target.result)
      }
      request.onerror = (e: any) => {
        rej()
      }
    })
  }

  delete(storeName: string, key: string) {
    const store = this.db.transaction([storeName], 'readwrite').objectStore(storeName)
    const request = store.delete(key)
    return new Promise((resolve, rej) => {
      request.onsuccess = (e: any) => {
        this.onmessage({
          type: '删除成功',
          message: key
        })
        resolve()
      }
      request.onerror = (e: any) => {
        this.onmessage({
          type: '删除失败',
          message: data
        })
        rej()
      }
    })
    
  }

  closeDB() {
    this.db.close()
  }

  deleteDB() {
    indexedDB.deleteDatabase(this.dbName)
  }

}

如上所示,由于indexedDB的put会在没有找到的时候创建一条数据,找到的话更新这条数据。所以没有封装post方法。对于indexedDB来说没有数据表的概念,它是根据数据库版本号来管理对象残酷的。

注意:打开数据库的时候,只有版本号改变,才可以在该数据库中创建对象仓库。本人这里偷了个懒,直接使用时间戳作为版本号,请大家自行改进优化。

原文地址:https://www.cnblogs.com/marvey/p/13216048.html