【HarmonyOS开发】ArkTs关系型和非关系型数据库的存储封装
前面使用了首选项的存储方式,因此将其他的两种存储方式(键值型数据库和关系型数据库)也学习一下,简单记录一下,并进行封装,方便后续使用。
1、效果预览
2、使用条件
2.1 键值型数据库
键值型数据库实现数据持久化width=device-width,initial-scale=1.0http://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.0http://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 = {// 当数据库文件不存在时是否创建数据库,默认为truecreateIfMissing: 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, (err, 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, (err, rdbStore: relationalStore.RdbStore) => {if (err) {console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);return;}console.info('Succeeded in getting RdbStore.');// 当数据库创建时,数据库默认版本为0store = 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, (err, 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, valueBucket, key, val) {let predicates = new relationalStore.RdbPredicates(tableName); // 创建表tableName的predicatespredicates.equalTo(key, val); // 匹配表tableName中key为val的字段if (store != undefined) {(store as relationalStore.RdbStore).update(valueBucket, predicates, (err, 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 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, (err, 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'], 'NAME', 'Test001Val');
相关文章:

【HarmonyOS开发】ArkTs关系型和非关系型数据库的存储封装
前面使用了首选项的存储方式,因此将其他的两种存储方式(键值型数据库和关系型数据库)也学习一下,简单记录一下,并进行封装,方便后续使用。 1、效果预览 2、使用条件 2.1 键值型数据库 键值型数据库实现数据…...
Latex编译出来的pdf文件缺少参考文献和交叉引用
参考文件通常需要在首次编译后,再次编译添加 依次执行下面的命令即可: xelatex main.tex main.tex为需要编译的主tex文件 biber mainxelatex main.tex 如果编译过程中遇到错误,请删除所有辅助文件和已打开的pdf文件后重试 辅助文件包括&#…...

