介绍

本示例基于关系型数据库实现了数据持久化,主要包含以下六个场景。

实现数据库数据持久化源码链接

效果预览

使用说明

分别在Name、Age、Salary三个输入框输入数据后,点击“添加数据”按钮,点击建表,建表成功后出现操作成功弹窗,再点击“查询”,下方输入框会出现添加的数据。

实现思路

场景一:基于RDB已提供API的数据库基础使用

通过insert、update、delete、query接口及关系型数据库谓词predicates 的数据库基础操作。 核心代码如下,源码参考Rdb.ets。

insertMultipleData(name: string, age: number, salary: number) {
    for (let i = 1; i <= 6000; i++) {
      // 插入数据
      const valueBucket: ValuesBucket = {
        'NAME': name + i,
        'AGE': age,
        'SALARY': salary
      };
      if (this.rdbStore) {
        // this.rdbStore.insert('STUDENT', valueBucket)
        this.rdbStore.insert('STUDENT', valueBucket, (err, rowId) => {
          if (err) {
            console.error(`Failed to insert data. Code:${err.code}, message:${err.message}`);
            return;
          }
          console.info(`Succeeded in inserting data. rowId:${rowId}`);
        })
      }
    }
  }

场景二:基于executeSql、querySql执行增删改查复杂SQL语句

在实际使用过程中,复杂的SQL语句可能无法直接通过场景一提供的方式实现,此时需要开发者通过executeSql、querySql接口执行自定义SQL语句。 executeSql能够执行包含指定参数但不返回值的SQL语句,如创建表、创建索引、数据库触发器等场景。 querySql能够根据指定SQL语句查询数据库中的数据,并返回查询结果ResultSet结果集。如递归查询、子查询等场景。核心代码如下,源码参考Rdb.ets。

myExecuteSql(sql: string) {
    if (this.rdbStore != undefined) {
      (this.rdbStore as relationalStore.RdbStore).executeSql(sql, (err) => {
        if (err) {
          console.error(`ExecuteSql failed, code is ${err.code},message is ${err.message}`);
          return;
        }
        console.info('ExecuteSql success');
      })
    }
  }
  myQuerySql(sql: string) {
    if (this.rdbStore) {
      (this.rdbStore as relationalStore.RdbStore).querySql(sql, (err, resultSet) => {
        if (err) {
          console.error(`Query failed, code is ${err.code},message is ${err.message}`);
          return;
        }
        console.info(`ResultSet column names: ${resultSet.columnNames}, column count: ${resultSet.columnCount}`);
        // resultSet是一个数据集合的游标,默认指向第-1个记录,有效的数据从0开始。
        while (resultSet.goToNextRow()) {
          const name = resultSet.getString(resultSet.getColumnIndex('NAME'));
          ``
          const age = resultSet.getLong(resultSet.getColumnIndex('AGE'));
          console.info(`name=${name}, age=${age}`);
        }
        // 释放数据集的内存
        resultSet.close();
      })
    }
  }

场景三:事务的使用

据库事务可以保证指一组数据库操作要么全部执行成功,要么全部回滚。鸿蒙关系型数据库提供了事务相关接口 beginTransaction、commit、rollBack。本例通过模拟一组操作中,有一条操作失败后,回滚已经执行的SQL语句。核心代码如下,源码参考Rdb.ets。

async insertDataByTransaction(name: string, age: number, salary: number) {
    if (this.rdbStore != undefined) {
      try {
        //开启事务
        this.rdbStore.beginTransaction();
        for (let i = 1; i <= 6000; i++) {
          // 插入数据
          const valueBucket: ValuesBucket = {
            'NAME': name + i,
            'AGE': age,
            'SALARY': salary
          };
          if (this.rdbStore) {
            this.rdbStore.insert('STUDENT', valueBucket)
          }
        }
        //提交事务
        this.rdbStore.commit();
      } catch (err) {
        //回滚事务
        let code = (err as BusinessError).code;
        let message = (err as BusinessError).message
        console.error(`Transaction failed, code is ${code},message is ${message}`);
        this.rdbStore.rollBack()
        return;
      }
    }
  }

场景四:批量插入数据的不同实现方式及性能对比

分别使用insert、事务insert、batchInsert三种方式各自插入5000条数据,统计各自任务耗时。核心代码如下,源码参考Rdb.ets。

batchInsert(name: string, age: number, salary: number) {
    if (this.rdbStore == null) {
      console.error(`Create Store1.db failed! store1 is null`);
      return;
    }

    let valueBucketArray: Array<relationalStore.ValuesBucket> = new Array();
    for (let i = 1; i <= 6000; i++) {
      const valueBucket: relationalStore.ValuesBucket = {
        'NAME': name + i,
        'AGE': age,
        'SALARY': salary
      }
      valueBucketArray.push(valueBucket);
    }
    try {
      this.rdbStore.batchInsert('STUDENT', valueBucketArray); // 该接口内部使用事务
      console.info(`Insert data successfully!`);
    } catch (err) {
      console.error(`Insert datae failed! err code:${err.code}, err message:${err.message}`)
    }
  }

场景五:数据库备份与恢复

在数据库的使用过程中,数据库可能会因为数据丢失、数据损坏、脏数据等而不可用情况,为了预防这种情况,可以通过backup接口,提前备份数据库数据到本地文件中,当发生意外后,可以通过restore接口,从指定的数据库备份文件恢复数据库。核心代码如下,源码参考Rdb.ets。

//备份数据库
  myBackup() {
    if (this.rdbStore) {
      (this.rdbStore as relationalStore.RdbStore).backup('dbBackup.db', (err) => {
        if (err) {
          console.error(`Backup failed, code is ${err.code},message is ${err.message}`);
          return;
        }
        console.info(`Backup success.`);
      })
    }
  }
  //恢复数据库
  myRestore(value: string) {
    // value:备份数据库名
    if (this.rdbStore) {
      (this.rdbStore as relationalStore.RdbStore).restore(value, (err) => {
        if (err) {
          console.error(`Restore failed, code is ${err.code},message is ${err.message}`);
          return;
        }
        console.info(`Restore success.`);
      })
    }
  }
本文由博客一文多发平台 OpenWrite 发布!

斯文的键盘
1 声望0 粉丝