数据持久化简述
非关系型数据库-对Key-Value结构的数据进行存取和持久化操作
轻量级数据存储功能通常用于保存应用的一些常用配置信息,并不适合需要存储大量数据和频繁改变数据的场景。应用的数据保存在文件中,这些文件可以持久化地存储在设备上。需要注意的是,应用访问的实例包含文件所有数据,这些数据会一直加载在设备的内存中,直到应用主动从内存中将其移除前,应用可以通过Preferences的API进行数据操作
常用接口介绍
- 保存数据(put)
- 获取数据(get)
- 是否包含指定的key(has)
- 删除数据(delete)
- 数据持久化(flush)
基本使用与封装
Preferences提供了获取实例、读、取、删对应操作的方法:
- getPreferences(context,name):获取Preferences实例,name是存储的文件名;
- get(k):通过key获取value值;
- getAll():获取文件所有的值;
- put(k,v):添加值,同一个key会将之前的值覆盖掉,需要通过flush()刷新到文件中;
- delete(k):通过key删除对应的value值;
- clear():删除所有的存储值。
注意:以上方法都是异步的。
下面对preferences
进行封装,基本思路:
在获取preferences
实例后会将其保存单例中,这个单例是GlobalContext
,方便后期可以通过单例直接获取实例;由于get()
返回值类型是不确定性,定义一个联合类型的别名ValueType
来接收
import dataPreferences from '@ohos.data.preferences'
import GlobalContext from '../../common/GlobalContext'
import { LogUtils } from '../LogUtils'
const LOG = 'PreferencesUtils-PUT'
// 默认文件名(数据库表名),可以在构造函数进行修改
const PREFERENCES_NAME = 'scjgPreferences'
const KEY_PREFERENCES = 'preferences'
type ValueType = number | string | boolean | Array<number> | Array<string> | Array<boolean>
class PreferencesUtils {
// preferences的文件名-数据库表名
private preferencesName: string = PREFERENCES_NAME
// 用于获取preferences实例的key值,保存到单例中
private keyPreferences: string = KEY_PREFERENCES
constructor(name: string = PREFERENCES_NAME, key: string = KEY_PREFERENCES) {
this.preferencesName = name
this.keyPreferences = key
}
/**
* 创建首选项实例
* @param context: 应用上下文
* @param preferencesName: 数据库表名
* @returns
*/
createPreferences(context): Promise<dataPreferences.Preferences> {
let preferences = dataPreferences.getPreferences(context, this.preferencesName)
GlobalContext.getContext().setObject(this.keyPreferences, preferences)
return
}
/**
* 获取首选项实例
* @returns
*/
getPreferences(): Promise<dataPreferences.Preferences> {
return GlobalContext.getContext().getObject(this.keyPreferences) as Promise<dataPreferences.Preferences>
}
/**
* 获取数据
* @param key: 读取key值
* @param def: 函数出参
* @returns
*/
async get(key: string, def?: ValueType): Promise<ValueType> {
return (await this.getPreferences()).get(key, def)
}
// 获取全部数据
async getAll(): Promise<Object> {
let preferences = await this.getPreferences()
return preferences.getAll()
}
/**
* 插入数据
* @param key: 存入key值
* @param value: 存储数据
* @returns
*/
async put(key: string, value: ValueType): Promise<void> {
let promise = await this.getPreferences().then(async preferences => {
// 插入数据
await preferences.put(key, value)
// 写入文件
await preferences.flush()
}).catch(error => {
LogUtils.error(LOG, `code:${error.code}, message:${error.message}`)
})
return promise
}
/**
* 删除数据
* @param key: 删除key的value值
* @returns
*/
async delete(key: string): Promise<void> {
return (await this.getPreferences()).delete(key).finally(async () => {
(await this.getPreferences()).flush()
})
}
// 清空数据
async clear(): Promise<void> {
return (await this.getPreferences()).clear().finally(async () => {
(await this.getPreferences()).flush()
})
}
}
export default new PreferencesUtils()
在EntryAbility中onCreate()
方法初始化:
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
PreferencesUtils.createPreferences(this.context)
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate')
}
}
GlobalContext
export default class GlobalContext {
private constructor() {}
private static instance: GlobalContext
private _objects = new Map<string, Object>()
public static getContext(): GlobalContext {
if (!GlobalContext.instance) {
GlobalContext.instance = new GlobalContext()
}
return GlobalContext.instance
}
getObject(value: string): Object | undefined {
return this._objects.get(value)
}
setObject(key: string, objectClass: Object): void {
this._objects.set(key, objectClass)
}
}
测试用例
图一:getAll 图二:put
注意:插入数据key相同时,会自动修改替换value值
代码示例
import PreferencesUtils from '../../utils/storage/Preference'
@Entry
@Component
struct Index {
@State text: string = ''
aboutToAppear() {
PreferencesUtils.put('userName', '张三')
PreferencesUtils.put('age', '24')
PreferencesUtils.put('sex', '男')
}
async getAll() {
this.text = JSON.stringify(await PreferencesUtils.getAll() as Object)
console.log('getAll', this.text)
}
build() {
Column() {
Text(this.text)
.width('100%')
.height(60)
Row() {
Button('get')
.onClick(async () => {
this.text = await PreferencesUtils.get('userName') as string
})
Button('getAll')
.onClick(async () => {
this.getAll()
})
Button('put')
.onClick(async () => {
await PreferencesUtils.put('userName', '李四')
await PreferencesUtils.put('age', 25)
await PreferencesUtils.put('sex', '女')
this.getAll()
})
Button('delete')
.onClick(async () => {
await PreferencesUtils.delete('sex')
this.getAll()
})
Button('clear')
.onClick(async () => {
await PreferencesUtils.clear()
this.getAll()
})
}
.width('100%')
.justifyContent(FlexAlign.Center)
}.margin({ top: 50 })
}
}
参考
- https://developer.huawei.com/consumer/cn/training/course/slightMooc/C101667367018821971?ha_linker=eyJ0cyI6MTcwMjM5NzEzNzM3MywiaWQiOiI4MmM3ZTI1MmFmMDJlMDZiODBmOGU1ZDM5ZTI5YmMyOCJ9