HarmonyOS 使用关系型数据库进行增删改查

HarmonyOS 中的关系型数据库基于 SQLite 组件,提供了一套完整的对本地数据库进行管理的机制。它支持事务、索引、视图、触发器、外键、参数化查询和预编译 SQL 语句等特性。关系型数据库适用于存储包含复杂关系数据的场景,例如学生信息或雇员信息,这些数据之间有较强的对应关系。

操作关系型数据库的常见步骤

  • 创建数据库和表:使用 relationalStore.getRdbStore 方法创建数据库,然后使用 executeSql 方法执行 SQL 语句来创建表。

  • 插入数据:使用 insert 方法向表中插入数据。

  • 批量插入数据:使用 batchInsert 方法向表中插入一组数据。

  • 更新数据:使用 update 方法根据指定条件更新数据库中的数据。

  • 删除数据:使用 delete 方法根据指定条件从数据库中删除数据。

  • 查询数据:使用 query 方法根据指定条件查询数据库中的数据。

此外,HarmonyOS 还提供了 ResultSet 对象来访问查询结果,提供灵活的数据访问方式。

表的数据模型

定义Person类,作为数据模型,用于表示数据库中的Person表的行。

// 常量类配置信息
export class Person {
  id: number
  name: string
  age: number

  constructor(id: number, name: string, age: number) {
    this.id = id
    this.name = name
    this.age = age
  }
}

数据库配置信息

首先,定义数据库和表的配置信息,包括数据库名称、安全级别、表名称、创建表的SQL语句和列配置。

/**
 * Rdb数据库配置。
 * name:数据库名称
 * securityLevel:数据库安全级别
 */
static readonly STORE_CONFIG: relationalStore.StoreConfig = {
  name: 'database.db',
  securityLevel: relationalStore.SecurityLevel.S1
};

/**
 * 表配置信息
 * tableName:表名称
 * sqlCreate:创建表的语句
 * columns:表的列项目
 */
static readonly PERSON_TABLE: PersonTable = {
  tableName: 'personTable',
  sqlCreate: 'CREATE TABLE IF NOT EXISTS personTable(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, ' +
  'age INTEGER)',
  columns: ['id', 'name', 'age']
};

/**
 * Log tag.
 */
static readonly RDB_TAG = '[Debug.Rdb]';
static readonly TABLE_TAG = '[Debug.PersonTable]';
static readonly INDEX_TAG = '[Debug.Index]';

封装CRUD操作

封装了对关系型数据库(RDB)的一些基本操作,如创建、插入、删除、更新和查询数据。这个类使用了 @ohos.data.relationalStore 包。


import relationalStore from '@ohos.data.relationalStore';
import CommonConstants from '../constants/CommonConstants';
import Logger from '../utils/Logger';

export default class Rdb {
  private rdbStore: relationalStore.RdbStore | null = null;
  private tableName: string;
  private sqlCreateTable: string;
  private columns: Array<string>;

  constructor(tableName: string, sqlCreateTable: string, columns: Array<string>) {
    this.tableName = tableName;
    this.sqlCreateTable = sqlCreateTable;
    this.columns = columns;
  }

  getRdbStore(callback: Function = () => {
  }) {
    if (!callback || typeof callback === 'undefined' || callback === undefined) {
      Logger.info(CommonConstants.RDB_TAG, 'getRdbStore() has no callback!');
      return;
    }
    if (this.rdbStore !== null) {
      Logger.info(CommonConstants.RDB_TAG, 'The rdbStore exists.');
      callback();
      return
    }
    let context: Context = getContext(this) as Context;
    relationalStore.getRdbStore(context, CommonConstants.STORE_CONFIG, (err, rdb) => {
      if (err) {
        Logger.error(CommonConstants.RDB_TAG, `gerRdbStore() failed, err: ${err}`);
        return;
      }
      this.rdbStore = rdb;
      this.rdbStore.executeSql(this.sqlCreateTable);
      Logger.info(CommonConstants.RDB_TAG, 'getRdbStore() finished.');
      callback();
    });
  }

  insertData(data: relationalStore.ValuesBucket, callback: Function = () => {
  }) {
    if (!callback || typeof callback === 'undefined' || callback === undefined) {
      Logger.info(CommonConstants.RDB_TAG, 'insertData() has no callback!');
      return;
    }
    let resFlag: boolean = false;
    const valueBucket: relationalStore.ValuesBucket = data;
    if (this.rdbStore) {
      this.rdbStore.insert(this.tableName, valueBucket, (err, ret) => {
        if (err) {
          Logger.error(CommonConstants.RDB_TAG, `insertData() failed, err: ${err}`);
          callback(resFlag);
          return;
        }
        Logger.info(CommonConstants.RDB_TAG, `insertData() finished: ${ret}`);
        callback(ret);
      });
    }
  }

  deleteData(predicates: relationalStore.RdbPredicates, callback: Function = () => {
  }) {
    if (!callback || typeof callback === 'undefined' || callback === undefined) {
      Logger.info(CommonConstants.RDB_TAG, 'deleteData() has no callback!');
      return;
    }
    let resFlag: boolean = false;
    if (this.rdbStore) {
      this.rdbStore.delete(predicates, (err, ret) => {
        if (err) {
          Logger.error(CommonConstants.RDB_TAG, `deleteData() failed, err: ${err}`);
          callback(resFlag);
          return;
        }
        Logger.info(CommonConstants.RDB_TAG, `deleteData() finished: ${ret}`);
        callback(!resFlag);
      });
    }
  }

