鸿蒙NEXT开辟-应用数据持久化之关系型数据库

打印 上一主题 下一主题

主题 880|帖子 880|积分 2640

 留意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下
假如大家觉得博主文章写的好的话,可以点下关注,博主会一直更新鸿蒙next相关知识

目次
1. 应用数据持久化
2. 应用数据持久化-关系型数据库
2.1 概述
2.2 运行机制
2.3 约束限制
2.4 常用方法
2.4.1 在生命周期函数中添加代码
2.4.2 创建实体类Student
2.4.3 创建工具类RdbUtil
2.4.4 在界面中操作数据库
2.4.5 删除数据库


1. 应用数据持久化


应用数据持久化,是指应用将内存中的数据通过文件或数据库的情势保存到设备上。内存中的数据形态通常是任意的数据布局或数据对象,存储介质上的数据形态大概是文本、数据库、二进制文件等。
HarmonyOS标准系统支持典型的存储数据形态,包罗用户首选项、键值型数据库、关系型数据库。


  • 用户首选项(Preferences):通常用于保存应用的配置信息。数据通过文本的情势保存在设备中,应用使用过程中会将文本中的数据全量加载到内存中,所以访问速率快、服从高,但不适合必要存储大量数据的场景。
  • 键值型数据库(KV-Store):一种非关系型数据库,其数据以“键值”对的情势进行构造、索引和存储,其中“键”作为唯一标识符。适合很少数据关系和业务关系的业务数据存储,同时因其在分布式场景中低落了办理数据库版本兼容题目的复杂度,和数据同步过程中辩论办理的复杂度而被广泛使用。相比于关系型数据库,更容易做到跨设备跨版本兼容。
  • 关系型数据库(RelationalStore):一种关系型数据库,以行和列的情势存储数据,广泛用于应用中的关系型数据的处置惩罚,包罗一系列的增、删、改、查等接口,开辟者也可以运行自己界说的SQL语句来满足复杂业务场景的必要。



2. 应用数据持久化-关系型数据库


2.1 概述


关系型数据库基于SQLite组件,适用于存储包含复杂关系数据的场景,比如一个班级的门生信息,必要包罗姓名、学号、各科结果等,又大概公司的雇员信息,必要包罗姓名、工号、职位等,由于数据之间有较强的对应关系,复杂程度比键值型数据更高,此时必要使用关系型数据库来持久化保存数据。

2.2 运行机制


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





2.3 约束限制



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

2.4 常用方法


2.4.1 在生命周期函数中添加代码





导入模块代码
  1. import { relationalStore } from '@kit.ArkData';
复制代码

在onWindowStageCreate生命周期函数中添加代码,初始化数据库

  1. // 创建数据库
  2. const STORE_CONFIG: relationalStore.StoreConfig = {
  3.   name: 'RdbTest.db', // 数据库文件名
  4.   securityLevel: relationalStore.SecurityLevel.S3, // 数据库安全级别
  5.   encrypt: false, // 可选参数,指定数据库是否加密,默认不加密
  6.   customDir: 'customDir/subCustomDir', // 可选参数,数据库自定义路径。数据库将在如下的目录结构中被创建:context.databaseDir + '/rdb/' + customDir,其中context.databaseDir是应用沙箱对应的路径,'/rdb/'表示创建的是关系型数据库,customDir表示自定义的路径。当此参数不填时,默认在本应用沙箱目录下创建RdbStore实例。
  7.   isReadOnly: false // 可选参数,指定数据库是否以只读方式打开。该参数默认为false,表示数据库可读可写。该参数为true时,只允许从数据库读取数据,不允许对数据库进行写操作,否则会返回错误码801。
  8. };
  9. relationalStore.getRdbStore(this.context, STORE_CONFIG, (err, store) => {
  10.   if (err) {
  11.     console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
  12.     return;
  13.   }
  14.   console.info(`Succeeded in getting RdbStore.`);
  15.   //保存store, 方便后面我们对数据库的操作
  16.   RdbUtil.setStore(store)
  17. })
复制代码



2.4.2 创建实体类Student

查询的时间必要用实体类接收下数据库里面数据



  1. export default class Student {
  2.   id: number = 0
  3.   username: string
  4.   age: number = 0
  5.   constructor(id: number, username: string, age: number) {
  6.     this.id = id
  7.     this.username = username
  8.     this.age = age
  9.   }
  10. }
复制代码

