7  第6章 分布式数据管理

HarmonyOS应用开发者高级认证教程

8 第6章 分布式数据管理

8.1 学习目标

本章将深入讲解HarmonyOS分布式数据管理的核心技术,涵盖分布式数据对象、数据同步机制、关系型数据库高级用法、键值对分布式存储、首选项与持久化以及数据共享与交换。通过本章学习,读者将能够:

  • 设计分布式数据对象模型并实现跨设备数据同步
  • 掌握不同同步模式的适用场景与数据一致性保证机制
  • 深入使用关系型数据库(RDB)进行复杂查询与性能优化
  • 运用分布式KV存储实现多设备数据自动同步
  • 掌握Preferences的高级用法与数据迁移策略
  • 实现跨应用数据共享与DataShare服务开发

8.2 6.1 分布式数据对象

8.2.1 6.1.1 数据对象模型设计

分布式数据对象(Distributed Data Object)是HarmonyOS提供的跨设备数据共享机制,允许开发者像操作本地对象一样操作分布式数据。

数据对象模型设计原则:

  1. 原子性:每个数据对象应代表一个完整的业务实体
  2. 可序列化:对象属性必须是可序列化的基本类型或嵌套对象
  3. 版本控制:设计时考虑数据结构的向后兼容
  4. 冲突策略:预设属性级别的冲突解决策略
import { distributedObject } from '@kit.ArkData'
import { common } from '@kit.AbilityKit'

// 数据对象模型 - 协同文档
class CollaborativeDocument {
  // 基础属性
  docId: string = ''
  title: string = ''
  content: string = ''
  version: number = 0

  // 元数据
  creatorId: string = ''
  creatorName: string = ''
  createdAt: number = 0
  updatedAt: number = 0

  // 协同信息
  collaborators: string[] = []
  lastModifiedBy: string = ''

  // 状态标记
  isDirty: boolean = false
  syncStatus: 'synced' | 'pending' | 'conflict' = 'synced'
}

// 数据对象管理器
class DistributedObjectManager {
  private session: distributedObject.Session | null = null
  private context: common.UIAbilityContext
  private sessionId: string

  constructor(context: common.UIAbilityContext, sessionId: string) {
    this.context = context
    this.sessionId = sessionId
  }

  // 初始化分布式数据对象会话
  async initialize(): Promise<void> {
    try {
      // 创建分布式数据对象会话
      this.session = distributedObject.create({
        context: this.context,
        sessionId: this.sessionId
      })

      // 初始化数据对象属性
      this.initializeProperties()

      // 注册变更监听
      this.registerChangeListeners()

      // 注册设备状态监听
      this.registerStatusListeners()

      console.info('分布式数据对象会话初始化成功')
    } catch (error) {
      console.error(`初始化失败: ${JSON.stringify(error)}`)
      throw error
    }
  }

  private initializeProperties(): void {
    if (!this.session) return

    // 设置初始属性值
    const doc = new CollaborativeDocument()
    doc.docId = `doc_${Date.now()}`
    doc.title = '新文档'
    doc.content = ''
    doc.version = 1
    doc.createdAt = Date.now()

    this.session['docId'] = doc.docId
    this.session['title'] = doc.title
    this.session['content'] = doc.content
    this.session['version'] = doc.version
    this.session['createdAt'] = doc.createdAt
    this.session['updatedAt'] = doc.createdAt
    this.session['collaborators'] = JSON.stringify([])
    this.session['syncStatus'] = doc.syncStatus
  }

  // 注册属性变更监听
  private registerChangeListeners(): void {
    if (!this.session) return

    this.session.on('change', (
        prop: string,
        value: distributedObject.ObjectValue): void => {
      console.info(`属性变更: ${prop} = ${JSON.stringify(value)}`)

      // 根据属性类型执行不同的处理逻辑
      switch (prop) {
        case 'content':
          this.handleContentChange(value as string)
          break
        case 'title':
          this.handleTitleChange(value as string)
          break
        case 'version':
          this.handleVersionChange(value as number)
          break
        default:
          break
      }
    })
  }

  // 注册设备状态监听
  private registerStatusListeners(): void {
    if (!this.session) return

    this.session.on('status', (
        sessionId: string,
        networkId: string,
        status: number): void => {
      // status: 0=设备加入, 1=设备退出, 2=设备在线
      switch (status) {
        case 0:
          console.info(`设备加入会话: ${networkId}`)
          break
        case 1:
          console.info(`设备离开会话: ${networkId}`)
          break
        case 2:
          console.info(`设备在线: ${networkId}`)
          break
      }
    })
  }

  // 更新文档内容
  updateContent(newContent: string): void {
    if (!this.session) return

    this.session['content'] = newContent
    this.session['updatedAt'] = Date.now()
    this.session['version'] = (this.session['version'] as number) + 1
  }

  // 添加协作者
  addCollaborator(userId: string): void {
    if (!this.session) return

    const collaborators = JSON.parse(
      (this.session['collaborators'] as string) ?? '[]'
    ) as string[]

    if (!collaborators.includes(userId)) {
      collaborators.push(userId)
      this.session['collaborators'] = JSON.stringify(collaborators)
    }
  }

  // 保存会话数据到本地
  async saveLocal(): Promise<void> {
    if (!this.session) return

    return new Promise((resolve, reject) => {
      this.session!.save((error: Error) => {
        if (error) {
          console.error(`保存失败: ${JSON.stringify(error)}`)
          reject(error)
        } else {
          console.info('会话数据已保存到本地')
          resolve()
        }
      })
    })
  }

  // 释放会话
  release(): void {
    if (this.session) {
      this.session.off('change')
      this.session.off('status')
      this.session = null
    }
  }

  private handleContentChange(content: string): void {
    console.info(`文档内容已更新, 长度: ${content.length}`)
  }

  private handleTitleChange(title: string): void {
    console.info(`文档标题已更新: ${title}`)
  }

  private handleVersionChange(version: number): void {
    console.info(`文档版本更新: v${version}`)
  }
}

8.2.2 6.1.2 对象变更通知机制

分布式数据对象的变更通知机制基于观察者模式,支持属性级别的细粒度监听:

// 高级变更通知管理
class ChangeNotificationManager {
  private changeHistory: ChangeRecord[] = []
  private maxHistorySize: number = 100
  private batchTimerId: number = -1
  private pendingChanges: Map<string, Object> = new Map()
  private batchInterval: number = 100 // 批量通知间隔(ms)

  // 注册细粒度属性监听
  registerPropertyWatch(
      session: distributedObject.Session,
      property: string,
      callback: (oldValue: Object, newValue: Object) => void): void {
    let lastValue = session[property]

    session.on('change', (prop: string,
        value: distributedObject.ObjectValue): void => {
      if (prop === property) {
        const oldValue = lastValue
        lastValue = value
        callback(oldValue, value)

        // 记录变更历史
        this.recordChange(property, oldValue, value)
      }
    })
  }

  // 批量变更通知
  registerBatchWatch(
      session: distributedObject.Session,
      properties: string[],
      callback: (changes: Map<string, { old: Object, new: Object }>) => void): void {

    const pendingChanges = new Map<string, { old: Object, new: Object }>()

    session.on('change', (prop: string,
        value: distributedObject.ObjectValue): void => {
      if (properties.includes(prop)) {
        const oldValue = session[prop]
        pendingChanges.set(prop, { old: oldValue, new: value })

        // 清除之前的定时器,重新计时
        if (this.batchTimerId !== -1) {
          clearTimeout(this.batchTimerId)
        }

        // 设置新的批量通知定时器
        this.batchTimerId = setTimeout(() => {
          callback(new Map(pendingChanges))
          pendingChanges.clear()
          this.batchTimerId = -1
        }, this.batchInterval)
      }
    })
  }

  // 记录变更历史
  private recordChange(property: string,
      oldValue: Object, newValue: Object): void {
    const record: ChangeRecord = {
      property,
      oldValue: JSON.stringify(oldValue),
      newValue: JSON.stringify(newValue),
      timestamp: Date.now()
    }

    this.changeHistory.push(record)

    // 限制历史记录大小
    if (this.changeHistory.length > this.maxHistorySize) {
      this.changeHistory.shift()
    }
  }

  // 获取变更历史
  getChangeHistory(property?: string): ChangeRecord[] {
    if (property) {
      return this.changeHistory.filter(r => r.property === property)
    }
    return [...this.changeHistory]
  }

  // 撤销最近的变更
  undo(session: distributedObject.Session): boolean {
    if (this.changeHistory.length === 0) return false

    const lastChange = this.changeHistory.pop()!
    session[lastChange.property] = JSON.parse(lastChange.oldValue)
    return true
  }
}

interface ChangeRecord {
  property: string
  oldValue: string
  newValue: string
  timestamp: number
}

8.2.3 6.1.3 跨设备数据同步策略

// 数据同步策略管理器
class SyncStrategyManager {
  private currentStrategy: SyncStrategy = SyncStrategy.REALTIME
  private conflictResolver: ConflictResolver = new TimestampConflictResolver()

  // 设置同步策略
  setStrategy(strategy: SyncStrategy): void {
    this.currentStrategy = strategy
    console.info(`同步策略已切换为: ${strategy}`)
  }

  // 实时同步模式
  async enableRealtimeSync(session: distributedObject.Session): Promise<void> {
    // 实时同步:属性变更立即同步到所有设备
    session.on('change', (prop: string,
        value: distributedObject.ObjectValue): void => {
      // 实时模式下,变更自动同步
      console.info(`实时同步: ${prop} 已同步`)
    })
  }

