【HarmonyOS开发】ArkTs关系型和非关系型数据库的存储封装

图片

前面使用了首选项的存储方式,因此将其他的两种存储方式(键值型数据库和关系型数据库)也学习一下,简单记录一下,并进行封装,方便后续使用。

1、效果预览

2、使用条件

2.1 键值型数据库

        键值型数据库实现数据持久化width=device-width,initial-scale=1.0

icon-default.png

http://test.openharmony.cn:7780/pages/v4.0/zh-cn/application-dev/database/data-persistence-by-kv-store.md/

  • 设备协同数据库,针对每条记录,Key的长度≤896 Byte,Value的长度<4 MB。
  • 单版本数据库,针对每条记录,Key的长度≤1 KB,Value的长度<4 MB。

  • 每个应用程序最多支持同时打开16个键值型分布式数据库。

  • 键值型数据库事件回调方法中不允许进行阻塞操作,例如修改UI组件。

2.2 关系型数据库

关系型数据库实现数据持久化width=device-width,initial-scale=1.0

icon-default.png

http://test.openharmony.cn:7780/pages/v4.0/zh-cn/application-dev/database/data-persistence-by-rdb-store.md/

  • 系统默认日志方式是WAL(Write Ahead Log)模式,系统默认落盘方式是FULL模式。
  • 数据库中连接池的最大数量是4个,用以管理用户的读操作。

  • 为保证数据的准确性,数据库同一时间只能支持一个写操作。

  • 当应用被卸载完成后,设备上的相关数据库文件及临时文件会被自动清除。

  • ArkTS侧支持的基本数据类型:number、string、二进制类型数据、boolean。

  • 为保证插入并读取数据成功,建议一条数据不要超过2M。超出该大小,插入成功,读取失败。

3、核心API

3.1 键值型数据库

  • createKVManager(创建一个KVManager对象实例)

  • getKVStore(指定Options和storeId,创建并得到指定类型的KVStore数据库)

  • put(添加指定类型的键值对到数据库)

  • get(获取指定键的值)

  • delete(从数据库中删除指定键值的数据)

3.2 关系型数据库

  • getRdbStore(获得一个相关的RdbStore,操作关系型数据库)

  • executeSql(执行包含指定参数但不返回值的SQL语句)

  • deleteRdbStore(删除数据库)

  • insert(插入一行数据)

  • delete(从数据库中删除数据)

  • update(更新数据库中的数据)

  • query(根据指定条件查询数据库中的数据)

4、封装与调用

4.1 键值型数据库

4.1.1 封装

import distributedKVStore from '@ohos.data.distributedKVStore';

const BUNDLE_NAME = "dbName_tengyu"

let context = getContext(this)
// 数据库对象
let kvManager: distributedKVStore.KVManager | undefined = undefined;
// KVStore数据库
let kvStore: distributedKVStore.SingleKVStore | undefined = undefined;

class DistributedUtil {
  constructor() {
    this.createKeyValueDB();
  }
  async getKvManager(bundleName?: string) {
    const kvStoreConfig: distributedKVStore.KVManagerConfig = {
      context: context,bundleName: bundleName || BUNDLE_NAME
    };
    try {
      kvManager = distributedKVStore.createKVManager(kvStoreConfig);
    }
    catch (err) {
      console.error(`error:${err}`)
    }
  }

  // 创建并得到指定类型的KVStore数据库
  async createKeyValueDB(op?: distributedKVStore.Options) {
    if (kvManager === undefined) {
      this.getKvManager();
    }
    try {
      const options: distributedKVStore.Options = {
        // 当数据库文件不存在时是否创建数据库,默认为true
        createIfMissing: true,// 设置数据库文件是否加密,默认为false,即不加密
        encrypt: false,// 设置数据库文件是否备份,默认为true,即备份
        backup: false,// 设置数据库文件是否自动同步。默认为false,即手动同步
        autoSync: true,// kvStoreType不填时,默认创建多设备协同数据库
        kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,// 多设备协同数据库:kvStoreType: distributedKVStore.KVStoreType.DEVICE_COLLABORATION,securityLevel: distributedKVStore.SecurityLevel.S1
      };
      kvManager.getKVStore<distributedKVStore.SingleKVStore>('storeId',op || options,(err,store: distributedKVStore.SingleKVStore) => {
        if (err) {
          console.error(`Failed to get KVStore: Code:${err.code},message:${err.message}`);
          return;
        }
        console.info('Succeeded in getting KVStore.');
        kvStore = store;
      });
    } catch (e) {
      console.error(`An unexpected error occurred. Code:${e.code},message:${e.message}`);
    }
    return kvStore;
  }

