前言导读
各位网友大家好,有段时间没有更大家见面了,之前我写过一个关于鸿蒙next 里面轻量化数据库的使用,那个过程复杂而且不好使用
今天我就带着大家一起封装一个开箱即用的sqlite 的工具类库 希望后面同学再存储数据的时候不再繁琐。那么废话不多说我们正式开始
效果图

具体实现
1封装我们的 策略接口 基类 BaseStrategy
我们一共定义了 建表 ,初始化数据库 插入数据 查询所有数据 删除数据等方法
ts
/**
* 策略接口
*/
export interface BaseStrategy {
/**
* 设置数据库SQL参数
* @param dbName 数据库名称
* @param tableName 表名
* @param sqlArgsMap SQL参数映射
*/
setDbSqlArgs(dbName: string, tableName: string, sqlArgsMap: Map<string, string>): void;
/**
* 初始化数据库
*/
initSssDb(context: any): Promise<void>;
/**
* 获取本地数据库订单信息
* @returns 订单信息列表
*/
getLocalDbOrderInfo(): Promise<Array<Map<string, string>>>;
/**
* 插入或更新子订单
* @param uniqueKey 唯一标识键
* @param uniqueValue 唯一标识值
* @param contentMap 内容映射
*/
insertOrUpdateSub(uniqueKey: string, uniqueValue: string, contentMap: Map<string, string>): Promise<void>;
/**
* 删除数据库数据
* @param uniqueKey 唯一标识键
* @param uniqueValue 唯一标识值
*/
deleteDbData(uniqueKey: string, uniqueValue: string): Promise<void>;
}
2 策略实现类
ts
import { LocalSaveHelper } from './helper/LocalSaveHelper';
import { BaseStrategy } from './inf/BaseStrategy';
import { DbLog } from './util/DbLog';
import {SdkRdbHelper} from './db/SdkRdbHelper'
/**
* 策略实现类
*/
export class MyPayStrategy implements BaseStrategy {
private static instance: MyPayStrategy | null = null;
private constructor() {
}
/**
* 获取单例实例
* @returns MkPaySsStrategy实例
*/
public static getInstance(): MyPayStrategy {
if (!MyPayStrategy.instance) {
MyPayStrategy.instance = new MyPayStrategy();
}
return MyPayStrategy.instance;
}
/**
* 设置数据库SQL参数
* @param dbName 数据库名称
* @param tableName 表名
* @param args SQL参数映射
*/
public setDbSqlArgs(dbName: string, tableName: string, args: Map<string, string>): void {
if (!args) {
this.printLog('table args is null!!!');
} else if (args.size <= 0) {
this.printLog('table args size is empty!!!');
} else {
if (!dbName) {
this.printLog('database name is empty!!!');
}
if (!tableName) {
this.printLog('table name is empty!!!');
}
LocalSaveHelper.getInstance().setDbName(dbName);
LocalSaveHelper.getInstance().setDbTableName(tableName);
LocalSaveHelper.getInstance().setDbSqlArgsMap(args);
}
}
/**
* 初始化数据库
*/
public async initSssDb(context:Context): Promise<void> {
try {
this.printLog('initSssDb');
if (!LocalSaveHelper.getInstance().getSqlArgsMap()) {
this.printErrLog('Please assign an instance first about SqlArgsMap');
} else {
await SdkRdbHelper.getInstance().initRdbStore(context);
}
} catch (error) {
DbLog.eWithStack(error.message, error);
}
}
/**
* 获取本地数据库订单信息
* @returns 订单信息列表
*/
public async getLocalDbOrderInfo(): Promise<Array<Map<string, string>>> {
try {
this.printLog('getLocalDbOrderInfo');
return await SdkRdbHelper.getInstance().getSdkOrderInfo();
} catch (error) {
DbLog.eWithStack(error.message, error);
return [];
}
}
/**
* 插入或更新子订单
* @param uniqueKey 唯一标识键
* @param uniqueValue 唯一标识值
* @param args 参数映射
*/
public async insertOrUpdateSub(uniqueKey: string, uniqueValue: string, args: Map<string, string>): Promise<void> {
try {
this.printLog('insertOrUpdateSub');
await SdkRdbHelper.getInstance().insertOrUpdateSub(uniqueKey, uniqueValue, args);
} catch (error) {
DbLog.eWithStack(error.message, error);
}
}
/**
* 删除数据库数据
* @param uniqueKey 唯一标识键
* @param uniqueValue 唯一标识值
*/
public async deleteDbData(uniqueKey: string, uniqueValue: string): Promise<void> {
try {
this.printLog('deleteDbData');
SdkRdbHelper.getInstance().deleteDbOrderData(uniqueKey, uniqueValue);
} catch (error) {
DbLog.eWithStack(error.message, error);
}
}
/**
* 打印日志
* @param msg 日志消息
*/
private printLog(msg: string): void {
DbLog.d(msg);
}
/**
* 打印错误日志
* @param msg 错误日志消息
*/
private printErrLog(msg: string): void {
DbLog.e(msg);
}
}
3 获取数据库建表SQL语句
ts
/**
* 获取数据库建表SQL语句
* @param tableName 表名
* @returns 建表SQL语句
*/
public static getSssDbSql(tableName: string): string {
const argsMap = LocalSaveHelper.getInstance().getSqlArgsMap();
let sql = `CREATE TABLE IF NOT EXISTS ${tableName} (ID INTEGER PRIMARY KEY AUTOINCREMENT`;
if (argsMap) {
const entries = argsMap.entries();
for (const entry of entries) {
const key = entry[0];
const value = entry[1];
sql += `, ${key} ${this.getArgsVariable(value)}`;
}
}
sql += ');';
DbLog.d(`sql: ${sql}`);
return sql;
}
4 SDK关系数据库帮助类
ts
import { LocalSaveHelper } from '../helper/LocalSaveHelper';
import { DbLog } from '../util/DbLog';
import { MYPayType } from '../constant/MYPayType';
import { PaySsUtils } from '../util/PaySsUtils';
import { relationalStore } from '@kit.ArkData';
/**
* SDK关系数据库帮助类
*/
export class SdkRdbHelper {
public static instance: SdkRdbHelper|null = null;
private store: relationalStore.RdbStore | undefined = undefined;
/**
* 获取单例实例
* @returns SdkRdbHelper实例
*/
public static getInstance(): SdkRdbHelper {
if (!SdkRdbHelper.instance) {
SdkRdbHelper.instance = new SdkRdbHelper();
}
return SdkRdbHelper.instance;
}
/**
* 初始化数据库
* @param context 上下文
*/
public async initRdbStore(context: Context){
const STORE_CONFIG: relationalStore.StoreConfig = {
name: 'RdbTest.db', // 数据库文件名
securityLevel: relationalStore.SecurityLevel.S1, // 数据库安全级别
encrypt: false, // 可选参数,指定数据库是否加密,默认不加密
customDir: 'customDir/subCustomDir', // 可选参数,数据库自定义路径。数据库将在如下的目录结构中被创建:context.databaseDir + '/rdb/' + customDir,其中context.databaseDir是应用沙箱对应的路径,'/rdb/'表示创建的是关系型数据库,customDir表示自定义的路径。当此参数不填时,默认在本应用沙箱目录下创建RdbStore实例。
isReadOnly: false // 可选参数,指定数据库是否以只读方式打开。该参数默认为false,表示数据库可读可写。该参数为true时,只允许从数据库读取数据,不允许对数据库进行写操作,否则会返回错误码801。
};
try {
// if(this.store){
// // this.store = await rdb.getRdbStore(context, this.STORE_CONFIG);
// await rdb.getRdbStore(context,this.STORE_CONFIG).then((data)=>{
//
// })
// }
// 获得一个相关的RdbStore,操作关系型数据库,用户可以根据自己的需求配置RdbStore的参数,
// 然后通过RdbStore调用相关接口可以执行相关的数据操作,使用callback异步回调。
relationalStore.getRdbStore(context, STORE_CONFIG, (err, store) => {
if (err) {
console.error(`At LoginPage Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
return;
}
console.info('At LoginPage Succeeded in getting RdbStore.');
// 当数据库创建时,数据库默认版本为0
if (store.version === 0) {
const tableName = LocalSaveHelper.getInstance().getDbTableName();
const sql = PaySsUtils.getSssDbSql(tableName);
store.executeSql(sql); // 创建数据表
// 设置数据库的版本,入参为大于0的整数
store.version = 1;
}
// 赋值给当前的rdbStore对象,确保获取到RdbStore实例后,再进行数据库的增、删、改、查等操作
this.store = store
});
} catch (error) {
DbLog.e(`初始化数据库失败: ${error.message}`);
}
}
/**
* 获取SDK订单信息
* @returns 订单信息列表
*/
public async getSdkOrderInfo(): Promise<Array<Map<string, string>>> {
const resultList: Array<Map<string, string>> = [];
try {
if (!this.store) {
DbLog.e('数据库未初始化');
return resultList;
}
const tableName = LocalSaveHelper.getInstance().getDbTableName();
const resultSet = await this.store.querySql(`SELECT * FROM ${tableName} ORDER BY ID DESC`, []);
while (resultSet.goToNextRow()) {
const resultMap = new Map<string, string>();
const argsMap = LocalSaveHelper.getInstance().getSqlArgsMap();
if (argsMap) {
const entries = argsMap.entries();
for (const entry of entries) {
const key = entry[0];
const value = entry[1];
const columnIndex = resultSet.getColumnIndex(key);
if (columnIndex !== -1) {
if (value === MYPayType.TEXT) {
resultMap.set(key, resultSet.getString(columnIndex));
} else {
resultMap.set(key, resultSet.getString(columnIndex));
}
}
}
}
resultList.push(resultMap);
}
resultSet.close();
} catch (error) {
DbLog.e(`查询订单信息失败: ${error.message}`);
}
return resultList;
}
/**
* 插入或更新子订单
* @param uniqueKey 唯一标识键
* @param uniqueValue 唯一标识值
* @param contentMap 内容映射
*/
public async insertOrUpdateSub(uniqueKey: string, uniqueValue: string, contentMap: Map<string, string>): Promise<void> {
try {
if (!this.store) {
DbLog.e('数据库未初始化');
return;
}
const tableName = LocalSaveHelper.getInstance().getDbTableName();
// 检查记录是否存在
const queryResultSet = await this.store.querySql(
`SELECT COUNT(*) AS count FROM ${tableName} WHERE ${uniqueKey} = ?`,
[uniqueValue]
);
let exists = false;
if (queryResultSet.goToNextRow()) {
const count = queryResultSet.getLong(queryResultSet.getColumnIndex('count'));
exists = count > 0;
}
queryResultSet.close();
if (exists) {
// 更新操作
let updateSql = `UPDATE ${tableName} SET `;
const values: string[] = [];
const params: string[] = [];
const entries = contentMap.entries();
for (const entry of entries) {
const key = entry[0];
const value = entry[1];
values.push(`${key} = ?`);
params.push(value);
}
updateSql += values.join(', ');
updateSql += ` WHERE ${uniqueKey} = ?`;
params.push(uniqueValue);
await this.store.executeSql(updateSql, params);
DbLog.d('记录已存在,执行更新操作');
} else {
// 插入操作
let insertSql = `INSERT INTO ${tableName} (`;
const columns: string[] = [];
const placeholders: string[] = [];
const params: string[] = [];
// 添加唯一键
columns.push(uniqueKey);
placeholders.push('?');
params.push(uniqueValue);
const entries = contentMap.entries();
for (const entry of entries) {
const key = entry[0];
const value = entry[1];
columns.push(key);
placeholders.push('?');
params.push(value);
}
insertSql += columns.join(', ') + ') VALUES (' + placeholders.join(', ') + ')';
await this.store.executeSql(insertSql, params);
DbLog.d('执行插入操作');
}
} catch (error) {
DbLog.e(`插入或更新子订单失败: ${error.message}`);
}
}
/**
* 删除数据库订单数据
* @param uniqueKey 唯一标识键
* @param uniqueValue 唯一标识值
*/
public async deleteDbOrderData(uniqueKey: string, uniqueValue: string): Promise<void> {
try {
if (!this.store) {
DbLog.e('数据库未初始化');
return;
}
const tableName = LocalSaveHelper.getInstance().getDbTableName();
// 检查记录是否存在
const queryResultSet = await this.store.querySql(
`SELECT COUNT(*) AS count FROM ${tableName} WHERE ${uniqueKey} = ?`,
[uniqueValue]
);
let exists = false;
if (queryResultSet.goToNextRow()) {
const count = queryResultSet.getLong(queryResultSet.getColumnIndex('count'));
exists = count > 0;
}
queryResultSet.close();
if (exists) {
const deleteSql = `DELETE FROM ${tableName} WHERE ${uniqueKey} = ?`;
await this.store.executeSql(deleteSql, [uniqueValue]);
DbLog.d('删除数据库订单数据成功');
}
} catch (error) {
DbLog.e(`删除数据库订单数据失败: ${error.message}`);
}
}
/**
* 关闭数据库连接
*/
public async close(): Promise<void> {
if (this.store) {
this.store.close();
}
}
}
使用示例
ts
import { MYPayType } from "./constant/MYPayType";
import { MyPayStrategy } from "./MyPayStrategy";
import { Context } from "@kit.AbilityKit";
import {UserInfo} from './model/UserInfo'
/**
* 使用示例
*/
export class PaySssSdkExample {
private static instance: PaySssSdkExample | null = null;
private constructor() {}
/**
* 获取单例实例
* @returns MyPayStrategy实例
*/
public static getInstance(): PaySssSdkExample {
if (!PaySssSdkExample.instance) {
PaySssSdkExample.instance = new PaySssSdkExample();
}
return PaySssSdkExample.instance;
}
/**
* 初始化SDK示例
*/
public async initSdkExample(context: Context): Promise<void> {
try {
// 获取SDK实例
const sdk = MyPayStrategy.getInstance();
// 设置数据库参数
const sqlArgs = new Map<string, string>();
sqlArgs.set('username', MYPayType.TEXT);
sqlArgs.set('password', MYPayType.TEXT);
sdk.setDbSqlArgs('user_database', 'username', sqlArgs);
// 初始化数据库
await sdk.initSssDb(context);
console.log('SDK初始化完成');
} catch (error) {
console.error('SDK初始化失败:', error);
}
}
/**
* 插入订单示例
*/
public async insertOrderExample(userInfo:UserInfo): Promise<void> {
try {
const sdk = MyPayStrategy.getInstance();
// 创建订单数据
const userData = new Map<string, string>();
userData.set('username', userInfo.username);
userData.set('password', userInfo.password);
// 插入或更新订单
await sdk.insertOrUpdateSub('username', userInfo.username, userData);
console.log('订单插入成功');
} catch (error) {
console.error('订单插入失败:', error);
}
}
/**
* 查询订单示例
*/
public async queryOrdersExample(): Promise<Array<Map<string, string>>> {
try {
const sdk = MyPayStrategy.getInstance();
// // 获取所有订单信息
// const orders = await sdk.getLocalDbOrderInfo();
//
// console.log('查询到的订单数量:', orders.length);
// orders.forEach((order, index) => {
// console.log(`订单 ${index + 1}:`, order);
// });
return await sdk.getLocalDbOrderInfo();
} catch (error) {
console.error('查询订单失败:', error);
return [];
}
}
}
我们封装一下 然后再我们的UI组件里面去使用
scss
import {PaySssSdkExample} from '../PaySssSdkExample'
import {UserInfo} from '../model/UserInfo'
@Extend(TextInput)function inputStyle(){
.placeholderColor($r('app.color.placeholder_color'))
.height(45)
.fontSize(18)
.backgroundColor($r('app.color.background'))
.width('100%')
.padding({left:0})
.margin({top:12})
}
@Extend(Line)function lineStyle(){
.width('100%')
.height(1)
.backgroundColor($r('app.color.linecolor'))
.margin({left:5,right:5})
}
@Extend(Text)function textStyle(){
.fontColor($r('app.color.black_text_color'))
.fontSize(18)
.fontWeight(FontWeight.Medium)
}
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
@State getid:string='';
@State username:string='';
@State password:string='';
@State datamap:Array<Map<string, string>>=[];
aboutToAppear(): void {
PaySssSdkExample.getInstance().initSdkExample(getContext());
}
build() {
RelativeContainer() {
Column({space:10}){
Row(){
Row(){
Text("username").textStyle()
}.width(100)
.height('100%')
.justifyContent(FlexAlign.Center)
TextInput({placeholder:"请输入username"})
.maxLength(20)
.type(InputType.Normal)
.inputStyle()
.onChange((value:string)=>{
this.username=value;
}).margin({left:20})
}.width('100%')
.height(50)
.justifyContent(FlexAlign.Start)
Line().lineStyle()
Row(){
Row(){
Text("password").textStyle()
}.width(100)
.height('100%')
.justifyContent(FlexAlign.Center)
TextInput({placeholder:"请输入password"})
.maxLength(20)
.type(InputType.Normal)
.inputStyle()
.onChange((value:string)=>{
this.password=value;
}).margin({left:20})
}.width('100%')
.height(50)
.justifyContent(FlexAlign.Start)
Line().lineStyle()
Row({space:10}){
Button("插入数据").onClick(()=>{
let userInfo: UserInfo=new UserInfo();
userInfo.id=this.getid;
userInfo.username=this.username;
userInfo.password=this.password;
PaySssSdkExample.getInstance().insertOrderExample(userInfo);
}).layoutWeight(1)
Button("查询数据").onClick(()=>{
PaySssSdkExample.getInstance().queryOrdersExample().then((data)=>{
this.datamap=data;
})
}).layoutWeight(1)
}.width("100%").margin({left:20,right:20})
List({space:10}){
ForEach(this.datamap,(item:Map<string, string>)=>{
ListItem(){
Column(){
Text(item?.get("id")).fontSize(18).fontColor(Color.Black)
.margin({top:5})
Text(item?.get("username")).fontSize(15).fontColor(Color.Gray)
.margin({top:5})
Text(item?.get("password")).fontSize(15).fontColor(Color.Black)
.margin({top:5})
}.justifyContent(FlexAlign.Start).margin({left:20}).alignItems(HorizontalAlign.Start)
}.height(100)
.width('100%')
})
}
}.width("100%")
.height("100%")
}
.height('100%')
.width('100%')
}
}
最后总结
我们封装了数据库工具类后 我们对比我们平常要写一堆的建表语句 还有需要编写我们的查询语句 和我们的删除语句 ,我们很好封装和
数据库辅助工具类就可以进减少我们调用者来编写这部分点,当然整个工具类不完善 我们其实可以继续完善 进一步抽象 ,可以·把我们的
model 转成map 这个时候我们只需要操作对象存储和查询获取 还有删除的动作即可,如果觉得文章还不错麻烦给我一键三连谢谢