  // 定时同步模式
  setupPeriodicSync(session: distributedObject.Session,
      intervalMs: number): number {
    return setInterval(async () => {
      try {
        await session.save()
        console.info('定时同步完成')
      } catch (error) {
        console.error(`定时同步失败: ${JSON.stringify(error)}`)
      }
    }, intervalMs)
  }

  // 手动同步模式
  async manualSync(session: distributedObject.Session): Promise<void> {
    try {
      await session.save()
      console.info('手动同步完成')
    } catch (error) {
      console.error(`手动同步失败: ${JSON.stringify(error)}`)
      throw error
    }
  }

  // 设置冲突解决器
  setConflictResolver(resolver: ConflictResolver): void {
    this.conflictResolver = resolver
  }
}

enum SyncStrategy {
  REALTIME = 'realtime',      // 实时同步
  PERIODIC = 'periodic',      // 定时同步
  MANUAL = 'manual'           // 手动同步
}

// 冲突解决器接口
interface ConflictResolver {
  resolve(localValue: Object, remoteValue: Object,
      property: string): Object
}

// 基于时间戳的冲突解决器
class TimestampConflictResolver implements ConflictResolver {
  resolve(localValue: Object, remoteValue: Object,
      property: string): Object {
    // 简单策略:后写入的覆盖先写入的
    if (property === 'updatedAt') {
      const localTime = localValue as number
      const remoteTime = remoteValue as number
      return localTime > remoteTime ? localValue : remoteValue
    }
    // 默认采用远程值
    return remoteValue
  }
}

// 基于版本的冲突解决器
class VersionConflictResolver implements ConflictResolver {
  resolve(localValue: Object, remoteValue: Object,
      property: string): Object {
    // 版本号大的优先
    if (typeof localValue === 'number' && typeof remoteValue === 'number') {
      return Math.max(localValue, remoteValue)
    }
    return remoteValue
  }
}

8.2.4 6.1.4 冲突检测与解决

// 高级冲突检测与解决系统
class AdvancedConflictDetector {
  private localVersion: number = 0
  private remoteVersion: number = 0
  private lastSyncVersion: number = 0
  private conflictLog: ConflictLogEntry[] = []

  // 检测冲突
  detectConflict(localData: Map<string, Object>,
      remoteData: Map<string, Object>): Conflict[] {
    const conflicts: Conflict[] = []

    // 检查本地修改是否与远程修改冲突
    for (const [key, localValue] of localData) {
      const remoteValue = remoteData.get(key)
      if (remoteValue !== undefined &&
          JSON.stringify(localValue) !== JSON.stringify(remoteValue)) {
        // 双方都修改了同一属性
        conflicts.push({
          property: key,
          localValue: localValue,
          remoteValue: remoteValue,
          type: ConflictType.MODIFY_MODIFY,
          timestamp: Date.now()
        })
      }
    }

    // 检查删除冲突
    for (const [key] of remoteData) {
      if (!localData.has(key) && this.wasModifiedLocally(key)) {
        conflicts.push({
          property: key,
          localValue: undefined,
          remoteValue: remoteData.get(key),
          type: ConflictType.DELETE_MODIFY,
          timestamp: Date.now()
        })
      }
    }

    return conflicts
  }

  // 自动解决冲突
  autoResolve(conflicts: Conflict[],
      strategy: ConflictResolutionStrategy): Map<string, Object> {
    const resolved = new Map<string, Object>()

    for (const conflict of conflicts) {
      let resolvedValue: Object

      switch (strategy) {
        case ConflictResolutionStrategy.LOCAL_WINS:
          resolvedValue = conflict.localValue
          break
        case ConflictResolutionStrategy.REMOTE_WINS:
          resolvedValue = conflict.remoteValue
          break
        case ConflictResolutionStrategy.TIMESTAMP:
          // 基于时间戳选择最新的值
          resolvedValue = conflict.remoteValue
          break
        case ConflictResolutionStrategy.MERGE:
          // 尝试合并(仅适用于特定类型的数据)
          resolvedValue = this.tryMerge(
            conflict.localValue, conflict.remoteValue)
          break
        default:
          resolvedValue = conflict.remoteValue
      }

      resolved.set(conflict.property, resolvedValue)

      // 记录冲突解决日志
      this.conflictLog.push({
        conflict: conflict,
        strategy: strategy,
        resolvedValue: resolvedValue,
        timestamp: Date.now()
      })
    }

    return resolved
  }

  private tryMerge(local: Object, remote: Object): Object {
    // 对于字符串类型,尝试拼接
    if (typeof local === 'string' && typeof remote === 'string') {
      return `${local}\n${remote}`
    }
    // 对于数组类型,尝试合并
    if (Array.isArray(local) && Array.isArray(remote)) {
      return [...new Set([...local, ...remote])]
    }
    // 默认返回远程值
    return remote
  }

  private wasModifiedLocally(key: string): boolean {
    return false
  }
}

interface Conflict {
  property: string
  localValue: Object
  remoteValue: Object
  type: ConflictType
  timestamp: number
}

enum ConflictType {
  MODIFY_MODIFY,   // 双方都修改
  DELETE_MODIFY,   // 一方删除,一方修改
  INSERT_INSERT    // 双方都插入
}

enum ConflictResolutionStrategy {
  LOCAL_WINS,
  REMOTE_WINS,
  TIMESTAMP,
  MERGE
}

interface ConflictLogEntry {
  conflict: Conflict
  strategy: ConflictResolutionStrategy
  resolvedValue: Object
  timestamp: number
}

8.3 6.2 分布式数据同步

8.3.1 6.2.1 同步模式

HarmonyOS提供了三种数据同步模式,开发者需要根据业务场景选择合适的模式:

import { distributedKVStore } from '@kit.ArkData'
import { common } from '@kit.AbilityKit'

// 同步模式管理器
class SyncModeManager {
  private kvStore: distributedKVStore.SingleKVStore | null = null
  private currentMode: SyncMode = SyncMode.MANUAL

  async initialize(context: common.UIAbilityContext): Promise<void> {
    const kvManagerConfig: distributedKVStore.KVManagerConfig = {
      context: context,
      bundleName: 'com.example.distributeddata'
    }
    const kvManager = distributedKVStore.createKVManager(kvManagerConfig)

    const options: distributedKVStore.Options = {
      createIfMissing: true,
      encrypt: false,
      backup: false,
      autoSync: false, // 手动控制同步
      kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,
      securityLevel: distributedKVStore.SecurityLevel.S2
    }

    this.kvStore = await kvManager.getKVStore<distributedKVStore.SingleKVStore>(
      'sync_demo_store', options
    )
  }

  // 设置同步模式
  setSyncMode(mode: SyncMode): void {
    this.currentMode = mode
    console.info(`同步模式切换为: ${mode}`)
  }

  // 实时同步 - 数据变更立即同步
  async enableRealtimeSync(): Promise<void> {
    if (!this.kvStore) return

    // 配置自动同步
    const syncOptions: distributedKVStore.SyncOptions = {
      syncMode: distributedKVStore.SyncMode.PUSH_PULL,
      syncInterval: 0 // 立即同步
    }

    // 注册设备列表变更监听
    this.kvStore.on('syncStatusChange', (
        syncState: distributedKVStore.SyncState): void => {
      console.info(`同步状态变更: ${syncState}`)
    })

    console.info('实时同步已启用')
  }

  // 定时同步 - 按固定间隔同步
  async enablePeriodicSync(intervalMs: number): Promise<number> {
    if (!this.kvStore) return -1

    const timerId = setInterval(async () => {
      try {
        await this.performSync()
        console.info(`定时同步完成, 间隔: ${intervalMs}ms`)
      } catch (error) {
        console.error(`定时同步失败: ${JSON.stringify(error)}`)
      }
    }, intervalMs)

    console.info(`定时同步已启用, 间隔: ${intervalMs}ms`)
    return timerId
  }

  // 手动同步 - 按需触发
  async performSync(): Promise<void> {
    if (!this.kvStore) {
      throw new Error('KV存储未初始化')
    }

    // 获取设备列表
    const deviceIds = this.getConnectedDeviceIds()
    if (deviceIds.length === 0) {
      console.warn('没有可用的同步设备')
      return
    }

    // 执行同步
    return new Promise((resolve, reject) => {
      this.kvStore!.sync(deviceIds, {
        mode: distributedKVStore.SyncMode.PUSH_PULL,
        delay: 0
      }, (err: Error) => {
        if (err) {
          console.error(`同步失败: ${JSON.stringify(err)}`)
          reject(err)
        } else {
          console.info('同步成功')
          resolve()
        }
      })
    })
  }

  private getConnectedDeviceIds(): string[] {
    // 获取已连接的设备ID列表
    return []
  }
}

enum SyncMode {
  REALTIME = 'realtime',
  PERIODIC = 'periodic',
  MANUAL = 'manual'
}

8.3.2 6.2.2 数据一致性保证

// 数据一致性管理器
class DataConsistencyManager {
  private versionMap: Map<string, number> = new Map()
  private pendingOperations: DataOperation[] = []
  private isProcessing: boolean = false

  // 写入数据(带版本号)
  async writeWithVersion(key: string, value: Object,
      expectedVersion: number): Promise<WriteResult> {
    const currentVersion = this.versionMap.get(key) ?? 0

    if (expectedVersion !== currentVersion) {
      // 版本冲突
      return {
        success: false,
        currentVersion: currentVersion,
        message: `版本冲突: 期望 ${expectedVersion}, 实际 ${currentVersion}`
      }
    }

    // 版本号递增
    const newVersion = currentVersion + 1
    this.versionMap.set(key, newVersion)

    // 记录操作日志(用于冲突恢复)
    this.pendingOperations.push({
      type: 'write',
      key: key,
      value: JSON.stringify(value),
      version: newVersion,
      timestamp: Date.now()
    })

    return {
      success: true,
      currentVersion: newVersion,
      message: '写入成功'
    }
  }

