赞
踩
官网介绍:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/database-orm-overview-0000000000030070
HarmonyOS对象关系映射(Object Relational Mapping,ORM)数据库是一款基于SQLite的数据库框架,屏蔽了底层SQLite数据库的SQL操作,针对实体和关系提供了增删改查等一系列的面向对象接口。应用开发者不必再去编写复杂的SQL语句, 以操作对象的形式来操作数据库,提升效率的同时也能聚焦于业务开发。
HarmonyOS对象关系映射数据库是建立在HarmonyOS关系型数据库的基础之上的,ORM就是在关系型数据库操作的基础上做了进一步封装,目的是将Java的类和数据库的表建立关联对应关系,除了数据库版本升降级等场景外,操作对象关系映射数据库一般不需要编写SQL语句,这样用起来更方便,更好用。
使用场景介绍:对象关系映射数据库适用于开发者使用的数据可以分解为一个或多个对象,且需要对数据进行增删改查等操作,但是不希望编写过于复杂的SQL语句的场景。
开发能力介绍:对象关系映射数据库目前可以支持数据库和表的创建,对象数据的增删改查、对象数据变化回调、数据库升降级和备份等功能。
对象关系映射数据库的三个主要组件:
①数据库:被开发者用@Database注解,且继承了OrmDatabase的类,对应关系型数据库。
②实体对象:被开发者用@Entity注解,且继承了OrmObject的类,对应关系型数据库中的表。
③对象数据操作接口:包括数据库操作的入口OrmContext类和谓词接口(OrmPredicate)等。
官网文档:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/database-orm-guidelines-0000000000030063
在build.gradle中配置(如果使用注解处理器的模块为“com.huawei.ohos.hap”模块,则需要在模块的“build.gradle”文件的“ohos”节点中添加以下配置)
compileOptions { annotationEnabled true }
如果没有添加这个配置,则会出现Cannot resolve symbol ‘Database‘、Cannot resolve symbol ‘Entity‘错误,详情可见本人《鸿蒙出现Cannot resolve symbol ‘Database‘、Cannot resolve symbol ‘Entity‘错误》文章。
开发者需要定义一个表示数据库的类,继承OrmDatabase,再通过@Database注解内的entities属性指定哪些数据模型类属于这个数据库。
/**
* 对象关系映射数据库的数据库类BookStore
*
* @author 舒小羽
* @date 2021/0/0 0027
*/
//创建数据库。
//开发者定义一个表示数据库的类,继承OrmDatabase,
//再通过@Database注解内的entities属性指定数据库内包含的表,version为数据库版本号。
@Database(entities = {User.class}, version = 1)
public abstract class BookStore extends OrmDatabase {
//数据库类的getVersion方法和getHelper方法不需要实现,直接将数据库类设为虚类即可。
//以下的方法可以不用实现
@Override
public int getVersion() {
return 1;//当前数据库版本号为1
}
@Override
public RdbOpenCallback getHelper() {
return new RdbOpenCallback() {
@Override
public void onCreate(RdbStore rdbStore) {
//创建成功后执行操作
HiLog.error(new HiLogLabel(HiLog.LOG_APP, 0xD00201, "Data_Log"), "对象关系映射数据库创建成功");
}
@Override
public void onUpgrade(RdbStore rdbStore, int oldVersion, int newVersion) {
//数据库升级需要执行的操作
}
};
}
}
开发者可通过创建一个继承了OrmObject并用@Entity注解的类,获取数据库实体对象,也就是表的对象。数据表必须与其所在的数据库在同一个模块中。
注解对照表
接口名称 | 描述 |
---|---|
@Database | 被@Database注解且继承了OrmDatabase的类对应数据库类。 |
@Entity | 被@Entity注解且继承了OrmObject的类对应数据表类。 |
@Column | 被@Column注解的变量对应数据表的字段。 |
@PrimaryKey | 被@PrimaryKey注解的变量对应数据表的主键。 |
@ForeignKey | 被@ForeignKey注解的变量对应数据表的外键。 |
@Index | 被@Index注解的内容对应数据表索引的属性。 |
/**
* 对象关系映射数据库的实体对象类User
*
* @author 舒小羽
* @date 2021/0/0 0027
*/
//创建数据表。(数据表必须与其所在的数据库在同一个模块中)
//开发者创建一个继承了OrmObject并用@Entity注解的类,
//获取数据库实体对象,也就是表的对象。
//tableName:表名
//"ignoredColumns"表示该字段不需要添加到"user"表的属性中
//indices:索引列表。indices为"identityCardNumber"和"telephoneNumber"两个字段建立了复合索引"name_index",并且索引值是唯一的
@Entity(tableName = "user", ignoredColumns = {"ignoreColumn1", "ignoreColumn2"},
indices = {@Index(value = {"identityCardNumber", "telephoneNumber"}, 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 String identityCardNumber;
private String telephoneNumber;
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 String getIdentityCardNumber() {
return identityCardNumber;
}
public void setIdentityCardNumber(String identityCardNumber) {
this.identityCardNumber = identityCardNumber;
}
public String getTelephoneNumber() {
return telephoneNumber;
}
public void setTelephoneNumber(String telephoneNumber) {
this.telephoneNumber = telephoneNumber;
}
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;
}
}
注:①数据表必须与其所在的数据库在同一个模块中
②如果要创建多个表一定注意索引的名字index这个值不能重复
通过对象数据操作接口OrmContext,创建一个别名为“BookStore”,数据库文件名为“BookStore.db”的数据库。如果数据库已经存在,执行以下代码不会重复创建。通过context.getDatabaseDir()可以获取创建的数据库文件所在的目录。
在MainAbilitySlice中
//在前面的配置、数据库类、数据库表类都弄好的前提下,创建数据库和表
DatabaseHelper helper = new DatabaseHelper(this);
OrmContext ormContext = helper.getOrmContext("BookStore", "BookStore.db", BookStore.class);
HiLog.error(LABEL_LOG, "创建数据库成功");
如果开发者有多个版本的数据库,通过设置数据库版本迁移类可以实现数据库版本升降级。
数据库版本升降级的调用示例如下。
//数据库升降级
//BookStoreUpgrade类也是一个继承了OrmDatabase的数据库类,与BookStore类的区别在于配置的版本号不同
mOrmContext = helper.getOrmContext(DATABASE_NAME_ALIAS, DATABASE_NAME, BookStoreUpgrade.class, new TestOrmMigration12());
有多次升降级的写法
OrmContext context = helper.getOrmContext("BookStore",
"BookStore.db",
BookStoreUpgrade.class,
new TestOrmMigration32(),
new TestOrmMigration23(),
new TestOrmMigration12(),
new TestOrmMigration21());
TestOrmMigration12的实现示例如下:
//数据库升降级
private static class TestOrmMigration12 extends OrmMigration {
// 此处用于配置数据库版本迁移的开始版本和结束版本,super(startVersion, endVersion)即数据库版本号从1升到2。
public TestOrmMigration12() {
super(1, 2);
}
@Override
public void onMigrate(RdbStore store) {
store.executeSql("ALTER TABLE `BookStore` ADD COLUMN `addColumn12` INTEGER");
}
}
数据库版本迁移类的起始版本和结束版本必须是连续的。
增删改查与事务
//增加数据
//在数据库的名为“user”的表中,新建一个User对象并设置对象的属性
User user_insert = new User();
user_insert.setFirstName("张");
user_insert.setLastName("三");
user_insert.setAge(20);
user_insert.setBalance(120.51);
//直接传入OrmObject对象的增加接口,只有在flush()接口被调用后才会持久化到数据库中
boolean isSuccessed1 = ormContext.insert(user_insert);//保存到内存(这里的插入是在内存,没有真正的把数据落地到仓库)
boolean isSuccessed2 = ormContext.flush();//保存到本地数据库(这个方法才是真正的落地到仓库)
HiLog.error(LABEL_LOG, "增加数据isSuccessed:" + isSuccessed1 + "," + isSuccessed2);
//开启事务
ormContext.beginTransaction();
HiLog.error(LABEL_LOG, "============开启事务============");
try {
User user1 = new User();
user1.setFirstName("王");
user1.setLastName("wu");
user1.setAge(28);
user1.setBalance(130.00);
ormContext.insert(user1);
ormContext.flush();
//获取数据,查询数据
OrmPredicates ormPredicates =
ormContext.where(User.class).equalTo("firstName", "王");
List<User> userList_transaction = ormContext.query(ormPredicates);
User user_transaction = userList_transaction.get(0);
//删除数据
ormContext.delete(user_transaction);
ormContext.flush();
//提交事务
ormContext.commit();
HiLog.error(LABEL_LOG, "============提交事务============");
} catch (Exception e) {
HiLog.error(LABEL_LOG, "============出错了============");
//回滚
ormContext.rollback();
HiLog.error(LABEL_LOG, "============回滚============");
}
//查询列表验证并打印
List<User> UserList_Transaction = ormContext.query(ormContext.where(User.class));
for (User user : UserList_Transaction) {
HiLog.error(LABEL_LOG, "查询到事务后的users的所有firstName:" + user.getFirstName());
}
//查询数据
//在数据库的“user”表中查询lastName为“三”的User对象列表,示例如下
OrmPredicates query1 = ormContext.where(User.class).equalTo("firstName", "张");
List<User> usersList1 = ormContext.query(query1);
HiLog.error(LABEL_LOG, "查询到的users的FirstName:" + usersList1.get(0).getFirstName());
OrmPredicates query2 = ormContext.where(User.class).equalTo("firstName", "张").and().equalTo("lastName", "三");
List<User> usersList2 = ormContext.query(query2);
HiLog.error(LABEL_LOG, "查询到的users的Age:" + usersList2.get(0).getAge());
ResultSet res_query = ormContext.query(query1, new String[]{"lastName", "firstName", "userId"});
//处理结果
while (res_query.goToNextRow()) {
//在此处理ResultSet中的记录
HiLog.error(LABEL_LOG, "查询到的users的userId:" + res_query.getString(2));
}
//更新或删除数据,分为两种情况:
//法一:
// 通过直接传入OrmObject对象的接口来更新数据
// 需要先从表中查到需要更新的User对象列表,然后修改对象的值,再调用更新接口持久化到数据库中。
// 删除数据与更新数据的方法类似,只是不需要更新对象的值。
// 更新数据(先查后改)
OrmPredicates predicates_update1 = ormContext.where(User.class);
predicates_update1.equalTo("age", 20);
List<User> userList_update1 = ormContext.query(predicates_update1);
User user_update1 = userList_update1.get(0);
user_update1.setFirstName("李");
boolean isTure_update1 = ormContext.update(user_update1);
ormContext.flush();
HiLog.error(LABEL_LOG, "更新数据成功" + isTure_update1);
//查询列表验证并打印
OrmPredicates query_update1 = ormContext.where(User.class).equalTo("age", 20);
List<User> usersList_update1 = ormContext.query(query_update1);
HiLog.error(LABEL_LOG, "更新数据后查询列表验证并打印FirstName:" + usersList_update1.get(0).getFirstName());
// 删除数据(先查后删)
OrmPredicates predicates_delete1 = ormContext.where(User.class);
predicates_delete1.equalTo("balance", 120.51);
List<User> userList_delete1 = ormContext.query(predicates_delete1);
User user_delete1 = userList_delete1.get(0);
boolean isTure_delete1 = ormContext.delete(user_delete1);
ormContext.flush();
HiLog.error(LABEL_LOG, "删除数据成功" + isTure_delete1);
//查询列表验证并打印
OrmPredicates query_delete1 = ormContext.where(User.class).equalTo("balance", 120.51);
List<User> usersList_delete1 = ormContext.query(query_delete1);
if (usersList_delete1.isEmpty()) {
HiLog.error(LABEL_LOG, "删除数据后查询列表验证并打印:Empty");
}
//法二:
// 通过传入谓词的接口来更新和删除数据,方法与OrmObject对象的接口类似,只是无需flush就可以持久化到数据库中
//释放下面方法时,请注释上方法一
// 更新数据
// ValuesBucket valuesBucket = new ValuesBucket();
// valuesBucket.putInteger("age", 30);
// valuesBucket.putDouble("balance", 150.00);
// OrmPredicates update = ormContext.where(User.class).equalTo("firstName", "张");
// ormContext.update(update, valuesBucket);
// HiLog.error(LABEL_LOG, "更新数据成功" + ormContext.update(update, valuesBucket));
// //查询列表验证并打印
// OrmPredicates query_update2 = ormContext.where(User.class).equalTo("firstName", "张");
// List<User> usersList_update2 = ormContext.query(query_update2);
// HiLog.error(LABEL_LOG, "更新数据后查询列表验证并打印Age:" + usersList_update2.get(0).getAge());
// // 删除数据
// OrmPredicates predicates_delete2 = ormContext.where(User.class).equalTo("balance", 150.00);
// int index_delete2 = ormContext.delete(predicates_delete2);
// HiLog.error(LABEL_LOG, "删除数据成功" + index_delete2);
// //查询列表验证并打印
// OrmPredicates query_delete2 = ormContext.where(User.class).equalTo("balance", 120.51);
// List<User> usersList_delete2 = ormContext.query(query_delete2);
// if (usersList_delete2.isEmpty()) {
// HiLog.error(LABEL_LOG, "删除数据后查询列表验证并打印:Empty");
// }
}
注册观察者、备份数据库、删除数据库等以后会补充在此文章中,敬请期待!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。