当前位置:   article > 正文

华为Harmony鸿蒙开发笔记五:DataAbility操作数据库_鸿蒙开发如何连接数据库

鸿蒙开发如何连接数据库

学习鸿蒙应用开发,在DataAbility这里卡了好久,因为官方文档太简单了,漏掉了很多的东西,还好网上已经有大神已经做出来了,我查查资料,也做出自己的Demo来了。

首先,在模块的build.gradle文件中添加compileOptions{            annotationEnabled true    }

  1. apply plugin: 'com.huawei.ohos.hap'
  2. ohos {
  3. compileSdkVersion 4
  4. defaultConfig {
  5. compatibleSdkVersion 3
  6. }
  7. compileOptions{ annotationEnabled true }
  8. }
  9. dependencies {
  10. implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
  11. testCompile'junit:junit:4.12'
  12. }

不添加的话,数据库的相关类的的包无法识别。

同步以后就可以创建数据库的类BookStore了:

  1. package com.example.dataabilitydemo;
  2. import ohos.data.orm.OrmDatabase;
  3. import ohos.data.orm.annotation.Database;
  4. @Database(entities = {User.class}, version = 1)
  5. public abstract class BookStore extends OrmDatabase {
  6. }

然后再创建数据表User了:

  1. package com.example.dataabilitydemo;
  2. import ohos.data.orm.OrmObject;
  3. import ohos.data.orm.annotation.Entity;
  4. import ohos.data.orm.annotation.Index;
  5. import ohos.data.orm.annotation.PrimaryKey;
  6. @Entity(tableName = "user", ignoredColumns = {"ignoreColumn1", "ignoreColumn2"},
  7. indices = {@Index(value = {"firstName", "lastName"}, name = "name_index", unique = true)})
  8. public class User extends OrmObject {
  9. // 此处将userId设为了自增的主键。注意只有在数据类型为包装类型时,自增主键才能生效。
  10. @PrimaryKey(autoGenerate = true)
  11. private Integer userId;
  12. private String firstName;
  13. private String lastName;
  14. private int age;
  15. private double balance;
  16. private int ignoreColumn1;
  17. private int ignoreColumn2;
  18. // 开发者自行添加字段的getter和setter 方法。
  19. public Integer getUserId() {
  20. return userId;
  21. }
  22. public void setUserId(Integer userId) {
  23. this.userId = userId;
  24. }
  25. public String getFirstName() {
  26. return firstName;
  27. }
  28. public void setFirstName(String firstName) {
  29. this.firstName = firstName;
  30. }
  31. public String getLastName() {
  32. return lastName;
  33. }
  34. public void setLastName(String lastName) {
  35. this.lastName = lastName;
  36. }
  37. public int getAge() {
  38. return age;
  39. }
  40. public void setAge(int age) {
  41. this.age = age;
  42. }
  43. public double getBalance() {
  44. return balance;
  45. }
  46. public void setBalance(double balance) {
  47. this.balance = balance;
  48. }
  49. public int getIgnoreColumn1() {
  50. return ignoreColumn1;
  51. }
  52. public void setIgnoreColumn1(int ignoreColumn1) {
  53. this.ignoreColumn1 = ignoreColumn1;
  54. }
  55. public int getIgnoreColumn2() {
  56. return ignoreColumn2;
  57. }
  58. public void setIgnoreColumn2(int ignoreColumn2) {
  59. this.ignoreColumn2 = ignoreColumn2;
  60. }
  61. }

下面就可以创建DataAbility了

有人说创建的时候要勾选visible,可是我这根本就没有这个选项,不过没关系,名字就叫UserDataAbility

创建后,配置config,

  1. "abilities": [
  2. ...........
  3. {
  4. "visible": true,
  5. "permissions": [
  6. "com.example.dataabilitydemo.UserDataAbility.DATA"
  7. ],
  8. "name": "com.example.dataabilitydemo.UserDataAbility",
  9. "icon": "$media:icon",
  10. "description": "$string:userdataability_description",
  11. "type": "data",
  12. "uri": "dataability://com.example.dataabilitydemo.UserDataAbility"
  13. }
  14. ]

其中"visible": true就是弥补创建页面没有visible勾选项的,permissions,name,uri这些项的值不一定非得是包名+类名,但保险起见,大家还是按规矩来。

然后就可以编辑UserDataAbility类了,首先,定义全局变量,并在onStart方法实现DatabaseHelper对象,用来操作数据库,并插入一条数据。

  1. rivate String uriString="dataability://com.example.dataabilitydemo.UserDataAbility";//这里要跟config.json中的URI保持一致
  2. private static final String DATABASE_NAME ="BookStore.db";
  3. private static final String DATABASE_NAME_ALIAS = "BookStore";
  4. private static OrmContext ormContext = null;
  5. private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "My_log");
  6. @Override
  7. public void onStart(Intent intent) {
  8. super.onStart(intent);
  9. DatabaseHelper helper = new DatabaseHelper(this);
  10. ormContext = helper.getOrmContext(DATABASE_NAME_ALIAS, DATABASE_NAME, BookStore.class);
  11. User user = new User();
  12. user.setFirstName("Zhang");
  13. user.setLastName("San");
  14. user.setAge(29);
  15. user.setBalance(100.51);
  16. boolean isSuccessed = ormContext.insert(user);
  17. isSuccessed = ormContext.flush();
  18. HiLog.info(LABEL_LOG, "ProviderAbility onStart");
  19. }

然后重写query方法,用来查询:

  1. @Override
  2. public ResultSet query(Uri uri, String[] columns, DataAbilityPredicates predicates) {
  3. HiLog.info(LABEL_LOG, "ProviderAbility query");
  4. if(ormContext == null){
  5. HiLog.error(LABEL_LOG,"failed to query, ormContext is null");
  6. return null;
  7. }
  8. //查询数据库
  9. OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates, User.class);
  10. ResultSet resultSet = ormContext.query(ormPredicates,columns);
  11. if (resultSet == null){
  12. HiLog.info(LABEL_LOG,"resultSet is null");
  13. }
  14. return resultSet;
  15. }

最后,在MainAbilitySlice来调用,其他的Ability要是访问DataAbility,就需要在config.json中授予访问权限,如下

  1. "orientation": "unspecified",
  2. "name": "com.example.dataabilitydemo.MainAbility",
  3. "icon": "$media:icon",
  4. "description": "$string:mainability_description",
  5. "label": "DataAbilityDemo",
  6. "type": "page",
  7. "launchType": "standard",
  8. //下面的name要跟DataAbility里的permissions保持一致呀
  9. "reqPermissions": [ { "name": "com.example.dataabilitydemo.UserDataAbility.DATA" }]

