indexDB的极简封装

初始目的

铺货PC 端缓存的商品类目数据大于 localstorage 的上限,继续存入会报错
于是采用 indexedDb 存放类目信息

思路一览

初始化:
打开一个数据库
声明一个变量 db 用来保存「数据库对象」的索引
在 onsuccess 和 onupgradeneeded 的回调中获取数据库对象,并赋值个变量 db;
在 onupgradeneeded 的回调中创建表,并创建索引
封装 增删改查 方法

核心代码

// 用于初始化多张表的list
const tableList = [
  {
    tableName: `category`, //表名
    config: {
      keyPath: `platform` // 主键
    },
    indexList: [
      // 索引
      {
        indexName: `platform`,
        keyPath: `platform`,
        config: {
          unique: true
        }
      },
      {
        indexName: `categoryContent`,
        keyPath: `categoryContent`,
        config: {
          unique: false
        }
      },
      {
        indexName: `updateTime`,
        keyPath: `updateTime`,
        config: {
          unique: false
        }
      }
    ]
  }
]'

let openRequestIndexedDB
openRequestIndexedDB = window.indexedDB.open(`1688dptDataBase`, 1)

export let db = null as unknown as IDBDatabase

// 成功打开数据库
openRequestIndexedDB.onsuccess = function (e) {
  db = openRequestIndexedDB.result
  console.info('indexedDB success')
}

// 数据库升级事件
// 数据库版本号发生变化时触发(数据库从无到有也是变化)
openRequestIndexedDB.onupgradeneeded = function (e: any) {
  console.info('indexedDB onupgradeneeded')
  db = e.target.result

  tableList.forEach((tableInitInfo, index) => {
    initTable(tableInitInfo, index)
  })

  /**
   * 初始化表
   * @param tableInfoObj
   * @param index
   * @returns
   */
  function initTable(tableInfoObj, index) {
    const { tableName, config: tableConfig, indexList } = tableInfoObj
    if (!tableInfoObj.tableName) {
      console.error(`tableList第${index}项,缺少表名`)
      return
    }

    let objectStore
    if (!db.objectStoreNames.contains(tableName)) {
      objectStore = db.createObjectStore(tableName, tableConfig) //建表(category 表),设置主键

      indexList.forEach((item) => {
        objectStore.createIndex(item.indexName, item.keyPath, item.config) // 新建索引
      })
    }
  }
}

/**
 * 增加数据
 * @param 表名 tableName
 * @param 数据对象 params
 */
export function addDataForDB(tableName, params) {
  const request = db.transaction([tableName], 'readwrite').objectStore(tableName).add(params)

  request.onsuccess = function (event) {
    // console.log('数据写入成功')
  }
  request.onerror = function (event) {
    // console.log('数据写入失败')
  }
}

/**
 * 删除数据
 * @param tableName 表名
 * @param keyPath 主键
 */
export function deleteDataForDB(tableName, keyPath) {
  var request = db.transaction([tableName], 'readwrite').objectStore(tableName).delete(keyPath)

  request.onsuccess = function () {
    console.log('数据删除成功')
  }

  request.onerror = function () {
    console.log('数据删除失败')
  }
}

/**
 * 更新数据 需要使用 put
 * @param tableName 表名
 * @param params 数据对象
 */
export function updateDataForDB(tableName, params) {
  var request = db.transaction([tableName], 'readwrite').objectStore(tableName).put(params)

  request.onsuccess = function (event) {
    // console.log('数据更新成功')
  }
  request.onerror = function (event) {
    // console.log('数据更新失败')
  }
}

/**
 * 根据 key 获取数据
 * @param tableName
 * @param key
 * @returns
 */
export async function asyncReadDataForDB(tableName, key) {
  return new Promise((resolve, reject) => {
    let transaction = db.transaction([tableName])
    let objectStore = transaction.objectStore(tableName)
    let request = objectStore.get(key)
    request.onerror = function (event) {
      console.log('事务失败')
    }

    request.onsuccess = function (event) {
      if (request.result) {
        resolve(request.result)
      } else {
        resolve(request.result)
        console.log('未获得数据记录')
      }
    }
  })
}

/**
 * 获取全部数据
 * @param tableName
 * @returns
 */
export async function asyncReadAllForDB(tableName): Promise<{ categoryTree; time: number }> {
  return new Promise((resolve, reject) => {
    const objectStore = db.transaction(tableName).objectStore(tableName)
    const allData = {}
    let time = 0
    objectStore.openCursor().onsuccess = function (event: Event) {
      const cursor = event.target.result
      // console.log(`cursor`, cursor)
      if (cursor) {
        // allData[cursor.key] = {
        //   categoryContent: cursor.value.categoryContent,
        //   updateTime: cursor.value.updateTime
        // }
        time = cursor.value.updateTime // 大家的时间都是一样的,取哪个都行
        allData[cursor.key] = JSON.parse(cursor.value.categoryContent || '[]')
        cursor.continue()
      } else {
        // console.log('没有更多数据了!')
        resolve({
          categoryTree: allData,
          time: time
        })
      }
    }
  })
}
import {
  addDataForDB,
  asyncReadAllForDB,
  asyncReadDataForDB,
  deleteDataForDB,
  updateDataForDB
} from './db'

export function addDataForDB_category(platform, categoryContent, updateTime): void {
  addDataForDB(`category`, { platform, categoryContent, updateTime })
}

export function deleteDataForDB_category(platform): void {
  deleteDataForDB(`category`, platform)
}

export function updateDataForDB_category(platform, categoryContent, updateTime) {
  updateDataForDB('category', { platform, categoryContent, updateTime })
}

export async function asyncReadDataForDB_category(key) {
  return await asyncReadDataForDB('category', key)
}ing

export async function asyncReadAllForDB_category() {
  return await asyncReadAllForDB('category')
}
Comments
Write a Comment