鸿蒙——数据长期化存储(AppStorage、PersitentStoreage、数据库、首选项 ...

打印 上一主题 下一主题

主题 991|帖子 991|积分 2973

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Localstorage-内存化存储- 局部可用
AppStorage-内存化存储- 全局可用
PersitentStoreage-写入磁盘(沙箱) 全局可用
首选项-写入磁盘-全局可用
关系型数据库-写入磁盘
1.用户首选项:

获取Preferences实例、生存/更新数据、获取数据

用户首选项为应用提供Key-Value键值型的数据处置处罚本领,支持应用长期化轻量级数据,并对其修改和查询
Key-Value 是什么结构?AppStorage.setOrCreate(key,value)
作用:当用户盼望有一个全局唯一存储数据的地方,可以采用用户首选项来进行存储。
应用首选项的长期化文件生存在应用沙箱内部,可以通过context获取其路径。
首选项适用于存储小型设置项数据,例如应用的用户个性化设置(字体巨细、是否开启夜间模式等)。
限制束缚:


  • Key键为string类型,要求非空且长度不凌驾80个字节。
  • 如果Value值为string类型,请使用UTF-8编码格式,不为空时长度不凌驾8192个字节。
  • 存储的数据量应该是轻量级的,发起存储的数据不凌驾一万条,否则会在内存方面产生较大的开销。
步调:

  • 初始化首选项实例
  1. import { preferences } from '@kit.ArkData';  // 导入首选项api
  2. const KEY = 'searchStore' // 获得首选项实例
  3. const preferencesInstance = preferences.getPreferencesSync(getContext(), { name: KEY })
复制代码
2.向首选项写入数据put 并长期化flush
  1. // 第一个参数KEY:要写入数据的key
  2. // 第二个参数value:要写入的数据
  3. preferencesInstance.put(KEY, 要保存的值)
  4. // 将数据写入到文件中
  5. preferencesInstance.flush()
复制代码
3.获取首选项数据 get
  1. // 利用首选项实例的get方法可以读取KEY中的数据
  2. // 第一个参数KEY:要获取数据的key
  3. // 第二个参数defValue:如果没有读取到数据,则返回默认数据
  4. preferencesInstance.get(KEY, 默认值)
复制代码

  • 删除指定KEY的数据 deleteSync
  1. preferencesInstance.deleteSync(KEY);
复制代码
查看数据文件:




 

2.AppStorage-页面内使用:

用法:


  • 初始化: AppStorage.SetOrCreate(key,value)
  • 单向 @StorageProp('user') 组件内可变
  • 双向 @StorageLink('user') 全局均可变
  1. // 需要通过 key 来指定对应的数据
  2. // 获取数据:
  3. // AppStorage.get<ValueType>(key)
  4. // 覆盖数据
  5. // AppStorage.set<ValueType>(key , value)
复制代码
  1. class User {
  2.   name: string = ''
  3.   age: number = 0
  4. }
  5. AppStorage.setOrCreate <User> ('user',  { name: 'jack', age: 18 } )
复制代码

3.PersistentStorage

LocalStorage和AppStorage都是运行时的内存,在应用退出后就没有了,如果要在应用退出后再次启动依然能生存选定的结果,这就必要用到PersistentStorage。
用法:
        PersistentStorage.PersistProp('属性名', 值)
        后续直接通过 AppStorage 的 Api 来获取并修改即可,AppStorage 的修改会自动同步到PersistentStorage中
3.1 生存基本类型:

        number, string, boolean, enum 等简单类型都支持

  • 初始化PersistentStorage
  • 通过 AppStorage 获取并修改数据
  1. PersistentStorage.persistProp<string>('info','你好啊!!')
  2. @Entry
  3. @Component
  4. struct PersistentStoragePage01 {
  5.   @StorageLink('info')
  6.   info:string=''
  7.   build() {
  8.     Row() {
  9.       Column() {
  10.         Text(this.info)
  11.           .fontSize(50)
  12.           .fontWeight(FontWeight.Bold)
  13.           .onClick(()=>{
  14.             this.info+='!'
  15.           })
  16.       }
  17.       .width('100%')
  18.     }
  19.     .height('100%')
  20.   }
  21. }
复制代码
3.2 生存复杂类型:

支持的复杂类型:


  • 可以被JSON.stringify( )和JSON.parse(  )重构的对象。例如Date, Map, Set等内置类型则不支持,以及对象的属性方法不支持长期化。
  • 自己定义的 class、interface 基本都是支持的
不答应的类型和值有:


  • 不支持嵌套对象(对象数组,对象的属性是对象等)。由于目前框架无法检测AppStorage中嵌套对象(包括数组)值的变化,以是无法写回到PersistentStorage中。
  • 不支持 undefined 和 null
        长期化变量最好是小于2kb的数据,如果开发者必要存储大量的数据,发起使用数据库api
  1. interface FoodInfo{
  2.   name:string
  3.   price:number
  4. }
  5. PersistentStorage.persistProp<FoodInfo[]>('foods',[
  6.   {name:'芒果',price:10},
  7.   {name:'草莓',price:15},
  8.   {name:'樱桃',price:14},
  9. ])
  10. @Entry
  11. @Component
  12. struct PersistentStoragePage02 {
  13.   @StorageLink('foods')
  14.   foods:FoodInfo[]=[]
  15.   build() {
  16.     Row() {
  17.       Column() {
  18.         Text(JSON.stringify(this.foods))
  19.           .fontSize(20)
  20.           .fontWeight(FontWeight.Bold)
  21.           .onClick(()=>{
  22.             // this.foods[0].name='西瓜'
  23.             this.foods[0] = {
  24.               name:'西瓜',
  25.               price:29
  26.             }
  27.           })
  28.       }
  29.       .width('100%')
  30.     }
  31.     .height('100%')
  32.   }
  33. }
复制代码
总结:LocalStorage & AppStorage & PersistentStorage区别?

        1.localStorage是页面级数据存储,在页面中创建实例,组件中使用@LocalStorageLink和@LocalStorageProp装饰器修饰对应的状态变量,绑定对应的组件使用比状态属性更灵活。
        appStorage是历程级数据存储,历程启动时自动创建了唯一实例,在各个页面组件中@StorageProp和@StorageLink装饰器修饰对应的状态变量
        localStorage和appStorage数据存取都是在主线程进行的,且api只提供了同步接口,存取数据时要注意数据的巨细
        2.LocalStorage、AppStorage和PersistentStorage是用于应用状态管理的不同机制,它们的区别如下:


  • LocalStorage:是页面级的 UI 状态存储。可以在页面内或 UIAbility 实例内共享状态,通常用于在页面间传递数据。它是内存中的非长期化存储,应用程序决定其生命周期,当没有引用时会被垃圾回收。
  • AppStorage由 UI 框架在应用程序启动时创建,为应用程序 UI 状态属性提供中心存储。它可以在应用程序的不同页面和组件之间共享数据。
  • PersistentStorage用于长期化存储 UI 状态。它通常与AppStorage共同使用,将AppStorage中选择的数据写入磁盘,以确保这些属性在应用程序重新启动时的值与应用程序关闭时的值相同。
        总的来说,LocalStorage和AppStorage重要用于在应用程序运行时存储和共享 UI 状态,而PersistentStorage则用于将特定的 UI 状态长期化到磁盘中,以便在应用程序重新启动后规复。

4.LocalStorage -页面内使用:

用法:


  • 创建 LocalStorage 实例:




    • const storage = new LocalStorage({ key: value })
    • 设置给@Entry的参数:@Entry(storage)



  • 单向 @LocalStorageProp('user') 雷同于@Prop,
  • 双向 @LocalStorageLink('user') 雷同于@Link,全局均可变
5.数据库存储:

   
        5.2应用数据长期化:

        是指应用将 内存中的数据通过文件或数据库的形式生存到装备上。
        内存中的数据形态通常是任意的数据结构或数据对象,存储介质上的数据形态大概是文本、数据库、二进制文件等。
        HarmonyOS标准系统支持典型的存储数据形态,包括用户首选项、键值型数据库、关系型数据库。

●用户首选项(Preferences):
        通常用于生存应用的设置信息。数据通过文本的形式生存在装备中,应用使用过程中会将文本中的数据全量加载到内存中,以是访问速度快、效率高,但不得当必要存储大量数据的场景。
●键值型数据库(KV-Store):
        一种非关系型数据库,其数据以“键值”对的形式进行构造、索引和存储,此中“键”作为唯一标识符。得当很少数据关系和业务关系的业务数据存储,同时因其在分布式场景中降低了办理数据库版本兼容问题的复杂度,和数据同步过程中冲突办理的复杂度而被广泛使用。相比于关系型数据库,更轻易做到跨装备跨版本兼容。
●关系型数据库(RelationalStore):
        一种关系型数据库,以行和列的形式存储数据,广泛用于应用中的关系型数据的处置处罚,包括一系列的增、删、改、查等接口,开发者也可以运行自己定义的SQL语句来满意复杂业务场景的必要。
        5.3关系型数据库RDB:

        是一种基于关系模型来管理数据的数据库。关系型数据库基于SQLite组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满意复杂的场景必要。不支持Worker线程。

        ArkTS侧支持的基本数据类型:number、string、二进制类型数据、boolean。为包管插入并读取数据成功,发起一条数据不要凌驾2M。超出该巨细,插入成功,读取失败。
        该模块提供以下关系型数据库相关的常勤奋能:


  • RdbPredicates: 数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项重要用来定义数据库的操纵条件。
  • RdbStore:提供管理关系数据库(RDB)方法的接口
  • ResultSet:提供用户调用关系型数据库查询接口之后返回的结果聚集
        5.4隐私条记数据库操纵封装:

  1. import { relationalStore, ValuesBucket } from '@kit.ArkData'
  2. // 隐私笔记的类型
  3. export interface PrivacyNoteDBInfo extends ValuesBucket {
  4.   id: number | null
  5.   title: string
  6.   content: string
  7.   date_added: number
  8. }
  9. class PrivacyNoteDB {
  10.   tableName = 'PRIVACY_NOTE'
  11.   // // 创建数据库的语句
  12.   sqlCreate = `CREATE TABLE IF NOT EXISTS ${this.tableName} (
  13.         id INTEGER PRIMARY KEY AUTOINCREMENT,
  14.         title TEXT NOT NULL,
  15.         content TEXT NOT NULL,
  16.         date_added INTEGER NOT NULL
  17.       )`
  18.   // 操作数据库的实例
  19.   store: relationalStore.RdbStore | null = null
  20.   // 获取管理数据库的对象
  21.   async getStoreInstance() {
  22.     if (this.store) {
  23.       // 如果 store 已经存在,直接返回使用
  24.       return this.store
  25.     }
  26.     // 获取管理数据库的对象
  27.     const store = await relationalStore.getRdbStore(getContext(), {
  28.       name: this.tableName + '.db',
  29.       securityLevel: relationalStore.SecurityLevel.S1
  30.     })
  31.     // store 保存起来,方便下次直接获取
  32.     this.store = store
  33.     store.executeSql(this.sqlCreate) // 创建数据库的表
  34.     return store
  35.   }
  36.   // 新增数据
  37.   async insert(item: PrivacyNoteDBInfo) {
  38.     const store = await this.getStoreInstance()
  39.     const rowId = await store.insert(this.tableName, item) //新增成功后返回 id
  40.     // Promise.resolve 表示成功
  41.     // Promise.reject  表示失败,失败可通过 try catch 捕获错误信息
  42.     return rowId > 0 ? Promise.resolve(rowId) : Promise.reject('insert error')
  43.   }
  44.   // 查询总数
  45.   async queryCount() {
  46.     const store = await this.getStoreInstance() // 获取管理数据库的对象
  47.     const predicates = new relationalStore.RdbPredicates(this.tableName) // 谓词(条件)
  48.     const resultSet = await store.query(predicates) // 查询,返回结果集
  49.     // 补充:新创建的数据库可能会返回 -1,通过三元表达式修正错误
  50.     return resultSet.rowCount > 0 ? resultSet.rowCount : 0
  51.   }
  52.   // 查询数据:
  53.   // 1. 不传入 id 查询所有数据  2. 传入 id 查询一条数据
  54.   // 3. 查询结果根据 id 倒序排列:orderByDesc 倒序(大到小),orderBy 正序(小到大)
  55.   async query(id?: number) {
  56.     const store = await this.getStoreInstance() // 获取管理数据库的对象
  57.     const predicates = new relationalStore.RdbPredicates(this.tableName) // 谓词(条件)
  58.     // 如果有id,增加id条件
  59.     if (id) {
  60.       predicates.equalTo('id', id)
  61.     }
  62.     predicates.orderByDesc('id') // 倒序(大到小)
  63.     const resultSet = await store.query(predicates) // 查询,返回结果集
  64.     // --准备数组,用于存储查询结果
  65.     const list: PrivacyNoteDBInfo[] = []
  66.     // 循环结果集
  67.     while (resultSet.goToNextRow()) {
  68.       list.push({
  69.         // 提取数据
  70.         id: resultSet.getLong(resultSet.getColumnIndex('id')),
  71.         title: resultSet.getString(resultSet.getColumnIndex('title')),
  72.         content: resultSet.getString(resultSet.getColumnIndex('content')),
  73.         date_added: resultSet.getLong(resultSet.getColumnIndex('date_added')),
  74.       })
  75.     }
  76.     // 释放结果集内存空间(性能优化)
  77.     resultSet.close()
  78.     return list // 循环结束后,返回结果
  79.   }
  80.   // 根据 id 删除数据
  81.   async delete(id: number) {
  82.     const store = await this.getStoreInstance()
  83.     const predicates = new relationalStore.RdbPredicates(this.tableName)
  84.     // 根据id查找
  85.     predicates.equalTo('id', id)
  86.     // 删除完成,返回受影响的行数
  87.     const rowCount = await store.delete(predicates)
  88.     return rowCount ? Promise.resolve() : Promise.reject('delete error')
  89.   }
  90.   // 根据id更新数据
  91.   async update(item: PrivacyNoteDBInfo) {
  92.     // 如果没有 id 直接退出
  93.     if (!item.id) {
  94.       return Promise.reject('id is null')
  95.     }
  96.     const store = await this.getStoreInstance()
  97.     const predicates = new relationalStore.RdbPredicates(this.tableName)
  98.     // 根据id更新数据
  99.     predicates.equalTo('id', item.id)
  100.     // 更新完成,返回受影响的行数
  101.     const rowCount = await store.update(item, predicates)
  102.     return rowCount ? Promise.resolve(rowCount) : Promise.reject('update error')
  103.   }
  104. }
  105. // 导出操作隐私笔记数据库的类
  106. export const privacyNoteDB = new PrivacyNoteDB()
复制代码
6.AppStorage、PersitentStoreage、数据库、首选项区别?

6.1AppStorage:



  • AppStorage 是鸿蒙操纵系统中用于存储应用全局 UI 状态的机制。它是与应用的历程绑定的,由 UI 框架在应用程序启动时创建,为应用程序 UI 状态属性提供中心存储。
  • AppStorage 是在应用启动时会被创建的单例,目标是为了提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。AppStorage 将在应用运行过程保留其属性,属性通过唯一的键字符串值访问。
6.2PersistentStorage:



  • PersistentStorage 是鸿蒙操纵系统中用于长期化存储选定的 AppStorage 属性的机制。
  • 它的作用是确保这些属性在应用程序重新启动时的值与应用程序关闭时的值相同。PersistentStorage 答应的类型和值有限,例如 number, string, boolean, enum 等简单类型,以及可以被 JSON.stringify() 和 JSON.parse() 重构的对象。
  • 必要注意的是,PersistentStorage 的长期化变量最好是小于2kb的数据,由于其写入磁盘的操纵是同步的,大量的数据本地化读写会同步在 UI 线程中执行,大概会影响 UI 渲染性能。如果开发者必要存储大量数据,发起使用数据库 API。
6.3数据库:



  • 鸿蒙操纵系统支持使用数据库来存储和管理数据。
  • 数据库是一种结构化的数据存储办理方案,采用表格的形式存储数据,支持复杂的查询和关联操纵。
  • 数据库适用于存储大量数据,并且必要进行复杂查询或多表关联的场景。它提供了变乱、索引、束缚等功能,用于包管数据的完整性和一致性。
6.4首选项:



  • 首选项(Preferences)是鸿蒙系统提供的一种轻量级的本地存储办理方案,
  • 适用于存储少量的简单数据。
  • 它以键值对的形式存储数据,支持基本的增删改查操纵。
区别总结:



  • AppStorage 是应用全局的 UI 状态存储,与应用历程绑定,得当存储应用级别的状态数据。
  • PersistentStorage 用于长期化存储选定的 AppStorage 属性,确保数据在应用重启后保持不变,得当存储小量数据。
  • 数据库 是结构化的数据存储办理方案,适用于存储大量数据和进行复杂查询,得当必要数据完整性和一致性保障的场景。
  • 首选项 是轻量级的本地存储办理方案,适用于存储少量简单数据,得当作为应用设置数据的存储方式。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

九天猎人

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表