暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

10分钟掌握HarmonyOS数据库

鸿蒙技术社区 2022-03-04
1106

项目需要用到数据持久化存储,没有使用过 HarmonyOS 数据库时,我们就需要去官方文档或其他渠道去学习怎么使用,但是官方文档等长长的文字教程通常需要自己花很长时间去学习和理解才能掌握那本可以很容易就上手的知识。


本篇速成教程直接使用最精准和简短的文字,再配上讲解代码,让我们能在 10 分钟左右就能掌握最基本的数据库使用方法。


数据库的三大要素:数据库、表、字段,接下来为大家介绍关系型数据库和对象关系数据库的使用方法。


关系型数据库


在关系型数据库中,负责对应的类或创建的方式分别为:

  • 数据库:RdbStore

  • 表:通过 RdbStore 的 executeSql 方法,传入对应的 sql 语句创建表

  • 字段:通过 RdbStore 的 executeSql 方法,传入对应的 sql 语句添加字段


建表和字段:

// 如果不存在表student,则创建student表,并创建“id”(自增主键)、“name”(不为空)、“age”(integer类型)、“salary”(real类型)这4个字段
rdbStore.executeSql("create table if not exists student(id integer primary key autoincrement,name text not null, age integer, salary real)");


使用 RdbStore 类创建数据库


根据数据库操作的辅助类 DatabaseHelper 创建,并传入对应的数据库配置对象、数据库版本号、数据库创建或升降级等操作的回调对象,创建 RdbStore 数据库对象,并在数据库创建的回调里新增对应的表和字段,如下:

// 表名称
private static String StudentTable = "student";
// 数据库操作类
private RdbStore rdbStore;
// 数据库辅助类
private DatabaseHelper helper;

// 根据slice创建数据库辅助类
helper = new DatabaseHelper(context);

// 初始化数据库,包括数据库的创建。
private void initDB() {
    // 创建数据库配置对象
    StoreConfig config = StoreConfig.newDefaultConfig(StudentTable + ".db");
    RdbOpenCallback callback = new RdbOpenCallback() {
        @Override
        public void onCreate(RdbStore rdbStore) {
            rdbStore.executeSql("create table if not exists student(id integer primary key autoincrement,name text not null, age integer, salary real)");
        }

        @Override
        public void onUpgrade(RdbStore rdbStore, int i, int i1) {

        }
    };
    // 1为数据库的版本号
    rdbStore = helper.getRdbStore(config,1,callback);
}


既然拿到了数据库操作类 RdbStore,我们就可以对数据库进行增删改查的操作了。

新增数据操作:

// 添加数据
public boolean insertStudent(Student student){
    ValuesBucket bucket = new ValuesBucket();
    bucket.putInteger("age",student.getAge());
    bucket.putString("name", student.getName());
    bucket.putDouble("salary", student.getSalary());
    long id = rdbStore.insert(StudentTable, bucket);
    return id > 0 ? true : false;
}


删除、修改、查询等操作,都需要配合谓词 AbsRdbPredicates 的子类 RdbPredicates 进行。

删除数据操作:

// 删除数据:删除StudentTable表中对应的id那一条数据
public boolean deleteStudent(Integer id){
    RdbPredicates predicates = new RdbPredicates(StudentTable);
    predicates.equalTo("id", id);
    int res = rdbStore.delete(predicates);
    return res > 0 ? true : false;
}


修改数据操作:

/*
 * 修改数据:修改StudentTable表中对应id的那一条数据
 * 以下更新语句相当于执行了:
 * update student set name=?, age=?, salary=? where id = ?
 */

public boolean updateStudent(Student student){
    RdbPredicates predicates = new RdbPredicates(StudentTable);
    // 以下代码相当于执行了 where id = ?
    predicates.equalTo("id", student.getId());
    ValuesBucket bucket = new ValuesBucket();
    bucket.putInteger("age",student.getAge());
    bucket.putString("name", student.getName());
    bucket.putDouble("salary", student.getSalary());
    int id = rdbStore.update(bucket, predicates);
    return id > 0 ? true : false;
}


查询数据操作:

// 查询数据:查询StudentTable表中所有包含指定name的数据
public List<Student> queryStudents(String name){
        // String[]为想要查询的字段
    String[] strings = new String[]{
            "id""age""name""salary"
    };
    RdbPredicates predicates = new RdbPredicates(StudentTable);
    predicates.like("name", name);
    // ResultSet:查询的结果都包含在这个对象里边
    ResultSet resultSet = rdbStore.query(predicates, strings);
    List<Student> students = new ArrayList<>();
    // resultSet.goToNextRow()为true时,表示还有下一条数据,并指定到下一条数据
    while (resultSet.goToNextRow()){
        Student student = new Student();
        student.setId(resultSet.getInt(resultSet.getColumnIndexForName("id")));
        student.setAge(resultSet.getInt(resultSet.getColumnIndexForName("age")));
        student.setName(resultSet.getString(resultSet.getColumnIndexForName("name")));
        student.setSalary(resultSet.getDouble(resultSet.getColumnIndexForName("salary")));
        students.add(student);
    }
    return students;
}


对象型数据库


配置“build.gradle”文件:


如果使用注解处理器的模块为“com.huawei.ohos.hap”模块,则需要在模块的“build.gradle”文件的 ohos 节点中添加以下配置:

