赞
踩
本Codelab以记账为例,使用关系型数据库的相关接口实现了对账单的增、删、改、查操作。实现效果如图所示:
完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:
[获取OpenHarmony系统版本]:标准系统解决方案(二进制)。以3.2 Release版本为例:
搭建烧录环境。
gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
点击或者复制转到。搭建开发环境。
本篇只对核心代码进行讲解,完整代码可以直接从gitee获取。HarmonyOS与OpenHarmony鸿蒙文档籽料:mau123789是v直接拿
├──entry/src/main/ets // 代码区 │ ├──common │ │ ├──constants │ │ │ └──CommonConstants.ets // 公共常量 │ │ ├──database │ │ │ ├──tables │ │ │ │ └──AccountTable.ets // 账目数据表 │ │ │ └──Rdb.ets // RDB数据库 │ │ └──utils // 日志类 │ │ ├──ConsoleLogger.ets │ │ ├──HiLogger.ets │ │ ├──ILogger.ets │ │ └──Logger.ets │ ├──entryability │ │ └──EntryAbility.ts // 程序入口类 │ ├──pages │ │ └──MainPage.ets // 应用首页 │ ├──view │ │ └──DialogComponent.ets // 自定义弹窗 │ └──viewmodel │ ├──AccountData.ets // 账目类接口 │ ├──AccountItem.ets // 账目资源类接口 │ ├──AccountList.ets // 账目类型model │ └──ConstantsInterface.ets // 常量接口 └──entry/src/main/resources // 资源文件夹
要使用关系型数据库存储用户数据,首先要进行数据库的创建,并提供基本的增、删、改、查接口。
导入关系型数据库模块:
import relationalStore from '@ohos.data.relationalStore';
关系型数据库提供以下两个基本功能:
首先要获取一个RdbStore实例来操作关系型数据库,代码如下:
// Rdb.ets getRdbStore(callback: Function = () => { }) { // 如果已经获取到RdbStore则不做操作 if (!callback || typeof callback == 'undefined' || callback == undefined) { Logger.verbose(`${CommonConstants.RDB_TAG}`, 'getRdbStore() has no callback!'); return; } // 应用上下文,本Codelab使用API9 Stage模型的Context let context: Context = getContext(this) as Context; relationalStore.getRdbStore(context, CommonConstants.STORE_CONFIG, (err, rdb) => { if (err) { Logger.error(`${RDB_TAG}`, 'gerRdbStore() failed, err: ' + err); return; } this.rdbStore = rdb; // 获取到RdbStore后,需使用executeSql接口初始化数据库表结构和相关数据 this.rdbStore.executeSql(this.sqlCreateTable); Logger.verbose(`${RDB_TAG}`, 'getRdbStore() finished.'); callback(); }); }
关系型数据库接口提供的增、删、改、查操作均有callback和Promise两种异步回调方式,本Codelab使用了callback异步回调,其中插入数据使用了insert()接口,实现代码如下:
// Rdb.ets insertData(data: relationalStore.ValuesBucket, callback: Function = () => { }) { if (!callback || typeof callback == 'undefined' || callback == undefined) { Logger.verbose(`${CommonConstants.RDB_TAG}`, 'insertData() has no callback!'); return; } let resFlag: boolean = false; const valueBucket: relationalStore.ValuesBucket = data; if (this.rdbStore) { this.rdbStore.insert(this.tableName, valueBucket, (err, ret) => { if (err) { Logger.error(`${CommonConstants.RDB_TAG}`, 'insertData() failed, err: ' + err); callback(resFlag); return; } Logger.verbose(`${CommonConstants.RDB_TAG}`, 'insertData() finished: ' + ret); callback(ret); }); } }
删除数据使用了delete()接口,实现代码如下:
// Rdb.ets deleteData(predicates: relationalStore.RdbPredicates, callback: Function = () => { }) { if (!callback || typeof callback == 'undefined' || callback == undefined) { Logger.verbose(`${CommonConstants.RDB_TAG}`, 'deleteData() has no callback!'); return; } let resFlag: boolean = false; if (this.rdbStore) { this.rdbStore.delete(predicates, (err, ret) => { if (err) { Logger.error(`${CommonConstants.RDB_TAG}`, 'deleteData() failed, err: ' + err); callback(resFlag); return; } Logger.verbose(`${CommonConstants.RDB_TAG}`, 'deleteData() finished: ' + ret); callback(!resFlag); }); } }
更新数据使用了update()接口,实现代码如下:
// Rdb.ets updateData(predicates: relationalStore.RdbPredicates, data: relationalStore.ValuesBucket, callback: Function = () => { }) { if (!callback || typeof callback == 'undefined' || callback == undefined) { Logger.verbose(`${CommonConstants.RDB_TAG}`, 'updateDate() has no callback!'); return; } let resFlag: boolean = false; const valueBucket: relationalStore.ValuesBucket = data; if (this.rdbStore) { this.rdbStore.update(valueBucket, predicates, (err, ret) => { if (err) { Logger.error(`${CommonConstants.RDB_TAG}`, 'updateData() failed, err: ' + err); callback(resFlag); return; } Logger.verbose(`${CommonConstants.RDB_TAG}`, 'updateData() finished: ' + ret); callback(!resFlag); }); } }
查找数据使用了query()接口,实现代码如下:
// Rdb.ets query(predicates: relationalStore.RdbPredicates, callback: Function = () => { }) { if (!callback || typeof callback == 'undefined' || callback == undefined) { Logger.verbose(`${CommonConstants.RDB_TAG}`, 'query() has no callback!'); return; } if (this.rdbStore) { this.rdbStore.query(predicates, this.columns, (err, resultSet) => { if (err) { Logger.error(`${CommonConstants.RDB_TAG}`, 'query() failed, err: ' + err); return; } Logger.verbose(`${CommonConstants.RDB_TAG}`, 'query() finished.'); callback(resultSet); resultSet.close(); }); } }
本Codelab需要记录账目的类型(收入/支出)、具体类别和金额,因此需要创建一张存储账目信息的表,表头如下:
创建该表的SQL语句为:
CREATE TABLE IF NOT EXISTS accountTable(
id INTEGER PRIMARY KEY AUTOINCREMENT,
accountType INTEGER,
typeText TEXT,
amount INTEGER
)
该表需要封装增、删、改、查接口,代码如下:
// AccountTable.ets // 插入数据 insertData(account: AccountData, callback: Function) { // 根据输入数据创建待插入的数据行 const valueBucket: relationalStore.ValuesBucket = generateBucket(account); this.accountTable.insertData(valueBucket, callback); } // 删除数据 deleteData(account: AccountData, callback: Function) { let predicates = new relationalStore.RdbPredicates(CommonConstants.ACCOUNT_TABLE.tableName); // 根据id匹配待删除的数据行 predicates.equalTo('id', account.id); this.accountTable.deleteData(predicates, callback); } // 修改数据 updateData(account: AccountData, callback: Function) { const valueBucket: relationalStore.ValuesBucket = generateBucket(account); let predicates = new relationalStore.RdbPredicates(CommonConstants.ACCOUNT_TABLE.tableName); // 根据id匹配待删除的数据行 predicates.equalTo('id', account.id); this.accountTable.updateData(predicates, valueBucket, callback); } // 查找数据 query(amount: number, callback: Function, isAll: boolean = true) { let predicates = new relationalStore.RdbPredicates(CommonConstants.ACCOUNT_TABLE.tableName); if (!isAll) { predicates.equalTo('amount', amount); } this.accountTable.query(predicates, (resultSet: relationalStore.ResultSet) => { let count: number = resultSet.rowCount; if (count === 0 || typeof count === 'string') { console.log(`${CommonConstants.TABLE_TAG}` + 'Query no results!'); callback([]); } else { resultSet.goToFirstRow(); const result: AccountData[] = []; for (let i = 0; i < count; i++) { let tmp: AccountData = { id: 0, accountType: 0, typeText: '', amount: 0 }; tmp.id = resultSet.getDouble(resultSet.getColumnIndex('id')); tmp.accountType = resultSet.getDouble(resultSet.getColumnIndex('accountType')); tmp.typeText = resultSet.getString(resultSet.getColumnIndex('typeText')); tmp.amount = resultSet.getDouble(resultSet.getColumnIndex('amount')); result[i] = tmp; resultSet.goToNextRow(); } callback(result); } }); }
首先创建应用主页面,主要包括使用Search组件创建的搜索栏和使用List组件创建的账目清单,如下图所示:
在打开应用时,需要查询数据库中存储的账目并显示在主页面,因此生命周期函数aboutToAppear()应写为:
// Mainpage.ets
aboutToAppear() {
this.AccountTable.getRdbStore(() => { // 获取数据库
this.AccountTable.query(0, (result: AccountData[]) => { // 查询数据库中的全部账目
this.accounts = result;
}, true);
});
}
点击右上角的“编辑”图标,主页面变为如下效果:
可以选中需要删除的账目,点击下方“删除”图标后删除对应账目,对应代码如下:
// Mainpage.ets
deleteListItem() {
for (let i = 0; i < this.deleteList.length; i++) { // 删除每一项选中的账目并更新页面上的账目清单
let index = this.accounts.indexOf(this.deleteList[i]);
this.accounts.splice(index, 1);
this.AccountTable.deleteData(this.deleteList[i], () => {});
}
this.deleteList = [];
this.isEdit = false;
}
搜索栏在键入文本并回车时,实现搜索功能:
// Mainpage.ets
.onSubmit((searchValue: string) => {
if (searchValue === '') { // 如果搜索栏为空,查找全部账目
this.AccountTable.query(0, (result: AccountData[]) => {
this.accounts = result;
}, true);
} else {
this.AccountTable.query(Number(searchValue), (result: AccountData[]) => { // 查找金额为val的账目
this.accounts = result;
}, false);
}
})
右下角的“添加”按钮可以打开一个自定义弹窗,并在弹窗里新建账目信息:
// Mainpage.ets
.onClick(() => {
this.isInsert = true; // 插入模式
this.newAccount = { id: 0, accountType: 0, typeText: '', amount: 0 };
this.dialogController.open();
})
点击账目清单中的某个账目,也可以打开自定义弹窗,并修改账目信息:
// Mainpage.ets
selectListItem(item: AccountData) {
this.isInsert = false; // 编辑模式
this.index = this.accounts.indexOf(item);
this.newAccount = {
id: item.id,
accountType: item.accountType,
typeText: item.typeText,
amount: item.amount
};
}
自定义弹窗由使用Tabs组件创建的账目类别、使用TextInput组件创建的输入栏和确定按钮组成,如下图所示:
点击“确定”按钮会调用accept()函数,根据isInsert的值来进行账目的添加或修改,代码如下:
// Mainpage.ets accept(isInsert: boolean, newAccount: AccountData): void { if (isInsert) { // 插入模式,往数据库插入一个新账目 Logger.verbose(`${CommonConstants.INDEX_TAG}`, 'The account inserted is: ' + JSON.stringify(newAccount)); this.AccountTable.insertData(newAccount, (id: number) => { newAccount.id = id; this.accounts.push(newAccount); }); } else { // 编辑模式,更新当前选中的账目并写入数据库,刷新页面的账目清单 this.AccountTable.updateData(newAccount, () => {}); let list = this.accounts; this.accounts = []; list[this.index] = newAccount; this.accounts = list; this.index = -1; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。