赞
踩
在鸿蒙中应用数据可以在本地单机存储,也支持分布式的跨设备相互同步的方式实现数据持久化。本地单机持久化有关系型数据库、对象关系映射数据库和轻量级偏好数据库。分布式持久化有分布式数据服务。下面进行详细介绍。
鸿蒙的关系型数据库是基于 SQLite 的,它运行所需的内存极小。鸿蒙提供的数据库功能更加完善,查询效率更高。对外提供了一系列的增、删、改、查接口,也可以直接运行SQL语句。
基本概念
- 关系型数据库
创建在关系模型基础上的数据库,以行和列的形式存储数据。
- 谓词
数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。
- 结果集
指用户查询之后的结果集合,可以对数据进行访问。结果集提供了灵活的数据访问方式,可以更方便的拿到用户想要的数据。
关系型数据库的使用,首先创建一个 DataAbility 命名为 AppDatabaseDataAbility(创建方法之前的文章有写)。或者直接复制以下代码。
- public class AppDatabaseDataAbility extends Ability {
- private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "Demo");
-
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- HiLog.info(LABEL_LOG, "DatabaseDataAbility onStart");
- }
-
- @Override
- public ResultSet query(Uri uri, String[] columns, DataAbilityPredicates predicates) {
- return null;
- }
-
- @Override
- public int insert(Uri uri, ValuesBucket value) {
- HiLog.info(LABEL_LOG, "DatabaseDataAbility insert");
- return 999;
- }
-
- @Override
- public int delete(Uri uri, DataAbilityPredicates predicates) {
- return 0;
- }
-
- @Override
- public int update(Uri uri, ValuesBucket value, DataAbilityPredicates predicates) {
- return 0;
- }
-
- @Override
- public FileDescriptor openFile(Uri uri, String mode) {
- return null;
- }
-
- @Override
- public String[] getFileTypes(Uri uri, String mimeTypeFilter) {
- return new String[0];
- }
-
- @Override
- public PacMap call(String method, String arg, PacMap extras) {
- return null;
- }
-
- @Override
- public String getType(Uri uri) {
- return null;
- }
- }
如果是手动创建,需要将 DataAbility 添加到配置文件中。
- "abilities": [
- "abilities": [
- {
- "permissions": [
- "com.example.helloharmony.db.DataAbilityShellProvider.PROVIDER"
- ],
- "name": "com.example.helloharmony.db.AppDatabaseDataAbility",
- "icon": "$media:icon",
- "description": "描述",
- "type": "data",
- "uri": "dataability://com.example.helloharmony.db.AppDatabaseDataAbility"
- }
- ]
- ]
假如我们现在需要创建一个商品信息表,其中包含GUID、商品名称、操作人员和商品数量。
- private StoreConfig storeConfig = StoreConfig.newDefaultConfig("goodsinfo.db");
-
- private RdbStore rdbStore;
-
- private RdbOpenCallback rdbOpenCallback = new RdbOpenCallback() {
- @Override
- public void onCreate(RdbStore rdbStore) {
- // 数据库首次创建时调用
- rdbStore.executeSql("CREATE TABLE IF NOT EXISTS goods(" +
- "guid PRIMARY KEY," +
- "name TEXT NOT NULL," +
- "operator TEXT NOT NULL," +
- "number INTEGER)");
- }
-
- @Override
- public void onUpgrade(RdbStore rdbStore, int i, int i1) {
- // 数据库升级时调用(版本号变更时)
- }
- };
在 onStart 函数中初始化数据库
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- HiLog.info(LABEL_LOG, "DatabaseDataAbility onStart");
-
- // 创建一个数据库助手用于访问数据库
- DatabaseHelper databaseHelper = new DatabaseHelper(this);
- // 获取RDB存储
- rdbStore = databaseHelper.getRdbStore(storeConfig, 1, rdbOpenCallback, null);
- }
重写 DataAbility 框架的查询、新增、删除和更新方法以便操作数据库(可以自定义方法)
query() 方法
- /**
- * 数据库查询
- *
- * @param uri 数据的数据库表
- * @param columns 要查询的列
- * @param predicates 过滤条件。如果该参数为空,则默认查询所有数据记录
- * @return 查询的数据
- */
- @Override
- public ResultSet query(Uri uri, String[] columns, DataAbilityPredicates predicates) {
- RdbPredicates rdbPredicates = DataAbilityUtils.createRdbPredicates(predicates, "goods");
-
- return rdbStore.query(rdbPredicates, columns);
- }
insert() 方法
- /**
- * 插入数据
- *
- * @param uri 数据的数据库表
- * @param value 要插入表中的数据行
- * @return 行ID
- */
- @Override
- public int insert(Uri uri, ValuesBucket value) {
- HiLog.info(LABEL_LOG, "AppDatabaseDataAbility insert");
-
- String path = uri.getLastPath();
- if ("goods".equals(path)) {
- ValuesBucket values = new ValuesBucket();
- values.putString("guid", value.getString("guid"));
- values.putString("name", value.getString("name"));
- values.putString("operator", value.getString("operator"));
- values.putInteger("number", value.getInteger("number"));
-
- // 行ID
- int index = (int) rdbStore.insert("goods", values);
- // 插入成功时知该表格数据的订阅者
- DataAbilityHelper.creator(this, uri).notifyChange(uri);
- return index;
- }
-
- HiLog.info(LABEL_LOG, "DataAbility insert path is not matched");
- return -1;
- }
delete() 函数
- /**
- * 删除数据
- *
- * @param uri 数据的数据库表
- * @param predicates 过滤条件。如果该参数为空,则默认查询所有数据记录
- * @return 受影响行ID
- */
- @Override
- public int delete(Uri uri, DataAbilityPredicates predicates) {
- RdbPredicates rdbPredicates = DataAbilityUtils.createRdbPredicates(predicates, "goods");
- // 受影响行ID
- int index = rdbStore.delete(rdbPredicates);
- // 删除成功时知该表格数据的订阅者
- DataAbilityHelper.creator(this, uri).notifyChange(uri);
- return index;
- }
updata() 函数
- /**
- * 更新数据
- *
- * @param uri 数据的数据库表
- * @param value 要插入表中的数据行
- * @param predicates 过滤条件。如果该参数为空,则默认查询所有数据记录
- * @return 受影响行ID
- */
- @Override
- public int update(Uri uri, ValuesBucket value, DataAbilityPredicates predicates) {
- RdbPredicates rdbPredicates = DataAbilityUtils.createRdbPredicates(predicates, "goods");
- int index = rdbStore.update(value, rdbPredicates);
- // 数据变更时知该表格数据的订阅者
- DataAbilityHelper.creator(this, uri).notifyChange(uri);
- return index;
- }
查询数据库
- private void query() {
- String[] columns = new String[]{"guid", "name", "number"};
- // 构造查询条件,假如我们要查询商品为可乐的数量在0到200之间的操作有哪些?
- DataAbilityPredicates predicates = new DataAbilityPredicates();
- // 这部分的含义是商品名称为可乐的
- predicates.equalTo("name", "可乐");
- // 这部分的含义是商品数量在0到200之间的
- predicates.between("number", 0, 200);
-
- try {
- ResultSet resultSet = databaseHelper.query(
- Uri.parse("dataability:///com.example.helloharmony.db.AppDatabaseDataAbility" + "/goods"),
- columns,
- predicates);
-
- if (resultSet.goToFirstRow()) {
- do {
- String name = resultSet.getString(resultSet.getColumnIndexForName("name"));
- String operator = resultSet.getString(resultSet.getColumnIndexForName("operator"));
- int number = resultSet.getInt(resultSet.getColumnIndexForName("number"));
- HiLog.info(LABEL_LOG, "商品:" + name + " 操作员:" + operator + " 数量:" + number);
- } while (resultSet.goToNextRow());
- }
- } catch (DataAbilityRemoteException e) {
- e.printStackTrace();
- }
- }
对象关系映射数据库是在 SQLite 上做了一层封装,屏蔽了底层数据库的SQL操作,提供一系列的面向对象接口,而不必再去编写复杂是SQL语句。
基本概念
- 对象关系映射数据库的三个主要组件:
- 数据库:被开发者用@Database注解,且继承了OrmDatabase的类,对应关系型数据库。
- 实体对象:被开发者用@Entity注解,且继承了OrmObject的类,对应关系型数据库中的表。
- 对象数据操作接口:包括数据库操作的入口OrmContext类和谓词接口(OrmPredicate)等。
- 谓词
数据库中是用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。对象关系映射数据库将SQLite数据库中的谓词封装成了接口方法供开发者调用。开发者通过对象数据操作接口,可以访问到应用持久化的关系型数据。
- 对象关系映射数据库
通过将实例对象映射到关系上,实现使用操作实例对象的语法,来操作关系型数据库。它是在SQLite数据库的基础上提供的一个抽象层。
首先在配置“build.gradle”文件中添加下面的模块启动注解编译
- ohos {
- ...
- compileOptions{
- annotationEnabled true
- }
- ...
- }
我们还是以人员信息为例:
- @Entity(tableName = "person_info")
- public class PersonEntity extends OrmObject {
-
- // 指定数据库主键
- @PrimaryKey
- private String guid;
-
- private String name;
- private String gender;
- private int age;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getGender() {
- return gender;
- }
-
- public void setGender(String gender) {
- this.gender = gender;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
- }
配置数据库版本和实体
- @Database(version = 1, entities = {PersonEntity.class})
- public abstract class AppDatabase extends OrmDatabase {
- }
- // 数据库助手
- DatabaseHelper databaseHelper = new DatabaseHelper(context);
- /*
- * 获取对象关系映射数据库上下文
- * 参数分别为:ORM数据库别名、数据库文件、ORM数据库
- */
- OrmContext ormContext = databaseHelper.getOrmContext("AppDatabase", "AppDatabase.db", AppDatabase.class);
- /**
- * 插入数据
- *
- * @param personEntity 人员信息
- * @return 操作结果
- */
- private boolean insert(PersonEntity personEntity) {
- if (ormContext.insert(personEntity)) {
- return ormContext.flush();
- }
-
- return false;
- }
- /**
- * 删除数据
- *
- * @param personEntity 人员信息
- * @return 操作结果
- */
- private boolean delete(PersonEntity personEntity) {
- if (ormContext.delete(personEntity)) {
- return ormContext.flush();
- }
-
- return false;
- }
- /**
- * 更新数据
- *
- * @param personEntity 人员信息
- * @return 操作结果
- */
- private boolean upData(PersonEntity personEntity) {
- if (ormContext.update(personEntity)) {
- return ormContext.flush();
- }
-
- return false;
- }
轻量级偏好数据库主要提供轻量级Key-Value操作,支持本地应用存储少量数据,数据存储在本地文件中,同时也加载在内存中的,所以访问速度更快,效率更高。轻量级偏好数据库属于非关系型数据库,不宜存储大量数据,经常用于操作键值对形式数据的场景。
基本概念
- Key-Value数据库
一种以键值对存储数据的一种数据库,类似Java中的map。Key是关键字,Value是值。
- 非关系型数据库
区别于关系数据库,不保证遵循ACID(Atomic、Consistency、Isolation及Durability)特性,不采用关系模型来组织数据,数据之间无关系,扩展性好。
- 偏好数据
用户经常访问和使用的数据。
- DatabaseHelper databaseHelper = new DatabaseHelper(context);
- // 通过文件名称获取偏好数据库
- Preferences preferences = databaseHelper.getPreferences("Setting");
- // 获取键为 intKey 的值,第二个参数是如果返回的值不是 int 型返回的值。
- int value = preferences.getInt("intKey", 0);
- preferences.putInt("intKey", 3);
- // 同步
- preferences.flushSync();
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。