  updateData(predicates: relationalStore.RdbPredicates, data: relationalStore.ValuesBucket, callback: Function = () => {
  }) {
    if (!callback || typeof callback === 'undefined' || callback === undefined) {
      Logger.info(CommonConstants.RDB_TAG, 'updateDate() has no callback!');
      return;
    }
    let resFlag: boolean = false;
    const valueBucket: relationalStore.ValuesBucket = data;
    if (this.rdbStore) {
      this.rdbStore.update(valueBucket, predicates, (err, ret) => {
        if (err) {
          Logger.error(CommonConstants.RDB_TAG, `updateData() failed, err: ${err}`);
          callback(resFlag);
          return;
        }
        Logger.info(CommonConstants.RDB_TAG, `updateData() finished: ${ret}`);
        callback(!resFlag);
      });
    }
  }

  query(predicates: relationalStore.RdbPredicates, callback: Function = () => {
  }) {
    if (!callback || typeof callback === 'undefined' || callback === undefined) {
      Logger.info(CommonConstants.RDB_TAG, 'query() has no callback!');
      return;
    }
    if (this.rdbStore) {
      this.rdbStore.query(predicates, this.columns, (err, resultSet) => {
        if (err) {
          Logger.error(CommonConstants.RDB_TAG, `query() failed, err:  ${err}`);
          return;
        }
        Logger.info(CommonConstants.RDB_TAG, 'query() finished.');
        callback(resultSet);
        resultSet.close();
      });
    }
  }
}

具体表操作封装

使用了之前定义的 Rdb 类来执行具体的Person数据库操作。

import relationalStore from '@ohos.data.relationalStore';
import CommonConstants from '../../constants/CommonConstants';
import Rdb from '../rdb';
import { Person } from '../../bean/Person';

export default class PersonTable {
  private accountTable = new Rdb(CommonConstants.PERSON_TABLE.tableName, CommonConstants.PERSON_TABLE.sqlCreate,
    CommonConstants.PERSON_TABLE.columns);

  constructor(callback: Function = () => {
  }) {
    this.accountTable.getRdbStore(callback);
  }

  getRdbStore(callback: Function = () => {
  }) {
    this.accountTable.getRdbStore(callback);
  }

  insert(person: Person, callback: Function) {
    const valueBucket: relationalStore.ValuesBucket = generateBucket(person);
    this.accountTable.insertData(valueBucket, callback);
  }

  deleteData(person: Person, callback: Function) {
    let predicates = new relationalStore.RdbPredicates(CommonConstants.PERSON_TABLE.tableName);
    predicates.equalTo('id', person.id);
    this.accountTable.deleteData(predicates, callback);
  }

  updateData(person: Person, callback: Function) {
    const valueBucket: relationalStore.ValuesBucket = generateBucket(person);
    let predicates = new relationalStore.RdbPredicates(CommonConstants.PERSON_TABLE.tableName);
    predicates.equalTo('id', person.id);
    this.accountTable.updateData(predicates, valueBucket, callback);
  }

  // 查(查询的字段,回调,是否查询全部)
  query(id: number, callback: Function, isAll: boolean = true) {
    let predicates = new relationalStore.RdbPredicates(CommonConstants.PERSON_TABLE.tableName);
    if (!isAll) {
      predicates.equalTo('id', id);
    }
    this.accountTable.query(predicates, (resultSet: relationalStore.ResultSet) => {
      let count: number = resultSet.rowCount;
      if (count === 0 || typeof count === 'string') {
        console.log(`${CommonConstants.TABLE_TAG}` + 'Query no results!');
        callback([]);
      } else {
        resultSet.goToFirstRow();
        const result: Person[] = [];
        for (let i = 0; i < count; i++) {
          let tmp: Person = {
            id: 0, name: '', age: 0
          };
          tmp.id = resultSet.getDouble(resultSet.getColumnIndex('id'));
          tmp.name = resultSet.getString(resultSet.getColumnIndex('name'));
          tmp.age = resultSet.getDouble(resultSet.getColumnIndex('age'));
          result[i] = tmp;
          resultSet.goToNextRow();
        }
        callback(result);
      }
    });
  }
}

function generateBucket(person: Person): relationalStore.ValuesBucket {
  let obj: relationalStore.ValuesBucket = {};
  obj.name = person.name;
  obj.age = person.age;
  return obj;
}

使用示例

以下是如何使用上述封装的CRUD操作的示例。

insertPerson() {
  this.newPerson =
  new Person(
    0,
    CommonConstants.NAMES[Math.floor(Math.random() * CommonConstants.NAMES.length)] + '某',
    Math.floor(Math.random() * 99
    ))
  this.PersonTable.insert(this.newPerson, (id: number) => {
    this.newPerson.id = id;
    Logger.info(TAG, `id = ${id}`);
    this.persons.push(this.newPerson)
  });
}

queryAllPerson() {
  this.PersonTable.getRdbStore(() => {
    this.PersonTable.query(0, (result: Person[]) => {
      this.persons.length = 0;
      this.persons = result;
      Logger.info(TAG, "persons = " + JSON.stringify(this.persons))
    }, true);
  });
}

updatePerson(item: Person, index: number) {
  // 修改数据
  this.newPerson = { ...item,
    name: CommonConstants.NAMES[Math.floor(Math.random() * CommonConstants.NAMES.length)] + '某',
    age: Math.floor(Math.random() * 99) }
  this.PersonTable.updateData(this.newPerson, () => {
  })
  //替换
  this.persons.splice(index, 1, this.newPerson)
}

deletePerson(item: Person, index: number) {
  this.PersonTable.deleteData(item, () => {
    this.persons.splice(index, 1)
  })
}

结语

通过封装CRUD操作,可以显著提高代码的可读性和可维护性。同时,它也简化了数据库操作的复杂性,使得开发者可以更专注于业务逻辑的实现。

posted @ 2024-05-13 22:00  西北野狼  阅读(639)  评论(0编辑  收藏  举报