  // 乐观锁机制
  async optimisticUpdate(key: string,
      updateFn: (currentValue: Object) => Object): Promise<boolean> {
    let retries = 0
    const maxRetries = 3

    while (retries < maxRetries) {
      const currentVersion = this.versionMap.get(key) ?? 0
      const currentValue = this.readValue(key)
      const newValue = updateFn(currentValue)

      const result = await this.writeWithVersion(key, newValue, currentVersion)
      if (result.success) {
        return true
      }

      retries++
      console.warn(`乐观锁冲突, 重试 ${retries}/${maxRetries}`)
    }

    return false
  }

  private readValue(key: string): Object {
    return {}
  }
}

interface WriteResult {
  success: boolean
  currentVersion: number
  message: string
}

interface DataOperation {
  type: 'write' | 'delete' | 'update'
  key: string
  value?: string
  version: number
  timestamp: number
}

8.3.3 6.2.3 离线数据处理

// 离线数据处理器
class OfflineDataHandler {
  private offlineQueue: OfflineOperation[] = []
  private isOnline: boolean = true
  private maxQueueSize: number = 1000
  private storageKey: string = 'offline_queue'

  // 网络状态感知
  setOnlineStatus(online: boolean): void {
    const wasOffline = !this.isOnline
    this.isOnline = online

    if (online && wasOffline) {
      // 从离线恢复为在线,处理积压的操作
      this.processOfflineQueue()
    }
  }

  // 离线时缓存操作
  async enqueueOperation(operation: OfflineOperation): Promise<void> {
    if (this.offlineQueue.length >= this.maxQueueSize) {
      // 队列已满,执行淘汰策略
      this.evictOldestOperations()
    }

    operation.timestamp = Date.now()
    operation.retryCount = 0
    this.offlineQueue.push(operation)

    // 持久化到本地存储
    await this.persistQueue()
    console.info(`操作已入队: ${operation.type} on ${operation.key}`)
  }

  // 处理离线队列
  async processOfflineQueue(): Promise<void> {
    if (this.isProcessing || this.offlineQueue.length === 0) return
    this.isProcessing = true

    console.info(`开始处理离线队列, 共 ${this.offlineQueue.length} 个操作`)

    const failedOps: OfflineOperation[] = []

    for (const op of this.offlineQueue) {
      try {
        await this.executeOperation(op)
        console.info(`操作执行成功: ${op.type} on ${op.key}`)
      } catch (error) {
        op.retryCount++
        if (op.retryCount < 3) {
          failedOps.push(op)
          console.warn(`操作执行失败, 将重试 (${op.retryCount}/3): ${op.key}`)
        } else {
          console.error(`操作执行失败, 已放弃: ${op.key}`)
          // 可以通知用户处理失败的操作
        }
      }
    }

    // 保留失败的操作
    this.offlineQueue = failedOps
    await this.persistQueue()
    this.isProcessing = false

    console.info(`离线队列处理完成, 剩余 ${this.offlineQueue.length} 个操作`)
  }

  private async executeOperation(op: OfflineOperation): Promise<void> {
    // 实际执行数据操作
    switch (op.type) {
      case 'put':
        // 执行写入
        break
      case 'delete':
        // 执行删除
        break
      case 'update':
        // 执行更新
        break
    }
  }

  private async persistQueue(): Promise<void> {
    // 将队列持久化到本地存储
  }

  private evictOldestOperations(): void {
    // 淘汰最旧的操作
    const removeCount = Math.floor(this.maxQueueSize * 0.1)
    this.offlineQueue.splice(0, removeCount)
    console.warn(`队列已满, 已淘汰 ${removeCount} 个最旧操作`)
  }

  // 获取离线队列状态
  getQueueStatus(): OfflineQueueStatus {
    return {
      totalOperations: this.offlineQueue.length,
      oldestTimestamp: this.offlineQueue.length > 0
        ? this.offlineQueue[0].timestamp : 0,
      isProcessing: this.isProcessing,
      isOnline: this.isOnline
    }
  }
}

interface OfflineOperation {
  type: 'put' | 'delete' | 'update'
  key: string
  value?: string
  timestamp: number
  retryCount: number
}

interface OfflineQueueStatus {
  totalOperations: number
  oldestTimestamp: number
  isProcessing: boolean
  isOnline: boolean
}

8.3.4 6.2.4 网络状态感知

import { connection } from '@kit.NetworkKit'

// 网络状态监听器
class NetworkAwarenessManager {
  private netConnection: connection.NetConnection | null = null
  private isNetworkAvailable: boolean = false
  private networkType: string = 'unknown'
  private listeners: NetworkStateListener[] = []

  // 初始化网络监听
  initialize(): void {
    this.netConnection = connection.createNetConnection()

    // 网络可用
    this.netConnection.on('netAvailable', (netHandle: connection.NetHandle): void => {
      this.isNetworkAvailable = true
      console.info('网络已连接')
      this.notifyListeners({ available: true, type: this.networkType })
    })

    // 网络状态变化
    this.netConnection.on('netCapabilitiesChange', (
        netHandle: connection.NetHandle,
        netCap: connection.NetCapabilityInfo): void => {
      if (netCap.netCap) {
        const bearerTypes = netCap.netCap.bearerTypes
        if (bearerTypes.includes(connection.NetBearType.BEARER_WIFI)) {
          this.networkType = 'wifi'
        } else if (bearerTypes.includes(connection.NetBearType.BEARER_CELLULAR)) {
          this.networkType = 'cellular'
        } else {
          this.networkType = 'other'
        }
      }
      console.info(`网络类型: ${this.networkType}`)
    })

    // 网络丢失
    this.netConnection.on('netLost', (netHandle: connection.NetHandle): void => {
      this.isNetworkAvailable = false
      this.networkType = 'none'
      console.info('网络已断开')
      this.notifyListeners({ available: false, type: 'none' })
    })

    // 网络连接
    this.netConnection.on('netConnectionPropertiesChange', (
        netHandle: connection.NetHandle,
        netConnectionProperties: connection.NetConnectionProperties): void => {
      console.info('网络连接属性变更')
    })

    // 注册网络监听
    this.netConnection.register((error) => {
      if (error) {
        console.error(`注册网络监听失败: ${JSON.stringify(error)}`)
      }
    })
  }

  // 添加网络状态监听器
  addListener(listener: NetworkStateListener): void {
    this.listeners.push(listener)
  }

  // 移除监听器
  removeListener(listener: NetworkStateListener): void {
    const index = this.listeners.indexOf(listener)
    if (index >= 0) {
      this.listeners.splice(index, 1)
    }
  }

  // 获取当前网络状态
  getNetworkStatus(): NetworkStatus {
    return {
      available: this.isNetworkAvailable,
      type: this.networkType
    }
  }

  // 根据网络状态决定同步策略
  getSyncStrategyForNetwork(): SyncMode {
    if (!this.isNetworkAvailable) {
      return SyncMode.MANUAL // 离线模式
    }
    switch (this.networkType) {
      case 'wifi':
        return SyncMode.REALTIME // WiFi下实时同步
      case 'cellular':
        return SyncMode.PERIODIC // 蜂窝网络下定时同步,节省流量
      default:
        return SyncMode.MANUAL
    }
  }

  private notifyListeners(status: NetworkStatus): void {
    for (const listener of this.listeners) {
      listener.onNetworkChange(status)
    }
  }

  // 释放资源
  destroy(): void {
    if (this.netConnection) {
      this.netConnection.unregister((error) => {
        if (error) {
          console.error(`注销网络监听失败: ${JSON.stringify(error)}`)
        }
      })
      this.netConnection = null
    }
  }
}

interface NetworkStateListener {
  onNetworkChange(status: NetworkStatus): void
}

interface NetworkStatus {
  available: boolean
  type: string
}

enum SyncMode {
  REALTIME = 'realtime',
  PERIODIC = 'periodic',
  MANUAL = 'manual'
}

8.4 6.3 关系型数据库高级

8.4.1 6.3.1 关系型数据库(RDB)深入

import { relationalStore } from '@kit.ArkData'
import { common } from '@kit.AbilityKit'

// RDB高级操作管理器
class AdvancedRDBManager {
  private rdbStore: relationalStore.RdbStore | null = null
  private context: common.UIAbilityContext

  constructor(context: common.UIAbilityContext) {
    this.context = context
  }

  // 初始化数据库
  async initialize(dbName: string): Promise<void> {
    const config: relationalStore.StoreConfig = {
      name: dbName,
      securityLevel: relationalStore.SecurityLevel.S1,
      isVector: false
    }

    try {
      this.rdbStore = await relationalStore.getRdbStore(this.context, config)
      await this.createTables()
      console.info('数据库初始化成功')
    } catch (error) {
      console.error(`数据库初始化失败: ${JSON.stringify(error)}`)
      throw error
    }
  }

