鸿蒙实现数据管理

目录:

    • 1、鸿蒙实现数据管理的三种方式
    • 2、用户首选项
    • 3、键值型数据管理
      • 3.1、获取KVManager实例,用于管理数据库对象
      • 3.2、创建并获取键值数据库
      • 3.3、调用put()方法向键值数据库中插入数据
      • 3.4、调用get()方法获取指定键的值
      • 3.5、调用delete()方法删除指定键值的数据
    • 4、关系型数据管理
      • 4.1、导入模块
      • 4.2、在abliity入口文件的生命周期函数onWindowStageCreat中添加初始化代码
      • 4.3、RdbUtils工具类
      • 4.4、创建数据库
      • 4.5、插入数据
      • 4.6、查询数据
      • 4.7、修改和删除数据
      • 4.8、删除数据库

1、鸿蒙实现数据管理的三种方式

  • 用户首选项
  • 键值型数据管理
  • 关系型数据管理

在这里插入图片描述

2、用户首选项

import dataPreferences from '@ohos.data.preferences';
import preferences from '@ohos.data.preferences';
import { Log } from './Log';
import { ValueType } from '@kit.ArkData';

/**
 * 用户首选项工具类
 */
export class PreferencesUtil {
  static mPreferences ?: dataPreferences.Preferences

  /**
   * 初始化
   * @param context
   */
  static init(context: Context) {
    try {
      dataPreferences.getPreferences(context, 'Looper_Sp', (err, preferences) => {
        if (err) {
          Log.error(`Failed to get preferences. Code:${err.code},message:${err.message}`);
          return;
        }
        PreferencesUtil.mPreferences = preferences
        Log.info('Succeeded in getting preferences.');
        // 进行相关数据操作
      })
    } catch (err) {
      Log.error(`Failed to get preferences. Code:${err.code},message:${err.message}`);
    }
  }

  /**
   * 写数据
   * @param isFlush 是否持久化
   */
  static writeData(key: string, value: ValueType, isFlush: boolean): Promise<boolean> {
    return new Promise((resolve, reject) => {
      try {
        PreferencesUtil.mPreferences?.put(key, value, (err) => {
          if (err) {
            Log.error(`Failed to put data. Code:${err.code}, message:${err.message}`);
            reject(false);
            return;
          }
          Log.info('Succeeded in putting data.');
          if (isFlush) {
            PreferencesUtil.flushData()
          }
          resolve(true);
        })
      } catch (err) {
        Log.error(`Failed to check the key 'startup'. Code:${err.code}, message:${err.message}`);
        reject(false);
      }
    });
  }

  /**
   * 读取数据
   */
  static readData<D>(key: string): Promise<D> {
    return new Promise((resolve, reject) => {
      if (PreferencesUtil.mPreferences == null) {
        reject(new Error("mPreferences is null"));
      } else {
        PreferencesUtil.mPreferences.get(key, "", (err, value) => {
          if (err) {
            reject(err);
            return;
          }
          resolve(value as D);
        })
      }
    });
  }

  /**
   * 删除数据
   * @param isFlush 是否持久化
   */
  static delData(key: string, isFlush: boolean): Promise<string> {
    return new Promise((resolve, reject) => {
      if (PreferencesUtil.mPreferences == null) {
        reject(new Error("mPreferences is null"));
      } else {
        PreferencesUtil.mPreferences.delete(key, (err, value) => {
          if (err) {
            reject(err);
            return;
          }
          if (isFlush) {
            PreferencesUtil.flushData()
          }
          resolve("删除成功");
        })
      }
    });
  }

  /**
   * 删除整个库
   * @param isFlush 是否持久化
   */
  static delDB(context: Context, storeName: string): Promise<string> {
    return new Promise((resolve, reject) => {
      dataPreferences.deletePreferences(context, storeName, (err, value) => {
        if (err) {
          reject(err);
          return;
        }
        resolve("删除成功");
      })
    });
  }

