FrontTools/DBManager/DBManagerReadme.md
Rain 3ab1f2db24 [入库]初次入库各种工具
- DBManager DB创建管理器
- FormatTimeTool
- ImageViewer工具
- InputArear工具
- OverlayPage工具
- 下拉刷新容器工具
- 视频查看器工具
2026-04-02 16:09:00 +08:00

217 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# DBManager (SQLite 封装工具类)
`DBManager` 是基于 `plus.sqlite` 的 Promise 化封装,旨在简化 App 端本地数据库的操作。它支持自动建表、自动创建索引、以及 JSON 字段的自动序列化/反序列化。
#✨ 核心特性
* **开箱即用**`open()` 时自动检测并创建数据库、表结构和索引。
* **配置灵活**:通过 `DBSchema` 接口纯配置化定义表结构。
* **JSON 友好**:配置 `jsonFields` 后,无需手动 `JSON.stringify/parse`,直接存取对象。
* **Promise 封装**:支持 `async/await`,告别回调地狱。
* **批量操作**:内置事务支持,提升批量插入性能。
---
## ⚙️ 配置说明 (DBSchema)
在使用前,你需要定义一个 `DBSchema` 对象。
```typescript
export interface DBSchema {
/** 数据库逻辑名称 (如: 'chat_db') */
dbName: string;
/** 数据库文件路径 (推荐: '_doc/xxx.db') */
dbPath: string;
/** 表名 */
tableName: string;
/**
* 建表列定义 (标准 SQL 语法)
* 必须在此处定义 PRIMARY KEY
*/
columns: string;
/**
* 需要创建索引的字段列表
* 支持单字段: ['timestamp']
* 支持组合索引: ['user_id, timestamp']
*/
indexes?: string[];
/**
* 需要自动 JSON 序列化的字段名
* 对应的 columns 类型建议为 TEXT
*/
jsonFields?: string[];
}
```
---
## 📝 填表案例 (Schema Examples)
以下是几种常见业务场景的配置写法:
### 场景一:聊天记录表 (标准场景)
* **需求**:使用 UUID 字符串作为主键,存储消息内容,其中 `media``extra` 字段存储复杂的 JSON 对象,需要按会话 ID 和时间查询。
```typescript
const ChatSchema: DBSchema = {
dbName: 'im_core',
dbPath: '_doc/im_core.db',
tableName: 'messages',
// 定义列:注意 media 和 extra 定义为 TEXT 以存储 JSON 字符串
columns: `
guid TEXT PRIMARY KEY,
session_id TEXT,
sender_id TEXT,
content TEXT,
msg_type INTEGER,
media TEXT,
extra TEXT,
is_read INTEGER,
timestamp INTEGER
`,
// 定义索引:加快查询速度
indexes: [
'timestamp', // 按时间排序
'session_id, timestamp' // 获取某个会话的历史记录 (组合索引)
],
// 自动转换:存入时自动 stringify取出时自动 parse
jsonFields: ['media', 'extra']
};
```
### 场景二:待办事项表 (自增主键)
* **需求**简单的任务列表ID 需要自动递增。
```typescript
const TodoSchema: DBSchema = {
dbName: 'todo_app',
dbPath: '_doc/todo.db',
tableName: 'tasks',
// 使用 SQLite 的自增语法
columns: `
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
is_completed INTEGER,
created_at INTEGER
`,
indexes: ['is_completed']
};
```
### 场景三:用户关系表 (联合主键)
* **需求**:存储群组成员关系,一个用户在一个群里只能有一条记录(`user_id` + `group_id` 唯一)。
```typescript
const MemberSchema: DBSchema = {
dbName: 'relation_db',
dbPath: '_doc/relation.db',
tableName: 'group_members',
// 在末尾定义联合主键
columns: `
group_id TEXT,
user_id TEXT,
nickname TEXT,
role TEXT,
join_time INTEGER,
PRIMARY KEY (group_id, user_id)
`,
indexes: ['user_id'] // group_id 已经在主键索引里了,不需要单独建
};
```
---
## 🚀 快速开始
### 1. 初始化
推荐在 Store 或 Service 层创建一个单例实例。
```typescript
import { DBManager, DBSchema } from './utils/DBManager';
// 1. 定义配置
const config: DBSchema = { /* 参考上面的案例 */ };
// 2. 创建实例
export const ChatDB = new DBManager(config);
// 3. 打开数据库 (通常在 App 启动或登录后调用)
await ChatDB.open();
```
### 2. 插入/更新数据 (Upsert)
使用 `Upsert` 方法,如果主键存在则更新,不存在则插入。
**注意**:可以直接传入包含对象的 JSON 字段,无需手动转换。
```typescript
const msg = {
guid: 'msg_1001',
session_id: 'sess_a',
content: 'Hello World',
timestamp: 1679000000,
is_read: true, // 会自动转为 1
// 这里的 media 对象会自动转为字符串存入数据库
media: {
type: 'image',
url: 'https://xxx.com/img.png',
width: 100
}
};
await ChatDB.Upsert(msg);
```
### 3. 查询数据 (Find)
支持 `where``orderBy``limit``offset`
```typescript
const history = await ChatDB.find({
where: {
session_id: 'sess_a',
// 支持简单的比较操作符 (需在 key 中包含空格)
'timestamp <': 1679999999
},
orderBy: 'timestamp DESC',
limit: 20
});
// history[0].media 会自动被还原为对象
console.log(history[0].media.url);
```
### 4. 复杂查询 (Raw SQL)
如果内置方法无法满足需求(如模糊搜索),可执行原生 SQL。
```typescript
// 模糊搜索示例
const keyword = '测试';
// 注意手动处理 SQL 转义,防止单引号报错
const safeKeyword = keyword.replace(/'/g, "''");
const sql = `
SELECT * FROM messages
WHERE content LIKE '%${safeKeyword}%'
ORDER BY timestamp DESC
`;
const res = await ChatDB.queryRaw(sql);
```
---
## ⚠️ 注意事项
1. **修改表结构**SQLite 不支持直接修改列类型或删除列。如果修改了 `DBSchema``columns`,通常需要卸载 App 或手动迁移数据(`ALTER TABLE ADD COLUMN` 可通过 `executeSql` 手动执行)。
2. **布尔值**SQLite 没有 Boolean 类型,本工具会自动将 `true/false` 转换为 `1/0` 存储。
3. **单引号转义**:在使用 `queryRaw` 手动拼接 SQL 时,务必使用 `.replace(/'/g, "''")` 处理字符串参数,防止 SQL 报错或注入。