HarmonyOS之数据管理·关系型数据库的应用
Posted Forever_wj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HarmonyOS之数据管理·关系型数据库的应用相关的知识,希望对你有一定的参考价值。
一、简介
① 基本概念
- 关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库。HarmonyOS 关系型数据库基于 SQLite 组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查接口,也可以直接运行用户输入的 SQL 语句来满足复杂的场景需要。HarmonyOS 提供的关系型数据库功能更加完善,查询效率更高。
- 关系型数据库:创建在关系模型基础上的数据库,以行和列的形式存储数据。
- 谓词:数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。
- 结果集:指用户查询之后的结果集合,可以对数据进行访问。结果集提供了灵活的数据访问方式,可以更方便的拿到用户想要的数据。
- SQLite 数据库:一款轻型的数据库,是遵守 ACID 的关系型数据库管理系统,它是一个开源的项目。
② 运作机制
- HarmonyOS 关系型数据库对外提供通用的操作接口,底层使用 SQLite 作为持久化存储引擎,支持 SQLite 具有的所有数据库特性,包括但不限于事务、索引、视图、触发器、外键、参数化查询和预编译 SQL 语句。
- 关系型数据库运作机制如下图所示:
③ 配置
- 如果不指定数据库的日志模式,那么系统默认日志方式是 WAL(Write Ahead Log)模式。
- 如果不指定数据库的落盘模式,那么系统默认落盘方式是 FULL 模式。
- HarmonyOS 数据库使用的共享内存默认大小是 2MB。
- 数据库中连接池的最大数量是 4 个,用以管理用户的读写操作。
- 为保证数据的准确性,数据库同一时间只能支持一个写操作。
④ 应用场景
- 关系型数据库是在 SQLite 基础上实现的本地数据操作机制,提供给用户无需编写原生 SQL 语句就能进行数据增删改查的方法,同时也支持原生 SQL 操作。
二、关系型数据库 API
① 数据库的创建和删除
- 关系型数据库提供了数据库创建方式,以及对应的删除接口,涉及的 API 如下所示:
类名 | 接口名 | 描述 |
---|---|---|
StoreConfig.Builder | public builder() | 对数据库进行配置,包括设置数据库名、存储模式、日志模式、同步模式,是否为只读,及对数据库加密 |
RdbOpenCallback | public abstract void onCreate(RdbStore store) | 数据库创建时被回调,开发者可以在该方法中初始化表结构,并添加一些应用使用到的初始化数据 |
RdbOpenCallback | public abstract void onUpgrade(RdbStore store, int currentVersion, int targetVersion) | 数据库升级时被回调 |
DatabaseHelper | public RdbStore getRdbStore(StoreConfig config, int version, RdbOpenCallback openCallback, ResultSetHook resultSetHook) | 根据配置创建或打开数据库 |
DatabaseHelper | public boolean deleteRdbStore(String name) | 删除指定的数据库 |
② 数据库的加密
- 关系型数据库提供数据库加密的能力,创建数据库时传入指定密钥、创建加密数据库,后续打开加密数据库时,需要传入正确密钥。
- 数据库传入密钥接口如下:
类名 | 接口名 | 描述 |
---|---|---|
StoreConfig.Builder | Builder setEncryptKey(byte[] encryptKey) | 为数据库配置类设置数据库加密密钥,创建或打开数据库时传入包含数据库加密密钥的配置类,即可创建或打开加密数据库 |
③ 数据库的增删改查
- 关系型数据库提供本地数据增删改查操作的能力。
- 新增:关系型数据库提供了插入数据的接口,通过 ValuesBucket 输入要存储的数据,通过返回值判断是否插入成功,插入成功时返回最新插入数据所在的行号,失败则返回-1。数据库插入 API 如下所示:
类名 | 接口名 | 描述 |
---|---|---|
RdbStore | long insert(String table, ValuesBucket initialValues) | 向数据库插入数据。table:待添加数据的表名。initialValues:以ValuesBucket存储的待插入的数据。它提供一系列put方法,如putString(String columnName, String values),putDouble(String columnName, double value),用于向ValuesBucket中添加数据 |
- 更新:调用更新接口,传入要更新的数据,并通过 AbsRdbPredicates 指定更新条件。该接口的返回值表示更新操作影响的行数。如果更新失败,则返回 0。数据库更新 API 如下:
类名 | 接口名 | 描述 |
---|---|---|
RdbStore | int update(ValuesBucket values, AbsRdbPredicates predicates) | 更新数据库表中符合谓词指定条件的数据。 values:以ValuesBucket存储的要更新的数据。 predicates:指定了更新操作的表名和条件。AbsRdbPredicates的实现类有两个:RdbPredicates和RawRdbPredicates。RdbPredicates:支持调用谓词提供的equalTo等接口,设置更新条件。RawRdbPredicates:仅支持设置表名、where条件子句、whereArgs三个参数,不支持equalTo等接口调用 |
- 删除:调用删除接口,通过 AbsRdbPredicates 指定删除条件,该接口的返回值表示删除的数据行数,可根据此值判断是否删除成功。如果删除失败,则返回 0。数据库删除 API 如下:
类名 | 接口名 | 描述 |
---|---|---|
RdbStore | int delete(AbsRdbPredicates predicates) | 删除数据。 predicates:Rdb谓词,指定了删除操作的表名和条件。 AbsRdbPredicates的实现类有两个:RdbPredicates和RawRdbPredicates。RdbPredicates:支持调用谓词提供的equalTo等接口,设置更新条件。RawRdbPredicates:仅支持设置表名、where条件子句、whereArgs三个参数,不支持equalTo等接口调用 |
- 查询:关系型数据库提供了两种查询数据的方式:
-
- 直接调用查询接口,使用该接口,会将包含查询条件的谓词自动拼接成完整的 SQL 语句进行查询操作,无需用户传入原生的 SQL。
-
- 执行原生的用于查询的 SQL 语句。
- 数据库查询 API 如下:
类名 | 接口名 | 描述 |
---|---|---|
RdbStore | ResultSet query(AbsRdbPredicates predicates, String[] columns) | 查询数据。 predicates:谓词,可以设置查询条件。AbsRdbPredicates的实现类有两个RdbPredicates和RawRdbPredicates。 RdbPredicates:支持调用谓词提供的equalTo等接口,设置查询条件。 RawRdbPredicates:仅支持设置表名、where条件子句、whereArgs三个参数,不支持equalTo等接口调用。 columns:规定查询返回的列。 |
RdbStore | ResultSet querySql(String sql, String[] sqlArgs) | 执行原生的用于查询操作的SQL语句。 sql:原生用于查询的sql语句。sqlArgs:sql语句中占位符参数的值,若select语句中没有使用占位符,该参数可以设置为null |
④ 数据库谓词的使用
- 关系型数据库提供了用于设置数据库操作条件的谓词 AbsRdbPredicates,其中包括两个实现子类 RdbPredicates 和 RawRdbPredicates:
-
- RdbPredicates:开发者无需编写复杂的 SQL 语句,仅通过调用该类中条件相关的方法,如 equalTo、notEqualTo、groupBy、orderByAsc、beginsWith 等,就可自动完成SQL 语句拼接,方便用户聚焦业务操作。
-
- RawRdbPredicates:可满足复杂 SQL 语句的场景,支持开发者自己设置 where 条件子句和 whereArgs 参数。不支持 equalTo 等条件接口的使用。
- 数据库谓词 API 如下:
类名 | 接口名 | 描述 |
---|---|---|
RdbPredicates | RdbPredicates equalTo(String field, String value) | 设置谓词条件,满足field字段与value值相等 |
RdbPredicates | RdbPredicates notEqualTo(String field, String value) | 设置谓词条件,满足field字段与value值不相等 |
RdbPredicates | RdbPredicates beginsWith(String field, String value) | 设置谓词条件,满足field字段以value值开头 |
RdbPredicates | RdbPredicates between(String field, int low, int high) | 设置谓词条件,满足field字段在最小值low和最大值high之间 |
RdbPredicates | RdbPredicates orderByAsc(String field) | 设置谓词条件,根据field字段升序排列 |
RawRdbPredicates | void setWhereClause(String whereClause) | 设置where条件子句 |
RawRdbPredicates | void setWhereArgs(List whereArgs) | 设置whereArgs参数,该值表示where子句中占位符的值 |
⑤ 查询结果集的使用
- 关系型数据库提供了查询返回的结果集 ResultSet,指向查询结果中的一行数据,供用户对查询结果进行遍历和访问。ResultSet 的对外 API 如下表格:
类名 | 接口名 | 描述 |
---|---|---|
ResultSet | boolean goTo(int offset) | 从结果集当前位置移动指定偏移量 |
ResultSet | boolean goToRow(int position) | 将结果集移动到指定位置 |
ResultSet | boolean goToNextRow() | 将结果集向后移动一行 |
ResultSet | boolean goToPreviousRow() | 将结果集向前移动一行 |
ResultSet | boolean isStarted() | 判断结果集是否被移动过 |
ResultSet | boolean isEnded() | 判断结果集当前位置是否在最后一行之后 |
ResultSet | boolean isAtFirstRow() | 判断结果集当前位置是否在第一行 |
ResultSet | boolean isAtLastRow() | 判断结果集当前位置是否在最后一行 |
ResultSet | int getRowCount() | 获取当前结果集中的记录条数 |
ResultSet | int getColumnCount() | 获取结果集中的列数 |
ResultSet | String getString(int columnIndex) | 获取当前行指定索列的值,以String类型返回 |
ResultSet | byte[] getBlob(int columnIndex) | 获取当前行指定列的值,以字节数组形式返回 |
ResultSet | double getDouble(int columnIndex) | 获取当前行指定列的值,以double型返回 |
⑥ 事务
- 关系型数据库提供事务机制,来保证用户操作的原子性。对单条数据进行数据库操作时,无需开启事务;插入大量数据时,开启事务可以保证数据的准确性。如果中途操作出现失败,会执行回滚操作。
- 事务 API 如下:
类名 | 接口名 | 描述 |
---|---|---|
RdbStore | beginTransaction() | 开启事务 |
RdbStore | markAsCommit() | 设置事务的标记为成功 |
RdbStore | endTransaction() | 结束事务 |
⑦ 事务和结果集观察者
- 关系型数据库提供了事务和结果集观察者能力,当对应的事件被触发时,观察者会收到通知。
- API 如下所示:
类名 | 接口名 | 描述 |
---|---|---|
RdbStore | beginTransactionWithObserver(TransactionObserver transactionObserver) | 开启事务,并观察事务的启动、提交和回滚 |
ResultSet | void registerObserver(DataObserver observer) | 注册结果集的观察者 |
ResultSet | void unregisterObserver(DataObserver observer) | 注销结果集的观察者 |
⑧ 数据库的备份和恢复
- 用户可以将当前数据库的数据进行保存进行备份,还可以在需要的时候进行数据恢复。
- 数据库备份和恢复 API 如下:
类名 | 接口名 | 描述 |
---|---|---|
RdbStore | boolean restore(String srcName) | 数据库恢复接口,从指定的非加密数据库文件中恢复数据 |
RdbStore | boolean restore(String srcName, byte[] srcEncryptKey, byte[] destEncryptKey) | 数据库恢复接口,从指定的数据库文件(加密和非加密均可)中恢复数据 |
RdbStore | boolean backup(String destName) | 数据库备份接口,备份出的数据库文件是非加密的 |
RdbStore | boolean backup(String destName, byte[] destEncryptKey) | 数据库备份接口,此方法经常用在备份出加密数据库场景 |
三、关系型数据库的使用
① 创建数据库
- 配置数据库相关信息,包括数据库的名称、存储模式、是否为只读模式等。
- 初始化数据库表结构和相关数据。
- 创建数据库。
StoreConfig config = StoreConfig.newDefaultConfig("RdbStoreTest.db");
private static RdbOpenCallback callback = new RdbOpenCallback() {
@Override
public void onCreate(RdbStore store) {
store.executeSql("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
}
@Override
public void onUpgrade(RdbStore store, int oldVersion, int newVersion) {
}
};
DatabaseHelper helper = new DatabaseHelper(context);
RdbStore store = helper.getRdbStore(config, 1, callback, null);
② 插入数据
- 构造要插入的数据,以 ValuesBucket 形式存储。
- 调用关系型数据库提供的插入接口。
ValuesBucket values = new ValuesBucket();
values.putInteger("id", 1);
values.putString("name", "zhangsan");
values.putInteger("age", 18);
values.putDouble("salary", 100.5);
values.putByteArray("blobType", new byte[] {1, 2, 3});
long id = store.insert("test", values);
③ 查询数据
- 构造用于查询的谓词对象,设置查询条件。
- 指定查询返回的数据列。
- 调用查询接口查询数据。
- 调用结果集接口,遍历返回结果。
String[] columns = new String[] {"id", "name", "age", "salary"};
RdbPredicates rdbPredicates = new RdbPredicates("test").equalTo("age", 25).orderByAsc("salary");
ResultSet resultSet = store.query(rdbPredicates, columns);
resultSet.goToNextRow();
以上是关于HarmonyOS之数据管理·关系型数据库的应用的主要内容,如果未能解决你的问题,请参考以下文章