如何在 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 进行构建具有挑战性。 更具体地说,缺…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
电脑桌面太单调,用Python写一个桌面小宠物应用。
下面是一个使用Python创建的简单桌面小宠物应用。这个小宠物会在桌面上游荡,可以响应鼠标点击,并且有简单的动画效果。 import tkinter as tk import random import time from PIL import Image, ImageTk import os import sysclass DesktopPet:def __i…...
2025-05-08-deepseek本地化部署
title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek:小白也能轻松搞定! 如何给本地部署的 DeepSeek 投喂数据,让他更懂你 [实验目的]:理解系统架构与原…...
【版本控制】GitHub Desktop 入门教程与开源协作全流程解析
目录 0 引言1 GitHub Desktop 入门教程1.1 安装与基础配置1.2 核心功能使用指南仓库管理日常开发流程分支管理 2 GitHub 开源协作流程详解2.1 Fork & Pull Request 模型2.2 完整协作流程步骤步骤 1: Fork(创建个人副本)步骤 2: Clone(克隆…...
【阅读笔记】MemOS: 大语言模型内存增强生成操作系统
核心速览 研究背景 研究问题:这篇文章要解决的问题是当前大型语言模型(LLMs)在处理内存方面的局限性。LLMs虽然在语言感知和生成方面表现出色,但缺乏统一的、结构化的内存架构。现有的方法如检索增强生成(RA…...
大模型真的像人一样“思考”和“理解”吗?
Yann LeCun 新研究的核心探讨:大语言模型(LLM)的“理解”和“思考”方式与人类认知的根本差异。 核心问题:大模型真的像人一样“思考”和“理解”吗? 人类的思考方式: 你的大脑是个超级整理师。面对海量信…...
