鸿蒙-关系型数据库
·
import { relationalStore, ValuesBucket,ValueType } from '@kit.ArkData';
import { Context } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { table_schemas } from '../sql/table'
// 数据库配置
const STORE_CONFIG: relationalStore.StoreConfig = {
// 数据库文件名
name: 'RdbTest.db',
// 数据库安全级别
securityLevel: relationalStore.SecurityLevel.S3,
// 可选参数,指定数据库是否加密,默认不加密
encrypt: false,
// 可选参数,数据库自定义路径。默认在本应用沙箱目录下创建RdbStore实例。
customDir: 'customDir/subCustomDir',
// 可选参数,指定数据库是否以只读方式打开。默认为false,表示数据库可读可写。为true时,只允许从数据库读取数据,不允许对数据库进行写操作,否则会返回错误码801。
isReadOnly: false,
// 可选参数,指定用户在全文搜索场景(FTS)下使用哪种分词器。默认在FTS下仅支持英文分词,不支持其他语言分词。
// tokenizer: tokenType
};
/**
* 关系型数据库工具类
*/
export class RdbStoreUtil {
private rdbStore: relationalStore.RdbStore | null = null;
// 静态属性,保存唯一实例
private static instance: RdbStoreUtil;
// 私有构造函数,防止外部直接 new RdbStoreUtil()
private constructor() {
}
// 获取单例的静态方法
public static getInstance(): RdbStoreUtil {
if (!RdbStoreUtil.instance) {
RdbStoreUtil.instance = new RdbStoreUtil();
}
return RdbStoreUtil.instance;
}
async init(context: Context) {
try {
console.log('开始初始化数据库...');
// 1. 获取RdbStore实例
this.rdbStore = await relationalStore.getRdbStore(context, STORE_CONFIG);
console.log(`this.rdbStore===${this.rdbStore}`)
console.log('RdbStore实例获取成功:', !!this.rdbStore);
if (!this.rdbStore) {
return;
}
// 2. 创建所有表结构(使用事务保证原子性)
await this.rdbStore.beginTransaction();
console.log('事务开始成功');
for (const sql of table_schemas) {
console.log('执行SQL:', sql);
await this.executeSql(sql);
console.log('SQL执行成功');
}
await this.rdbStore.commit();
console.log('事务提交成功');
console.info('All tables created successfully');
} catch (error) {
console.error(`初始化失败: ${JSON.stringify(error)}`);
// throw error;
if (error instanceof Error) {
throw error;
} else {
throw new Error('Batch insert failed: ' + String(error));
}
}
}
/**
* 执行SQL语句
*/
private async executeSql(sql: string, params: ValueType[] = []): Promise<void> {
if (!this.rdbStore) {
throw new Error('RdbStore not initialized');
}
return new Promise((resolve, reject) => {
this.rdbStore!.executeSql(sql, params, (err: BusinessError) => {
if (err) {
console.error(`SQL error: ${sql}`, err);
reject(err);
} else {
resolve();
}
});
});
}
/**
* 通用插入方法
* @param tableName 表名
* @param data 要插入的数据对象
* @returns 插入的行ID
*/
async insert<T extends Record<string, ValueType>>(
tableName: string,
data: T
): Promise<number> {
return new Promise((resolve, reject) => {
if (!this.rdbStore) {
reject(new Error('RdbStore未初始化'));
return;
}
// 自动过滤undefined值
const valueBucket: ValuesBucket = {};
Object.keys(data).forEach(key => {
if (data[key] !== undefined) {
valueBucket[key] = data[key];
}
});
console.log(`valueBucket===${JSON.stringify(valueBucket)}`)
this.rdbStore.insert(
tableName,
valueBucket,
(err: BusinessError, rowId: number) => {
if (err) {
console.error(`插入到 ${tableName} 失败`, err);
reject(err);
} else {
console.log(`插入 ${tableName}, 行ID: ${rowId}`);
resolve(rowId);
}
}
);
});
}
/**
* 通用批量插入方法
* @param tableName 表名
* @param dataArray 要插入的数据数组
* @returns 插入的行数
*/
async batchInsert<T extends Record<string, ValueType>>(
tableName: string,
dataArray: T[]
): Promise<number> {
if (!this.rdbStore) {
throw new Error('RdbStore not initialized');
}
await this.rdbStore.beginTransaction();
let successCount = 0;
try {
for (const data of dataArray) {
await this.insert(tableName, data);
successCount++;
}
await this.rdbStore.commit();
return successCount;
} catch (error) {
// await this.rdbStore.rollback();
// throw error;
await this.rdbStore.rollback(1);
if (error instanceof Error) {
throw error;
} else {
throw new Error('Batch insert failed: ' + String(error));
}
}
}
/**
* 通用查询方法
* @param tableName 表名
* @param columns 要查询的列(可选,默认查询所有列)
* @param whereClause WHERE条件(可选)
* @param whereArgs WHERE参数(可选)
* @returns 查询结果数组
*/
async query<T extends Record<string, relationalStore.ValueType>>(
tableName: string,
columns?: string[],
whereClause?: string,
whereArgs?: relationalStore.ValueType[]
): Promise<T[]> {
return new Promise((resolve, reject) => {
if (!this.rdbStore) {
reject(new Error('RdbStore not initialized'));
return;
}
const cols = columns?.length ? columns.join(', ') : '*';
let sql = `SELECT ${cols} FROM ${tableName}`;
if (whereClause) {
sql += ` WHERE ${whereClause}`;
}
console.log(`sql====${sql}`)
console.log(`whereArgs===${JSON.stringify(whereArgs)}`)
this.rdbStore.querySql(
sql,
whereArgs || [],
(err: BusinessError, resultSet: relationalStore.ResultSet) => {
if (err) {
reject(err);
return;
}
console.log(`resultSet===${JSON.stringify(resultSet)}`)
try {
const results: T[] = [];
const columnCount = resultSet.columnCount;
while (resultSet.goToNextRow()) {
const row: Record<string, relationalStore.ValueType> = {};
for (let i = 0; i < columnCount; i++) {
const columnName = resultSet.getColumnName(i);
row[columnName] = resultSet.getValue(i);
}
results.push(row as T);
}
resultSet.close();
resolve(results);
} catch (e) {
resultSet.close();
reject(e);
}
}
);
});
}
/**
* 使用RdbPredicates查询
* @param predicates 查询条件
* @returns 查询结果数组
*/
async queryWithPredicates<T extends Record<string, relationalStore.ValueType>>(
predicates: relationalStore.RdbPredicates
): Promise<T[]> {
return new Promise((resolve, reject) => {
if (!this.rdbStore) {
reject(new Error('RdbStore not initialized'));
return;
}
this.rdbStore.query(
predicates,
(err: BusinessError, resultSet: relationalStore.ResultSet) => {
if (err) {
reject(err);
return;
}
try {
const results: T[] = [];
const columnCount = resultSet.columnCount;
while (resultSet.goToNextRow()) {
const row: Record<string, relationalStore.ValueType> = {};
for (let i = 0; i < columnCount; i++) {
const columnName = resultSet.getColumnName(i);
row[columnName] = resultSet.getValue(i);
}
results.push(row as T);
}
resultSet.close();
resolve(results);
} catch (e) {
resultSet.close();
reject(e);
}
}
);
});
}
/**
* 通用更新方法
* @param tableName 表名
* @param values 要更新的值
* @param whereClause WHERE条件
* @param whereArgs WHERE参数
* @returns 影响的行数
*/
async update(
tableName: string,
values: ValuesBucket,
whereClause: string,
whereArgs: ValueType
): Promise<number> {
return new Promise((resolve, reject) => {
if (!this.rdbStore) {
reject(new Error('RdbStore not initialized'));
return;
}
const predicates = new relationalStore.RdbPredicates(tableName);
predicates.equalTo(whereClause, whereArgs);
this.rdbStore.update(
values,
predicates,
(err: BusinessError, rowsAffected: number) => {
if (err) {
reject(err);
} else {
resolve(rowsAffected);
}
}
);
});
}
/**
* 通用删除方法
* @param tableName 表名
* @param whereClause WHERE条件
* @param whereArgs WHERE参数
* @returns 删除的行数
*/
async delete(
tableName: string,
whereClause: string,
whereArgs: ValueType
): Promise<number> {
return new Promise((resolve, reject) => {
if (!this.rdbStore) {
reject(new Error('RdbStore not initialized'));
return;
}
const predicates = new relationalStore.RdbPredicates(tableName);
predicates.equalTo(whereClause, whereArgs);
this.rdbStore.delete(
predicates,
(err: BusinessError, rowsAffected: number) => {
if (err) {
reject(err);
} else {
resolve(rowsAffected);
}
}
);
});
}
}
// 单例导出
export const rdbStoreUtil = RdbStoreUtil.getInstance();
使用
import { relationalStore, ValuesBucket, ValueType } from '@kit.ArkData';
import { Context } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { rdbStoreUtil } from './RdbStoreUtil';
// 1. 定义数据接口
interface User extends Record<string, ValueType> {
// id?: number; // number 是 ValueType 的子类型
name: string; // string 是 ValueType 的子类型
age: number;
email: string;
}
interface Product extends Record<string, ValueType> {
// id?: number;
name: string;
price: number;
stock: number;
}
// onWindowStageCreate(windowStage: window.WindowStage): void {
// rdbStoreUtil.init(this.context)
// }
export class RdbStoreUtilExample {
async example(context:Context) {
// 2. 初始化数据库
await rdbStoreUtil.init(context);
// 3. 插入用户数据
const userId = await rdbStoreUtil.insert<User>('users', {
name: '张三',
age: 30,
email: 'zhangsan@example.com'
});
// 4. 插入产品数据
const productId = await rdbStoreUtil.insert<Product>('products', {
name: '智能手机',
price: 3999,
stock: 100
});
// 5. 查询所有用户
const allUsers = await rdbStoreUtil.query<User>('users');
// 6. 条件查询
const adultUsers = await rdbStoreUtil.query<User>(
'users',
['id', 'name', 'email'],
'age >= ?',
[18]
);
// 7. 使用RdbPredicates查询
const predicates = new relationalStore.RdbPredicates('users');
predicates.equalTo('name', '张三');
const zhangSan = await rdbStoreUtil.queryWithPredicates<User>(predicates);
// 8. 更新数据
await rdbStoreUtil.update(
'users',
{ age: 31 },
'id',
1
);
// 9. 删除数据
await rdbStoreUtil.delete(
'products',
'id',
1
);
// 10. 批量插入
const newUsers:User[] = [
{ name: '李四', age: 25, email: 'lisi@example.com' },
{ name: '王五', age: 28, email: 'wangwu@example.com' }
];
await rdbStoreUtil.batchInsert<User>('users', newUsers);
}
}
// 单例导出
更多推荐
所有评论(0)