HarmonyOS 数据库系列之对象关系映射数据库 原创 精华

深开鸿开发板
发布于 2021-8-26 11:03
浏览
7收藏

前言

鸿蒙提供了非常强大的数据库操作功能, 前面讲到了 关系型数据库, 是基于关系模型来管理数据的数据库。

其实鸿蒙还有一种 体验更好,操作更方便的数据库 ,对象关系映射数据库, 这种数据库的好处是 直接基于sqlite数据库架构的, 操作sql语句的操作更简单,可以直接配置进行。

其实这种配置更像做web后台系统的开发,一个类就是一个表,如果需要添加信息直接更新实体类就行。

简介

先了解一下概念,概念是一切功能的使用总结。

HarmonyOS对象关系映射(Object Relational Mapping,ORM)数据库是一款基于SQLite的数据库框架,屏蔽了底层SQLite数据库的SQL操作,针对实体和关系提供了增删改查等一系列的面向对象接口。应用开发者不必再去编写复杂的SQL语句, 以操作对象的形式来操作数据库,提升效率的同时也能聚焦于业务开发。

在我看来 对象关系映射数据库非常重要的 三个 组件:

  • 数据库:被开发者用@Database注解,且继承了OrmDatabase的类,对应关系型数据库。
  • 实体对象:被开发者用@Entity注解,且继承了OrmObject的类,对应关系型数据库中的表。
  • 对象数据操作接口:包括数据库操作的入口OrmContext类和谓词接口(OrmPredicate)。

肯定还有更多的其它方面,以后继续补充吧。

运作机制

运作机制 我查看了一下官网的说明, 说了一大堆。其实主要的还是对 关系型数据库的扩展:

对象关系映射数据库操作是基于关系型数据库操作接口完成的,实际是在关系型数据库操作的基础上又实现了对象关系映射等特性。

全部介绍如下:

  • 对象关系映射数据库操作是基于关系型数据库操作接口完成的,实际是在关系型数据库操作的基础上又实现了对象关系映射等特性。因此对象关系映射数据库跟关系型数据库一样,都使用SQLite作为持久化引擎,底层使用的是同一套数据库连接池和数据库连接机制。

  • 使用对象关系映射数据库的开发者需要先配置实体模型与关系映射文件。应用数据管理框架提供的类生成工具会解析这些文件,生成数据库帮助类,这样应用数据管理框架就能在运行时,根据开发者的配置创建好数据库,并在存储过程中自动完成对象关系映射。开发者再通过对象数据操作接口,如OrmContext接口和谓词接口等操作持久化数据库。

  • 对象数据操作接口提供一组基于对象映射的数据操作接口,实现了基于SQL的关系模型数据到对象的映射,让用户不需要再和复杂的 SQL语句打交道,只需简单地操作实体对象的属性和方法。对象数据操作接口支持对象的增删改查操作,同时支持事务操作等。

对象关系映射数据库运作机制:

HarmonyOS 数据库系列之对象关系映射数据库-鸿蒙开发者社区

从上图运行机制可以看出,对象关系型数据库 是在关系型数据库基础上做了 一部分扩展, 就是将数据库的 库和表的创建 给简化了,不需要我们自己去做添加了,配置就行。

这也是数据库的一种很好的扩展,让开发更简单方便。

创建数据库及其表

数据库的创建可以根据自己需求,如果 在项目启动就需要创建数据库,建议在 application中执行启动操作。

这里我们 在 每一个 ability中 的 onStart 函数中执行如下创建操作:

DatabaseHelper helper = new DatabaseHelper(this);
OrmContext connect = helper.getOrmContext("UserDatabase", "UserDatabase.db", UserDatabase.class);

getOrmContext 参数说明 :

  • 1、别名
  • 2、数据库名
  • 3、对象-对应关系型数据库。

还有一点 需要注意,最后的参数就是表的创建,如果要创建多张表,可以添加多个 实体类。

来看看如下的 对象关系:

package com.hadiidbouk.databasemanager.database.object;
import ohos.data.orm.OrmDatabase;
import ohos.data.orm.annotation.Database;
/**
 * Database
 */
@Database(
        entities = {User.class},
        version = 1)
public abstract class UserDatabase extends OrmDatabase { }

@Database注解,继承了OrmDatabase的类,对应关系型数据库。

数据对象:

每一个数据对象就是一个表,字段信息可以根据需求更新变化。

/**
 * user Table
 */
@Entity(tableName = "user")
public class User extends OrmObject {
    @PrimaryKey()
    private Long formId;
    private String formName;
    private Integer dimension;

    public User(Long formId, String formName, Integer dimension) {
        this.formId = formId;
        this.formName = formName;
        this.dimension = dimension;
    }

    public User() { }

    public Integer getDimension() {
        return dimension;
    }

    public void setDimension(Integer dimension) {
        this.dimension = dimension;
    }

    public Long getFormId() {
        return formId;
    }

    public void setFormId(Long formId) {
        this.formId = formId;
    }

    public String getFormName() {
        return formName;
    }

    public void setFormName(String formName) {
        this.formName = formName;
    }
}

用@Entity注解,且继承了OrmObject的类,对应关系型数据库中的表。

数据库使用

在使用数据库之前最好是整理一个 工具类,所有的操作都放在工具类中,这样调用和扩展都方便了。

我就对数据库的有关操作 做了一个封装,目前也是比较简单的,只是做了增,删,改,查等操作。

关系对象型数据库的操作工具类:

/**
 * Database Operations
 *
 * @since 2021-06-23
 */
public class DatabaseUtils {
    /**
     * add card info
     *
     * @param form card object
     * @param connect data connection
     */
    public static void insertForm(User form, OrmContext connect) {
        connect.insert(form);
        connect.flush();
    }

