学习鸿蒙应用开发,在DataAbility这里卡了好久,因为官方文档太简单了,漏掉了很多的东西,还好网上已经有大神已经做出来了,我查查资料,也做出自己的Demo来了。
首先,在模块的build.gradle文件中添加compileOptions{ annotationEnabled true }
apply plugin: 'com.huawei.ohos.hap'
ohos {
compileSdkVersion 4
defaultConfig {
compatibleSdkVersion 3
}
compileOptions{ annotationEnabled true }
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
testCompile'junit:junit:4.12'
}
不添加的话,数据库的相关类的的包无法识别。
同步以后就可以创建数据库的类BookStore了:
package com.example.dataabilitydemo;
import ohos.data.orm.OrmDatabase;
import ohos.data.orm.annotation.Database;
@Database(entities = {User.class}, version = 1)
public abstract class BookStore extends OrmDatabase {
}
然后再创建数据表User了:
package com.example.dataabilitydemo;
import ohos.data.orm.OrmObject;
import ohos.data.orm.annotation.Entity;
import ohos.data.orm.annotation.Index;
import ohos.data.orm.annotation.PrimaryKey;
@Entity(tableName = "user", ignoredColumns = {"ignoreColumn1", "ignoreColumn2"},
indices = {@Index(value = {"firstName", "lastName"}, name = "name_index", unique = true)})
public class User extends OrmObject {
// 此处将userId设为了自增的主键。注意只有在数据类型为包装类型时,自增主键才能生效。
@PrimaryKey(autoGenerate = true)
private Integer userId;
private String firstName;
private String lastName;
private int age;
private double balance;
private int ignoreColumn1;
private int ignoreColumn2;
// 开发者自行添加字段的getter和setter 方法。
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public int getIgnoreColumn1() {
return ignoreColumn1;
}
public void setIgnoreColumn1(int ignoreColumn1) {
this.ignoreColumn1 = ignoreColumn1;
}
public int getIgnoreColumn2() {
return ignoreColumn2;
}
public void setIgnoreColumn2(int ignoreColumn2) {
this.ignoreColumn2 = ignoreColumn2;
}
}
下面就可以创建DataAbility了
有人说创建的时候要勾选visible,可是我这根本就没有这个选项,不过没关系,名字就叫UserDataAbility
创建后,配置config,
"abilities": [
...........
{
"visible": true,
"permissions": [
"com.example.dataabilitydemo.UserDataAbility.DATA"
],
"name": "com.example.dataabilitydemo.UserDataAbility",
"icon": "$media:icon",
"description": "$string:userdataability_description",
"type": "data",
"uri": "dataability://com.example.dataabilitydemo.UserDataAbility"
}
]
其中"visible": true就是弥补创建页面没有visible勾选项的,permissions,name,uri这些项的值不一定非得是包名+类名,但保险起见,大家还是按规矩来。
然后就可以编辑UserDataAbility类了,首先,定义全局变量,并在onStart方法实现DatabaseHelper对象,用来操作数据库,并插入一条数据。
rivate String uriString="dataability://com.example.dataabilitydemo.UserDataAbility";//这里要跟config.json中的URI保持一致
private static final String DATABASE_NAME ="BookStore.db";
private static final String DATABASE_NAME_ALIAS = "BookStore";
private static OrmContext ormContext = null;
private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "My_log");
@Override
public void onStart(Intent intent) {
super.onStart(intent);
DatabaseHelper helper = new DatabaseHelper(this);
ormContext = helper.getOrmContext(DATABASE_NAME_ALIAS, DATABASE_NAME, BookStore.class);
User user = new User();
user.setFirstName("Zhang");
user.setLastName("San");
user.setAge(29);
user.setBalance(100.51);
boolean isSuccessed = ormContext.insert(user);
isSuccessed = ormContext.flush();
HiLog.info(LABEL_LOG, "ProviderAbility onStart");
}
然后重写query方法,用来查询:
@Override
public ResultSet query(Uri uri, String[] columns, DataAbilityPredicates predicates) {
HiLog.info(LABEL_LOG, "ProviderAbility query");
if(ormContext == null){
HiLog.error(LABEL_LOG,"failed to query, ormContext is null");
return null;
}
//查询数据库
OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates, User.class);
ResultSet resultSet = ormContext.query(ormPredicates,columns);
if (resultSet == null){
HiLog.info(LABEL_LOG,"resultSet is null");
}
return resultSet;
}
最后,在MainAbilitySlice来调用,其他的Ability要是访问DataAbility,就需要在config.json中授予访问权限,如下
"orientation": "unspecified",
"name": "com.example.dataabilitydemo.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "DataAbilityDemo",
"type": "page",
"launchType": "standard",
//下面的name要跟DataAbility里的permissions保持一致呀
"reqPermissions": [ { "name": "com.example.dataabilitydemo.UserDataAbility.DATA" }]
配置完就可以在Slice里写代码啦:
public class MainAbilitySlice extends AbilitySlice {
//下面的uriString要与config.json中DataAbility的uri保持一致,但是坑爹的事他有三个斜杠
private String uriString = "dataability:///com.example.dataabilitydemo.UserDataAbility";
private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "My_log");
private DataAbilityHelper helper;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
helper = DataAbilityHelper.creator(this);
Button btnDataSelect = (Button) findComponentById(ResourceTable.Id_btn_data_select);
if (btnDataSelect != null) {
// 为按钮设置点击回调
btnDataSelect.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
try {
queryDataAbility();
} catch (DataAbilityRemoteException e) {
e.printStackTrace();
}
}
});
}
}
public void queryDataAbility() throws DataAbilityRemoteException {
// 构造查询条件
DataAbilityPredicates predicates = new DataAbilityPredicates();
predicates.equalTo("lastName", "San");
// 进行查询
String[] columns = new String[]{"firstName"};
Uri uri = Uri.parse(uriString);
ResultSet resultSet = helper.query(uri, columns, predicates);
// 处理结果
HiLog.info(LABEL_LOG, "queryDataAbilitystart");
resultSet.goToFirstRow();
do {
// 在此处理ResultSet中的记录;
HiLog.info(LABEL_LOG, "firstName=" + resultSet.getString(0));
} while (resultSet.goToNextRow());
}
}
就是单击按钮,查询一个lastName叫san的人他的firstName:
12-31 21:37:18.617 22937-5343/? I 01100/My_log: ProviderAbility onStart
12-31 21:37:26.628 22937-22937/com.example.dataabilitydemo I 01100/My_log: ProviderAbility query
12-31 21:37:26.632 22937-22937/com.example.dataabilitydemo I 01100/My_log: queryDataAbilitystart
12-31 21:37:26.633 22937-22937/com.example.dataabilitydemo I 01100/My_log: firstName=Zhang
简单的查询功能就完成啦。
既然查询能走通,那么继续试试其他的,先插入一条数据吧,首先重新DataAbility的insert方法:
@Override
public int insert(Uri uri, ValuesBucket value) {
// 参数校验
HiLog.info(LABEL_LOG, "UserDataAbility insert");
if (ormContext == null) {
HiLog.error(LABEL_LOG, "failed to insert, ormContext is null");
return -1;
}
// 构造插入数据
User user = new User();
user.setUserId(value.getInteger("userId"));
user.setFirstName(value.getString("firstName"));
user.setLastName(value.getString("lastName"));
user.setAge(value.getInteger("age"));
user.setBalance(value.getDouble("balance"));
// 插入数据库
boolean isSuccessed = true;
isSuccessed = ormContext.insert(user);
if (!isSuccessed) {
HiLog.error(LABEL_LOG, "failed to insert");
return -1;
}
isSuccessed = ormContext.flush();
if (!isSuccessed) {
HiLog.error(LABEL_LOG, "failed to insert flush");
return -1;
}
DataAbilityHelper.creator(this, uri).notifyChange(uri);
int id = Math.toIntExact(user.getRowId());
HiLog.info(LABEL_LOG, "UserDataAbility insert id="+id);
return id;
}
在Slice中先调用插入,然后再查询我们插入的数据:
public void queryDataAbility() throws DataAbilityRemoteException {
// 构造查询条件
DataAbilityPredicates predicates = new DataAbilityPredicates();
predicates.equalTo("lastName", "史蒂夫");
// 进行查询
String[] columns = new String[]{"firstName"};
Uri uri = Uri.parse(uriString);
ResultSet resultSet = helper.query(uri, columns, predicates);
// 处理结果
HiLog.info(LABEL_LOG, "queryDataAbilitystart");
resultSet.goToFirstRow();
do {
// 在此处理ResultSet中的记录;
HiLog.info(LABEL_LOG, "firstName=" + resultSet.getString(0));
} while (resultSet.goToNextRow());
}
public void insertDataAbility() throws DataAbilityRemoteException {
// 构造插入数据
HiLog.info(LABEL_LOG, "MainAbilitySlice insertDataAbility");
DataAbilityHelper helper = DataAbilityHelper.creator(this);
Uri uri = Uri.parse(uriString);
ValuesBucket valuesBucket = new ValuesBucket();
valuesBucket.putString("firstName", "孬蛋");
valuesBucket.putString("lastName", "史蒂夫");
valuesBucket.putInteger("age", 12);
valuesBucket.putDouble("balance", 200.0);
helper.insert(uri, valuesBucket);
}
日志输出:
01-01 09:18:21.256 20487-20487/com.example.dataabilitydemo I 01100/My_log: MainAbilitySlice insertDataAbility
01-01 09:18:21.262 20487-20487/com.example.dataabilitydemo I 01100/My_log: UserDataAbility insert
01-01 09:18:21.270 20487-20487/com.example.dataabilitydemo I 01100/My_log: UserDataAbility insert id=2
01-01 09:18:30.485 20487-20487/com.example.dataabilitydemo I 01100/My_log: ProviderAbility query
01-01 09:18:30.505 20487-20487/com.example.dataabilitydemo I 01100/My_log: queryDataAbilitystart
01-01 09:18:30.506 20487-20487/com.example.dataabilitydemo I 01100/My_log: firstName=孬蛋
再试试修改我们插入的数据,重写DataAbility的update方法:
@Override
public int update(Uri uri, ValuesBucket value, DataAbilityPredicates predicates) {
if (ormContext == null) {
HiLog.error(LABEL_LOG, "failed to update, ormContext is null");
return -1;
}
OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates,User.class);
int index = ormContext.update(ormPredicates, value);
HiLog.info(LABEL_LOG, "UserDataAbility update value:" + index);
DataAbilityHelper.creator(this, uri).notifyChange(uri);
return index;
}
在Slice中,更新刚插入的数据,修改她的名字,然后再查询:
public void updateDataAbility() throws DataAbilityRemoteException {
// 构造插入数据
DataAbilityHelper helper = DataAbilityHelper.creator(this);
// 构造更新条件
DataAbilityPredicates predicates = new DataAbilityPredicates();
predicates.equalTo("lastName", "史蒂夫");
// 构造更新数据
ValuesBucket valuesBucket = new ValuesBucket();
valuesBucket.putString("firstName", "小精豆");
valuesBucket.putInteger("age", 12);
Uri uri = Uri.parse(uriString);
try {
helper.update(uri, valuesBucket, predicates);
} catch (DataAbilityRemoteException e) {
e.printStackTrace();
}
}
结果(一定要先插入,再查询):
01-01 10:21:47.149 26565-26565/com.example.dataabilitydemo I 01100/My_log: ProviderAbility query
01-01 10:21:47.156 26565-26565/com.example.dataabilitydemo I 01100/My_log: queryDataAbilitystart
01-01 10:21:47.157 26565-26565/com.example.dataabilitydemo I 01100/My_log: firstName=孬蛋
01-01 10:21:51.961 26565-26565/com.example.dataabilitydemo I 01100/My_log: MainAbilitySlice updateDataAbility
01-01 10:21:51.966 26565-26565/com.example.dataabilitydemo I 01100/My_log: UserDataAbility update value:1
01-01 10:21:54.741 26565-26565/com.example.dataabilitydemo I 01100/My_log: ProviderAbility query
01-01 10:21:54.743 26565-26565/com.example.dataabilitydemo I 01100/My_log: queryDataAbilitystart
01-01 10:21:54.744 26565-26565/com.example.dataabilitydemo I 01100/My_log: firstName=小精豆
最后,删除这条数据,DataAbility的delete()方法:
@Override
public int delete(Uri uri, DataAbilityPredicates predicates) {
if (ormContext == null) {
HiLog.error(LABEL_LOG, "failed to delete, ormContext is null");
return -1;
}
OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates,User.class);
int value = ormContext.delete(ormPredicates);
DataAbilityHelper.creator(this, uri).notifyChange(uri);
return value;
}
访问:
public void deleteDataAbility() throws DataAbilityRemoteException {
DataAbilityHelper helper = DataAbilityHelper.creator(this);
Uri uri = Uri.parse(uriString);
// 构造删除条件
DataAbilityPredicates predicates = new DataAbilityPredicates();
predicates.equalTo("lastName", "史蒂夫");
helper.delete(uri,predicates);
}
增删改查就都写好了