如何在 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 进行构建具有挑战性。 更具体地说,缺…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...
leetcode73-矩阵置零
leetcode 73 思路 记录 0 元素的位置:遍历整个矩阵,找出所有值为 0 的元素,并将它们的坐标记录在数组zeroPosition中置零操作:遍历记录的所有 0 元素位置,将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...
基于stm32F10x 系列微控制器的智能电子琴(附完整项目源码、详细接线及讲解视频)
注:文章末尾网盘链接中自取成品使用演示视频、项目源码、项目文档 所用硬件:STM32F103C8T6、无源蜂鸣器、44矩阵键盘、flash存储模块、OLED显示屏、RGB三色灯、面包板、杜邦线、usb转ttl串口 stm32f103c8t6 面包板 …...
CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?
在现代前端开发中,Utility-First (功能优先) CSS 框架已经成为主流。其中,Tailwind CSS 无疑是市场的领导者和标杆。然而,一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...