2.4.3 创建工具类RdbUtil






  1. import relationalStore from '@ohos.data.relationalStore';
  2. import Student from '../models/Student';
  3. import { BusinessError } from '@ohos.base';
  4. /**
  5. * 关系型数据库工具类
  6. */
  7. export default class RdbUtil {
  8.   /**
  9.    * 数据库对象
  10.    */
  11.   private static rdbStore: relationalStore.RdbStore;
  12.   static setStore(store: relationalStore.RdbStore) {
  13.     RdbUtil.rdbStore = store;
  14.   }
  15.   static getStore(): relationalStore.RdbStore {
  16.     return RdbUtil.rdbStore;
  17.   }
  18.   /**
  19.    * 执行sql
  20.    * @param sql
  21.    * @returns
  22.    */
  23.   static executeSql(sql: string): Promise<void> {
  24.     return RdbUtil.getStore().executeSql(sql);
  25.   }
  26.   /**
  27.    * 插入数据
  28.    * @param tableName
  29.    * @param data
  30.    * @returns
  31.    */
  32.   static insert(tableName: string, data: relationalStore.ValuesBucket): Promise<number> {
  33.     return RdbUtil.getStore().insert(tableName, data);
  34.   }
  35.   /**
  36.    * 查询数据
  37.    * @returns
  38.    */
  39.   static queryAll(): Promise<Array<Student>> {
  40.     let predicates = new relationalStore.RdbPredicates('STUDENT');
  41.     return new Promise<Array<Student>>((resolve, reject) => {
  42.       RdbUtil.getStore().query(predicates).then((result) => {
  43.         let students = new Array<Student>();
  44.         while (result.goToNextRow()) {
  45.           let student = new Student(
  46.             result.getLong(0),
  47.             result.getString(1),
  48.             result.getLong(2),
  49.           );
  50.           students.push(student);
  51.         }
  52.         resolve(students);
  53.       }).catch((error: BusinessError) => {
  54.         reject(error)
  55.       })
  56.     })
  57.   }
  58.   /**
  59.    * 删除
  60.    * @param id
  61.    * @returns
  62.    */
  63.   static deleteById(id: number) {
  64.     let predicates = new relationalStore.RdbPredicates('STUDENT');
  65.     predicates.equalTo('ID', id)
  66.     return RdbUtil.getStore().delete(predicates);
  67.   }
  68.   /**
  69.    * 更新
  70.    * @param id
  71.    * @param data
  72.    * @returns
  73.    */
  74.   static updateById(id: number, data: relationalStore.ValuesBucket) {
  75.     let predicates = new relationalStore.RdbPredicates('STUDENT');
  76.     predicates.equalTo('ID', id)
  77.     return RdbUtil.getStore().update(data, predicates);
  78.   }
  79. }
复制代码

留意:该工具类里面包含了创建表,新增数据,查询数据,更新数据,删除数据 的api


2.4.4 在界面中操作数据库


  1. import RdbUtil from '../utils/RdbUtil';
  2. import { BusinessError } from '@kit.BasicServicesKit';
  3. import { promptAction } from '@kit.ArkUI';
  4. import { relationalStore } from '@kit.ArkData';
  5. import Student from '../models/Student';
  6. @Entry
  7.   @Component
  8.   struct Index {
  9.     build() {
  10.       Column() {
  11.         Button('创建数据库表')
  12.           .onClick(() => {
  13.             const SQL_CREATE_TABLE =
  14.               'CREATE TABLE IF NOT EXISTS STUDENT (ID INTEGER PRIMARY KEY AUTOINCREMENT, USERNAME TEXT NOT NULL, AGE INTEGER)'; // 建表Sql语句
  15.             RdbUtil.executeSql(SQL_CREATE_TABLE)
  16.               .then(() => {
  17.                 promptAction.showToast({
  18.                   message: 'success create table'
  19.                 })
  20.               }).catch((err: BusinessError) => {
  21.                 promptAction.showToast({
  22.                   message: 'fail  create table'
  23.                 })
  24.               })
  25.           }).margin({ bottom: 50 })
  26.         Button('插入数据')
  27.           .onClick(() => {
  28.             const valueBucket: relationalStore.ValuesBucket = {
  29.               'USERNAME': '东林',
  30.               'AGE': 18
  31.             };
  32.             RdbUtil.insert('STUDENT', valueBucket)
  33.               .then((updateNumber) => {
  34.                 promptAction.showToast({
  35.                   message: 'insert data success ' + updateNumber
  36.                 })
  37.               }).catch((error: BusinessError) => {
  38.                 promptAction.showToast({
  39.                   message: 'insert data fail ' + error
  40.                 })
  41.               })
  42.           }).margin({ bottom: 50 })
  43.         Button('查询数据')
  44.           .onClick(() => {
  45.             RdbUtil.queryAll()
  46.               .then((students: Array<Student>) => {
  47.                 promptAction.showToast({
  48.                   message: 'query students success  ' + JSON.stringify(students)
  49.                 })
  50.               }).catch((error: BusinessError) => {
  51.                 promptAction.showToast({
  52.                   message: ' query students fail  ' + error
  53.                 })
  54.               })
  55.           }).margin({ bottom: 50 })
  56.         Button('修改数据')
  57.           .onClick(() => {
  58.             const valueBucket: relationalStore.ValuesBucket = {
  59.               'USERNAME': '小红',
  60.               'AGE': 20
  61.             };
  62.             RdbUtil.updateById(1, valueBucket)
  63.               .then((updateNumber) => {
  64.                 promptAction.showToast({
  65.                   message: 'update student success ' + updateNumber.toString()
  66.                 })
  67.               }).catch((err: BusinessError) => {
  68.                 promptAction.showToast({
  69.                   message: ' update student fail  ' + err
  70.                 })
  71.               })
  72.           }).margin({ bottom: 50 })
  73.         Button('删除数据')
  74.           .onClick(() => {
  75.             RdbUtil.deleteById(1)
  76.               .then((updateNumber) => {
  77.                 promptAction.showToast({
  78.                   message: 'delete student success ' + updateNumber.toString()
  79.                 })
  80.               }).catch((err: BusinessError) => {
  81.                 promptAction.showToast({
  82.                   message: 'delete student fail ' + err
  83.                 })
  84.               })
  85.           })
  86.       }
  87.       .height('100%')
  88.         .width('100%')
  89.     }
  90.   }
复制代码


2.4.5 删除数据库

在生命周期函数里面删除数据库





  1. onDestroy(): void {
  2.   hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  3.   // 删除数据库
  4.   relationalStore.deleteRdbStore(this.context, 'RdbTest.db', (err) => {
  5.     if (err) {
  6.       console.error(`Failed to delete RdbStore. Code:${err.code}, message:${err.message}`);
  7.       return;
  8.     }
  9.     console.info('Succeeded in deleting RdbStore.');
  10.   });
  11. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

羊蹓狼

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表