  // 创建表结构
  private async createTables(): Promise<void> {
    if (!this.rdbStore) return

    // 用户表
    const createUsersSQL = `
      CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        email TEXT UNIQUE NOT NULL,
        age INTEGER,
        department_id INTEGER,
        created_at TEXT DEFAULT (datetime('now', 'localtime')),
        updated_at TEXT DEFAULT (datetime('now', 'localtime')),
        is_active INTEGER DEFAULT 1,
        FOREIGN KEY (department_id) REFERENCES departments(id)
      )
    `

    // 部门表
    const createDepartmentsSQL = `
      CREATE TABLE IF NOT EXISTS departments (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        description TEXT,
        manager_id INTEGER,
        created_at TEXT DEFAULT (datetime('now', 'localtime'))
      )
    `

    // 项目表
    const createProjectsSQL = `
      CREATE TABLE IF NOT EXISTS projects (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        status TEXT DEFAULT 'active',
        start_date TEXT,
        end_date TEXT,
        budget REAL,
        department_id INTEGER,
        FOREIGN KEY (department_id) REFERENCES departments(id)
      )
    `

    // 用户-项目关联表
    const createUserProjectsSQL = `
      CREATE TABLE IF NOT EXISTS user_projects (
        user_id INTEGER NOT NULL,
        project_id INTEGER NOT NULL,
        role TEXT DEFAULT 'member',
        joined_at TEXT DEFAULT (datetime('now', 'localtime')),
        PRIMARY KEY (user_id, project_id),
        FOREIGN KEY (user_id) REFERENCES users(id),
        FOREIGN KEY (project_id) REFERENCES projects(id)
      )
    `

    await this.rdbStore.executeSql(createUsersSQL)
    await this.rdbStore.executeSql(createDepartmentsSQL)
    await this.rdbStore.executeSql(createProjectsSQL)
    await this.rdbStore.executeSql(createUserProjectsSQL)

    // 创建索引
    await this.createIndexes()
  }

  // 创建索引
  private async createIndexes(): Promise<void> {
    if (!this.rdbStore) return

    const indexSQLs = [
      'CREATE INDEX IF NOT EXISTS idx_users_email ON users(email)',
      'CREATE INDEX IF NOT EXISTS idx_users_department ON users(department_id)',
      'CREATE INDEX IF NOT EXISTS idx_projects_status ON projects(status)',
      'CREATE INDEX IF NOT EXISTS idx_projects_department ON projects(department_id)',
      'CREATE INDEX IF NOT EXISTS idx_user_projects_user ON user_projects(user_id)',
      'CREATE INDEX IF NOT EXISTS idx_user_projects_project ON user_projects(project_id)'
    ]

    for (const sql of indexSQLs) {
      await this.rdbStore.executeSql(sql)
    }
  }

  // 高级查询 - 多表关联查询
  async queryUsersWithDepartment(): Promise<relationalStore.ResultSet> {
    if (!this.rdbStore) {
      throw new Error('数据库未初始化')
    }

    const sql = `
      SELECT
        u.id, u.name, u.email, u.age,
        d.name AS department_name,
        u.created_at
      FROM users u
      LEFT JOIN departments d ON u.department_id = d.id
      WHERE u.is_active = 1
      ORDER BY u.created_at DESC
      LIMIT ? OFFSET ?
    `

    const predicates = new relationalStore.RdbPredicates('users')
    return this.rdbStore.querySql(sql, ['20', '0'])
  }

  // 事务操作
  async executeInTransaction(
      operations: (store: relationalStore.RdbStore) => Promise<void>):
      Promise<void> {
    if (!this.rdbStore) {
      throw new Error('数据库未初始化')
    }

    try {
      // 开始事务
      await this.rdbStore.beginTransaction()

      // 执行操作
      await operations(this.rdbStore)

      // 提交事务
      await this.rdbStore.commit()
      console.info('事务提交成功')
    } catch (error) {
      // 回滚事务
      if (this.rdbStore) {
        await this.rdbStore.rollback()
      }
      console.error(`事务回滚: ${JSON.stringify(error)}`)
      throw error
    }
  }

  // 批量插入
  async batchInsert(tableName: string,
      data: relationalStore.ValuesBucket[]): Promise<number> {
    if (!this.rdbStore) {
      throw new Error('数据库未初始化')
    }

    let insertedCount = 0

    await this.executeInTransaction(async (store) => {
      for (const bucket of data) {
        const rowId = await store.insert(tableName, bucket)
        if (rowId !== -1) {
          insertedCount++
        }
      }
    })

    console.info(`批量插入完成: ${insertedCount}/${data.length}`)
    return insertedCount
  }

  // 关闭数据库
  async close(): Promise<void> {
    if (this.rdbStore) {
      await relationalStore.deleteRdbStore(this.context, 'app.db')
      this.rdbStore = null
    }
  }
}

8.4.2 6.3.2 SQL查询优化

// SQL查询优化器
class QueryOptimizer {
  private rdbStore: relationalStore.RdbStore | null = null

  constructor(store: relationalStore.RdbStore) {
    this.rdbStore = store
  }

  // 使用谓词查询代替SQL字符串(更安全、更高效)
  async optimizedQueryWithPredicates(
      departmentId: number,
      minAge: number,
      maxAge: number,
      page: number,
      pageSize: number): Promise<relationalStore.ResultSet> {
    if (!this.rdbStore) {
      throw new Error('数据库未初始化')
    }

    // 使用 RdbPredicates 构建查询
    const predicates = new relationalStore.RdbPredicates('users')

    // 条件过滤(谓词下推)
    predicates.equalTo('department_id', departmentId.toString())
    predicates.greaterThanOrEqualTo('age', minAge.toString())
    predicates.lessThanOrEqualTo('age', maxAge.toString())
    predicates.equalTo('is_active', 1)

    // 排序
    predicates.orderByDesc('created_at')

    // 分页
    predicates.limitAs(pageSize.toString())
    predicates.offsetAs((page * pageSize).toString())

    // 指定返回列(避免 SELECT *)
    predicates.resultColumnsAs(['id', 'name', 'email', 'age', 'created_at'])

    return this.rdbStore.query(predicates)
  }

  // 使用预编译语句(防止SQL注入,提高重复查询效率)
  async queryWithPreparedStatement(
      email: string): Promise<relationalStore.ResultSet> {
    if (!this.rdbStore) {
      throw new Error('数据库未初始化')
    }

    // 预编译SQL
    const sql = 'SELECT * FROM users WHERE email = ?'
    return this.rdbStore.querySql(sql, [email])
  }

  // 聚合查询优化
  async getDepartmentStats(): Promise<DepartmentStats[]> {
    if (!this.rdbStore) {
      throw new Error('数据库未初始化')
    }

    const sql = `
      SELECT
        d.id,
        d.name AS department_name,
        COUNT(u.id) AS user_count,
        AVG(u.age) AS avg_age,
        MIN(u.age) AS min_age,
        MAX(u.age) AS max_age
      FROM departments d
      LEFT JOIN users u ON d.id = u.department_id AND u.is_active = 1
      GROUP BY d.id, d.name
      HAVING COUNT(u.id) > 0
      ORDER BY user_count DESC
    `

    const resultSet = this.rdbStore.querySqlSync(sql)
    const stats: DepartmentStats[] = []

    while (resultSet.goToNextRow()) {
      stats.push({
        departmentId: resultSet.getLong(0),
        departmentName: resultSet.getString(1),
        userCount: resultSet.getLong(2),
        avgAge: resultSet.getDouble(3),
        minAge: resultSet.getLong(4),
        maxAge: resultSet.getLong(5)
      })
    }

    resultSet.close()
    return stats
  }
}

interface DepartmentStats {
  departmentId: number
  departmentName: string
  userCount: number
  avgAge: number
  minAge: number
  maxAge: number
}

8.4.3 6.3.3 谓词下推与索引优化

// 谓词下推与索引优化示例
class PredicatePushdownDemo {
  private rdbStore: relationalStore.RdbStore | null = null

  constructor(store: relationalStore.RdbStore) {
    this.rdbStore = store
  }

  // 反模式:不使用索引的查询
  async badQuery(): Promise<void> {
    if (!this.rdbStore) return

    // 对字段使用函数,导致索引失效
    const badSQL = `
      SELECT * FROM users
      WHERE UPPER(name) = 'ZHANG SAN'
      AND created_at LIKE '2024%'
    `
    // 这个查询无法使用索引,因为对name使用了UPPER函数
  }

  // 优化方案:使用索引友好的查询
  async optimizedQuery(): Promise<void> {
    if (!this.rdbStore) return

    // 使用精确匹配,可以利用索引
    const predicates = new relationalStore.RdbPredicates('users')
    predicates.equalTo('name', '张三')
    predicates.between('created_at', '2024-01-01', '2024-12-31')

    this.rdbStore.query(predicates)
  }

  // 复合索引的使用
  async compositeIndexQuery(): Promise<void> {
    if (!this.rdbStore) return

    // 创建复合索引
    await this.rdbStore.executeSql(
      'CREATE INDEX IF NOT EXISTS idx_dept_age_active ' +
      'ON users(department_id, age, is_active)'
    )

    // 查询条件与复合索引匹配
    const predicates = new relationalStore.RdbPredicates('users')
    predicates.equalTo('department_id', '1')
    predicates.greaterThanOrEqualTo('age', '25')
    predicates.equalTo('is_active', 1)

    // 这个查询可以充分利用复合索引
    this.rdbStore.query(predicates)
  }

  // 覆盖索引查询(只查询索引包含的列)
  async coveringIndexQuery(): Promise<void> {
    if (!this.rdbStore) return

    // 创建覆盖索引
    await this.rdbStore.executeSql(
      'CREATE INDEX IF NOT EXISTS idx_covering ' +
      'ON users(department_id, name, email)'
    )

    // 只查询索引中包含的列,无需回表
    const sql = `
      SELECT department_id, name, email
      FROM users
      WHERE department_id = 1
    `
    this.rdbStore.querySql(sql)
  }
}

8.4.4 6.3.4 数据备份与恢复