sql_lab靶场搭建以及存在的一些问题
sql_lab靶场搭建问题 首先检查小皮版本 把小皮改到5.3.29版本如果没有可以直接点击更多版本进行选择安装 当版本不对时则会暴出这种错误 SETTING UP THE DATABASE SCHEMA AND POPULATING DATA IN TABLES: Fatal error: Uncaught Error: Call to undefined function mysql_co…...
Https接口调用问题
使用场景: 因为项目需要爬点接口数据, 接口是https, 在网上找的笔记整理了一下. 仅供参考 1. 调用Https的Get方法 /*** 只需要url** param url* return*/public static String doGetForHTML(String url) {return doGetForHTML(url, null);}/*** param url 请求地址* para…...

CSS自适应分辨率 amfe-flexible 和 postcss-pxtorem:大屏高宽自适应问题
前言 继上篇《CSS自适应分辨率 amfe-flexible 和 postcss-pxtorem》。 发现一个有趣的问题,文件 rem.js 中按照宽度设置自适应,适用于大多数页面,但当遇到大屏就不那么合适了。 问题 使用宽度,注意代码第2 和 4 行:…...

SQL面试题挑战01:打折日期交叉问题
目录 问题:SQL解答:第一种方式:第二种方式: 问题: 如下为某平台的商品促销数据,字段含义分别为品牌名称、打折开始日期、打折结束日期,现在要计算每个品牌的打折销售天数(注意其中的…...

三大主流前端框架介绍及选型
在前端项目中,可以借助某些框架(如React、Vue、Angular等)来实现组件化开发,使代码更容易复用。此时,一个网页不再是由一个个独立的HTML、CSS和JavaScript文件组成,而是按照组件的思想将网页划分成一个个组…...

云原生消息流系统 Apache Pulsar 在腾讯云的大规模生产实践
导语 由 InfoQ 主办的 Qcon 全球软件开发者大会北京站上周已精彩落幕,腾讯云中间件团队的冉小龙参与了《云原生机构设计与音视频技术应用》专题,带来了以《云原生消息流系统 Apache Pulsar 在腾讯云的大规模生产实践》为主题的精彩演讲,在本…...

【LeetCode刷题】--245.最短单词距离III
245.最短单词距离III class Solution {public int shortestWordDistance(String[] wordsDict, String word1, String word2) {int len wordsDict.length;int ans len;if(word1.equals(word2)){int prev -1;for(int i 0;i<len;i){String word wordsDict[i];if(word.equa…...

数字化时代的智能支持:亚马逊云科技轻量应用服务器技术领先
轻量应用服务器是一种简化运维、门槛低的弹性服务器,它的"轻"主要体现在几个方面:开箱即用、应用优质、上手简洁、投入划算、运维简便以及稳定可靠。相较于普通的云服务器,轻量应用服务器简化了云服务的操作难度、使用和管理流程&a…...

【智慧之窗】AI驱动产品探索
一.初识 ChatGPT ChatGPT 是由 OpenAI 开发的自然语言处理(NLP)模型,基于 GPT(Generative Pre-trained Transformer)架构。GPT 系列的模型旨在理解和生成自然语言文本。ChatGPT 专注于支持对话性任务,即与…...

BBS项目--登录
BBS阶段性测试总要求 django登录报错 Error: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试。 原因分析:出现这种情况在Windows中很常见,就是端口被占用 解决措施:这时我们只需改一下端口便可以了 登录前端页面(HTML…...

Python---TCP服务端程序开发
1. 开发 TCP 服务端程序开发步骤回顾 创建服务端端套接字对象绑定端口号设置监听等待接受客户端的连接请求接收数据发送数据关闭套接字 2. socket 类的介绍 导入 socket 模块import socket 创建服务端 socket 对象socket.socket(AddressFamily, Type) 参数说明: AddressF…...

回归预测 | MATLAB实现GWO-DHKELM基于灰狼算法优化深度混合核极限学习机的数据回归预测 (多指标,多图)
回归预测 | MATLAB实现GWO-DHKELM基于灰狼算法优化深度混合核极限学习机的数据回归预测 (多指标,多图) 目录 回归预测 | MATLAB实现GWO-DHKELM基于灰狼算法优化深度混合核极限学习机的数据回归预测 (多指标,多图&#…...

听GPT 讲Rust源代码--src/tools(15)
File: rust/src/tools/rust-analyzer/crates/mbe/src/token_map.rs 在Rust源代码中,rust/src/tools/rust-analyzer/crates/mbe/src/token_map.rs文件的作用是实现了一个能够将输入的文本映射为标记的结构。具体来说,它定义和实现了几个结构体(…...

python可以做小程序研发嘛,python能做微信小程序吗
大家好,给大家分享一下python可以做微信小程序开发吗,很多人还不知道这一点。下面详细解释一下。现在让我们来看看! 大家好,给大家分享一下用python编写一个小程序,很多人还不知道这一点。下面详细解释一下用python代码…...
创建型模式 | 单例模式
一、单例模式 单例模式(Singleton Pattern),使用最广泛的设计模式之一。其意图是保证一个类仅有一个实例被构造,并提供一个访问它的全局访问接口,该实例被程序的所有模块共享。 1、饿汉式 1.1、基础版本 在程序启动后立刻构造单例࿰…...
【无标题】欢迎使用Markdown编辑器
这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…...

Postgresql中PL/pgSQL的游标、自定义函数、存储过程的使用
场景 Postgresql中PL/pgSQL代码块的语法与使用-声明与赋值、IF语句、CASE语句、循环语句: Postgresql中PL/pgSQL代码块的语法与使用-声明与赋值、IF语句、CASE语句、循环语句-CSDN博客 上面讲了基本语法,下面记录游标、自定义函数、存储过程的使用。 …...

【IDEA】Intellij IDEA相关配置
IDEA 全称 IntelliJ IDEA,是java编程语言的集成开发环境。IntelliJ在业界被公认为最好的Java开发工具,尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能可以说是超…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...