HarmonyOS NEXT - RelationalStore关系型数据库

举报
鸿蒙开发工程师 发表于 2025/03/31 21:20:31 2025/03/31
112 0 0
【摘要】 关系型数据库对应用提供通用的操作接口,底层使用SQLite作为持久化存储引擎,支持SQLite具有的数据库特性,包括但不限于事务、索引、视图、触发器、外键、参数化查询和预编译SQL语句。适用的场景:存储包含复杂关系数据的场景,比如一个班级的学生信息,需要包括姓名、学号、各科成绩等,又或者公司的雇员信息,需要包括姓名、工号、职位等,由于数据之间有较强的对应关系,复杂程度比键值型数据更高,此时需...

关系型数据库对应用提供通用的操作接口,底层使用SQLite作为持久化存储引擎,支持SQLite具有的数据库特性,包括但不限于事务、索引、视图、触发器、外键、参数化查询和预编译SQL语句。

适用的场景:
存储包含复杂关系数据的场景,比如一个班级的学生信息,需要包括姓名、学号、各科成绩等,又或者公司的雇员信息,需要包括姓名、工号、职位等,由于数据之间有较强的对应关系,复杂程度比键值型数据更高,此时需要使用关系型数据库来持久化保存数据。

约束限制

  • 系统默认日志方式是WAL(Write Ahead Log)模式,系统默认落盘方式是FULL模式。
  • 数据库中有4个读连接和1个写连接,线程获取到空闲读连接时,即可进行读取操作。当没有空闲读连接且有空闲写连接时,会将写连接当做读连接来使用。
  • 为保证数据的准确性,数据库同一时间只能支持一个写操作。
  • 当应用被卸载完成后,设备上的相关数据库文件及临时文件会被自动清除。
  • ArkTS侧支持的基本数据类型:number、string、二进制类型数据、boolean。
  • 为保证插入并读取数据成功,建议一条数据不要超过2M。超出该大小,插入成功,读取失败。

基本概念:
·谓词:数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。
·结果集:指用户查询之后的结果集合,可以对数据进行访问。结果集提供了灵活的数据访问方式,可以更方便地拿到用户想要的数据。

代码示例
SQLiteUtil

export default class SQLiteUtil {
  static getCreateTableSql(tableName: string, columns: ColumnInfo[]): string {
    let sql = `CREATE TABLE IF NOT EXISTS ${tableName} (`;
    columns.forEach((element, index) => {
      if (index == 0) {
        //拼接首个元素,默认为主键
        sql += `${element.name} ${DataType[element.type]} PRIMARY KEY AUTOINCREMENT,`;
      } else if (index == columns.length - 1) {
        //最后一个元素拼接语句
        sql += `${element.name} ${DataType[element.type]} NOT NULL);`;
      } else {
        sql += `${element.name} ${DataType[element.type]} NOT NULL,`;
      }
    });
    return sql;
  }
}

export interface ColumnInfo {
  name: string;
  type: DataType;
}

export enum DataType {
  NULL = 'NULL',
  INTEGER = 'INTEGER',
  REAL = 'REAL',
  TEXT = 'TEXT',
  BLOB = 'BLOB'
}

RelationalStoreService

import SQLiteUtil, { ColumnInfo, DataType } from '../ChicKit/data/SQLiteUtil'
import relationalStore from '@ohos.data.relationalStore'
import { common } from '@kit.AbilityKit';
import Logger from '../utils/Logger';
import AppError from '../models/AppError';
import Schedule from '../entities/Schedule';
import { BusinessError } from '@kit.BasicServicesKit';
import { ValuesBucket, ValueType } from '@ohos.data.ValuesBucket';
import { DataModel } from '../ChicKit/data/DataModel';
import Target from '../entities/Target';
import Plan from '../entities/Plan';

const RelationalStoreName = 'shijianxu.db'

export default class RelationalStoreService {
  static rdbStore: relationalStore.RdbStore;

  /**
   * 初始化关系型数据库
   * @param context
   */
  static init(context: common.UIAbilityContext) {
    // RelationalStore配置
    let storeConfig: relationalStore.StoreConfig = {
      // 数据库文件名称
      name: RelationalStoreName,
      //安全等级
      securityLevel: relationalStore.SecurityLevel.S1
    }

    relationalStore.getRdbStore(context, storeConfig, (err, store) => {
      if (err) {
        Logger.error(`RelationalStoreService init error, error=${JSON.stringify(new AppError(err))}`)
        return;
      } else {
        RelationalStoreService.rdbStore = store
        RelationalStoreService.createScheduleTable()
        RelationalStoreService.createTargetTable()
        RelationalStoreService.createPlanTable()
      }
    });
  }

  /**
   * 创建schedule表
   */
  static createScheduleTable() {
    //表字段
    const columns: ColumnInfo[] = Schedule.getColumns()
    // 获取创建表SQL语句
    const sql = SQLiteUtil.getCreateTableSql(Schedule.TableName, columns)
    // 创建数据表
    RelationalStoreService.rdbStore.executeSql(sql, (err) => {
      if (err) {
        Logger.error(`RelationalStoreService createScheduleTable error, error=${JSON.stringify(new AppError(err))}`)
        return;
      }
    });
  }

  /**
   * 创建target表
   */
  static createTargetTable() {
    //表字段
    const columns: ColumnInfo[] = Target.getColumns()
    // 获取创建表SQL语句
    const sql = SQLiteUtil.getCreateTableSql(Target.TableName, columns)
    // 创建数据表
    RelationalStoreService.rdbStore.executeSql(sql, (err) => {
      if (err) {
        Logger.error(`RelationalStoreService createTargetTable error, error=${JSON.stringify(new AppError(err))}`)
        return;
      }
    });
  }

  /**
   * 创建plan表
   */
  static createPlanTable() {
    //表字段
    const columns: ColumnInfo[] = Plan.getColumns()
    // 获取创建表SQL语句
    const sql = SQLiteUtil.getCreateTableSql(Plan.TableName, columns)
    // 创建数据表
    RelationalStoreService.rdbStore.executeSql(sql, (err) => {
      if (err) {
        Logger.error(`RelationalStoreService createPlanTable error, error=${JSON.stringify(new AppError(err))}`)
        return;
      }
    });
  }

  /**
   * 插入数据
   * @param tableName
   * @param values
   */
  static insert(tableName: string, values: ValuesBucket) {
    RelationalStoreService.rdbStore.insert(tableName, values, (err: BusinessError, rowId: number) => {
      if (err) {
        Logger.error(`RelationalStoreService insert error, error=${JSON.stringify(new AppError(err))}`)
        return;
      } else {
        return rowId
      }
    })
  }

  /**
   * 删除
   * @param predicates
   * @returns 删除的条数
   */
  static delete(predicates: relationalStore.RdbPredicates):number{
    return RelationalStoreService.rdbStore.deleteSync(predicates)
  }

  /**
   * 更新
   * @param values
   * @param predicates
   * @returns 更新的记录条数
   */
  static update(values: ValuesBucket,predicates: relationalStore.RdbPredicates):number{
    let rows: number = RelationalStoreService.rdbStore.updateSync(values, predicates, relationalStore.ConflictResolution.ON_CONFLICT_REPLACE);
    return rows
  }

  static querySync(predicates: relationalStore.RdbPredicates, columns: ColumnInfo[]): DataModel[] {
    let dataList: DataModel[] = []
    try {
      let columnsStringArray: string[] = []
      columns.forEach(element => {
        columnsStringArray.push(element.name)
      });
      const resultSet = RelationalStoreService.rdbStore.querySync(predicates, columnsStringArray)
      resultSet.columnNames
      // resultSet.getColumnName('')
      // resultSet.getValue()

      //循环处理结果,循环条件:当所在行不是最后一行
      while (!resultSet.isAtLastRow) {
        //去往下一行
        resultSet.goToNextRow()
        let schedule: DataModel = {}
        columns.forEach(element => {
          switch (element.type) {
            case DataType.INTEGER:
              schedule[element.name] = resultSet.getLong(resultSet.getColumnIndex(element.name))
              break;
            case DataType.REAL:
              schedule[element.name] = resultSet.getDouble(resultSet.getColumnIndex(element.name))
              break;
            case DataType.TEXT:
              schedule[element.name] = resultSet.getString(resultSet.getColumnIndex(element.name))
              break;
            case DataType.BLOB:
              schedule[element.name] = resultSet.getBlob(resultSet.getColumnIndex(element.name))
              break;
          }
        })
        dataList.push(schedule)
      }
    } catch (err) {
      Logger.error(`RelationalStoreService querySync error, error=${JSON.stringify(new AppError(err))}`)
    }
    return dataList
  }
}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。