// 数据库备份与恢复管理器
class DatabaseBackupManager {
  private rdbStore: relationalStore.RdbStore | null = null
  private context: common.UIAbilityContext

  constructor(context: common.UIAbilityContext,
      store: relationalStore.RdbStore) {
    this.context = context
    this.rdbStore = store
  }

  // 导出数据库为JSON
  async exportToJSON(): Promise<string> {
    if (!this.rdbStore) {
      throw new Error('数据库未初始化')
    }

    const exportData: Record<string, Object[]> = {}

    // 获取所有表名
    const tables = ['users', 'departments', 'projects', 'user_projects']

    for (const table of tables) {
      const resultSet = this.rdbStore.querySqlSync(
        `SELECT * FROM ${table}`
      )
      const rows: Object[] = []
      const columnNames = resultSet.columnNames

      while (resultSet.goToNextRow()) {
        const row: Record<string, Object> = {}
        for (let i = 0; i < columnNames.length; i++) {
          const type = resultSet.getColumnType(i)
          switch (type) {
            case relationalStore.ColumnType.INTEGER:
              row[columnNames[i]] = resultSet.getLong(i)
              break
            case relationalStore.ColumnType.FLOAT:
              row[columnNames[i]] = resultSet.getDouble(i)
              break
            case relationalStore.ColumnType.STRING:
              row[columnNames[i]] = resultSet.getString(i)
              break
            case relationalStore.ColumnType.BLOB:
              row[columnNames[i]] = 'BLOB_DATA'
              break
            default:
              row[columnNames[i]] = null
              break
          }
        }
        rows.push(row)
      }

      resultSet.close()
      exportData[table] = rows
    }

    return JSON.stringify(exportData, null, 2)
  }

  // 从JSON恢复数据
  async restoreFromJSON(jsonData: string): Promise<void> {
    if (!this.rdbStore) {
      throw new Error('数据库未初始化')
    }

    const data = JSON.parse(jsonData) as Record<string, Object[]>

    await this.rdbStore.beginTransaction()

    try {
      // 按依赖顺序恢复:先恢复被引用的表
      const tableOrder = ['departments', 'users', 'projects', 'user_projects']

      for (const table of tableOrder) {
        const rows = data[table]
        if (!rows) continue

        // 清空表
        const predicates = new relationalStore.RdbPredicates(table)
        await this.rdbStore.delete(predicates)

        // 恢复数据
        for (const row of rows) {
          const bucket: relationalStore.ValuesBucket = row as relationalStore.ValuesBucket
          await this.rdbStore.insert(table, bucket)
        }
      }

      await this.rdbStore.commit()
      console.info('数据恢复成功')
    } catch (error) {
      await this.rdbStore.rollback()
      console.error(`数据恢复失败: ${JSON.stringify(error)}`)
      throw error
    }
  }

  // 增量备份
  async incrementalBackup(lastBackupTime: number):
      Promise<Record<string, Object[]>> {
    if (!this.rdbStore) {
      throw new Error('数据库未初始化')
    }

    const backupData: Record<string, Object[]> = {}
    const tables = ['users', 'departments', 'projects']
    const lastBackupStr = new Date(lastBackupTime).toISOString()

    for (const table of tables) {
      const resultSet = this.rdbStore.querySqlSync(
        `SELECT * FROM ${table} WHERE updated_at > ?`,
        [lastBackupStr]
      )

      const rows: Object[] = []
      const columnNames = resultSet.columnNames

      while (resultSet.goToNextRow()) {
        const row: Record<string, Object> = {}
        for (let i = 0; i < columnNames.length; i++) {
          const type = resultSet.getColumnType(i)
          switch (type) {
            case relationalStore.ColumnType.INTEGER:
              row[columnNames[i]] = resultSet.getLong(i)
              break
            case relationalStore.ColumnType.FLOAT:
              row[columnNames[i]] = resultSet.getDouble(i)
              break
            case relationalStore.ColumnType.STRING:
              row[columnNames[i]] = resultSet.getString(i)
              break
            default:
              row[columnNames[i]] = null
              break
          }
        }
        rows.push(row)
      }

      resultSet.close()
      backupData[table] = rows
    }

    return backupData
  }
}

8.5 6.4 键值对分布式存储

8.5.1 6.4.1 分布式KV存储架构

import { distributedKVStore } from '@kit.ArkData'
import { common } from '@kit.AbilityKit'

// 分布式KV存储管理器
class DistributedKVManager {
  private kvManager: distributedKVStore.KVManager | null = null
  private kvStore: distributedKVStore.SingleKVStore | null = null
  private context: common.UIAbilityContext

  constructor(context: common.UIAbilityContext) {
    this.context = context
  }

  // 初始化KV存储
  async initialize(storeId: string): Promise<void> {
    try {
      // 创建KV管理器
      const kvManagerConfig: distributedKVStore.KVManagerConfig = {
        context: this.context,
        bundleName: 'com.example.distributeddata'
      }
      this.kvManager = distributedKVStore.createKVManager(kvManagerConfig)

      // 配置KV存储选项
      const options: distributedKVStore.Options = {
        createIfMissing: true,
        encrypt: true,              // 启用加密
        backup: true,               // 允许备份
        autoSync: true,             // 自动同步
        kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,
        securityLevel: distributedKVStore.SecurityLevel.S2
      }

      // 获取KV存储实例
      this.kvStore = await this.kvManager.getKVStore<distributedKVStore.SingleKVStore>(
        storeId, options
      )

      // 注册数据变更监听
      this.registerDataChangeListeners()

      console.info('分布式KV存储初始化成功')
    } catch (error) {
      console.error(`初始化失败: ${JSON.stringify(error)}`)
      throw error
    }
  }

  // 写入数据
  async put(key: string, value: string | number | boolean | Uint8Array):
      Promise<void> {
    if (!this.kvStore) {
      throw new Error('KV存储未初始化')
    }

    try {
      await this.kvStore.put(key, value)
      console.info(`数据写入成功: ${key}`)
    } catch (error) {
      console.error(`数据写入失败: ${JSON.stringify(error)}`)
      throw error
    }
  }

  // 批量写入
  async batchPut(entries: Map<string, string>): Promise<void> {
    if (!this.kvStore) {
      throw new Error('KV存储未初始化')
    }

    try {
      const putBatch: distributedKVStore.Entry[] = []
      entries.forEach((value: string, key: string) => {
        putBatch.push({ key: key, value: { type: distributedKVStore.ValueType.STRING, value: value } })
      })

      await this.kvStore.putBatch(putBatch)
      console.info(`批量写入成功: ${entries.size} 条`)
    } catch (error) {
      console.error(`批量写入失败: ${JSON.stringify(error)}`)
      throw error
    }
  }

  // 读取数据
  async get(key: string): Promise<string | undefined> {
    if (!this.kvStore) {
      throw new Error('KV存储未初始化')
    }

    try {
      const value = await this.kvStore.get(key) as string
      return value
    } catch (error) {
      console.error(`数据读取失败: ${JSON.stringify(error)}`)
      return undefined
    }
  }

  // 批量读取
  async batchGet(keys: string[]): Promise<Map<string, string>> {
    if (!this.kvStore) {
      throw new Error('KV存储未初始化')
    }

    const result = new Map<string, string>()

    try {
      const entries = await this.kvStore.getBatch(keys)
      for (const entry of entries) {
        result.set(entry.key, entry.value.value as string)
      }
    } catch (error) {
      console.error(`批量读取失败: ${JSON.stringify(error)}`)
    }

    return result
  }

  // 删除数据
  async delete(key: string): Promise<void> {
    if (!this.kvStore) {
      throw new Error('KV存储未初始化')
    }

    try {
      await this.kvStore.delete(key)
      console.info(`数据删除成功: ${key}`)
    } catch (error) {
      console.error(`数据删除失败: ${JSON.stringify(error)}`)
      throw error
    }
  }

  // 注册数据变更监听
  private registerDataChangeListeners(): void {
    if (!this.kvStore) return

    // 监听本地数据变更
    this.kvStore.on('change', (data: distributedKVStore.ChangeNotification): void => {
      // 处理插入事件
      for (const entry of data.insertEntries) {
        console.info(`数据插入: ${entry.key}`)
      }

      // 处理更新事件
      for (const entry of data.updateEntries) {
        console.info(`数据更新: ${entry.key}`)
      }

      // 处理删除事件
      for (const entry of data.deleteEntries) {
        console.info(`数据删除: ${entry.key}`)
      }
    })

    // 监听同步状态变更
    this.kvStore.on('syncStatusChange', (
        syncState: distributedKVStore.SyncState): void => {
      console.info(`同步状态: ${syncState}`)
    })
  }

  // 手动触发同步
  async sync(deviceIds: string[]): Promise<void> {
    if (!this.kvStore) {
      throw new Error('KV存储未初始化')
    }

    return new Promise((resolve, reject) => {
      this.kvStore!.sync(deviceIds, {
        mode: distributedKVStore.SyncMode.PUSH_PULL,
        delay: 0
      }, (err: Error) => {
        if (err) reject(err)
        else resolve()
      })
    })
  }

  // 释放资源
  async destroy(): Promise<void> {
    if (this.kvStore) {
      this.kvStore.off('change')
      this.kvStore.off('syncStatusChange')
    }
    if (this.kvManager) {
      await this.kvManager.closeAllKVStores()
    }
  }
}

8.5.2 6.4.2 数据分区策略

// KV数据分区管理器
class KVPartitionManager {
  private kvManager: distributedKVStore.KVManager | null = null
  private partitions: Map<string, distributedKVStore.SingleKVStore> =
    new Map()
  private context: common.UIAbilityContext