  /**
   * 持久化
   */
  static flushData() {
    if (PreferencesUtil.mPreferences != null) {
      try {
        PreferencesUtil.mPreferences.flush((err) => {
          if (err) {
            Log.error(`Failed to flush. Code:${err.code}, message:${err.message}`);
            return;
          }
          Log.info('Succeeded in flushing.');
        })
      } catch (err) {
        Log.error(`Failed to flush. Code:${err.code}, message:${err.message}`);
      }
    }
  }
}

let preferencesUtil = new PreferencesUtil()

export default preferencesUtil as PreferencesUtil

//下面首选项的方法可以在这里面执行,页面栈创建时就初始化用户首选项,就可以直接在代码中使用了
onWindowStageCreate(ability, windowStage) {
PreferencesUtil.init(this.context)
console.info(TAG, “onWindowStageCreate ability:+ JSON.stringify(ability));
console.info(TAG, “onWindowStageCreate windowStage:+ JSON.stringify(windowStage));
}
//sp储存初始化
PreferencesUtil.init(this.context)
//写入信息
PreferencesUtil.writeData("zzz", "bbb", true)
//读取信息
PreferencesUtil.readData<string>("zzz").then(res => {
      Log.info("读取数据:" + res)
    })

3、键值型数据管理

3.1、获取KVManager实例,用于管理数据库对象

// 导入模块
import { distributedKVStore } from '@kit.ArkData';
 
// Stage模型
import { window } from '@kit.ArkUI';
import { UIAbility } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
 
let kvManager: distributedKVStore.KVManager | undefined = undefined;
 
export default class EntryAbility extends UIAbility {
  onCreate() {
    let context = this.context;
    const kvManagerConfig: distributedKVStore.KVManagerConfig = {
      context: context,
      bundleName: 'com.example.datamanagertest'
    };
    try {
      // 创建KVManager实例
      kvManager = distributedKVStore.createKVManager(kvManagerConfig);
      console.info('Succeeded in creating KVManager.');
      // 继续创建获取数据库
    } catch (e) {
      let error = e as BusinessError;
      console.error(`Failed to create KVManager. Code:${error.code},message:${error.message}`);
    }
  }
}
if (kvManager !== undefined) {
   kvManager = kvManager as distributedKVStore.KVManager;
  //进行后续操作
  //...
}

3.2、创建并获取键值数据库

let kvStore: distributedKVStore.SingleKVStore | undefined = undefined;
try {
  const options: distributedKVStore.Options = {
    createIfMissing: true,
    encrypt: false,
    backup: false,
    autoSync: false,
    // kvStoreType不填时,默认创建多设备协同数据库
    kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,
    // 多设备协同数据库:kvStoreType: distributedKVStore.KVStoreType.DEVICE_COLLABORATION,
    securityLevel: distributedKVStore.SecurityLevel.S1
  };
  kvManager.getKVStore<distributedKVStore.SingleKVStore>('storeId', 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) {
  let error = e as BusinessError;
  console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);
}
if (kvStore !== undefined) {
  kvStore = kvStore as distributedKVStore.SingleKVStore;
    //进行后续操作
    //...
}

3.3、调用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(`Failed to put data. Code:${err.code},message:${err.message}`);
      return;
    }
    console.info('Succeeded in putting data.');
  });
} catch (e) {
  let error = e as BusinessError;
  console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);
}

说明:

当Key值存在时,put()方法会修改其值,否则新增一条数据。

3.4、调用get()方法获取指定键的值

try {
  kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => {
    if (err !== undefined) {
      console.error(`Failed to put data. Code:${err.code},message:${err.message}`);
      return;
    }
    console.info('Succeeded in putting data.');
    kvStore = kvStore as distributedKVStore.SingleKVStore;
    kvStore.get(KEY_TEST_STRING_ELEMENT, (err, data) => {
      if (err != undefined) {
        console.error(`Failed to get data. Code:${err.code},message:${err.message}`);
        return;
      }
      console.info(`Succeeded in getting data. Data:${data}`);
    });
  });
} catch (e) {
  let error = e as BusinessError;
  console.error(`Failed to get data. Code:${error.code},message:${error.message}`);
}

