local-storage

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Isar Database

Isar 数据库

  • Use Isar as the primary local database for structured data persistence
  • Define collections using
    @collection
    annotation with
    Id
    field
  • Place collection definitions in the
    data/local/
    directory of the relevant feature
  • Run
    dart run build_runner build --delete-conflicting-outputs
    after modifying collections
  • 使用 Isar 作为结构化数据持久化的首选本地数据库
  • 使用带有
    Id
    字段的
    @collection
    注解定义集合
  • 将集合定义放在对应功能模块的
    data/local/
    目录下
  • 修改集合后执行
    dart run build_runner build --delete-conflicting-outputs
    命令

Schema Design

模式设计

  • Keep collections focused — one collection per domain entity
  • Use
    @Index
    annotations for fields queried frequently
  • Use
    @enumerated
    for enum fields
  • Use
    Links
    and
    Backlinks
    for relationships between collections
  • NEVER store derived/computed values — compute them in the domain layer
  • 保持集合职责单一:每个领域实体对应一个集合
  • 对高频查询的字段使用
    @Index
    注解
  • 枚举字段使用
    @enumerated
    注解
  • 集合之间的关联关系使用
    Links
    Backlinks
    定义
  • 绝对不要存储派生/计算值:在领域层完成相关计算

Migrations

数据迁移

  • Isar handles additive schema changes automatically (new fields, new collections)
  • For breaking changes (renamed fields, removed fields), write migration logic in the repository
  • Version your database schema and check version on app startup
  • Isar 会自动处理增量式的 schema 变更(新增字段、新增集合)
  • 对于破坏性变更(重命名字段、删除字段),需要在仓库层编写迁移逻辑
  • 为数据库 schema 添加版本控制,在应用启动时检查版本

Repository Pattern for Local Data

本地数据的仓库模式

  • Local DataSource wraps all Isar
    put
    ,
    get
    ,
    delete
    ,
    watch
    calls
  • Repositories orchestrate between remote and local DataSources
  • Repositories decide cache-first vs network-first strategy per use case
  • 本地数据源封装所有 Isar 的
    put
    get
    delete
    watch
    调用
  • 仓库层负责协调远程数据源和本地数据源
  • 仓库层根据不同使用场景决定采用缓存优先还是网络优先策略

Offline-First Patterns

离线优先模式

  • Cache-First: Read from Isar first, fetch from network in background, update Isar on success
  • Network-First: Fetch from network, fall back to Isar on failure
  • Write-Behind: Write to Isar immediately, sync to server asynchronously (queue pending changes)
  • Always show cached data immediately while refreshing in background
  • 缓存优先:优先从 Isar 读取数据,后台发起网络请求,请求成功后更新 Isar
  • 网络优先:优先发起网络请求,请求失败时回退到从 Isar 读取数据
  • 写后置:立即写入 Isar,异步同步到服务端(队列存储待变更内容)
  • 后台刷新数据时始终优先立即展示已缓存的数据

Reactive Queries

响应式查询

  • Use Isar's
    watchLazy()
    or
    watch()
    to stream changes to the UI via BLoC
  • Wrap Isar watch streams in the repository and expose as
    Stream<List<DomainModel>>
  • Dispose stream subscriptions properly in BLoC
    close()
    method
  • 使用 Isar 的
    watchLazy()
    watch()
    方法,通过 BLoC 向 UI 流式推送变更
  • 在仓库层封装 Isar 监听流,对外暴露为
    Stream<List<DomainModel>>
    类型
  • 在 BLoC 的
    close()
    方法中正确释放流订阅

Secure Storage

安全存储

  • Use
    flutter_secure_storage
    for sensitive key-value data (tokens, encryption keys)
  • Use
    SharedPreferences
    ONLY for non-sensitive user preferences (theme, locale, onboarding flags)
  • NEVER store passwords, tokens, or secrets in
    SharedPreferences
    or plain Isar
  • 敏感的键值对数据(令牌、加密密钥)使用
    flutter_secure_storage
    存储
  • 仅在存储非敏感用户偏好(主题、语言、新手引导标记)时使用
    SharedPreferences
  • 绝对不要在
    SharedPreferences
    或未加密的 Isar 中存储密码、令牌或密钥