  constructor(context: common.UIAbilityContext) {
    this.context = context
  }

  async initialize(): Promise<void> {
    const config: distributedKVStore.KVManagerConfig = {
      context: this.context,
      bundleName: 'com.example.distributeddata'
    }
    this.kvManager = distributedKVStore.createKVManager(config)
  }

  // 创建数据分区
  async createPartition(partitionName: string,
      options: PartitionOptions): Promise<void> {
    if (!this.kvManager) {
      throw new Error('KV管理器未初始化')
    }

    const storeOptions: distributedKVStore.Options = {
      createIfMissing: true,
      encrypt: options.encrypted ?? false,
      backup: options.backup ?? false,
      autoSync: options.autoSync ?? true,
      kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,
      securityLevel: options.securityLevel ??
        distributedKVStore.SecurityLevel.S1
    }

    const store = await this.kvManager.getKVStore<distributedKVStore.SingleKVStore>(
      partitionName, storeOptions
    )

    this.partitions.set(partitionName, store)
    console.info(`数据分区已创建: ${partitionName}`)
  }

  // 根据数据类型获取对应分区
  getPartitionForType(dataType: DataType): distributedKVStore.SingleKVStore | null {
    const partitionName = this.getPartitionName(dataType)
    return this.partitions.get(partitionName) ?? null
  }

  private getPartitionName(dataType: DataType): string {
    switch (dataType) {
      case DataType.USER_SETTINGS:
        return 'partition_settings'
      case DataType.CACHE:
        return 'partition_cache'
      case DataType.SYNC_DATA:
        return 'partition_sync'
      case DataType.OFFLINE:
        return 'partition_offline'
      default:
        return 'partition_default'
    }
  }
}

interface PartitionOptions {
  encrypted?: boolean
  backup?: boolean
  autoSync?: boolean
  securityLevel?: distributedKVStore.SecurityLevel
}

enum DataType {
  USER_SETTINGS,
  CACHE,
  SYNC_DATA,
  OFFLINE
}

8.5.3 6.4.3 数据加密存储

// 加密KV存储管理器
class EncryptedKVManager {
  private kvStore: distributedKVStore.SingleKVStore | null = null
  private kvManager: distributedKVStore.KVManager | null = null

  async initialize(context: common.UIAbilityContext): Promise<void> {
    const config: distributedKVStore.KVManagerConfig = {
      context: context,
      bundleName: 'com.example.distributeddata'
    }
    this.kvManager = distributedKVStore.createKVManager(config)

    // 使用最高安全级别
    const options: distributedKVStore.Options = {
      createIfMissing: true,
      encrypt: true,  // 启用加密
      backup: false,
      autoSync: true,
      kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,
      securityLevel: distributedKVStore.SecurityLevel.S4  // 最高安全级别
    }

    this.kvStore = await this.kvManager.getKVStore<distributedKVStore.SingleKVStore>(
      'encrypted_store', options
    )
  }

  // 存储敏感数据
  async storeSensitiveData(key: string, data: SensitiveData): Promise<void> {
    if (!this.kvStore) {
      throw new Error('加密存储未初始化')
    }

    // 序列化并加密存储
    const serialized = JSON.stringify(data)
    await this.kvStore.put(key, serialized)
    console.info(`敏感数据已加密存储: ${key}`)
  }

  // 读取敏感数据
  async retrieveSensitiveData<T extends SensitiveData>(
      key: string): Promise<T | null> {
    if (!this.kvStore) {
      throw new Error('加密存储未初始化')
    }

    try {
      const value = await this.kvStore.get(key) as string
      return JSON.parse(value) as T
    } catch (error) {
      console.error(`读取敏感数据失败: ${JSON.stringify(error)}`)
      return null
    }
  }
}

interface SensitiveData {
  type: string
  data: string
  timestamp: number
  expiresAt?: number
}

8.6 6.5 首选项与持久化

8.6.1 6.5.1 Preferences异步操作

import { preferences } from '@kit.ArkData'
import { common } from '@kit.AbilityKit'

// Preferences高级管理器
class AdvancedPreferencesManager {
  private prefStore: preferences.Preferences | null = null
  private context: common.UIAbilityContext
  private prefName: string = 'app_preferences'

  constructor(context: common.UIAbilityContext) {
    this.context = context
  }

  // 初始化Preferences
  async initialize(): Promise<void> {
    try {
      this.prefStore = await preferences.getPreferences(
        this.context, this.prefName
      )
      console.info('Preferences初始化成功')
    } catch (error) {
      console.error(`Preferences初始化失败: ${JSON.stringify(error)}`)
      throw error
    }
  }

  // 异步读取
  async getString(key: string, defaultValue: string = ''): Promise<string> {
    if (!this.prefStore) {
      throw new Error('Preferences未初始化')
    }
    return await this.prefStore.get(key, defaultValue) as string
  }

  async getNumber(key: string, defaultValue: number = 0): Promise<number> {
    if (!this.prefStore) {
      throw new Error('Preferences未初始化')
    }
    return await this.prefStore.get(key, defaultValue) as number
  }

  async getBoolean(key: string, defaultValue: boolean = false):
      Promise<boolean> {
    if (!this.prefStore) {
      throw new Error('Preferences未初始化')
    }
    return await this.prefStore.get(key, defaultValue) as boolean
  }

  // 异步写入
  async putString(key: string, value: string): Promise<void> {
    if (!this.prefStore) {
      throw new Error('Preferences未初始化')
    }
    await this.prefStore.put(key, value)
    await this.prefStore.flush()
  }

  async putNumber(key: string, value: number): Promise<void> {
    if (!this.prefStore) {
      throw new Error('Preferences未初始化')
    }
    await this.prefStore.put(key, value)
    await this.prefStore.flush()
  }

  // 批量操作
  async batchPut(entries: Map<string, preferences.ValueType>): Promise<void> {
    if (!this.prefStore) {
      throw new Error('Preferences未初始化')
    }

    for (const [key, value] of entries) {
      await this.prefStore.put(key, value)
    }
    // 统一刷新,减少IO操作
    await this.prefStore.flush()
    console.info(`批量写入完成: ${entries.size} 条`)
  }

  // 监听数据变更
  onDataChange(key: string,
      callback: (key: string, value: preferences.ValueType) => void): void {
    if (!this.prefStore) return

    this.prefStore.on('change', (keys: Array<string>) => {
      if (keys.includes(key)) {
        this.prefStore!.get(key, '').then((value) => {
          callback(key, value)
        })
      }
    })
  }

  // 删除指定键
  async delete(key: string): Promise<void> {
    if (!this.prefStore) {
      throw new Error('Preferences未初始化')
    }
    await this.prefStore.delete(key)
    await this.prefStore.flush()
  }

  // 清除所有数据
  async clear(): Promise<void> {
    if (!this.prefStore) {
      throw new Error('Preferences未初始化')
    }
    await this.prefStore.clear()
    await this.prefStore.flush()
  }

  // 检查键是否存在
  async has(key: string): Promise<boolean> {
    if (!this.prefStore) {
      throw new Error('Preferences未初始化')
    }
    return await this.prefStore.has(key)
  }

  // 获取所有键
  async getAllKeys(): Promise<Array<string>> {
    if (!this.prefStore) {
      throw new Error('Preferences未初始化')
    }
    return await this.prefStore.getAllKeys()
  }

  // 删除Preferences文件
  async deletePreferences(): Promise<void> {
    await preferences.deletePreferences(this.context, this.prefName)
    this.prefStore = null
  }
}

8.6.2 6.5.2 数据迁移策略

// Preferences数据迁移管理器
class PreferencesMigrationManager {
  private context: common.UIAbilityContext

  constructor(context: common.UIAbilityContext) {
    this.context = context
  }

  // 版本化数据迁移
  async migrateIfNeeded(): Promise<void> {
    const currentVersion = 3 // 当前数据版本
    const storedVersion = await this.getStoredVersion()

    if (storedVersion >= currentVersion) {
      console.info('数据已是最新版本,无需迁移')
      return
    }

    console.info(`开始数据迁移: v${storedVersion} → v${currentVersion}`)

    // 逐步执行迁移
    let version = storedVersion

    if (version < 1) {
      await this.migrateToV1()
      version = 1
    }
    if (version < 2) {
      await this.migrateToV2()
      version = 2
    }
    if (version < 3) {
      await this.migrateToV3()
      version = 3
    }

    // 更新版本号
    await this.setStoredVersion(currentVersion)
    console.info(`数据迁移完成: v${currentVersion}`)
  }

  // V1迁移:初始化默认设置
  private async migrateToV1(): Promise<void> {
    console.info('执行V1迁移: 初始化默认设置')
    const pref = await preferences.getPreferences(this.context, 'app_preferences')

    await pref.put('theme', 'light')
    await pref.put('language', 'zh-CN')
    await pref.put('fontSize', 16)
    await pref.put('notifications_enabled', true)
    await pref.flush()
  }

  // V2迁移:重构设置项
  private async migrateToV2(): Promise<void> {
    console.info('执行V2迁移: 重构设置项')
    const pref = await preferences.getPreferences(this.context, 'app_preferences')

    // 将旧的 'fontSize' 迁移到新的 'display.fontSize'
    const fontSize = await pref.get('fontSize', 16) as number
    await pref.put('display_font_size', fontSize)
    await pref.delete('fontSize')

    // 添加新设置
    await pref.put('display_dark_mode', false)
    await pref.flush()
  }