compileOptions{        
    annotationEnabled true    



如果使用注解处理器的模块为“com.huawei.ohos.library”模块,则需要在模块的“build.gradle”文件的“dependencies”节点中配置注解处理器。


查看“orm_annotations_java.jar”、“orm_annotations_processor_java.jar” 、“javapoet_java.jar”这 3 个 jar 包在 HUAWEI SDK 中的 Sdk/java/x.x.x.xx/build-tools/lib/ 目录,并将目录的这三个 jar 包导进来。

dependencies {
    compile files("orm_annotations_java.jar的路径""orm_annotations_processor_java.jar的路径""javapoet_java.jar的路径")
    annotationProcessor files("orm_annotations_java.jar的路径""orm_annotations_processor_java.jar的路径""javapoet_java.jar的路径")
}


如下图所示配置:

<img src=“./image.png” alt=“image” style=“zoom:50%;” />


在对象型数据库中,负责操作对应三大要素的类分别为:


①数据库:被开发者用 @Database 注解,且继承了 OrmDatabase 的类,对应关系型数据库。

// 定义了一个数据库类UserStore.java,数据库包含了“User”,"Book","AllDataType"三个表,版本号为“1”。数据库类的getVersion方法和getHelper方法不需要实现,直接将数据库类设为虚类即可。
@Database(entities = {User.class, Book.class, AllDataType.class}, version = 1
public abstract class UserStore extends OrmDatabase 

}


②表:被开发者用 @Entity 注解的实体类,且继承了 OrmObject 的类,对应关系型数据库中的表。

// 定义了一个实体类User.java,对应数据库内的表名为“user”;indices 为“firstName”和“lastName”两个字段建立了复合索引“name_index”,并且索引值是唯一的;“ignoredColumns”表示该字段不需要添加到“user”表的属性中。
@Entity(tableName = "user", ignoredColumns = {"ignoredColumn1""ignoredColumn2"},
    indices = {@Index(value = {"firstName""lastName"}, name = "name_index", unique = true)}) 
public class User extends OrmObject 
    // 此处将userId设为了自增的主键。注意只有在数据类型为包装类型时,自增主键才能生效。
    // 注意:实体类至少要声明一个主键并实现对应的getter和setter方法,不然会编译报错!
    @PrimaryKey(autoGenerate = true
    private Integer userId;   
    private String firstName;   
    private String lastName;   
    private int age;   
    private double balance;   
    private int ignoredColumn1; 
    private int ignoredColumn2; 

    // 需添加各字段的getter和setter方法。
    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }
    ...
}


③字段:对应实体类的属性,在 HarmonyOS 的对象型数据库中,有一个最重要的负责对象数据操作接口的类:OrmContext。


对象数据操作接口类 OrmContext 配合谓词接口 OrmPredicate 等,就可以实现对数据库的增删改查功能!


如下为数据库的增删改查操作:

// 插入数据
public boolean insertUser(User user){
    boolean flag = ormContext.insert(user);
    return ormContext.flush();
}

// 删除数据:删除User表中,对应userId的那一条数据。
public boolean deleteUser(Integer userId){
    OrmPredicates predicates = ormContext.where(User.class).equalTo("userId", userId);
    int flag = ormContext.delete(predicates);
    return flag > 0 ? true : false;
}

// 修改数据:修改User表中对应userId的那一条数据。
public boolean updateUser(Integer userId, User user){

    ValuesBucket bucket = new ValuesBucket();
    bucket.putInteger("age",user.getAge());
    bucket.putString("firstName", user.getFirstName());
    bucket.putString("lastName",user.getLastName());
    bucket.putDouble("balance",user.getBalance());

    OrmPredicates predicates = ormContext.where(user.getClass()).equalTo("userId", userId);

    int row_id = ormContext.update(predicates, bucket);
    return row_id > 0 ? true : false;
}

// 查询数据:查询User表中包含对应firstName的所有数据。
public List<User> queryUsersWithFirstName(String firstName){
    OrmPredicates predicates = ormContext.where(User.class).like("firstName", firstName);
    List<User> users = ormContext.query(predicates);
    return users;
}


那 ormContext 是怎么创建出来的呢?

// 数据库名称
private String database_name = "mydb.db";
// 数据库别名
private String database_name_alias = "mydb";

DatabaseHelper helper = new DatabaseHelper(context);
// UserStore.class:数据库类
ormContext = helper.getOrmContext(database_name_alias, database_name, UserStore.class);


DatabaseHelper 是数据库操作的辅助类,当数据库创建成功后,数据库文件将存储在由上下文指定的目录里。


注意:context 入参类型为 ohos.app.Context,注意不要使用 slice.getContext() 来获取 context,请直接传入 slice,否则会出现找不到类的报错。

总结


此文章用较小的篇幅讲解了最基本的 HarmonyOS 中关系型数据库和对象型数据库的使用,使读者能够快速理解和上手相关的知识和操作,当读者上手了这篇文章时,再去看其他更全更深层次的知识,相信会更加容易读懂和上手。


作者:肖瑜博

HarmonyOS开发者创新大赛城市交流会


👇点击关注鸿蒙技术社区👇
了解鸿蒙一手资讯


求分享

求点赞

求在看

文章转载自鸿蒙技术社区,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论