一、數據持久化介紹
數據持久化是將內存數據(內存是臨時的存儲空間),通過文件或數據庫的形式保存在設備中。
HarmonyOS提供兩種數據持久化方案:
1.1、用戶首選項(Preferences):
通常用于保存應用的配置信息。數據通過文本的形式保存在設備中,應用使用過程中會將文本中的數據全量加載到內存中,所以訪問速度快、效率高,但不適合需要存儲大量數據的場景。
1.2、數據庫:
鍵值型數據庫(KV-Store):一種非關系型數據庫,其數據以“鍵值”對的形式進行組織、索引和存儲,其中“鍵”作為唯一標識符。適合很少數據關系和業務關系的業務數據存儲,同時因其在分布式場景中降低了解決數據庫版本兼容問題的復雜度,和數據同步過程中沖突解決的復雜度而被廣泛使用。相比于關系型數據庫,更容易做到跨設備跨版本兼容。
關系型數據庫(RelationalStore):一種關系型數據庫,以行和列的形式存儲數據,廣泛用于應用中的關系型數據的處理,包括一系列的增、刪、改、查等接口,開發者也可以運行自己定義的SQL語句來滿足復雜業務場景的需要。
二、通過用戶首選項實現數據持久化
使用場景:用戶首選項為應用提供Key-Value鍵值型的數據處理能力,支持應用持久化輕量級數據,并對其修改和查詢。
說明:
①Key鍵為string類型,要求非空且長度不超過80個字節。
②Value可以是string、number、boolean及以上類型數組,大小不超過8192字節
③數據量建議不超過一萬條
2.1、基本案例
2.1.1、案例代碼
@Entry
@Component
struct Index {@State message: string = '頁面列表'@State showPanel: boolean = false@Provide fontSize: number = 16build() {Column(){// 頂部標題this.Title()// 導航列表this.RouterList()// 字體修改面板if(this.showPanel){IndexFontSizePanel().transition({translate: { y: 115 }})}}.width('100%').height('100%')}@Builder Title(){Row() {Text(this.message).fontSize(50).fontWeight(FontWeight.Bold).height(80)Image($r('app.media.ic_public_settings')).width(30).onClick(() => {animateTo({ duration: 500, curve: Curve.EaseOut }, () => this.showPanel = !this.showPanel)})}.justifyContent(FlexAlign.SpaceAround).width('100%')}@Builder RouterList() {List({ space: 15 }) {ForEach(['導航','屏幕','圖片','圖書','書架'],(item,index) => {ListItem() {Row(){Text((index+1) + '.').fontSize(this.fontSize).fontColor(Color.White)Blank()Text(item).fontSize(this.fontSize).fontColor(Color.White)}.width('90%').padding(12).backgroundColor('#38f').borderRadius(20).shadow({radius: 6, color: '#4F000000', offsetX: 2, offsetY: 4})}})}.layoutWeight(1).alignListItem(ListItemAlign.Center).width('100%')}
}@Component
struct IndexFontSizePanel {@Consume fontSize: numberfontSizLabel: object = {14: '小',16: '標準',18: '大',20: '特大',}build() {Column() {Text(this.fontSizLabel[this.fontSize]).fontSize(20)Row({ space: 5 }) {Text('A').fontSize(14).fontWeight(FontWeight.Bold)Slider({min: 14,max: 20,step: 2,value: this.fontSize}).showSteps(true).trackThickness(6).layoutWeight(1).onChange(val => {// 修改字體大小this.fontSize = val})Text('A').fontSize(20).fontWeight(FontWeight.Bold)}.width('100%')}.width('100%').padding(15).backgroundColor('#fff1f0f0').borderRadius(20)}
}
2.1.2、案例效果:
案例說明:
這是一個頁面列表展示案例,點擊右上角的設置按鈕,底部會彈出字體修改面板,字體有4個不同的大小(小/標準/大/特大),當點擊滑動條可以修改字體大小
目前更改了滑動條的字體大小數據是保存在內存的,關閉頁面后再進來數據顯示默認大小,現在是想通過用戶首選項實現數據持久化,持久化保存設置的字體大小
2.2、具體實現
2.2.1、定義用戶首選項操作文件
import preferences from '@ohos.data.preferences';class PreferencesUtil{prefMap: Map<string, preferences.Preferences> = new Map()async loadPreference(context, name: string){try { // 加載preferenceslet pref = await preferences.getPreferences(context, name)this.prefMap.set(name, pref)console.log('testTag', `加載Preferences[${name}]成功`)} catch (e) {console.log('testTag', `加載Preferences[${name}]失敗`, JSON.stringify(e))}}async putPreferenceValue(name: string, key: string, value: preferences.ValueType){if (!this.prefMap.has(name)) {console.log('testTag', `Preferences[${name}]尚未初始化!`)return}try {let pref = this.prefMap.get(name)// 寫入數據await pref.put(key, value)// 刷盤await pref.flush()console.log('testTag', `保存Preferences[${name}.${key} = ${value}]成功`)} catch (e) {console.log('testTag', `保存Preferences[${name}.${key} = ${value}]失敗`, JSON.stringify(e))}}async getPreferenceValue(name: string, key: string, defaultValue: preferences.ValueType){if (!this.prefMap.has(name)) {console.log('testTag', `Preferences[${name}]尚未初始化!`)return}try {let pref = this.prefMap.get(name)// 讀數據let value = await pref.get(key, defaultValue)console.log('testTag', `讀取Preferences[${name}.${key} = ${value}]成功`)return value} catch (e) {console.log('testTag', `讀取Preferences[${name}.${key} ]失敗`, JSON.stringify(e))}}
}const preferencesUtil = new PreferencesUtil()export default preferencesUtil as PreferencesUtil
2.2.2、將數據加載到Preferences實例,用于數據操作。
放入應用啟動時來操作,找到EntryAbility文件,在onCreate應用創建時,加載Preferences實例
2.2.3、Index頁面使用
第一步:一進入首頁就進行讀取
使用頁面生命周期aboutToAppear來執行
第二步:修改字體大小時寫入Preferences
最后:👏👏😊😊😊👍👍?