  // V3迁移:添加用户偏好
  private async migrateToV3(): Promise<void> {
    console.info('执行V3迁移: 添加用户偏好')
    const pref = await preferences.getPreferences(this.context, 'app_preferences')

    await pref.put('user_experience_level', 'intermediate')
    await pref.put('auto_sync_enabled', true)
    await pref.put('sync_interval_minutes', 30)
    await pref.flush()
  }

  private async getStoredVersion(): Promise<number> {
    const pref = await preferences.getPreferences(this.context, 'app_preferences')
    return await pref.get('data_version', 0) as number
  }

  private async setStoredVersion(version: number): Promise<void> {
    const pref = await preferences.getPreferences(this.context, 'app_preferences')
    await pref.put('data_version', version)
    await pref.flush()
  }
}

8.6.3 6.5.3 配置管理最佳实践

// 应用配置管理器 - 最佳实践
class AppConfigManager {
  private prefManager: AdvancedPreferencesManager
  private static instance: AppConfigManager | null = null

  // 单例模式
  static getInstance(context: common.UIAbilityContext): AppConfigManager {
    if (!AppConfigManager.instance) {
      const prefManager = new AdvancedPreferencesManager(context)
      AppConfigManager.instance = new AppConfigManager(prefManager)
    }
    return AppConfigManager.instance
  }

  constructor(prefManager: AdvancedPreferencesManager) {
    this.prefManager = prefManager
  }

  async initialize(): Promise<void> {
    await this.prefManager.initialize()
  }

  // 主题配置
  async getTheme(): Promise<string> {
    return await this.prefManager.getString('theme', 'light')
  }

  async setTheme(theme: string): Promise<void> {
    await this.prefManager.putString('theme', theme)
  }

  // 用户偏好配置
  async getUserPreferences(): Promise<UserPreferences> {
    return {
      theme: await this.prefManager.getString('theme', 'light'),
      language: await this.prefManager.getString('language', 'zh-CN'),
      fontSize: await this.prefManager.getNumber('display_font_size', 16),
      darkMode: await this.prefManager.getBoolean('display_dark_mode', false),
      notificationsEnabled: await this.prefManager.getBoolean(
        'notifications_enabled', true),
      autoSyncEnabled: await this.prefManager.getBoolean(
        'auto_sync_enabled', true),
      syncIntervalMinutes: await this.prefManager.getNumber(
        'sync_interval_minutes', 30)
    }
  }

  async saveUserPreferences(prefs: UserPreferences): Promise<void> {
    const entries = new Map<string, preferences.ValueType>()
    entries.set('theme', prefs.theme)
    entries.set('language', prefs.language)
    entries.set('display_font_size', prefs.fontSize)
    entries.set('display_dark_mode', prefs.darkMode)
    entries.set('notifications_enabled', prefs.notificationsEnabled)
    entries.set('auto_sync_enabled', prefs.autoSyncEnabled)
    entries.set('sync_interval_minutes', prefs.syncIntervalMinutes)
    await this.prefManager.batchPut(entries)
  }
}

interface UserPreferences {
  theme: string
  language: string
  fontSize: number
  darkMode: boolean
  notificationsEnabled: boolean
  autoSyncEnabled: boolean
  syncIntervalMinutes: number
}

8.6.4 6.5.4 数据版本控制

// 数据版本控制器
class DataVersionController {
  private static readonly VERSION_KEY = 'schema_version'
  private static readonly MIGRATION_LOG_KEY = 'migration_log'
  private prefStore: preferences.Preferences | null = null

  async initialize(context: common.UIAbilityContext): Promise<void> {
    this.prefStore = await preferences.getPreferences(context, 'version_control')
  }

  // 获取当前数据版本
  async getCurrentVersion(): Promise<number> {
    if (!this.prefStore) return 0
    return await this.prefStore.get(DataVersionController.VERSION_KEY, 0) as number
  }

  // 设置数据版本
  async setVersion(version: number): Promise<void> {
    if (!this.prefStore) return
    await this.prefStore.put(DataVersionController.VERSION_KEY, version)
    await this.prefStore.flush()
  }

  // 记录迁移日志
  async logMigration(fromVersion: number,
      toVersion: number, description: string): Promise<void> {
    if (!this.prefStore) return

    const logEntry = {
      from: fromVersion,
      to: toVersion,
      description: description,
      timestamp: Date.now()
    }

    const existingLogs = await this.getMigrationLogs()
    existingLogs.push(logEntry)

    await this.prefStore.put(
      DataVersionController.MIGRATION_LOG_KEY,
      JSON.stringify(existingLogs)
    )
    await this.prefStore.flush()
  }

  // 获取迁移日志
  async getMigrationLogs(): Promise<MigrationLogEntry[]> {
    if (!this.prefStore) return []

    const logStr = await this.prefStore.get(
      DataVersionController.MIGRATION_LOG_KEY, '[]') as string
    return JSON.parse(logStr) as MigrationLogEntry[]
  }
}

interface MigrationLogEntry {
  from: number
  to: number
  description: string
  timestamp: number
}

8.7 6.6 数据共享与交换

8.7.1 6.6.1 跨应用数据共享

import { dataShare } from '@kit.ArkData'
import { common } from '@kit.AbilityKit'

// 跨应用数据共享客户端
class DataShareClient {
  private context: common.UIAbilityContext
  private dataShareProxy: dataShare.DataShareProxy | null = null

  constructor(context: common.UIAbilityContext) {
    this.context = context
  }

  // 连接到DataShare服务
  async connect(providerUri: string): Promise<void> {
    try {
      this.dataShareProxy = this.context.dataShareAcquire(providerUri)
      console.info(`已连接到DataShare: ${providerUri}`)
    } catch (error) {
      console.error(`连接DataShare失败: ${JSON.stringify(error)}`)
      throw error
    }
  }

  // 查询数据
  async query(uri: string, predicates: dataShare.DataSharePredicates,
      columns: string[]): Promise<dataShare.ResultSet> {
    if (!this.dataShareProxy) {
      throw new Error('DataShare未连接')
    }

    const result = await this.dataShareProxy.query(uri, predicates, columns)
    return result
  }

  // 插入数据
  async insert(uri: string,
      bucket: dataShare.DataShareValueObject): Promise<number> {
    if (!this.dataShareProxy) {
      throw new Error('DataShare未连接')
    }

    return await this.dataShareProxy.insert(uri, bucket)
  }

  // 更新数据
  async update(uri: string,
      predicates: dataShare.DataSharePredicates,
      bucket: dataShare.DataShareValueObject): Promise<number> {
    if (!this.dataShareProxy) {
      throw new Error('DataShare未连接')
    }

    return await this.dataShareProxy.update(uri, predicates, bucket)
  }

  // 删除数据
  async delete(uri: string,
      predicates: dataShare.DataSharePredicates): Promise<number> {
    if (!this.dataShareProxy) {
      throw new Error('DataShare未连接')
    }

    return await this.dataShareProxy.delete(uri, predicates)
  }

  // 断开连接
  disconnect(): void {
    if (this.dataShareProxy) {
      this.context.dataShareRelease(this.dataShareProxy)
      this.dataShareProxy = null
    }
  }
}

8.7.2 6.6.2 DataShare服务实现

import { dataShare } from '@kit.ArkData'
import { relationalStore } from '@kit.ArkData'
import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit'

// DataShare Provider Ability 实现
export default class DataShareProviderAbility extends dataShare.DataShareExtensionAbility {
  private rdbStore: relationalStore.RdbStore | null = null

  async onCreate(want: Want): Promise<void> {
    console.info('DataShare Provider onCreate')

    // 初始化数据库
    const config: relationalStore.StoreConfig = {
      name: 'shared_data.db',
      securityLevel: relationalStore.SecurityLevel.S1,
      isVector: false
    }

    const context = this.context as common.UIAbilityContext
    this.rdbStore = await relationalStore.getRdbStore(context, config)

    // 创建共享数据表
    await this.rdbStore.executeSql(`
      CREATE TABLE IF NOT EXISTS shared_items (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        key TEXT UNIQUE NOT NULL,
        value TEXT,
        owner_app TEXT NOT NULL,
        permission TEXT DEFAULT 'read',
        created_at TEXT DEFAULT (datetime('now', 'localtime')),
        updated_at TEXT DEFAULT (datetime('now', 'localtime'))
      )
    `)
  }

  // 实现查询接口
  async query(uri: string,
      predicates: dataShare.DataSharePredicates,
      columns: string[]): Promise<dataShare.ResultSet> {
    if (!this.rdbStore) {
      throw new Error('数据库未初始化')
    }

    // 将 DataSharePredicates 转换为 SQL 查询
    const resultSet = this.rdbStore.querySqlSync(
      'SELECT * FROM shared_items WHERE key = ?',
      [this.extractKeyFromUri(uri)]
    )

    return resultSet as unknown as dataShare.ResultSet
  }

  // 实现插入接口
  async insert(uri: string,
      bucket: dataShare.DataShareValueObject): Promise<number> {
    if (!this.rdbStore) {
      throw new Error('数据库未初始化')
    }

    const valuesBucket: relationalStore.ValuesBucket = {
      key: this.extractKeyFromUri(uri),
      value: bucket['value'] as string,
      owner_app: bucket['owner_app'] as string ?? 'unknown',
      permission: bucket['permission'] as string ?? 'read'
    }

    return await this.rdbStore.insert('shared_items', valuesBucket)
  }

  // 实现更新接口
  async update(uri: string,
      predicates: dataShare.DataSharePredicates,
      bucket: dataShare.DataShareValueObject): Promise<number> {
    if (!this.rdbStore) {
      throw new Error('数据库未初始化')
    }

    const valuesBucket: relationalStore.ValuesBucket = {
      value: bucket['value'] as string,
      updated_at: new Date().toISOString()
    }

    const rdbPredicates = new relationalStore.RdbPredicates('shared_items')
    rdbPredicates.equalTo('key', this.extractKeyFromUri(uri))

    return await this.rdbStore.update(valuesBucket, rdbPredicates)
  }