  // 删除指定键值的数据
  async deleteStoreData(key: string) {
    if (!kvStore) {
      return;
    }

    try {
      kvStore.delete(key,(err) => {
        if (err !== undefined) {
          console.error(`Failed to delete data. Code:${err.code},message:${err.message}`);
          return;
        }
        console.info('Succeeded in deleting data.');
      });
    } catch (e) {
      console.error(`An unexpected error occurred. Code:${e.code},message:${e.message}`);
    }
  }

  // 向键值数据库中插入数据
  async putStoreData(key: string,value: any) {
    if (!key || !value) {
      return
    }

    if(!kvStore) {
      kvStore = await this.createKeyValueDB();
    }

    try {
      kvStore.put(key,value,(err) => {
        if (err !== undefined) {
          console.error(`Failed to put data. Code:${err.code},message:${err.message}`);
          return;
        }
        console.info('Succeeded in putting data.');
      });
    } catch (e) {
      console.error(`An unexpected error occurred. Code:${e.code},message:${e.message}`);
    }
  }

  // 获取指定键的值
  async getStoreData(key: string) {
    if (!key) {
      return
    }

    if(!kvStore) {
      kvStore = await this.createKeyValueDB();
    }

    return new Promise((resolve,reject) => {
      try {
        kvStore.get(key,data) => {
          if (err != undefined) {
            console.error(`Failed to get data. Code:${err.code},message:${err.message}`);
            reject(err)
            return;
          }
          resolve(data)
        });
      } catch (err) {
        reject(err)
        console.error('TAG',`Failed to get value,Cause: ${err}`)
      }
    });
  }
}

export default new DistributedUtil();

4.1.2 调用

import distributedUtil from '../../utils/distributedStrong'

// 向数据库新增数据
distributedUtil.putStoreData('test0011',JSON.stringify({
  name: 666,age: 32,date: '2023.06.26'
}))

// 获取数据库中的数据
distributedUtil.getStoreData('test0011').then(res => {
  console.log('===获取数据库中的数据====',JSON.stringify(res))
})

4.2 关系型数据库

关系型数据库运作机制 

4.2.1 封装

import relationalStore from '@ohos.data.relationalStore';

const DB_NAME = "RelationStoreDB.db"

let context = getContext(this)
let store: relationalStore.RdbStore | undefined = undefined;

class RelationalUtil {
  async getRdbStoreConfig(dbName?: string,config?: relationalStore.StoreConfig) {
    const STORE_CONFIG: relationalStore.StoreConfig = config || {
      // 数据库文件名
      name: dbName || DB_NAME,// 数据库安全级别
      securityLevel: relationalStore.SecurityLevel.S1,// 可选参数,指定数据库是否加密,默认不加密
      encrypt: false,};

    return STORE_CONFIG;
  }

