鸿蒙关系型数据库操作实践尝试

网友投稿 763 2023-06-01

鸿蒙关系型数据库操作实践尝试

鸿蒙关系型数据库操作实践尝试

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

和***官方合作共建的鸿蒙技术社区

简单使用

1. 创建数据库

初始化数据库

public class HiDbHelper {      //1. 配置数据库相关信息     private static StoreConfig config = StoreConfig.newDefaultConfig("RdbStoreTest.db");      //RdbOpenCallback用于管理数据库的创建、升级和降级     private static RdbOpenCallback callback = new RdbOpenCallback() {         @Override         public void onCreate(RdbStore rdbStore) {             //该方法当数据库不存在时会被调用             //2. 初始化数据库表             rdbStore.executeSql("CREATE TABLE IF NOT EXISTS employee (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");         }          @Override         public void onUpgrade(RdbStore rdbStore, int i, int i1) {          }     };      //RdbStore是一个接口,提供了对数据库进行增删改查等操作     private static volatile RdbStore store;      //3. 获取对数据库操作的对象     public static RdbStore singleStore() {         synchronized (HiDbHelper.class) {             if (store == null) {                 synchronized (HiDbHelper.class) {                     //DatabaseHelper提供了多种模式来操作数据库,主要是对ORM(Object Relational Mapping),RDB(Relational Database),Preferences这三类数据库的构建和删除                     DatabaseHelper helper = new DatabaseHelper(MyApplication.appContext);                     //通过getRdbStore获取关系型数据库对象                     //getRdbStore四个参数分别是:                     //StoreConfig config: 对数据库的配置,包括数据库路径,存储模式,是否为只读等                     //int version: 数据库版本,主要用于指示数据库的升级或降级                     //RdbOpenCallback openCallback: 用于管理数据库的创建、升级和降级                     //ResultSetHook resultSetHook: 这个类允许用户自定义结果集                     store = helper.getRdbStore(config, 1, callback, null);                 }             }         }         return store;     } }

2. 插入数据

关系型数据库提供了插入数据的接口,通过ValuesBucket输入要存储的数据,通过返回值判断是否插入成功,插入成功时返回最新插入数据所在的行号,失败则返回-1。

//1. 构建需要插入的数据,关系型数据库中,插入的数据是以ValuesBucket形式存储的 ValuesBucket values = new ValuesBucket(); values.putInteger("id", 1); values.putString("name", "zhangsan"); values.putInteger("age", 18); values.putDouble("salary", 100.5); values.putByteArray("blobType", new byte[] {1, 2, 3}); //2. 执行插入操作,第一个参数为数据需要插入的表名,第二个参数为需要插入的数据 long id = HiDbHelper.singleStore().insert("employee", values);

3. 查询数据

查询操作

关系型数据库查询提供类两种查询方式:

1.通过调用ResultSet query(AbsRdbPredicates predicates, String[] columns)查询,该方法将包含查询条件的谓词自动拼接成完整的SQL语句进行查询操作,无需调用者传入原生的SQL

传入参数说明

AbsRdbPredicates predicates:谓词,可设置查询条件。AbsRdbPredicates的实现类有两个:RdbPredicates和RawRdbPredicatesRdbPredicates:支持调用谓词提供的equalTo等接口,设置查询条件。RawRdbPredicates:仅支持设置表名、where条件子句、whereArgs三个参数,不支持equalTo等接口调用。columns:规定查询返回的列。

关于更多谓词的使用可以查询官方文档关系型数据库开发指导

//1. 需要查询的列 String[] columns = new String[] {"id", "name", "age", "salary"}; //2. 构建查询条件 RdbPredicates rdbPredicates = new RdbPredicates("employee").equalTo("age", 23).orderByAsc("salary"); //3. 查询获取结果集 ResultSet resultSet = HiDbHelper.singleStore().query(rdbPredicates, columns);

通过调用ResultSet querySql(String sql, String[] sqlArgs)使用原生SQL语句进行查询

参数说明:

String sql:原生用于查询的sql语句String[] sqlArgs:sql语句中占位符参数的值,若select语句中没有使用占位符,该参数可以设置为null。

String sql = "select id,name,age,salary from employee where age = 23"; ResultSet resultSet = HiDbHelper.singleStore().querySql(sql, null);

结果集处理

当调用查询方法获取到ResultSet时,其默认并没有指向当前结果集中的数据,如果此时调用其String getString(int columnIndex)获取当前行指定索列的值,则会抛出异常

ohos.data.resultset.ResultSetIndexOutOfRangeException: checkState :row index is illegal.

正确的操作应该是:

先调用boolean goToNextRow()将结果集向后移动一行,返回true这表示当前位置有数据,再对结果进行处理,如果要获取ResultSet更多使用方式,可以查看官方文档

if (resultSet.goToNextRow()) {     HiLog.debug(TAG, "select name is %{public}s", resultSet.getString(1)); }

4. 更新数据

调用更新接口,传入要更新的数据,并通过AbsRdbPredicates指定更新条件。该接口的返回值表示更新操作影响的行数。如果更新失败,则返回0。

//1. 构建需要更新的数据的条件 RdbPredicates rdbPredicates = new RdbPredicates("employee")                         .equalTo("id",1); //2. 构建需要更新的数据 ValuesBucket values = new ValuesBucket(); values.putString("name","Mo"); //3. 执行更新操作 HiDbHelper.singleStore().update(values, rdbPredicates);

5. 删除数据

调用删除接口,通过AbsRdbPredicates指定删除条件。该接口的返回值表示删除的数据行数,可根据此值判断是否删除成功。如果删除失败,则返回0。

//1. 构建需要删除数据的条件 RdbPredicates rdbPredicates = new RdbPredicates("test")                         .equalTo("id", 1); //2. 执行删除操作 HiDbHelper.singleStore().delete(rdbPredicates);

事务

关系型数据库提供事务机制,来保证用户操作的原子性。对单条数据进行数据库操作时,无需开启事务;插入大量数据时,开启事务可以保证数据的准确性。如果中途操作出现失败,会执行回滚操作。

事务的API一共有三个

beginTransaction():开启事务。

markAsCommit():设置事务的标记为成功。

endTransaction():结束事务。

其中markAsCommit()和endTransaction()必须与beginTransaction(),如果单独调用,则会抛出异常

markAsCommit()与endTransaction()不能独立调用

如果单独调用markAsCommit()

则会抛出异常

java.util.EmptyStackException

如果单独调用endTransaction()

则会抛出异常

java.lang.IllegalStateException: Cannot do the transaction operation, because there is no current transaction.

如果在事务块中如果调用了markAsCommit(),本次批量操作数据出现错误,则不会进行回滚操作,该方法可以用于某些情况下阻止回滚

示例代码

ValuesBucket values = new ValuesBucket(); values.putInteger("id", 1); values.putString("name", "zhangsan"); values.putInteger("age", 18); values.putDouble("salary", 100.5); values.putByteArray("blobType", new byte[] {1, 2, 3});  //开启事务 HiDbHelper.singleStore().beginTransaction(); //插入两条id相同的数据 long id1 = HiDbHelper.singleStore().insert("employee", values); long id2 = HiDbHelper.singleStore().insert("employee", values); //加入下列的判断,即使id2插入不成功,本次事务也不会进行回滚 //if(id1 == 1) { //  HiDbHelper.singleStore().markAsCommit(); //} //结束事务 HiDbHelper.singleStore().endTransaction();

开启事务除使用beginTransaction()外,还可以使用beginTransactionWithObserver(TransactionObserver transactionObserver),在开启事务的同时注册观察者,用于监听事务的开启,提交,回滚操作。

注意:在开启事务后,一定记得在适当的时机进行关闭操作,否则在对数据库进行备份等操作时会抛出异常

java.lang.IllegalArgumentException: The rdb is in transaction.

为了代码的健壮性,可以在对数据库进行备份等操作前调用RdbStore的isInTransaction判断当前是否有事务还没有关闭,如果没有关闭,则进行关闭操作

数据库升级,降级,备份,删除,恢复

作为一名老移动端开发者,由于最近事务繁忙,这部分功能暂时没有有效的验证,有玩过的朋友欢迎进行进一步的分享。也可以期待后续我的帖子。

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

和***官方合作共建的鸿蒙技术社区

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot集成Redis用法笔记
下一篇:单线程不香吗?Redis6.0为何引入多线程?
相关文章