  // 实现删除接口
  async delete(uri: string,
      predicates: dataShare.DataSharePredicates): Promise<number> {
    if (!this.rdbStore) {
      throw new Error('数据库未初始化')
    }

    const rdbPredicates = new relationalStore.RdbPredicates('shared_items')
    rdbPredicates.equalTo('key', this.extractKeyFromUri(uri))

    return await this.rdbStore.delete(rdbPredicates)
  }

  private extractKeyFromUri(uri: string): string {
    // 从URI中提取key
    const parts = uri.split('/')
    return parts[parts.length - 1]
  }
}

8.7.3 6.6.3 数据权限控制

// 数据权限管理器
class DataPermissionManager {
  // 权限级别定义
  static readonly PERMISSION_PUBLIC_READ = 'public_read'
  static readonly PERMISSION_PUBLIC_WRITE = 'public_write'
  static readonly PERMISSION_SAME_SIGNATURE = 'same_signature'
  static readonly PERMISSION_SYSTEM = 'system_only'

  // 检查访问权限
  static checkPermission(requestingApp: string,
      dataOwner: string, permission: string): boolean {
    switch (permission) {
      case DataPermissionManager.PERMISSION_PUBLIC_READ:
        return true // 所有应用可读

      case DataPermissionManager.PERMISSION_PUBLIC_WRITE:
        return true // 所有应用可写

      case DataPermissionManager.PERMISSION_SAME_SIGNATURE:
        // 需要相同签名
        return DataPermissionManager.hasSameSignature(requestingApp, dataOwner)

      case DataPermissionManager.PERMISSION_SYSTEM:
        // 仅系统应用
        return DataPermissionManager.isSystemApp(requestingApp)

      default:
        return false
    }
  }

  // 检查是否同签名
  private static hasSameSignature(app1: string, app2: string): boolean {
    // 实际实现中比较应用签名
    return app1 === app2
  }

  // 检查是否系统应用
  private static isSystemApp(bundleName: string): boolean {
    // 实际实现中检查应用类型
    return bundleName.startsWith('com.huawei.')
  }

  // 生成权限配置
  static generatePermissionConfig(
      rules: PermissionRule[]): DataPermissionConfig {
    return {
      version: 1,
      rules: rules,
      updatedAt: Date.now()
    }
  }
}

interface PermissionRule {
  pathPattern: string
  permission: string
  allowedApps?: string[]
  deniedApps?: string[]
}

interface DataPermissionConfig {
  version: number
  rules: PermissionRule[]
  updatedAt: number
}

8.7.4 6.6.4 数据格式标准化

// 标准化数据格式转换器
class DataFormatStandardizer {
  // 将应用内部数据转换为标准交换格式
  static toStandardFormat(data: Object,
      schema: DataSchema): StandardDataFormat {
    const result: StandardDataFormat = {
      version: '1.0',
      type: schema.type,
      timestamp: Date.now(),
      source: schema.source,
      payload: {}
    }

    // 按照Schema映射字段
    for (const field of schema.fields) {
      const value = (data as Record<string, Object>)[field.sourceName]
      if (value !== undefined) {
        result.payload[field.targetName] = {
          value: DataFormatStandardizer.convertValue(value, field.type),
          type: field.type,
          unit: field.unit
        }
      }
    }

    return result
  }

  // 将标准格式转换为应用内部格式
  static fromStandardFormat(standard: StandardDataFormat,
      schema: DataSchema): Object {
    const result: Record<string, Object> = {}

    for (const field of schema.fields) {
      const standardField = standard.payload[field.targetName]
      if (standardField) {
        result[field.sourceName] = DataFormatStandardizer
          .convertValue(standardField.value, field.type)
      }
    }

    return result
  }

  // 值类型转换
  private static convertValue(value: Object,
      targetType: string): Object {
    switch (targetType) {
      case 'string':
        return String(value)
      case 'number':
        return Number(value)
      case 'boolean':
        return Boolean(value)
      case 'timestamp':
        return typeof value === 'number' ? value : Date.parse(String(value))
      default:
        return value
    }
  }
}

interface DataSchema {
  type: string
  source: string
  fields: FieldMapping[]
}

interface FieldMapping {
  sourceName: string
  targetName: string
  type: string
  unit?: string
  required: boolean
}

interface StandardDataFormat {
  version: string
  type: string
  timestamp: number
  source: string
  payload: Record<string, StandardFieldValue>
}

interface StandardFieldValue {
  value: Object
  type: string
  unit?: string
}

8.8 本章小结

本章全面介绍了HarmonyOS分布式数据管理的核心技术:

  1. 分布式数据对象:掌握了数据对象模型的设计原则,理解了属性级别的变更通知机制,学会了配置不同的同步策略(实时/定时/手动),以及冲突检测与解决的多种方案。

  2. 分布式数据同步:理解了三种同步模式的特点与适用场景,掌握了数据一致性保证机制(乐观锁、版本号),学会了离线数据处理和网络状态感知的实现方法。

  3. 关系型数据库高级:深入使用了RDB进行复杂查询,掌握了SQL查询优化技巧(谓词下推、索引优化、覆盖索引),学会了事务操作、批量插入和数据备份恢复。

  4. 键值对分布式存储:理解了分布式KV存储的架构,掌握了数据分区策略和加密存储的实现方法。

  5. 首选项与持久化:掌握了Preferences的异步操作、数据版本化迁移策略和配置管理最佳实践。

  6. 数据共享与交换:学会了跨应用数据共享的实现,掌握了DataShare服务的开发和数据权限控制方法。


8.9 练习题

8.9.1 一、单选题

1. 在HarmonyOS分布式KV存储中,以下哪个安全级别最高?

A. SecurityLevel.S1 B. SecurityLevel.S2 C. SecurityLevel.S3 D. SecurityLevel.S4

答案:D

解析: SecurityLevel 枚举值从 S1 到 S4,安全级别依次递增。S4 是最高安全级别,适用于存储高度敏感的数据,如用户密码、支付信息等。S1 适用于一般数据存储。


2. 在关系型数据库(RDB)中,以下哪种做法会导致索引失效?

A. 使用等值查询 WHERE id = 1 B. 对查询字段使用函数 WHERE UPPER(name) = 'ABC' C. 使用范围查询 WHERE age > 18 D. 使用复合索引的前缀列进行查询

答案:B

解析: 对查询字段使用函数(如 UPPER()LOWER() 等)会导致数据库无法使用该列上的索引,因为索引存储的是原始值而非函数处理后的值。应改为在应用层处理或使用函数索引。


3. Preferences数据迁移的最佳实践是什么?

A. 直接覆盖旧数据 B. 使用版本号逐步迁移 C. 删除旧数据后重新创建 D. 不做迁移,让用户重新配置

答案:B

解析: 最佳实践是使用版本号进行逐步迁移。每次应用更新时检查存储的数据版本号,如果低于当前版本,则按版本顺序逐步执行迁移操作。这样可以确保数据完整性和向后兼容性。


4. 分布式数据对象的冲突解决策略中,哪种策略适用于多人协同编辑场景?

A. 本地优先(LOCAL_WINS) B. 远程优先(REMOTE_WINS) C. 时间戳优先(TIMESTAMP) D. 合并策略(MERGE)

答案:D

解析: 在多人协同编辑场景中,多个用户可能同时修改同一文档的不同部分。合并策略(MERGE)可以尝试将各方的修改进行合并,保留所有人的编辑内容,而不是简单地覆盖某一方的修改。


8.9.2 二、多选题

5. 以下哪些是HarmonyOS提供的分布式数据存储方式?

A. 分布式数据对象(Distributed Data Object) B. 分布式KV存储(Distributed KV Store) C. 关系型数据库(RDB) D. 首选项(Preferences) E. 文件系统(File)

答案:A、B

解析: HarmonyOS提供的分布式数据存储方式主要包括分布式数据对象和分布式KV存储,它们支持跨设备数据自动同步。关系型数据库(RDB)和首选项(Preferences)是本地存储方式,不直接支持分布式同步。文件系统也是本地存储。


6. 关于RDB(关系型数据库)的查询优化,以下哪些做法是正确的?

A. 使用 RdbPredicates 代替手写SQL B. 避免在WHERE子句中对索引列使用函数 C. 使用 SELECT * 获取所有列 D. 创建复合索引时遵循最左前缀原则 E. 使用预编译语句提高重复查询效率

答案:A、B、D、E

解析: 使用 RdbPredicates 更安全且高效(A正确);对索引列使用函数会导致索引失效(B正确);SELECT * 会返回不需要的列,浪费资源,应只查询需要的列(C错误);复合索引遵循最左前缀原则(D正确);预编译语句可以避免重复解析SQL(E正确)。


8.9.3 三、判断题

7. 分布式KV存储的 autoSync 选项设置为 true 时,数据变更会自动同步到所有已连接的设备。

答案:正确

解析:autoSync 设置为 true 时,KV存储会在数据变更时自动触发同步操作,将变更推送到同一网络中的其他设备。开发者也可以通过设置为 false 来手动控制同步时机。


8. DataShare服务只能提供数据读取功能,不支持数据写入。

答案:错误

解析: DataShare服务支持完整的CRUD操作,包括查询(query)、插入(insert)、更新(update)和删除(delete)。Provider端需要实现这些接口来提供数据共享服务。