如何在 HarmonyOS 对数据库进行备份,恢复与加密
数据库备份与恢复
场景介绍
当应用在处理一项重要的操作,显然是不能被打断的。例如:写入多个表关联的事务。此时,每个表的写入都是单独的,但是表与表之间的事务关联性不能被分割。
如果操作的过程中出现问题,开发者可以使用恢复功能,将数据库恢复到之前的状态,重新对数据库进行操作。
在数据库被篡改、删除、或者设备断电场景下,数据库可能会因为数据丢失、数据损坏、脏数据等而不可用,可以通过数据库的备份恢复能力将数据库恢复至可用状态。
键值型数据库和关系型数据库均支持对数据库的备份和恢复。另外,键值型数据库还支持删除数据库备份,以释放本地存储空间。
键值型数据库备份、恢复与删除
键值型数据库,通过 backup 接口实现数据库备份,通过 restore 接口实现数据库恢复,通过 deletebackup 接口删除数据库备份。具体接口及功能,可见分布式键值数据库。
1. 创建数据库。(1) 创建 kvManager。
(2) 配置数据库参数。
(3) 创建 kvStore。
import distributedKVStore from '@ohos.data.distributedKVStore';let kvManager;let context = getContext(this);const kvManagerConfig = {context: context,bundleName: 'com.example.datamanagertest'}try {kvManager = distributedKVStore.createKVManager(kvManagerConfig);console.info('Succeeded in creating KVManager.');} catch (e) {console.error(`Failed to create KVManager. Code:${e.code},message:${e.message}`);}let kvStore;try {const options = {createIfMissing: true,encrypt: false,backup: false,kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,securityLevel: distributedKVStore.SecurityLevel.S2};kvManager.getKVStore('storeId', options, (err, store) => {if (err) {console.error(`Fail 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}`);}
2. 使用 put()方法插入数据。
const KEY_TEST_STRING_ELEMENT = 'key_test_string';const VALUE_TEST_STRING_ELEMENT = 'value_test_string';try {kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => {if (err !== undefined) {console.error(`Fail 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}`);}
3. 使用 backup()方法备份数据。
let file = 'BK001';try {kvStore.backup(file, (err) => {if (err) {console.error(`Fail to backup data.code:${err.code},message:${err.message}`);} else {console.info('Succeeded in backupping data.');}});} catch (e) {console.error(`An unexpected error occurred. Code:${e.code},message:${e.message}`);}
4. 使用 delete()方法删除数据(模拟意外删除、篡改场景)。
try {kvStore.delete(KEY_TEST_STRING_ELEMENT, (err) => {if (err !== undefined) {console.error(`Fail 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}`);}
5. 使用 restore()方法恢复数据。
let file = 'BK001';try {kvStore.restore(file, (err) => {if (err) {console.error(`Fail to restore data. Code:${err.code},message:${err.message}`);} else {console.info('Succeeded in restoring data.');}});} catch (e) {console.error(`An unexpected error occurred. Code:${e.code},message:${e.message}`);}
6. 当本地设备存储空间有限或需要重新备份时,还可使用 deleteBackup()方法删除备份,释放存储空间。
let kvStore;let files = ['BK001'];try {kvStore.deleteBackup(files).then((data) => {console.info(`Succeed in deleting Backup. Data:filename is ${data[0]},result is ${data[1]}.`);}).catch((err) => {console.error(`Fail to delete Backup. Code:${err.code},message:${err.message}`);})} catch (e) {console.error(`An unexpected error occurred. Code:${e.code},message:${e.message}`);}
关系型数据库备份与恢复
关系型数据库,通过 backup 接口实现数据库备份,通过 restore 接口实现数据库恢复。具体接口及功能,可见关系型数据库。
1. 使用 getRdbStore()方法创建关系型数据库。
import relationalStore from '@ohos.data.relationalStore';let store;let context = getContext(this);const STORE_CONFIG = {name: 'RdbTest.db',securityLevel: relationalStore.SecurityLevel.S1};relationalStore.getRdbStore(context, STORE_CONFIG, (err, rdbStore) => {store = rdbStore;if (err) {console.error(`Failed to get RdbStore. Code:${err.code},message:${err.message}`);return;}store.executeSql("CREATE TABLE IF NOT EXISTS EMPLOYEE (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER, salary INTEGER, codes Uint8Array);", null);console.info('Succeeded in getting RdbStore.');})
2. 使用 insert()方法插入数据。
const valueBucket = {'NAME': 'Lisa','AGE': 18,'SALARY': 100.5, 'CODES': new Uint8Array([1, 2, 3, 4, 5])};store.insert('EMPLOYEE', valueBucket, relationalStore.ConflictResolution.ON_CONFLICT_REPLACE, (err, rowId) => {if (err) {console.error(`Failed to insert data. Code:${err.code},message:${err.message}`);return;}console.info(`Succeeded in inserting data. rowId:${rowId}`);})
3. 使用 backup()方法备份数据。
store.backup('dbBackup.db', (err) => {if (err) {console.error(`Failed to backup data. Code:${err.code},message:${err.message}`);return;}console.info(`Succeeded in backuping data.`);})
4. 使用 delete()方法删除数据(模拟意外删除、篡改场景)。
let predicates = new relationalStore.RdbPredicates('EMPLOYEE');predicates.equalTo('NAME', 'Lisa');let promise = store.delete(predicates);promise.then((rows) => {console.info(`Delete rows: ${rows}`);}).catch((err) => {console.error(`Failed to delete data. Code:${err.code},message:${err.message}`);})
5. 使用 restore()方法恢复数据。
store.restore('dbBackup.db', (err) => {if (err) {console.error(`Failed to restore data. Code:${err.code},message:${err.message}`);return;}console.info(`Succeeded in restoring data.`);})
数据库加密
场景介绍
为了增强数据库的安全性,数据库提供了一个安全适用的数据库加密能力,从而对数据库存储的内容实施有效保护。通过数据库加密等安全方法实现了数据库数据存储的保密性和完整性要求,使得数据库以密文方式存储并在密态方式下工作,确保了数据安全。
加密后的数据库只能通过接口进行访问,无法通过其它方式打开数据库文件。数据库的加密属性在创建数据库时确认,无法变更。
键值型数据库和关系型数据库均支持数据库加密操作。
键值型数据库加密
键值型数据库,通过 options 中 encrypt 参数来设置是否加密,默认为 false,表示不加密。encrypt 参数为 true 时表示加密。
具体接口及功能,可见分布式键值数据库。
import distributedKVStore from '@ohos.data.distributedKVStore';let kvManager;let context = getContext(this);const kvManagerConfig = {context: context,bundleName: 'com.example.datamanagertest'}try {kvManager = distributedKVStore.createKVManager(kvManagerConfig);console.info('Succeeded in creating KVManager.');} catch (e) {console.error(`Failed to create KVManager. Code:${e.code},message:${e.message}`);}let kvStore;try {const options = {createIfMissing: true,// 设置数据库加密encrypt: true,backup: false,kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,securityLevel: distributedKVStore.SecurityLevel.S2};kvManager.getKVStore('storeId', options, (err, store) => {if (err) {console.error(`Fail 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}`);}
关系型数据库加密
关系型数据库,通过 StoreConfig 中 encrypt 属性来设置是否加密,默认为 false,表示不加密。encrypt 参数为 true 时表示加密。
具体接口及功能,可见关系型数据库。
import relationalStore from '@ohos.data.relationalStore';let store;let context = getContext(this);const STORE_CONFIG = {name: 'RdbTest.db',securityLevel: relationalStore.SecurityLevel.S1,encrypt: true};relationalStore.getRdbStore(context, STORE_CONFIG, (err, rdbStore) => {store = rdbStore;if (err) {console.error(`Failed to get RdbStore. Code:${err.code},message:${err.message}`);return;}console.info(`Succeeded in getting RdbStore.`);})
相关文章:
如何在 HarmonyOS 对数据库进行备份,恢复与加密
数据库备份与恢复 场景介绍 当应用在处理一项重要的操作,显然是不能被打断的。例如:写入多个表关联的事务。此时,每个表的写入都是单独的,但是表与表之间的事务关联性不能被分割。 如果操作的过程中出现问题,开发者可…...
js实现向上、向下、向左、向右无缝滚动
向左滚动 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, ini…...
6 Hive引擎集成Apache Paimon
更多Paimon数据湖内容请关注:https://edu.51cto.com/course/35051.html 在实际工作中,我们通查会使用Flink计算引擎去读写Paimon,但是在批处理场景中,更多的是使用Hive去读写Paimon,这样操作起来更加方便。 前面我们…...
发布版本自动化记录版本功能方法
# 安装commitizennpm install --save-dev commitizen# 初始化Conventional Commits规范适配器npx commitizen init cz-conventional-changelog --save-dev --save-exact最后一步,需要在package.json中添加一个script"scripts": {..., // 此处省略其它配置…...
Elastic Stack 8.11:引入一种新的强大查询语言 ES|QL
作者:Tyler Perkins, Ninoslav Miskovic, Gilad Gal, Teresa Soler, Shani Sagiv, Jason Burns Elastic Stack 8.11 引入了数据流生命周期、一种配置数据流保留和降采样(downsampling) 的简单方法(技术预览版)…...
wx:for-item wx:for-index wx:for-key
wx:for-item wx:for-item , 数组当前项的变量名,默认为 item 作用:使用 (当前项变量名.属性名) 取得属性值每一项 <view wx:for"{{array}}"><view>{{item.name item.age }}</view> </view>等同于 &…...
老师还不会评课?这里有你需要的解决方案
优点: 1.课件制作: 老师的PPT设计得很新颖,插入的音乐视频都非常贴合课堂内容,看得出老师非常用心地进行了设计。 2.教师素养:老师的语言丰富、朗读能力很出色、板书设计很工整。 3.教师风格: xx老师上课激情澎湃/非常有亲和力…...
Talk | 马里兰大学博士生吴曦旸:分布式多智能体强化学习在复杂交通轨迹规划中的应用
本期为TechBeat人工智能社区第545期线上Talk! 北京时间11月09日(周四)20:00,马里兰大学博士生—吴曦旸的Talk已准时在TechBeat人工智能社区开播! 他与大家分享的主题是: “分布式多智能体强化学习在复杂交通轨迹规划中的应用”,介…...
2023年下半年架构案例真题及答案
案例的考点: 大数据架构 Lambda架构和Kappa架构 jwt特点 数据持久层,Redis数据丢失,数据库读写分离方案 Hibernat架构 SysML七个关系,填需求图 大数据的必选题: 某网作为某电视台在互联网上的大型门户入口&#…...
Java必考面试题,谈谈你对 Spring AOP 的理解
大家好,我是伍六七。 今天我们来学习 Spring 框架中最重要的概念之一:AOP。 这是一个 Java 程序员必考的面试题,大家好好理解。我们开始正文。 AOP 的概念 Spring AOP 是 Java 程序员们面试经常被问到的一个问题,但 AOP&#…...
BERT和ChatGPT简单对比
OpenAI发布了第一个版本的GPT(Generative Pretrained Transformer)模型在2018年6月。 谷歌的BERT模型(Bidirectional Encoder Representations from Transformers)是在2018年10月发布的。 BERT和ChatGPT都是由人工智能研究实验室…...
又一重要合作,创邻科技华为云联营产品正式发布
近日,创邻科技旗下的“Galaxybase高性能图平台”正式入驻华为云云商店联营商品,创邻科技成为华为云在数据库与缓存领域的联营联运合作伙伴。通过联营联运模式,双方合作能够深入产品、生态、解决方案等多个领域,助力各行业用户数字…...
PHP+Swoole应用示例
**Swoole是一个C编写的基于异步事件驱动和协程的并行网络通信引擎,为PHP提供高性能网络编程支持** ## ⚙️ 快速启动 可以直接使用 [Docker](https://github.com/swoole/docker-swoole) 来执行Swoole的代码,例如: bash docker run --rm php…...
3线硬件SPI+DMA驱动 HX8347 TFT屏
3线硬件SPIDMA驱动 HX8347 TFT屏,实现用DMA清屏。 参考:基于stm32 标准库spi驱动st7789彩屏TFT(使用DMA)-技术天地-深圳市修德电子有限公司 一、源码 HX8347.h #ifndef USER_HX8347_H_ #define USER_HX8347_H_#define SPI_hardware #define SPI_hardw…...
实验语音学的基本概念
语音学 实验语音学只是语音学的一个分支,那么语音学到底是研究什么的呢?我们先有一个大致了解。 语音学是研究语言声音体系的学科。语音学的任务是研究说明语音的性质,内部结构和单位,语音的分类和组合,语音的产生、…...
市场上ios签名公司做什么的?
iOS签名公司是提供iOS应用程序签名服务的公司。它们为开发者提供了一种简单的方式来将他们的应用程序发布到iOS设备上,同时也为用户提供了一种下载和安装这些应用程序的方法。这些公司提供的签名服务包括苹果企业签名和开发者签名,其中企业签名是为企业开…...
12. 一文快速学懂常用工具——docker 命令
本章讲解知识点 Docker 引擎Docker 常用命令Docker 生命周期详解Containerd 与 Docker 命令对比本专栏适合于软件开发刚入职的学生或人士,有一定的编程基础,帮助大家快速掌握工作中必会的工具和指令。本专栏针对面试题答案进行了优化,尽量做到好记、言简意赅。如专栏内容有错…...
API低代码开发应用场景
什么是API低代码开发平台 API低代码开发平台是一种基于低代码开发的技术平台,它可以帮助企业快速构建和部署API应用程序。该平台通过提供可视化的开发工具、预定义的组件和模板、自动化的代码生成等功能,使得开发者可以在不需要编写大量代码的情况下&am…...
从零开始搭建React+TypeScript+webpack开发环境-性能优化
前言 当我们开发React应用时,性能始终是一个重要的考虑因素。随着应用规模的增长,React组件的数量和复杂性也会相应增加,这可能会导致性能问题的出现。在这篇博文中,我们将探讨如何通过一系列的技巧和最佳实践来优化React应用的性…...
sCrypt 现在支持 Ordinals 了
比特币社区对 1Sat Ordinals 的接受度正在迅速增加,已有超过 4800 万个铭文被铸造,这一新创新令人兴奋不已。 尽管令人兴奋,但 Ordinals 铭文的工具仍然不发达,这使得使用 Ordinals 进行构建具有挑战性。 更具体地说,缺…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
