一、键值型数据库(KVManger)
键值型数据库存储键值对形式的数据,当需要存储的数据没有复杂的关系模型,比如存储商品名称及对应价格、员工工号及今日是否已出勤等,由于数据复杂度低,更容易兼容不同数据库版本和设备类型,因此推荐使用键值型数据库持久化此类数据。
二、需求描述
目前我在开发个人博客的项目中包含一个搜索功能,当用户通过搜索功能搜索文章数据时,将本次搜索的关键词保存到搜索历史中。当输入框获取焦点时,显示之前的搜索历史,并有删除指定搜索历史和清空搜索历史的操作。
实现效果如下图所示:
三、实现步骤
-
创建ets文件,并创建SearchHistory组件,创建需要用到的State。
theme:上级组件提供的主题色数据,用于统一页面颜色(与本功能无关)
items:历史搜索数据集,用于存放搜索到的数据
isError:加载搜索历史数据是否出现错误
value:搜索的关键字,由父组件提供,监听该值修改后将关键字添加到数据集中保存
initValue:父组件输入框中默认文字,当点击某个搜索历史后,修改initValue再通过父组件监听后修改输入框的数据
struct SearchHistory { // 主题色 @Consume private theme: Theme // 搜索历史数据集 @State private items: Array<string> = [] // 搜索是否出错 @State private isError: boolean = false // 搜索关键字 @Prop @Watch("onValueChange") value: string // 搜索默认值 @Link initValue: string private kvStore: distributedKVStore.SingleKVStore build() { Column() { // ... } } }
-
在EntryAblity中创建KVManger然后再获取SingleKVStore并在globalThis上保存kvStore
import UIAbility from '@ohos.app.ability.UIAbility'; import hilog from '@ohos.hilog'; import window from '@ohos.window'; import distributedKVStore from '@ohos.data.distributedKVStore'; let kvStoreOptions = { createIfMissing: true, // 当数据库文件不存在时是否创建数据库,默认创建 encrypt: false, // 设置数据库文件是否加密,默认不加密 backup: false, // 设置数据库文件是否备份,默认备份 kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION, // 设置要创建的数据库类型,默认为多设备协同数据库 securityLevel: distributedKVStore.SecurityLevel.S2 // 设置数据库安全级别 } export default class EntryAbility extends UIAbility { onCreate(want, launchParam) { let kvManger = distributedKVStore.createKVManager({ bundleName: "com.example.harmonytengblog", context: this.context }) kvManger.getKVStore("history", kvStoreOptions, async (err, kvStore: distributedKVStore.SingleKVStore) => { if (err) { console.info(err.code.toString()) globalThis.kvStore = null return } globalThis.kvStore = kvStore }) } onWindowStageCreate(windowStage: window.WindowStage) { // Main window is created, set main page for this ability hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); windowStage.loadContent('pages/Index', (err, data) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); }); } onWindowStageDestroy() { // Main window is destroyed, release UI related resources hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); } onForeground() { // Ability has brought to foreground hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); } onBackground() { // Ability has back to background hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); } }
-
对kvStore进行封装,实现对搜索历史数据进行增加、删除、清空等。实现思路是将文章搜索数据集转换为JSON格式的字符串保存到kvStore键为history中,当进行add/delete/reset操作时,将当前数据集转为JSON后重新保存到kvStore。以下代码是写在SearchHistory组件中
// 从首选项获取搜索历史数据 private getHistory() { try { this.kvStore.get("history", (err, val) => { try { let items = JSON.parse((err ? "[]" : val).toString()) this.items.splice(0, this.items.length, ...items) } catch (e) { console.info("error------------------") console.info(e) this.isError = true } }) } catch (e) { this.isError = true } } // 将数据添加到首选项 private setHistory() { let itemJson = JSON.stringify(this.items) this.kvStore.put("history", itemJson) } private deleteHistoryKVManger(index: number) { this.items.splice(index, 1) this.setHistory() } private clearHistory() { this.items.splice(0, this.items.length) this.setHistory() } private initHistory() { try { this.kvStore = globalThis.kvStore this.getHistory() } catch(e) { this.isError = true } }
-
编写UI代码。并根据当前State状态来进行渲染
-
在父组件的build中渲染该组件,并绑定需要的数据
四、效果展示
基于Harmony个人博客搜索历史效果展示
五、总结
今天我在项目中通过运用键值数据库,对搜索历史的数据进行本地存储。其中包含了一些Api的基本使用,以及对它们进行简单的封装以实现项目中的功能。在实际开发中可以利用这些Api来实现具体的功能