【仓颉开发 HarmonyOS 系列】仓颉关系型数据库基础操作实战

在 HarmonyOS 中 ArkData 数据管理模块提供了用户首选项、键值型数据管理、关系型数据管理、分布式数据对象、跨应用数据管理和统一数据管理框架。其中关系型数据管理(RelationalStore)提供了关系型数据库的增删改查、加密、手动备份以及订阅通知能力;提供了向量数据库的存储、管理、向量数据检索以及向量数据相似度计算的能力。应用需要使用关系型数据库的分布式能力时,RelationalStore 部件会将同步请求发送给 DatamgrService 由其完成跨设备数据同步。ArkData 数据管理架构图如下:
在仓颉中也提供了对应的 relationalStore 模块实现关系型数据库各种操作,也提供了分布式相关能力,本文介绍仓颉中 relationalStore 关系型数据库相关的 API。
关系型数据库介绍
关系型数据库以关系模型为基础,用二维表(行/列)存储结构化数据,表与表通过主键/外键建立关联;采用 SQL 进行数据的定义、查询与更新,并以 ACID 事务(原子性、一致性、隔离性、持久性)保障关键业务的数据一致性与可靠性;支持索引、约束、事务隔离级别等机制以提升查询与并发性能,典型产品包括 MySQL、PostgreSQL、Oracle、SQL Server、IBM Db2、SQLite,广泛应用于电商、金融、ERP/CRM 等对数据一致性与复杂查询要求较高的场景。在移动端关系型数据库一般采用 sqllite,HarmonyOS 关系型数据库基于 SQLite 组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的 SQL 语句来满足复杂的场景需要。
仓颉侧支持的基本数据类型:Int64、Float64、String、二进制类型数据、Bool。为保证插入并读取数据成功,建议一条数据不要超过 2M。超出该大小,插入成功,读取失败。
仓颉核心对象
在仓颉 API 中使用关系型数据库需要导入包mport ohos.relational_store.*,仓颉 API 提供了管理关系数据库方法的接口 RdbStore,条件对象 RdbPredicates,以及查询结果对象 ResultSet。
RdbStore
可以通过 getRdbStore 方法获取 RdbStore 对象,函数原型如下:
context 是应用的上下文,StoreConfig 结构定义如下:
参数说明如下:
name:数据库文件名
securityLevel:设置数据库安全级别,SecurityLevel 类型,从低到高支持 S1 到 S4
encrypt:指定数据库是否加密,默认不加密。true:加密,false:非加密。
dataGroupId:应用组 ID,需要向应用市场获取(此属性仅在 Stage 模型下可用。指定在此 dataGroupId 对应的沙箱路径下创建 RdbStore 实例,当此参数不填时,默认在本应用沙箱目录下创建 RdbStore 实例。)
customDir:数据库自定义路径,数据库路径大小限制为 128 字节,如果超过该大小会开库失败,返回错误。数据库将在如下的目录结构中被创建:context.databaseDir + "/rdb/" + customDir,其中 context.databaseDir 是应用沙箱对应的路径,"/rdb/"表示创建的是关系型数据库,customDir 表示自定义的路径。当此参数不填时,默认在本应用沙箱目录下创建 RdbStore 实例。
autoCleanDirtyData:指定是否自动清理云端删除后同步到本地的数据,true 表示自动清理,false 表示手动清理,默认自动清理。对于端云协同的数据库,当云端删除的数据同步到设备端时,可通过该参数设置设备端是否自动清理。手动清理可以通过 cleanDirtyData 接口清理。
创建完成 RdbStore 对象就可以执行数据库的增删改查了。
执行 sql 语句
RdbStore 提供了func executeSql(sql: String): Unit和public func executeSql(sql: String, bindArgs: Array<ValueType>): Unit执行包含指定参数但不返回值的 SQL 语句。比如创建数据库表:
创建完数据库表可以继续介绍增删改查。
增
插入数据提供了如下方法:
其中 ConflictResolution 指定冲突解决方式,比如 ON_CONFLICT_REPLACE,表示替换。
删
删除数据仓颉 API 提供了下面方法:
根据 RdbPredicates 的指定实例对象从数据库中删除数据,放回受影响的行数,删除条件通过构造谓词对象 RdbPredicates 来限定条件。
改
更新数据提供了下面两个 API:
第二个方法增加了冲突解决方式。
查
查找仓颉提供了下面的两个方法:
查找参数是谓词对象 RdbPredicates,返回结果是 ResultSet。
事务
仓颉 API 提供了开始事务,提交事务,回滚事务的方法:
备份与回滚
仓颉 API 提供了下面方法备份数据库:
以及从指定的数据库备份文件恢复数据库。
RdbPredicates
RdbPredicates类作为构建数据库查询条件的关键类,允许我们定义各种查询条件和排序规则,从而精准地获取所需的数据。本文将详细介绍RdbPredicates类的用法,包括其构造函数及各种配置方法。RdbPredicates类表示关系型数据库(RDB)的谓词,用于确定 RDB 中条件表达式的值是true还是false。通过该类,我们可以配置各种查询条件,如等于、不等于、包含、排序等,以构建复杂的查询语句。需要注意的是,RdbPredicates类型不是多线程安全的。如果应用中存在多线程同时操作该类派生出的实例,务必加锁保护以确保数据的一致性和线程安全。
ResultSet
ResultSet 是处理数据库查询结果的重要对象,为开发者提供了丰富的方法来访问和操作查询返回的数据。ResultSet类提供了通过查询数据库生成的数据库结果集的访问方法。当用户调用关系型数据库查询接口后,返回的结果集合就是通过ResultSet对象来访问的。它提供了多种灵活的数据访问方式,使开发者能够方便地获取各项数据。
要使用ResultSet,首先需要通过查询操作获取该对象。以下是一个基本的示例:
在这个示例中,我们创建了一个查询条件(RdbPredicates),筛选年龄为 18 岁的员工,然后执行查询并获取包含指定列的结果集。ResultSet提供了多个属性,用于获取结果集的基本信息和状态:
这些属性帮助我们了解当前结果集的状态,从而进行相应的操作。
ResultSet类提供了丰富的方法,用于导航和获取结果集中的数据。以下是主要方法的详细说明:
根据列名或索引获取信息
getColumnIndex(columnName: String): Int32根据指定的列名获取列索引。
getColumnName(columnIndex: Int32): String根据指定的列索引获取列名。
ResultSet 还提供了导航结果集的方法:
goTo(offset: Int32): Bool 向前或向后转至结果集的指定行,相对于其当前位置偏移。
goToRow(position: Int32): Bool 转到结果集的指定行。
goToFirstRow(): Bool 转到结果集的第一行。
goToLastRow(): Bool 转到结果集的最后一行。
goToNextRow(): Bool 转到结果集的下一行。
goToPreviousRow(): Bool 转到结果集的上一行。
ResultSet 提供了获取当前行的数据
getBlob(columnIndex: Int32): Array<UInt8>以字节数组的形式获取当前行中指定列的值。getString(columnIndex: Int32): String 以字符串形式获取当前行中指定列的值。
getLong(columnIndex: Int32): Int64 以 Long 形式获取当前行中指定列的值。
getDouble(columnIndex: Int32): Float64 以 double 形式获取当前行中指定列的值。
getAsset(columnIndex: Int32): Asset 以 Asset 形式获取当前行中指定列的值。
getAssets(columnIndex: Int32): Array<Asset>以 Assets 形式获取当前行中指定列的值。
getRow(): Map<String, ValueType> 获取当前行的所有列及其值。isColumnNull(columnIndex: Int32): Bool 检查当前行中指定列的值是否为 null。
ResultSet是仓颉语言中操作关系型数据库查询结果的核心类,提供了丰富的属性和方法,使得数据的获取和操作变得灵活且高效。通过掌握ResultSet的使用,开发者可以轻松地处理数据库查询结果,实现复杂的数据交互逻辑。在实际开发中,合理使用ResultSet的各种方法,结合错误码的处理,可以有效提升应用的稳定性和用户体验。希望本文对你在使用仓颉开发 HarmonyOS 应用中的关系型数据库操作有所帮助。
数据操作实战
了解了仓颉提供的关系型数据库接口能力后,在 HarmonyOS 仓颉工程中进行数据库基础的增删改查操作。
首先创建 HarmonyOS 仓颉工程:
在 main_ability.cj 中创建创建上下文变量:
在 onCreate 中建上下文赋值给 globalAbilityContext:
接下来封装一个数据库操作类 RdbStoreManager,在构造方法中完成 RdbStore 对象的创建:
Context 使用在 MainAbility 获取的,StoreConfig 使用最小构造,传入数据库名称和等级。
接下来调用 executeSql 创建一张用户表:
创建完表后插入数据:
插入完成后从模拟器设备/data/app/el2/100/database/包名/entry/下可以看到刚创建的数据库:
将数据库文件导出后,使用 sqlite 工具打开,可以看到刚才插入的数据:
接下来可以修改本条数据,比如将年龄改为 19:
接着查询 NAME 为 Lisa 的行数据并打印:
成功查询到一行内容,并且 age 也已经被改为 19 了。
最后删除 NAME 为 Lisa 的行:
最后再查询已经没有该条记录了。
调试入口简单加了几个按钮,代码如下:
总结
本文介绍了 HarmonyOS 关系型数据库能力,以及仓颉提供的三大核心接口:RdbStore、RdbPredicates、ResultSet,并通过简单的增删改查 Demo 演示了仓颉接口的使用。后续继续将继续介绍多表、联表、联合组件等复杂操作,以及对象转换框架的实现。
版权声明: 本文为 InfoQ 作者【轻口味】的原创文章。
原文链接:【http://xie.infoq.cn/article/153a3a39f49adaf495367a5fc】。文章转载请联系作者。







评论