0

HarmonyOS —十分钟教会数据库快速上手

 2 years ago
source link: https://os.51cto.com/article/703210.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
HarmonyOS —十分钟教会数据库快速上手-51CTO.COM
HarmonyOS —十分钟教会数据库快速上手
作者:肖瑜博 2022-03-04 16:06:33
数据库的三大要素:数据库、表、字段,接下来为大家介绍关系型数据库和对象关系数据库的使用方法。

97dd5d11147cb86e0da964a27d70470e8020e3.png

​想了解更多内容,请访问:​

​51CTO和华为官方合作共建的鸿蒙技术社区​

​https://ost.51cto.com​

项目需要用到数据持久化存储,没有使用过HarmonyOS数据库时,我们就需要去官方文档或其他渠道去学习怎么使用,但是官方文档等长长的文字教程通常需要自己花很长时间去学习和理解才能掌握那本可以很容易就上手的知识。本篇速成教程直接使用最精准和简短的文字,再配上讲解代码,让我们能在10分钟左右就能掌握最基本的数据库使用方法。数据库的三大要素:数据库、表、字段,接下来为大家介绍关系型数据库和对象关系数据库的使用方法。

关系型数据库

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

  1. 数据库:RdbStore
  2. 表:通过RdbStore的executeSql方法,传入对应的sql语句创建表
  3. 字段:通过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”文件:

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

compileOptions{        
    annotationEnabled true    
} 

2、如果使用注解处理器的模块为“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的路径")
}

如下图所示配置:

89cf620204590b6610100830ff947a2f248712.png

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

数据库:被开发者用@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中关系型数据库和对象型数据库的使用,使读者能够快速理解和上手相关的知识和操作,当读者上手了这篇文章时,再去看其他更全更深层次的知识,相信会更加容易读懂和上手。

​想了解更多内容,请访问:​

​51CTO和华为官方合作共建的鸿蒙技术社区​

​https://ost.51cto.com​

38ad0f3008dcaa6aa7b1286f9a420571425f7b.jpg


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK