HarmonyOS Next快速入门:RelationalStore关系型数据库

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核8GB 50GB
简介: 本课程《HarmonyOS Next快速入门》涵盖HarmonyOS应用开发中的关系型数据库使用,介绍基于SQLite的持久化存储、适用场景及开发实践,适用于教育与初学者。

HarmonyOS Next快速入门##HarmonyOS应用开发##教育

点击跳转《HarmonyOS Next快速入门》视频教程

关系型数据库对应用提供通用的操作接口,底层使用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
  }
}
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
14天前
|
开发者
HarmonyOS Next快速入门:@State状态变量
本课程《HarmonyOS Next快速入门》专为初学者设计,涵盖ArkUI声明式开发核心概念。通过实例讲解@State状态管理机制,帮助开发者掌握状态驱动UI更新的原理与应用,提升应用交互体验。适合想快速上手HarmonyOS应用开发的学习者。点击学习视频教程:[HarmonyOS Next快速入门](https://edu.51cto.com/course/38375.html)
55 0
|
14天前
|
存储 缓存 搜索推荐
HarmonyOS Next快速入门:Preferences用户首选项
《HarmonyOS Next快速入门》视频教程讲解了基于HarmonyOS的应用开发核心知识,涵盖Preferences数据存储机制、适用场景及代码实现。内容包括用户首选项的键值操作、内存管理、约束限制与运作原理,并提供ArkTS接口调用示例和工具类封装方法,助力开发者快速掌握轻量级数据持久化技巧。点击学习:[视频链接](https://edu.51cto.com/course/38375.html)
56 0
|
14天前
|
开发者
HarmonyOS Next快速入门:@Provide和@Consume
本课程《HarmonyOS Next快速入门》适合初学者,重点讲解@Provide与@Consume装饰器在跨层级组件间实现双向数据同步的应用。通过实例演示如何在祖先与后代组件中传递状态变量,提升开发效率,掌握HarmonyOS应用开发核心技巧。点击学习视频教程,快速掌握UI范式与状态管理。
55 0
|
14天前
|
开发者
HarmonyOS Next快速入门:@Prop和@Link
本课程介绍HarmonyOS Next应用开发中@Prop和@Link装饰器的使用,讲解父子组件数据同步机制、类型限制及代码实例,帮助开发者快速掌握ArkTS状态管理技巧。点击学习完整视频教程。
58 0
|
14天前
|
容器
HarmonyOS Next快速入门:AlertDialog警告弹窗
本教程介绍HarmonyOS Next应用开发中AlertDialog组件的使用,涵盖弹窗参数配置与交互逻辑实现,适合初学者快速掌握弹窗开发技巧。
54 0
|
14天前
|
开发者 容器
HarmonyOS Next快速入门:@Component自定义组件
本课程介绍HarmonyOS Next中ArkUI自定义组件的开发,涵盖组件定义、结构、成员函数与变量、代码复用等内容,帮助开发者构建可维护、可扩展的UI界面。
54 0
|
14天前
|
开发者 UED 容器
HarmonyOS Next快速入门:@CustomDialog自定义弹窗
《HarmonyOS Next快速入门》是一门面向开发者的教育课程,重点讲解如何在HarmonyOS应用开发中使用CustomDialog实现自定义弹窗功能。通过该课程,开发者可以学习到如何利用CustomDialogController类及其相关参数,灵活控制弹窗的显示与交互,包括设置样式、动画、遮罩层等。课程结合实例代码,帮助开发者快速掌握自定义弹窗的设计与实现,适用于广告提示、用户协议、软件更新等多种应用场景,提升应用用户体验。[点击跳转视频教程](https://edu.51cto.com/course/38375.html)
57 0
|
10天前
|
开发工具 开发者
HarmonyOS NEXT实战:openCustomDialog自定义弹窗
本文介绍了在HarmonyOS SDK中使用UIContext获取PromptAction对象,通过openCustomDialog接口实现自定义弹出框的方法。重点讲解了ComponentContent方式创建弹窗,支持动态更新与灵活样式定制,并附实现步骤与完整示例代码。
57 0
|
11天前
|
开发工具 开发者
HarmonyOS NEXT实战:使用Emitter进行线程间通信
HarmonyOS Next实战教程,介绍基于SDK的Emitter事件处理机制。Emitter用于进程内事件订阅与发布,支持跨线程通信,提供on、once、emit、off等接口,实现异步任务处理。通过示例演示事件订阅、发布及取消订阅操作,帮助开发者高效管理应用内事件流,提升开发效率与系统资源利用率。
60 0
|
11天前
|
JSON JavaScript 前端开发
HarmonyOS NEXT实战:接入和使用axios
HarmonyOS Next 实战中,使用 Axios 可实现高效网络请求。Axios 是基于 Promise 的库,支持 GET、POST 等方法,并具备拦截器、自动 JSON 转换等功能。适配 OpenHarmony 后,仍保留其原有特性。需安装 @ohos/axios 并配置网络权限,可创建工具类统一管理请求与响应。
62 0