十、初始化数据库
开发思路:
-
定义方法签名: 创建一个名为
initDB
的异步方法,它接受一个context
参数(类型为common.UIAbilityContext
),代表当前应用程序的上下文环境。 -
配置数据库: 定义一个
config
对象,包含数据库的配置信息。这里设置数据库文件名DB_FILENAME
和安全等级relationalStore.SecurityLevel.S1
。 -
使用 Promise 封装异步操作: 由于数据库初始化是一个异步操作,使用
new Promise<void>
创建一个 Promise 对象,以便在操作完成时处理成功或失败的结果。 -
获取数据库存储对象: 调用
relationalStore.getRdbStore
方法,传入上下文context
和配置config
,尝试获取数据库存储对象rdbStore
。 -
处理成功情况: 使用
.then
方法添加成功回调,一旦数据库存储对象获取成功,将其赋值给类成员变量this.rdbStore
并在日志中记录,然后调用resolve
方法解决 Promise。 -
处理失败情况: 使用
.catch
方法添加失败回调,如果获取数据库存储对象失败,记录错误信息到日志,并调用reject
方法拒绝 Promise。 -
返回 Promise 对象:
initDB
方法返回创建的 Promise 对象,允许调用者根据数据库初始化操作的结果执行相应的逻辑。 -
日志记录: 使用
Logger.debug
方法记录数据库初始化的日志信息,包括成功和失败的情况。 -
错误处理: 在
catch
回调中,将错误信息转换为字符串格式,并记录下来,便于调试和追踪问题。 -
安全性考虑: 设置数据库的安全等级,确保数据库文件的安全性。
/**
* initDB
* 初始化数据库
**/
initDB(context: common.UIAbilityContext): Promise<void> {
let config: relationalStore.StoreConfig = {
name: DB_FILENAME,
//安全等级
securityLevel: relationalStore.SecurityLevel.S1
}
return new Promise<void>((resolve, reject) => {
relationalStore.getRdbStore(context, config)
.then(rdbStore => {
this.rdbStore = rdbStore
Logger.debug('rdbStore 初始化完成')
resolve()
})
.catch(reason => {
Logger.debug('rdbStore 初始化异常', JSON.stringify(reason))
reject(reason)
})
})
}
十一、完成DBUtil
类
开发思路:
-
定义数据库文件名:首先定义了一个常量
DB_FILENAME
来存储数据库文件的名称。 -
类成员和方法声明:
DBUtil
类中声明了一个私有成员rdbStore
用于存储关系型数据库存储对象。 -
初始化数据库:
initDB
方法用于初始化数据库,它接收一个应用上下文context
并返回一个 Promise 对象。在这个方法中,首先定义了数据库的配置,然后调用relationalStore.getRdbStore
方法获取RdbStore
对象,并将其赋值给rdbStore
成员变量。 -
创建表:
createTable
方法接收一个创建表的 SQL 语句,并执行这个语句来创建表。 -
插入数据:
insert
方法接收表名、要插入的数据对象和列信息数组,构建数据值桶,然后执行插入操作。 -
删除数据:
delete
方法接收删除条件,执行删除操作,并返回被删除的行数。 -
查询数据:
queryForList
是一个泛型方法,它接收查询条件和需要查询的列信息数组,执行查询操作,并返回查询结果数组。 -
更新数据:
update
方法接收要更新的数据对象、需要更新的列信息数组和更新条件,执行更新操作,并返回被更新的行数。 -
解析查询结果集:
parseResulSet
方法将查询结果集从原生数据格式转换为 JavaScript 对象数组。 -
构建数据值桶:
buildValueBucket
方法根据数据对象和列信息构建用于数据库操作的数据值桶。 -
日志记录:在每个数据库操作的方法中,都有相应的日志记录,以便于调试和追踪操作结果。
-
错误处理:每个方法都使用 Promise 的
catch
来捕获并记录错误。 -
模块化:最后,创建了
DBUtil
类的实例,并将其作为模块的默认导出,这样其他模块可以方便地使用这个数据库工具类。
注意:
查询方法返回的是一个
ResultSet
类型的数据,需要做处理
const DB_FILENAME: string = 'BaiZhanKeep.db'; // 定义数据库文件名
class DBUtil {
rdbStore: relationalStore.RdbStore; // 声明关系型数据库存储对象
/**
* 初始化数据库
* @param context 应用上下文
* @returns {Promise<void>} 初始化操作的Promise对象
*/
initDB(context: common.UIAbilityContext): Promise<void> {
let config: relationalStore.StoreConfig = {
name: DB_FILENAME, // 设置数据库名称
securityLevel: relationalStore.SecurityLevel.S1 // 设置数据库安全等级为S1
};
return new Promise<void>((resolve, reject) => {
relationalStore.getRdbStore(context, config) // 调用关系型数据库接口获取RdbStore对象
.then((rdbStore) => {
this.rdbStore = rdbStore; // 将获取的RdbStore对象赋值给类成员变量
Logger.debug('rdbStore 初始化完成'); // 记录初始化完成的日志
resolve(); // 初始化成功,解决Promise
})
.catch((reason) => {
Logger.debug('rdbStore 初始化异常', JSON.stringify(reason)); // 记录初始化异常的日志
reject(reason); // 初始化失败,拒绝Promise
});
});
}
/**
* 创建数据库表
* @param createSQL 创建表的SQL语句
* @returns {Promise<void>} 创建表操作的Promise对象
*/
createTable(createSQL: string): Promise<void> {
return new Promise((resolve, reject) => {
this.rdbStore.executeSql(createSQL) // 执行SQL语句创建表
.then(() => {
Logger.debug('成功创建表', createSQL); // 记录创建表成功的日志
resolve(); // 创建成功,解决Promise
})
.catch((err) => {
Logger.error('创建表失败,' + err.message, JSON.stringify(err)); // 记录创建表失败的日志
reject(err); // 创建失败,拒绝Promise
});
});
}
/**
* 插入数据
* @param tableName 表名
* @param obj 要插入的数据对象
* @param columns 列信息数组
* @returns {Promise<number>} 插入操作的Promise对象,返回插入数据的ID
*/
insert(tableName: string, obj: any, columns: ColumnInfo[]) {
return new Promise((resolve, reject) => {
let value = this.buildValueBucket(obj, columns); // 构建用于插入的数据值桶
this.rdbStore.insert(tableName, value, (err, id) => { // 执行插入操作
if (err) {
Logger.error('新增失败', JSON.stringify(err)); // 记录插入失败的日志
reject(err); // 插入失败,拒绝Promise
} else {
Logger.debug('新增成功,新增数据ID:' + id.toString()); // 记录插入成功的日志
resolve(id); // 插入成功,解决Promise
}
});
});
}
/**
* 删除数据
* @param predicates 删除条件
* @returns {Promise<number>} 删除操作的Promise对象,返回被删除的行数
*/
delete(predicates: relationalStore.RdbPredicates) {
return new Promise((resolve, reject) => {
this.rdbStore.delete(predicates, (err, rows) => { // 执行删除操作
if (err) {
Logger.error('删除失败', JSON.stringify(err)); // 记录删除失败的日志
reject(err); // 删除失败,拒绝Promise
} else {
Logger.debug('删除成功,删除第' + rows.toString() + '行数据'); // 记录删除成功的日志
resolve(rows); // 删除成功,解决Promise
}
});
});
}
/**
* 查询数据
* @param predicates 查询条件
* @param columns 需要查询的列信息数组
* @returns {Promise<T[]>} 查询操作的Promise对象,返回查询结果数组
*/
queryForList<T>(predicates: relationalStore.RdbPredicates, columns: ColumnInfo[]): Promise<T[]> {
return new Promise((resolve, reject) => {
this.rdbStore.query(predicates, columns.map(info => info.columnName), (err, result) => { // 执行查询操作
if (err) {
Logger.error('查询失败', JSON.stringify(err)); // 记录查询失败的日志
reject(err); // 查询失败,拒绝Promise
} else {
Logger.debug('查询成功,查询到 ' + result.rowCount.toString() + ' 行'); // 记录查询成功的日志
resolve(this.parseResulSet(result, columns)); // 解析查询结果并解决Promise
}
});
});
}
/**
* 更新数据
* @param obj 要更新的数据对象
* @param columns 需要更新的列信息数组
* @param predicates 更新条件
* @returns {Promise<number>} 更新操作的Promise对象,返回被更新的行数
*/
update(obj: any, columns: ColumnInfo[], predicates: relationalStore.RdbPredicates) {
return new Promise((resolve, reject) => {
let value = this.buildValueBucket(obj, columns); // 构建用于更新的数据值桶
this.rdbStore.update(value, predicates, (err, id) => { // 执行更新操作
if (err) {
Logger.error('修改失败', JSON.stringify(err)); // 记录更新失败的日志
reject(err); // 更新失败,拒绝Promise
} else {
Logger.debug('修改成功,修改数据ID为:' + id); // 记录更新成功的日志
resolve(id); // 更新成功,解决Promise
}
});
});
}
/**
* 解析查询结果集,将原生数据格式转换为JavaScript对象数组
* @param result 查询结果集
* @param columns 列信息数组
* @returns {T[]} 转换后的数据数组
*/
parseResulSet<T>(result: relationalStore.ResultSet, columns: ColumnInfo[]): T[] {
let arr = []; // 声明存储结果的数组
if (result.rowCount <= 0) {
return arr; // 如果没有数据,直接返回空数组
}
// 循环处理每一行数据
while (!result.isAtLastRow) {
result.goToNextRow(); // 移动到下一行
let obj = {}; // 存储当前行数据的对象
columns.forEach((info) => { // 遍历列信息
let val = null; // 声明存储列值的变量
switch (info.type) { // 根据列类型获取对应值
case ColumnType.LONG:
val = result.getLong(result.getColumnIndex(info.columnName));
break;
case ColumnType.DOUBLE:
val = result.getDouble(result.getColumnIndex(info.columnName));
break;
case ColumnType.STRING:
val = result.getString(result.getColumnIndex(info.columnName));
break;
case ColumnType.BLOB:
val = result.getBlob(result.getColumnIndex(info.columnName));
break;
}
obj[info.name] = val; // 将列值添加到对象
});
arr.push(obj); // 将对象添加到结果数组
Logger.debug('查询到的数据:' + JSON.stringify(obj)); // 记录查询到的数据
}
return arr; // 返回结果数组
}
/**
* 根据对象和列信息构建用于数据库操作的数据值桶
* @param obj 数据对象
* @param columns 列信息数组
* @returns {relationalStore.ValuesBucket} 构建的数据值桶
*/
buildValueBucket(obj: any, columns: ColumnInfo[]): relationalStore.ValuesBucket {
let value = {}; // 声明数据值桶对象
columns.forEach((info) => { // 遍历列信息
let val = obj[info.name]; // 获取对象属性值
if (typeof val !== 'undefined') {
value[info.columnName] = val; // 将属性值添加到数据值桶
}
});
return value; // 返回数据值桶
}
}
// 创建DBUtil类的实例
let dbUtil: DBUtil = new DBUtil();
// 导出DBUtil实例作为模块的默认导出
export default dbUtil as DBUtil;
十二、完成RecordModel
类(建表语句和任务的增删改查)
注意:
数据库建语句的编写,一定要规范
数据库列的命名要规范
数据库的增删改操作语句及相应的调用方法
const CREATE_TABLE_SQL: string = `
CREATE TABLE IF NOT EXISTS record
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
keep_id INTEGER NOT NULL,
amount INTEGER NOT NULL,
create_time INTEGER NOT NULL,
success_amount INTEGER NOT NULL
)`
/*
数据库列名信息
*/
const COLUMNS: ColumnInfo[] = [
{ name: 'id', columnName: 'id', type: ColumnType.LONG },
{ name: 'keepId', columnName: 'keep_id', type: ColumnType.LONG },
{ name: 'amount', columnName: 'amount', type: ColumnType.DOUBLE },
{ name: 'createTime', columnName: 'create_time', type: ColumnType.LONG },
{ name: 'successAmount', columnName: 'success_amount', type: ColumnType.DOUBLE }
]
/*
表明,ID列名,时间列名 常量
*/
const TABLE_NAME = 'record';
const ID_COLUMN = 'id';
const DATE_COLUMN = 'create_time';
class RecordModel {
getCreateTableSql(): string {//返回创建表
return CREATE_TABLE_SQL
}
//插入一条新记录到record表中。
// record是一个RecordPO对象,用于表示记录的数据
/*
增
*/
insert(record: RecordPO) {
return DBUtil.insert(TABLE_NAME, record, COLUMNS)
}
/*
删
*/
//根据记录的ID删除一条记录
delete(id: number) {
//使用relationalStore.RdbPredicates来构建查询条件。
let predicates = new relationalStore.RdbPredicates(TABLE_NAME)
predicates.equalTo(ID_COLUMN, id)
return DBUtil.delete(predicates)
}
/*
改
*/
//根据ID更新记录。使用relationalStore.RdbPredicates来指定更新条件。
update(record: RecordPO, id: number) {
let predicates = new relationalStore.RdbPredicates(TABLE_NAME)
predicates.equalTo(ID_COLUMN, id)
return DBUtil.update(record, COLUMNS, predicates)
}
/*
查所有
*/
//查询表中的所有记录,并返回一个RecordPO对象的数组。
queryAll(): Promise<RecordPO[]> {
let predicates = new relationalStore.RdbPredicates(TABLE_NAME)
return DBUtil.queryForList(predicates, COLUMNS)
}
/*
根据日期查
*/
//根据创建时间查询记录,并返回符合条件的记录数组。
queryByDate(date: number): Promise<RecordPO[]> {
let predicates = new relationalStore.RdbPredicates(TABLE_NAME)
predicates.equalTo(DATE_COLUMN, date)
return DBUtil.queryForList(predicates, COLUMNS)
}
}
//创建一个recordModel的实例,并将其作为默认导出,其他模块可以导入并使用这个实例来执行数据库操作。
let recordModel = new RecordModel();
export default recordModel as RecordModel