    /**
     * query database
     *
     * @param connect data connection
     * @return database
     */
    public static List<User> queryForm(OrmContext connect){
        // 从数据库中获取信息
        OrmPredicates ormPredicates = new OrmPredicates(User.class);// 搜索实例
        List<User> formList = connect.query(ormPredicates);
        if (formList.size() <= 0) {
            return formList;
        }
        for (User form : formList) {
            // 遍历
            System.out.println("FormId = "+form.getFormId()+" = FormName"+form.getFormName()+" = Dimension"+form.getDimension());
        }
        return formList;
    }

    /**
     * update database
     *
     * @param connect 数据库实体
     * @param user user
     */
    public static void updateForms(OrmContext connect,User user) {
        // 从数据库中获取信息
        ValuesBucket valuesBucket = new ValuesBucket();
        valuesBucket.putString("formName", user.getFormName());
        valuesBucket.putInteger("dimension", user.getDimension());
        OrmPredicates update = connect.where(User.class).equalTo("formId", user.getFormId());
        connect.update(update, valuesBucket);
    }

    /**
     * delete data
     *
     * @param formId form id
     * @param connect data connection
     */
    public static void deleteFormData(long formId, OrmContext connect) {
        OrmPredicates where = connect.where(User.class);
        where.equalTo("formId", formId); // 在数据库的“user”表中查询formId为“”的User对象列表
        List<User> query = connect.query(where);
        if (!query.isEmpty()) {
            connect.delete(query.get(0));
            connect.flush();
        }
    }
}
  • 1、数据库操作的入口OrmContext类 ,进行数据库操作
  • 2、谓词接口(OrmPredicate),进行实例的制定(例如:条件查询,条件删除)
  • 3、ValuesBucket 实例

操作使用:

创建一个 ability,该类是需求操作界面类。

public class DatabaseObjectAbility extends Ability implements Component.ClickedListener {
    private DatabaseHelper helper = new DatabaseHelper(this);
    private OrmContext connect;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_database_object);
        connect = helper.getOrmContext("UserDatabase", "UserDatabase.db", UserDatabase.class);
        findComponentById(ResourceTable.Id_xinzeng_db).setClickedListener(this);
        findComponentById(ResourceTable.Id_chaxun_db).setClickedListener(this);
        findComponentById(ResourceTable.Id_xiugai_db).setClickedListener(this);
        findComponentById(ResourceTable.Id_shagnchu_db).setClickedListener(this);
    }

    @Override
    public void onClick(Component component) {
        switch (component.getId()){
            case ResourceTable.Id_xinzeng_db:
                insertDB();
                break;
            case ResourceTable.Id_chaxun_db:
                DatabaseUtils.queryForm(connect);
                break;
            case ResourceTable.Id_xiugai_db:
                User form = new User(100l, "陈建朋", 101);
                DatabaseUtils.updateForms(connect,form);
                break;
            case ResourceTable.Id_shagnchu_db:
                DatabaseUtils.deleteFormData(100l,connect);
                break;
            default:
        }
    }
    private void insertDB(){
        // 存储卡片信息
        User form = new User(100l, "陈建朋", 101);
        try {
            DatabaseUtils.insertForm(form, connect);
        } catch (Exception e) {
            DatabaseUtils.deleteFormData(form.getFormId(), connect);
        }
    }

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

ohos {
   compileSdkVersion 5
   defaultConfig {
       compatibleSdkVersion 5
   }
   buildTypes {
       release {
           proguardOpt {
               proguardEnabled false
               rulesFiles 'proguard-rules.pro'
           }
       }
   }
   compileOptions { annotationEnabled true } // 数据库使用必备
}

可以在该类中直接创建数据库和表,也可以在启动应用的时候创建,全局使用connect,

在该类中可以进行 数据库的调用操作,直接调用已经封装好的 数据库操作工具类。

到此,有关对象关系映射数据库 就结束了,是不是很简单。

感悟

通过学习鸿蒙的关系型数据库和对象关系映射数据库发现鸿蒙的强大之处,其实在对象关系映射数据库中都可以做到不需要写sql语句就能完成项目的开发和使用。

鸿蒙系统这么强大肯定还有很多强大之处我还没有了解到,还有很多好东西还等待我去探索,探索还在进行中,但是这些对鸿蒙来说只是九牛一毛罢了。

作者: 陈建朋

更多原创内容请关注:开鸿 HarmonyOS 学院

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2021-9-10 15:29:36修改
10
收藏 7
回复
举报
7条回复
按时间正序
/
按时间倒序
中软何兴彦
中软何兴彦

讲的很详细,撸码研究一下

1
回复
2021-8-26 11:08:25
黑板报呀
黑板报呀

收藏一下,学习学习。

回复
2021-8-26 11:12:35
深开鸿开发板
深开鸿开发板 回复了 黑板报呀
收藏一下,学习学习。

共同进步

回复
2021-8-26 11:33:17
mb607a438e1e09f
mb607a438e1e09f

讲解很透彻很细致,共学习同进步!

回复
2021-8-26 11:37:37
深开鸿
深开鸿 回复了 中软何兴彦
讲的很详细,撸码研究一下

谢谢认可

回复
2021-8-26 14:33:53
深开鸿
深开鸿 回复了 mb607a438e1e09f
讲解很透彻很细致,共学习同进步!

加油,一起努力

回复
2021-8-26 14:34:09
chaoxiaoshu
chaoxiaoshu

老师能不能写一篇对象关系映射数据库中一对多,多对多的表关系设计的文章

这方面用途还是挺多的,官方又搜不到相关的文档。

回复
2021-9-9 12:36:00
回复
    相关推荐