先容
本Codelab以记账为例,利用关系型数据库的相关接口实现了对账单的增、删、改、查操作。实现结果如图所示:
相关概念
- 关系型数据库:基于关系模子来管理数据的数据库,提供了增、删、改、查等接口,也可运行输入的SQL语句满足复杂场景必要。
环境搭建
软件要求
- DevEco Studio版本:DevEco Studio 3.1 Release。
- OpenHarmony SDK版本:API version 9。
硬件要求
- 开发板类型:润和RK3568开发板。
- OpenHarmony体系:3.2 Release。
环境搭建
完资本篇Codelab我们起首要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步调进行:
- 获取OpenHarmony体系版本:尺度体系办理方案(二进制)。以3.2 Release版本为例:
2.搭建烧录环境。
- 完成DevEco Device Tool的安装
- 完成RK3568开发板的烧录
3.搭建开发环境。
- 开始前请参考工具准备,完成DevEco Studio的安装和开发环境配置。
- 开发环境配置完成后,请参考利用工程领导创建工程(模板选择“Empty Ability”),选择JS大概eTS语言开发。
- 工程创建完成后,选择利用真机进行调测。
代码结构解读
本篇Codelab只对核心代码进行讲解,
- ├──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;
- }
- }
复制代码
通过本Codelab的学习,您已经学会了关系型数据库的根本用法。
总结
您已经完成了本次Codelab的学习,并学会了利用关系型数据库的相关接口实现对数据的增、删、改、查操作。
为了帮助各人更深入有效的学习到鸿蒙开发知识点,小编特意给各人准备了一份全套最新版的HarmonyOS NEXT学习资源,获取完整版方式请点击→《HarmonyOS教学视频》
HarmonyOS教学视频:语法ArkTS、TypeScript、ArkUI等.....视频教程
鸿蒙生态应用开发白皮书V2.0PDF:
获取完整版白皮书方式请点击《鸿蒙生态应用开发白皮书V2.0PDF》
鸿蒙 (Harmony OS)开发学习手册
一、入门必看
二、HarmonyOS 概念
- 体系定义
- 技术架构
- 技术特性
- 体系安全
- ........
三、如何快速入门?《做鸿蒙应用开发到底学习些啥?》
四、开发基础知识
- 应用基础知识
- 配置文件
- 应用数据管理
- 应用安全管理
- 应用隐私保护
- 三方应用调用管控机制
- 资源分类与访问
- 学习ArkTS语言
- ……
五、基于ArkTS 开发
- Ability开发
- UI开发
- 公共事件与通知
- 窗口管理
- 媒体
- 安全
- 网络与链接
- 电话服务
- 数据管理
- 后台使命(Background Task)管理
- 装备管理
- 装备利用信息统计
- DFX
- 国际化开发
- 折叠屏系列
- ……
更多了解更多鸿蒙开发的相关知识可以参考:《鸿蒙 (Harmony OS)开发学习手册》
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |