前端数据库 -- Dexie实战

Dexie项目实战

在现代Web应用开发中,浏览器端的本地数据存储变得日益重要。Dexie.js是一个强大的IndexedDB封装库,它通过简化IndexedDB的使用难度,提供了更为直观和友好的API来管理浏览器数据库。在实际项目中,Dexie.js可以用于存储应用的配置数据、缓存请求数据等,以提高应用的性能和用户体验。本文介绍了一个使用Dexie.js在项目中实现数据缓存和读取的实践案例。

Dexie.js概述

Dexie.js为IndexedDB提供了一系列的简化操作,开发者可以通过它很方便地定义数据库、添加记录、检索数据等。它的使用遵循Promise风格,能够很好地融入现代的异步编程环境。

设计库结构

在实践中,首先需要定义数据库和其架构。以下是CommonPanelDB类的结构,它为面板类型(panelTypes)和面板数据(panelData)定义了两张表:

typescript 复制代码
import Dexie from 'dexie';

export interface CommonPanel {
  id?: number;
  typeName?: string;
  panelId?: string;
}

export interface CommonPanelData {
  id?: number;
  panelId?: string;
  content?: string;
}

export class CommonPanelDB {
  panelDB: Dexie | null;
  panelTypes: Dexie.Table<CommonPanel, number> | undefined;
  panelData: Dexie.Table<CommonPanelData, number> | undefined;

  constructor() {
    this.panelDB = new Dexie('commonPanel');
    this.panelDB!.version(1).stores({
      panelTypes: '++id,typeName,panelId',
      panelData: '++id,panelId,content',
    });

    this.panelTypes = this.panelDB!.table('panelTypes');
    this.panelData = this.panelDB!.table('panelData');
  }
  // ...
}

通过Dexie库的version方法,定义了数据库的版本和表的结构。++id表示主键id是自增的。panelTypes表将存储面板类型信息,而panelData则存储具体的面板内容。

数据库初始化

定义好数据库架构后,接下来是初始化过程。初始化主要做两件事情:清空已有数据和从远端API填充数据。

typescript 复制代码
init = async () => {
  // 清空
  await this.panelTypes?.clear();
  await this.panelData?.clear();

  // 向模型服务请求变量面板
  try {
    const { modelServer } = window.constant;
    const panelInfoUrl = `http://*******`;

    // 请求数据并处理
    const rsp = await axios.get({ url: panelInfoUrl });
    // ...
  } catch (error) {
    console.error('处理面板缓存异常。', error);
  }
};

数据库初始化函数先调用clear方法清空表数据,然后使用axios请求远端API获取新的数据。这里假设modelServer是一个从window.constant获取的远端API地址,根据这个地址请求得到了一系列面板数据。

接下来,将这些数据添加到对应的Dexie表中:

typescript 复制代码
// 遍历响应数据填充到Dexie数据表
for (const [tagName, tagPanelVal] of Object.entries(rsp)) {
  const panelType: CommonPanel = { /* ... */ };
  await this.panelTypes!.add(panelType);

  const panelsIdList = Object.keys((tagPanelVal as any).panels);
  if (panelsIdList.length !== 0) {
    panelsIdList.forEach(async (panelId) => {
      const panelData: CommonPanelData = { /* ... */ };
      await this.panelData!.add(panelData);
    });
  }
}

循环遍历从API获得的数据。每个tagName和tagPanelVal代表不同的面板类型和面板数据,在数据库不同的表中分别存储面板类型和面板数据。

数据的读取

在Dexie中,可以很方便地通过表的查询API获取需要的数据:

typescript 复制代码
export const getPanelData = async (panelId: string) => {
  let db = new CommonPanelDB();
  const graphPanelData = await db.panelData?.where('panelId').equalsIgnoreCase(panelId).first();
  db.close();
  return JSON.parse(graphPanelData?.content ?? '');
};

这个getPanelData函数接受一个panelId参数,然后通过where方法结合equalsIgnoreCase函数完成对大小写不敏感的查询。first表示我们只需要第一条匹配的记录。

收尾工作

在数据库操作完成后,应关闭数据库连接并清理资源:

typescript 复制代码
close = () => {
  delete this.panelData;
  this.panelDB?.close();
  this.panelDB = null;
};

CommonPanelDB类的close方法卸载了Dexie表,并调用Dexie的close方法关闭数据库连接。调用close方法确保在对象不再使用时释放了数据库资源。

小结

本文通过一个实际案例展示了如何在Web应用中使用Dexie.js管理本地数据库。通过Dexie.js,开发者能够以更友好的API轻松实现数据的CRUD操作,不必直接面对底层的IndexedDB复杂的API。结合异步函数和Promise,可以构建出可读性强、结构清晰的数据存储逻辑。

在实战中,Dexie.js发挥了它在简化IndexedDB使用方面的优势,提升了开发效率并确保了代码的可读性。通过合理设计数据库表结构,并配合有效的初始化和收尾策略,可以保证数据的及时性和准确性,使应用具备更好的响应速度和用户体验。

相关推荐
文心快码BaiduComate1 分钟前
Comate搭载Kimi K2.6,长程13h!
前端·后端·程序员
豹哥学前端11 分钟前
新手小白学前端day4: Position定位
前端
阿杰学AI16 分钟前
AI核心知识129—大语言模型之 向量数据库(简洁且通俗易懂版)
数据库·人工智能·ai·语言模型·自然语言处理·向量数据库·vector database
fishmemory7sec17 分钟前
Vue大屏自适应容器组件:v-scale-screen
前端·javascript·vue.js
SPC的存折18 分钟前
D在 Alpine 容器中手动搭建 Discuz 全攻略(包含镜像一键部署脚本,可直接用)
linux·数据库·mysql·缓存
饺子不吃醋18 分钟前
Promise原理、手写与 async、await
前端·javascript
PILIPALAPENG22 分钟前
第3周 Day 2:Function Calling —— 让 Agent 听懂人话,自己干活
前端·人工智能·python
李兆龙的博客23 分钟前
从一到无穷大 #67 大查询根因分析 - 从 PinSQL 到 RCRank
数据库·时序数据库
AgCl2341 分钟前
MYSQL-6-函数与约束-3/17
android·数据库·mysql
junqiduhang1 小时前
Win11 MySQL 8.0 安装八步走
数据库·mysql