HarmonyOS之数据管理·关系型数据库的应用

举报
Serendipity·y 发表于 2022/02/17 00:05:38 2022/02/17
【摘要】 一、简介 ① 基本概念 关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库。HarmonyOS 关系型数据库基于 SQLite 组件提供了一套完整的对本...

一、简介

① 基本概念
  • 关系型数据库(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);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
② 插入数据
  • 构造要插入的数据,以 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);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
③ 查询数据
  • 构造用于查询的谓词对象,设置查询条件。
  • 指定查询返回的数据列。
  • 调用查询接口查询数据。
  • 调用结果集接口,遍历返回结果。
	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();

  
 
  • 1
  • 2
  • 3
  • 4

四、完整示例

文章来源: blog.csdn.net,作者:Serendipity·y,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/Forever_wj/article/details/118653356

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。