  // 创建并得到指定类型的KVStore数据库
  async createDatabaseTable(sqlCreateTable: string) {
    const STORE_CONFIG = await this.getRdbStoreConfig();
    relationalStore.getRdbStore(context,STORE_CONFIG,rdbStore: relationalStore.RdbStore) => {
      if (err) {
        console.error(`Failed to get RdbStore. Code:${err.code},message:${err.message}`);
        return;
      }
      console.info('Succeeded in getting RdbStore.');

      // 当数据库创建时,数据库默认版本为0
      store = rdbStore;
      store.executeSql(sqlCreateTable); // 创建数据表
    })
  }

  // 删除数据库
  async deleteDB(dbName: string = DB_NAME) {
    relationalStore.deleteRdbStore(context,dbName,(err) => {
      if (err) {
        console.error(`Failed to delete RdbStore. Code:${err.code},message:${err.message}`);
        return;
      }
      console.info('Succeeded in deleting RdbStore.');
    });
  }

  // 向数据库中插入数据
  async insertDatas(tableName: string,valueBucket) {
    if (store != undefined) {
      (store as relationalStore.RdbStore).insert(tableName,valueBucket,rowId: number) => {
        if (err) {
          console.error(`Failed to insert data. Code:${err.code},message:${err.message}`);
          return;
        }
        console.info(`Succeeded in inserting data. rowId:${rowId}`);
      })
    }
  }

  // 对数据进行修改
  async updateDatas(tableName: string,key,val) {
    let predicates = new relationalStore.RdbPredicates(tableName); // 创建表tableName的predicates
    predicates.equalTo(key,val); // 匹配表tableName中key为val的字段
    if (store != undefined) {
      (store as relationalStore.RdbStore).update(valueBucket,predicates,message:${err.message}`);
          return;
        }
        console.info(`Succeeded in inserting data. rowId:${rowId}`);
      })
    }
  }

  //根据谓词指定的查询条件查找数据
  async getDatas(tableName: string,atomArr: Array<string>,key: string,val: string | number) {
    let predicates = new relationalStore.RdbPredicates(tableName);
    predicates.equalTo(key,val);
    if (store != undefined) {
      return new Promise((resolve,reject) => {
        (store as relationalStore.RdbStore).query(predicates,atomArr,resultSet) => {
          if (err) {
            console.error(`Failed to query data. Code:${err.code},message:${err.message}`);
            reject(err);
            return;
          }
          resolve(resultSet);
          console.info(`ResultSet column names: ${resultSet.columnNames},column count: ${resultSet.columnCount}`);
        })
      })
    }
  }
}

export default new RelationalUtil();

4.2.2 调用

import relationalUtil from '../../utils/relationalStrong';
import { ValuesBucket } from '@ohos.data.ValuesBucket';

const DB_NAME = 'testDB'
const TABLE_NAME = 'table1'
// 建库建表
const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT NOT NULL,AGE INTEGER,SALARY REAL,CODES BLOB)'; 
relationalUtil.createDatabaseTable(SQL_CREATE_TABLE,DB_NAME);

// 删除数据库
relationalUtil.deleteDB(DB_NAME);

// 新增数据
const valBucket: ValuesBucket = {
  'NAME': 111,'AGE': 222,'SALARY': 333,'CODES': 444,};
relationalUtil.insertDatas(TABLE_NAME,valBucket);

// 修改数据
relationalUtil.updateDatas(TABLE_NAME,valBucket,'NAME','Test001Val');

// 获取数据
relationalUtil.getDatas(TABLE_NAME,['NAME','AGE','SALARY'],'Test001Val');

原文地址:https://blog.csdn.net/qq_23334071/article/details/135104854

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读1.4k次。被@Observed装饰的类,可以被观察到属性的变化;子组件中@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定。这个实例可以是数组中的被@Observed装饰的项,或者是class object中是属性,这个属性同样也需要被@Observed装饰。单独使用@Observed是没有任何作用的,需要搭配@ObjectLink或者@Prop使用。_鸿蒙ark对象数组
文章浏览阅读1k次。Harmony OS_harmonyos创建数据库
文章浏览阅读1.1k次,点赞25次,收藏23次。自定义组件Header.ets页面(子组件)//自定义组件@Component//组件声明private title:ResourceStr//接收的参数build(){Row() {index.ets(父组件)//导入自定义组件@Entry@Componentbuild() {Column() {/*** 1. 自定义组件调用-----自定义组件------* 2. 在调用的组件上设置样式*/ShopTitle({ title: '商品列表' })
文章浏览阅读952次,点赞11次,收藏25次。ArkUI是一套构建分布式应用界面的声明式UI开发框架。它使用极简的UI信息语法、丰富的UI组件、以及实时界面预览工具,帮助您提升移动应用界面开发效率30%。您只需使用一套ArkTS API,就能在Android、iOS、鸿蒙多个平台上提供生动而流畅的用户界面体验。_支持ios 安卓 鸿蒙next的跨平台方案
文章浏览阅读735次。​错误: 找不到符号符号: 变量 Layout_list_item位置: 类 ResourceTable_错误: 找不到符号 符号: 变量 resourcetable 位置: 类 mainabilityslice
文章浏览阅读941次,点赞23次,收藏21次。harmony ARKTS base64 加解密_鸿蒙 鸿蒙加解密算法库
文章浏览阅读860次,点赞21次,收藏24次。使用自定义布局,实现子组件自动换行功能。图1自定义布局的使用效果创建自定义布局的类,并继承ComponentContainer,添加构造方法。//如需支持xml创建自定义布局,必须添加该构造方法实现ComponentContainer.EstimateSizeListener接口,在onEstimateSize方法中进行测量。......@Override//通知子组件进行测量//关联子组件的索引与其布局数据idx++) {//测量自身。_鸿蒙javaui
文章浏览阅读917次,点赞25次,收藏25次。这里需要注意的是,真机需要使用华为侧提供的测试机,测试机中会安装纯鸿蒙的系统镜像,能够体验到完整的鸿蒙系统功能,纯鸿蒙应用目前还不能完美地在 HarmonyOS 4.0 的商用机侧跑起来。当前,真机调试需要使用华为侧提供的测试机,测试机中会安装纯鸿蒙的系统镜像,能够体验到完整的鸿蒙系统功能,纯鸿蒙应用目前还不能完美地在 HarmonyOS 4.0 的商用机侧跑起来。另外,由于样式的解析是基于组件文件的纬度的,因此样式文件只能应用于被其引用的组件文件中,而不能跨文件应用,并且样式文件也只支持类选择器。_鸿蒙 小程序
文章浏览阅读876次,点赞17次,收藏4次。2. HarmonyOS应用开发DevEcoStudio准备-1HUAWEI DevEco Studio为运行在HarmonyOS和OpenHarmony系统上的应用和服务(以下简称应用/服务)提供一站式的开发平台。
文章浏览阅读811次。此对象主要映射JSON数组数据,比如服务器传的数据是这样的。_arkts json
文章浏览阅读429次。鸿蒙小游戏-数字华容道_华为鸿蒙手机自带小游戏
文章浏览阅读1.1k次,点赞24次,收藏19次。Ability是应用/服务所具备的能力的抽象,一个Module可以包含一个或多个Ability。
文章浏览阅读846次。本文带大家使用MQTT协议连接华为IoT平台,使用的是E53_IA1 智慧农业扩展板与 BearPi-HM_Nano 开发主板_mqtt 如何对接第三方iot平台
文章浏览阅读567次。HarmonyOS_arkts卡片
文章浏览阅读1k次,点赞19次,收藏20次。ArkTS开发鸿蒙OS连接mongoDB(后端node.js)2024最新教程
文章浏览阅读1.2k次,点赞23次,收藏15次。HarmonyOS与OpenHarmony(1)本质上的不同是:HarmonyOS是鸿蒙操作系统,而OpenHarmony则是从开源项目。这里可以联想一下Android,比如小米手机在Android开源系统的基础上开发了MIUI的手机操作系统,HarmonyOS就类似于MIUI,OpenHarmony类似Android基础底座。(2)HarmonyOS:是双框架,内聚了AOSP(Android Open Source Project )和OpenHarmony等。_鸿蒙模拟器开了怎么跑代码
文章浏览阅读1.1k次,点赞21次,收藏21次。鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Navigation组件。
文章浏览阅读2k次。由于之前的哥们匆忙离职了,所以鸿蒙手表项目的新版本我临时接过来打包发布,基本上之前没有啥鸿蒙经验,但是一直是做Android开发的,在工作人员的指导下发现打包配置基本上和Android一样,所以这些都不是问题,这里记录一下使用过程中遇到的问题。!过程和遇到的问题基本上都讲解了,关机睡觉,打卡收工。_鸿蒙系统adb命令
文章浏览阅读7.3k次,点赞9次,收藏29次。39. 【多选题】_column和row容器中,设置子组件在主轴方向上的对齐格式
文章浏览阅读1.1k次,点赞13次,收藏24次。18.鸿蒙HarmonyOS App(JAVA)日期选择器-时间选择器点击button按钮显示月份与获取的时间。_harmonyos农历获取