3.5、调用delete()方法删除指定键值的数据

try {
  kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => {
    if (err !== undefined) {
      console.error(`Failed to put data. Code:${err.code},message:${err.message}`);
      return;
    }
    console.info('Succeeded in putting data.');
    kvStore = kvStore as distributedKVStore.SingleKVStore;
    kvStore.delete(KEY_TEST_STRING_ELEMENT, (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) {
  let error = e as BusinessError;
  console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);
}

4、关系型数据管理

4.1、导入模块

import relationalStore from '@ohos.data.relationalStore'; // 导入模块 

4.2、在abliity入口文件的生命周期函数onWindowStageCreat中添加初始化代码

const STORE_CONFIG = {
      name: 'RdbTest.db', // 数据库文件名
      securityLevel: relationalStore.SecurityLevel.S1 // 数据库安全级别
    };

    relationalStore.getRdbStore(this.context, STORE_CONFIG, (err, store) => {
      if (err) {
        console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
        return;
      }
      console.info(`Succeeded in getting RdbStore.`);
      //保存store, 方便后面我们对数据库的操作
      RdbUtils.setStore(store)

    });

4.3、RdbUtils工具类

import relationalStore from '@ohos.data.relationalStore';
export default class RdbUtils {
  private static rdbStore: relationalStore.RdbStore;
  static setStore(store: relationalStore.RdbStore) {
    RdbUtils.rdbStore = store;
  }
  static getStore(): relationalStore.RdbStore {
    return RdbUtils.rdbStore;
  }
}

4.4、创建数据库

import relationalStore from '@ohos.data.relationalStore';
export default class RdbUtils {
  ...
  static executeSql(sql: string): Promise<void> {
    return RdbUtils.getStore().executeSql(sql);
  }
  ...
}

示例:

import RdbUtils from '../common/rdbUtils/RdbUtils';
@Entry
@Component
struct Index {
  build() {
    Row() {
      Column() {
        Button('创建数据库表')
          .onClick(() => {
            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)'; // 建表Sql语句
            RdbUtils.executeSql(SQL_CREATE_TABLE)
            .then(() =>{
                openDialog('successfully created table')
              }).catch((err) => {
              openDialog(err);
            })
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

function openDialog(text: string) {
  AlertDialog.show(
    {
      title: 'title',
      message: text,
      autoCancel: true,
      alignment: DialogAlignment.Bottom,
      offset: { dx: 0, dy: -20 },
    }
  )
}

4.5、插入数据

import relationalStore from '@ohos.data.relationalStore';
export default class RdbUtils {
  ...
  static insert(tableName: string, data: any): Promise<number> {
    return RdbUtils.getStore().insert(tableName, data);
  }
  ...
}

示例:

import RdbUtils from '../common/rdbUtils/RdbUtils';
@Entry
@Component
struct Index {
  build() {
    Row() {
      Column() {
        ...
        Button('插入数据')
          .onClick(() => {
            const valueBucket = {
              'NAME': 'Lisa',
              'AGE': 18,
              'SALARY': 100.5,
              'CODES': new Uint8Array([1, 2, 3, 4, 5])
            };
            RdbUtils.insert('EMPLOYEE', valueBucket)
              .then((updateNumber) => {
                openDialog('已插入数据:' + updateNumber)
            }).catch((error) => {
              openDialog('error: ' + error)
            })
          })
        ...
      }
      .width('100%')
    }
    .height('100%')
  }
}
...

4.6、查询数据

static queryAll(): Promise<Array<Employee>> {
    let predicates = new relationalStore.RdbPredicates('EMPLOYEE');
    return new Promise<Array<Employee>>((resolve, reject) => {
      RdbUtils.getStore().query(predicates).then((result) => {
        let employees = new Array<Employee>();
        while (result.goToNextRow()) {
          let employee = new Employee(
            result.getLong(0),
            result.getString(1),
            result.getLong(2),
            result.getDouble(3),
            result.getBlob(4)
          );
          employees.push(employee);
        }
        resolve(employees);
      }).catch((error) => {
        reject(error)
      })
    })
  }

该方法将通过RdbUtils.getStore().query(predicates)获取的结果集封装到Employee类中,然后通过Promise进行返回。

实体类Employee:

export default class Employee {
  id: number; // 员工ID
  name: string; // 姓名
  age: number | null; // 年龄,允许为null
  salary: number | null; // 工资,允许为null
  codes: Uint8Array | null; // 二进制数据,用于存储 BLOB 类型,允许为null

  constructor(id: number, name: string, age: number | null, salary: number | null, codes: Uint8Array | null) {
    this.id = id;
    this.name = name;
    this.age = age;
    this.salary = salary;
    this.codes = codes;
  }
}

示例:

import RdbUtils from '../common/rdbUtils/RdbUtils';
@Entry
@Component
struct Index {
  build() {
    Row() {
      Column() {
        ...
        Button('查询数据')
          .onClick(() => {
            RdbUtils.queryAll()
              .then((employees: Array<Employee>) => {
                openDialog('employees: ' + JSON.stringify(employees))
              }).catch((error) => {
              openDialog('error' + error.toString())
            })
          })
        ...
      }
      .width('100%')
    }
    .height('100%')
  }
}
...

4.7、修改和删除数据

在工具包中添加:

...
  static deleteById(id: number) {
    let predicates = new relationalStore.RdbPredicates('EMPLOYEE');
    predicates.equalTo('ID', id)
    return RdbUtils.getStore().delete(predicates);
  }

  static updateById(id: number, data: any) {
    let predicates = new relationalStore.RdbPredicates('EMPLOYEE');
    predicates.equalTo('ID', id)
    return RdbUtils.getStore().update(data, predicates);
  }
...

      	Button('修改数据')
          .onClick(() => {
            const valueBucket = {
              'NAME': 'Rose',
              'AGE': 999,
              'SALARY': 100.5,
              'CODES': new Uint8Array([1, 2, 3, 4, 5])
            };
            RdbUtils.updateById(1, valueBucket)
              .then((updateNumber) => {
                openDialog('已更新数据:' + updateNumber.toString())
              }).catch((err) => {
              openDialog(err)
            })
          })

        Button('删除数据')
          .onClick(() => {
            RdbUtils.deleteById(1)
              .then((updateNumber) => {
                openDialog('已删除数据:' + updateNumber.toString())
              }).catch((err) => {
              openDialog(err)
            })
          })

4.8、删除数据库

export default class EntryAbility extends UIAbility {
  ...
  onDestroy() {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
    relationalStore.deleteRdbStore(this.context, 'RdbTest.db', (err) => {
      if (err) {
        console.error(`Failed to delete RdbStore. Code:${err.code}, message:${err.message}`);
        return;
      }
      console.info('Succeeded in deleting RdbStore.');
    });
  }
  ....
}

这里我在EntryAbility中的onDestroy生命周期函数中调用了删除数据库的操作,这意味着当我们的Ability被销毁的时候,自动将数据库删除。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/935174.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux 下硬盘挂载c

1. 检查硬盘的文件系统类型 确保你所尝试挂载的硬盘 /dev/vdb 上已经有一个有效的文件系统。你可以用 lsblk -f 令查看硬盘的文件系统类型。 lsblk -f2. 检查挂载命令的语法 硬盘已经格式化为 ext4 sudo mount -t ext4 /dev/vdb /data 确保你在挂载时没有指定错误的文件系统…

1.网络知识-IP与子网掩码的关系及计算实例

IP与子网掩码 说实话&#xff0c;之前没有注意过&#xff0c;今天我打开自己的办公地电脑&#xff0c;看到我的网络配置如下&#xff1a; 我看到我的子网掩码是255.255.254.0&#xff0c;我就奇怪了&#xff0c;我经常见到的子网掩码都是255.255.255.0啊&#xff1f;难道公司配…

learn-(Uni-app)输入框u-search父子组件与input输入框(防抖与搜索触发)

1.父子组件u-search &#xff08;1&#xff09;父组件 <!-- 父组件 --> <template> <div><searchBar change"change" search"search"></searchBar> </div> </template> <script> // 子组件搜索 import…

基于PHP课堂签到系统的设计与实现

摘 要 随着教育业的迅速发展和学生人数的不断增加&#xff0c;导致在班级登记制度中传统的“点到”方式不能适应学校的实际需要。从而需要设计一个好的课堂签到系统将会对课堂签到管理工作带来事半功倍的效果。文章着重介绍了基于实践应用的班级签到系统的开发流程&#xff0c…

Qt Designer,仿作一个ui界面的练习(一):界面的基本布局

初学不要太复杂&#xff0c;先做一个结构简单的&#xff0c;大致规划一下功能分区&#xff0c;绘制草图&#xff1a; 最终的效果&#xff1a; 界面主要由顶边栏、侧边栏、内容区构成。顶边栏左边是logo&#xff0c;右边是时钟显示。侧边栏最上边是切换按钮&#xff0c;用以动画…

NES游戏机项目制作笔记(未完成)

24年12月1日晚记——在网上找项目学习的时候发现一个有意思的项目&#xff0c;准备靠这个应用一些STM32的高级功能。值得提醒的是——目的在于学习不可贪杯&#xff0c;注意效率 01 根据项目需求分析 为确保充分考虑每一个细节&#xff0c;并且让自己高效的完成项目制作&#…

C#开发-集合使用和技巧(十)Union用法-并集

在 C# 中&#xff0c;IEnumerable 的 Union 方法用于返回两个序列的并集。Union 方法会去除重复的元素&#xff0c;确保结果集中每个元素都是唯一的。以下是 Union 方法的基本用法&#xff1a; 基本语法 public static IEnumerable<TSource> Union<TSource>(this…

Unity集成Wwise并进行开发

1. 背景 项目要接入WWise&#xff0c;学习一下 1.1 与Unity自带音频系统的区别 Unity有自己的原生音乐功能&#xff1a;AduioSound。但是这个功能较为简单&#xff0c;对于音效开发人员来说并不是很友好。在一些大型的游戏中&#xff0c;音效会接入Wwise这个软件。音效开发者…

如何绕过IP禁令

网站、游戏和应用程序可以屏蔽特定IP地址&#xff0c;从而阻止使用该IP地址的任何人访问其服务。这称为IP禁令。管理员可以出于多种原因&#xff08;例如发出过多请求或可疑活动&#xff09;屏蔽IP地址。但是&#xff0c;这些禁令会使收集数据或访问在线内容变得更加困难。 一…

Oracle EBS FA 如何打开关闭的资产会计期间?

用户“运行折旧”,误勾选为“关闭期间”,还有一部分资产还需要操作报废和调整,希望后台打开关闭的资产会计期 系统环境 RDBMS : 12.1.0.2.0 Oracle Applications : 12.2.9 解决方案 由官方提供SQL脚本代码如下: /*rollback120.sql - for Release 12.X only(based on r…

分布式 分布式事务 总结

前言 相关系列 《分布式 & 目录》《分布式 & 分布式事务 & 总结》《分布式 & 分布式事务 & 问题》 分布式事务 所谓分布式事务是指操作范围笼罩多个不同节点的事务。例如对于订单节点&库存节点而言&#xff0c;一次完整的交易需要同时调动两个节…

部署GitLab服务器

文章目录 环境准备GitLab部署GitLab服务器GitLab中主要的概念客户端上传代码到gitlab服务器CI-CD概述软件程序上线流程安装Jenkins服务器 配置jenkins软件版本管理配置jenkins访问gitlab远程仓库下载到子目录部署代码到web服务器自动化部署流程 配置共享服务器配置jenkins把git…

kubeadm安装K8s集群之基础环境配置

系列文章目录 1.kubeadm安装K8s集群之基础环境配置 2.kubeadm安装K8s集群之高可用组件keepalivednginx 3.kubeadm安装K8s集群之master节点加入 4.kubeadm安装K8s集群之worker1节点加入 kubeadm安装K8s集群基础环境配置 1.首先确保所有机器可以通信&#xff0c;然后配置主机host…

海康威视摄像头RTSP使用nginx推流到服务器直播教程

思路&#xff1a; 之前2020年在本科的时候&#xff0c;由于项目的需求需要将海康威视的摄像头使用推流服务器到网页进行直播。这里将自己半个月琢磨出来的步骤给大家发一些。切勿转载&#xff01;&#xff01;&#xff01;&#xff01; 使用网络摄像头中的rtsp协议---------通…

GLM-4V-Flash:智谱AI引领多模态视觉模型新潮流

点击访问 chatTools 免费体验GPT最新模型&#xff0c;包括o1推理模型、GPT4o 和Claude等模型&#xff01; 随着人工智能技术的不断进步&#xff0c;多模态模型逐渐成为行业关注的焦点。智谱AI作为国内领先的人工智能公司&#xff0c;再次以创新姿态推出了首款免费多模态视觉模型…

头歌 计算机操作系统 Linux之线程同步二

第1关&#xff1a;信号量 任务描述 在上一个实训中&#xff0c;我们学习了使用互斥锁来实现线程的同步&#xff0c;Linux系统中还提供了另一个类似互斥锁的线程不同操作&#xff0c;那就是信号量。 本关任务&#xff1a;学会使用信号量来实现线程间的同步与互斥。 相关知识 …

WADesk 升级 Webpack5 一些技术细节认识5和4的区别在哪里

背景 升级过程中发现有很多新的知识点&#xff0c;虽然未来可能永远都不会再遇到&#xff0c;但是仍然是一次学习的好机会&#xff0c;可以让自己知道&#xff0c;打包软件的进化之路&#xff0c;和原来 Webpack 4 版本的差异在哪里。 移除的依赖记录 babel/register: 在 Nod…

unity打包web,如何减小文件体积,特别是 Build.wasm.gz

unity打包WebGL&#xff0c;使用的是wasw&#xff0c;最终生成的Build.wasm.gz体积很大&#xff0c;有6.5M&#xff0c;有几个方法可以稍微减小这个文件的大小 1. 裁剪引擎代码&#xff1a; 此步可将大小从6.5减小到 6.2&#xff08;此项默认开启&#xff0c;只是改了裁剪等级…

敏捷开发04:Scrum 中的 Product Backlog(产品待办列表) 详细介绍

Product Backlog 产品待办列表 在计划开发产品功能时&#xff0c;都希望产品功能上线后&#xff0c;用户能够喜欢并经常使用。 因此在开发产品新功能时&#xff0c;就要衡量哪些产品需求是对用户最有价值&#xff0c;这是最应该思考的问题。 然后把这些有价值的需求集合放在一…

C# 探险之旅:第一节 - 我的第一个C# 程序

说明&#xff1a;教程针对初学者入门到精通的整个教程&#xff0c;采用连载的方式&#xff0c;会不定时更新。时间多的话可能会更新多一些。 一、首先&#xff0c;我们需要去微软官方下载vs2022安装程序&#xff0c;然后在自己的计算机中安装完编程的IDE程序。 二、假设我们已…