配置完就可以在Slice里写代码啦:

  1. public class MainAbilitySlice extends AbilitySlice {
  2. //下面的uriString要与config.json中DataAbility的uri保持一致,但是坑爹的事他有三个斜杠
  3. private String uriString = "dataability:///com.example.dataabilitydemo.UserDataAbility";
  4. private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "My_log");
  5. private DataAbilityHelper helper;
  6. @Override
  7. public void onStart(Intent intent) {
  8. super.onStart(intent);
  9. super.setUIContent(ResourceTable.Layout_ability_main);
  10. helper = DataAbilityHelper.creator(this);
  11. Button btnDataSelect = (Button) findComponentById(ResourceTable.Id_btn_data_select);
  12. if (btnDataSelect != null) {
  13. // 为按钮设置点击回调
  14. btnDataSelect.setClickedListener(new Component.ClickedListener() {
  15. @Override
  16. public void onClick(Component component) {
  17. try {
  18. queryDataAbility();
  19. } catch (DataAbilityRemoteException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. });
  24. }
  25. }
  26. public void queryDataAbility() throws DataAbilityRemoteException {
  27. // 构造查询条件
  28. DataAbilityPredicates predicates = new DataAbilityPredicates();
  29. predicates.equalTo("lastName", "San");
  30. // 进行查询
  31. String[] columns = new String[]{"firstName"};
  32. Uri uri = Uri.parse(uriString);
  33. ResultSet resultSet = helper.query(uri, columns, predicates);
  34. // 处理结果
  35. HiLog.info(LABEL_LOG, "queryDataAbilitystart");
  36. resultSet.goToFirstRow();
  37. do {
  38. // 在此处理ResultSet中的记录;
  39. HiLog.info(LABEL_LOG, "firstName=" + resultSet.getString(0));
  40. } while (resultSet.goToNextRow());
  41. }
  42. }

就是单击按钮,查询一个lastName叫san的人他的firstName:

  1. 12-31 21:37:18.617 22937-5343/? I 01100/My_log: ProviderAbility onStart
  2. 12-31 21:37:26.628 22937-22937/com.example.dataabilitydemo I 01100/My_log: ProviderAbility query
  3. 12-31 21:37:26.632 22937-22937/com.example.dataabilitydemo I 01100/My_log: queryDataAbilitystart
  4. 12-31 21:37:26.633 22937-22937/com.example.dataabilitydemo I 01100/My_log: firstName=Zhang

简单的查询功能就完成啦。

既然查询能走通,那么继续试试其他的,先插入一条数据吧,首先重新DataAbility的insert方法:

  1. @Override
  2. public int insert(Uri uri, ValuesBucket value) {
  3. // 参数校验
  4. HiLog.info(LABEL_LOG, "UserDataAbility insert");
  5. if (ormContext == null) {
  6. HiLog.error(LABEL_LOG, "failed to insert, ormContext is null");
  7. return -1;
  8. }
  9. // 构造插入数据
  10. User user = new User();
  11. user.setUserId(value.getInteger("userId"));
  12. user.setFirstName(value.getString("firstName"));
  13. user.setLastName(value.getString("lastName"));
  14. user.setAge(value.getInteger("age"));
  15. user.setBalance(value.getDouble("balance"));
  16. // 插入数据库
  17. boolean isSuccessed = true;
  18. isSuccessed = ormContext.insert(user);
  19. if (!isSuccessed) {
  20. HiLog.error(LABEL_LOG, "failed to insert");
  21. return -1;
  22. }
  23. isSuccessed = ormContext.flush();
  24. if (!isSuccessed) {
  25. HiLog.error(LABEL_LOG, "failed to insert flush");
  26. return -1;
  27. }
  28. DataAbilityHelper.creator(this, uri).notifyChange(uri);
  29. int id = Math.toIntExact(user.getRowId());
  30. HiLog.info(LABEL_LOG, "UserDataAbility insert id="+id);
  31. return id;
  32. }

在Slice中先调用插入,然后再查询我们插入的数据:

  1. public void queryDataAbility() throws DataAbilityRemoteException {
  2. // 构造查询条件
  3. DataAbilityPredicates predicates = new DataAbilityPredicates();
  4. predicates.equalTo("lastName", "史蒂夫");
  5. // 进行查询
  6. String[] columns = new String[]{"firstName"};
  7. Uri uri = Uri.parse(uriString);
  8. ResultSet resultSet = helper.query(uri, columns, predicates);
  9. // 处理结果
  10. HiLog.info(LABEL_LOG, "queryDataAbilitystart");
  11. resultSet.goToFirstRow();
  12. do {
  13. // 在此处理ResultSet中的记录;
  14. HiLog.info(LABEL_LOG, "firstName=" + resultSet.getString(0));
  15. } while (resultSet.goToNextRow());
  16. }
  17. public void insertDataAbility() throws DataAbilityRemoteException {
  18. // 构造插入数据
  19. HiLog.info(LABEL_LOG, "MainAbilitySlice insertDataAbility");
  20. DataAbilityHelper helper = DataAbilityHelper.creator(this);
  21. Uri uri = Uri.parse(uriString);
  22. ValuesBucket valuesBucket = new ValuesBucket();
  23. valuesBucket.putString("firstName", "孬蛋");
  24. valuesBucket.putString("lastName", "史蒂夫");
  25. valuesBucket.putInteger("age", 12);
  26. valuesBucket.putDouble("balance", 200.0);
  27. helper.insert(uri, valuesBucket);
  28. }

日志输出:

  1. 01-01 09:18:21.256 20487-20487/com.example.dataabilitydemo I 01100/My_log: MainAbilitySlice insertDataAbility
  2. 01-01 09:18:21.262 20487-20487/com.example.dataabilitydemo I 01100/My_log: UserDataAbility insert
  3. 01-01 09:18:21.270 20487-20487/com.example.dataabilitydemo I 01100/My_log: UserDataAbility insert id=2
  4. 01-01 09:18:30.485 20487-20487/com.example.dataabilitydemo I 01100/My_log: ProviderAbility query
  5. 01-01 09:18:30.505 20487-20487/com.example.dataabilitydemo I 01100/My_log: queryDataAbilitystart
  6. 01-01 09:18:30.506 20487-20487/com.example.dataabilitydemo I 01100/My_log: firstName=孬蛋

再试试修改我们插入的数据,重写DataAbility的update方法:

  1. @Override
  2. public int update(Uri uri, ValuesBucket value, DataAbilityPredicates predicates) {
  3. if (ormContext == null) {
  4. HiLog.error(LABEL_LOG, "failed to update, ormContext is null");
  5. return -1;
  6. }
  7. OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates,User.class);
  8. int index = ormContext.update(ormPredicates, value);
  9. HiLog.info(LABEL_LOG, "UserDataAbility update value:" + index);
  10. DataAbilityHelper.creator(this, uri).notifyChange(uri);
  11. return index;
  12. }

在Slice中,更新刚插入的数据,修改她的名字,然后再查询:

  1. public void updateDataAbility() throws DataAbilityRemoteException {
  2. // 构造插入数据
  3. DataAbilityHelper helper = DataAbilityHelper.creator(this);
  4. // 构造更新条件
  5. DataAbilityPredicates predicates = new DataAbilityPredicates();
  6. predicates.equalTo("lastName", "史蒂夫");
  7. // 构造更新数据
  8. ValuesBucket valuesBucket = new ValuesBucket();
  9. valuesBucket.putString("firstName", "小精豆");
  10. valuesBucket.putInteger("age", 12);
  11. Uri uri = Uri.parse(uriString);
  12. try {
  13. helper.update(uri, valuesBucket, predicates);
  14. } catch (DataAbilityRemoteException e) {
  15. e.printStackTrace();
  16. }
  17. }

结果(一定要先插入,再查询):

  1. 01-01 10:21:47.149 26565-26565/com.example.dataabilitydemo I 01100/My_log: ProviderAbility query
  2. 01-01 10:21:47.156 26565-26565/com.example.dataabilitydemo I 01100/My_log: queryDataAbilitystart
  3. 01-01 10:21:47.157 26565-26565/com.example.dataabilitydemo I 01100/My_log: firstName=孬蛋
  4. 01-01 10:21:51.961 26565-26565/com.example.dataabilitydemo I 01100/My_log: MainAbilitySlice updateDataAbility
  5. 01-01 10:21:51.966 26565-26565/com.example.dataabilitydemo I 01100/My_log: UserDataAbility update value:1
  6. 01-01 10:21:54.741 26565-26565/com.example.dataabilitydemo I 01100/My_log: ProviderAbility query
  7. 01-01 10:21:54.743 26565-26565/com.example.dataabilitydemo I 01100/My_log: queryDataAbilitystart
  8. 01-01 10:21:54.744 26565-26565/com.example.dataabilitydemo I 01100/My_log: firstName=小精豆

最后,删除这条数据,DataAbility的delete()方法:

  1. @Override
  2. public int delete(Uri uri, DataAbilityPredicates predicates) {
  3. if (ormContext == null) {
  4. HiLog.error(LABEL_LOG, "failed to delete, ormContext is null");
  5. return -1;
  6. }
  7. OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates,User.class);
  8. int value = ormContext.delete(ormPredicates);
  9. DataAbilityHelper.creator(this, uri).notifyChange(uri);
  10. return value;
  11. }

访问:

  1. public void deleteDataAbility() throws DataAbilityRemoteException {
  2. DataAbilityHelper helper = DataAbilityHelper.creator(this);
  3. Uri uri = Uri.parse(uriString);
  4. // 构造删除条件
  5. DataAbilityPredicates predicates = new DataAbilityPredicates();
  6. predicates.equalTo("lastName", "史蒂夫");
  7. helper.delete(uri,predicates);
  8. }

增删改查就都写好了

Demo:https://download.csdn.net/download/y280903468/13999695

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/236858
推荐阅读
相关标签
  

闽ICP备14008679号