HarmonyOS 鸿蒙 本地数据库开发实战指南:从原理到封装

HarmonyOS 鸿蒙 本地数据库开发实战指南:从原理到封装

本文基于 HarmonyOS 5.1 (API 11) 深度解析,原创封装数据库工具类已开源至Gitee

一、HarmonyOS 数据库核心架构

1.1 关系型数据库(RDB)三大核心组件

组件 功能描述 核心类
RdbStore 数据库核心操作接口 @ohos.data.relationalStore.RdbStore
Predicates 数据查询条件构建 @ohos.data.relationalStore.RdbPredicates
ResultSet 查询结果集处理 @ohos.data.ResultSet

1.2 数据库事务处理机制

typescript 复制代码
await rdbStore.beginTransaction();  // 开启事务

try {
  // 执行多个操作
  await rdbStore.insert('User', { name: 'Alice', age: 28 });
  await rdbStore.update({ age: 30 }, predicates);
  
  await rdbStore.commit();  // 提交事务
} catch (err) {
  await rdbStore.rollback();  // 回滚事务
  Logger.error(`Transaction failed: ${err.message}`);
}

1.3 分布式数据库同步原理

graph LR A[设备A] -->|加密通道| B[分布式数据服务] B --> C[设备B] C --> D[自动冲突解决]

二、数据库操作全流程实战

2.1 数据库初始化封装

typescript 复制代码
import relationalStore from '@ohos.data.relationalStore';
import { BusinessError } from '@ohos.base';

class DatabaseManager {
  private static instance: DatabaseManager | null = null;
  private rdbStore: relationalStore.RdbStore | null = null;
  
  // 单例模式
  static getInstance(context: Context): DatabaseManager {
    if (!DatabaseManager.instance) {
      DatabaseManager.instance = new DatabaseManager(context);
    }
    return DatabaseManager.instance;
  }
  
  private constructor(private context: Context) {}
  
  // 初始化数据库
  async init(config: relationalStore.StoreConfig): Promise<void> {
    const defaultConfig: relationalStore.StoreConfig = {
      name: 'AppData.db',
      securityLevel: relationalStore.SecurityLevel.S4,
      encrypt: true,
      dataGroupId: 'com.example.app.datagroup'
    };
    
    const mergeConfig = { ...defaultConfig, ...config };
    
    try {
      this.rdbStore = await relationalStore.getRdbStore(this.context, mergeConfig);
      Logger.info('Database initialized successfully');
    } catch (err) {
      const error = err as BusinessError;
      Logger.error(`Database init failed: ${error.message}`);
      throw error;
    }
  }
  
  // 创建表结构
  async createTable(tableName: string, schema: string): Promise<void> {
    if (!this.rdbStore) {
      throw new Error('Database not initialized');
    }
    
    const sql = `CREATE TABLE IF NOT EXISTS ${tableName} (${schema})`;
    try {
      await this.rdbStore.executeSql(sql);
      Logger.info(`Table ${tableName} created`);
    } catch (err) {
      const error = err as BusinessError;
      Logger.error(`Create table failed: ${error.message}`);
      throw error;
    }
  }
}

2.2 数据操作CRUD封装

typescript 复制代码
class DataRepository<T extends Object> {
  constructor(
    private rdbStore: relationalStore.RdbStore,
    private tableName: string
  ) {}
  
  // 插入数据
  async insert(entity: T): Promise<number> {
    try {
      const rowId = await this.rdbStore.insert(this.tableName, entity);
      Logger.info(`Inserted to ${this.tableName}: ${rowId}`);
      return rowId;
    } catch (err) {
      const error = err as BusinessError;
      Logger.error(`Insert failed: ${error.message}`);
      throw error;
    }
  }
  
  // 条件查询
  async query(predicates: relationalStore.RdbPredicates): Promise<T[]> {
    try {
      const resultSet = await this.rdbStore.query(predicates, 
        ['*'] // 返回所有字段
      );
      
      const results: T[] = [];
      while (resultSet.goToNextRow()) {
        results.push(resultSet.getRow() as T);
      }
      resultSet.close();
      
      return results;
    } catch (err) {
      const error = err as BusinessError;
      Logger.error(`Query failed: ${error.message}`);
      throw error;
    }
  }
  
  // 更新数据
  async update(values: Object, predicates: relationalStore.RdbPredicates): Promise<number> {
    try {
      const rowsUpdated = await this.rdbStore.update(values, predicates);
      Logger.info(`Updated ${rowsUpdated} rows in ${this.tableName}`);
      return rowsUpdated;
    } catch (err) {
      const error = err as BusinessError;
      Logger.error(`Update failed: ${error.message}`);
      throw error;
    }
  }
  
  // 删除数据
  async delete(predicates: relationalStore.RdbPredicates): Promise<number> {
    try {
      const rowsDeleted = await this.rdbStore.delete(predicates);
      Logger.info(`Deleted ${rowsDeleted} rows from ${this.tableName}`);
      return rowsDeleted;
    } catch (err) {
      const error = err as BusinessError;
      Logger.error(`Delete failed: ${error.message}`);
      throw error;
    }
  }
}

2.3 高级查询构建器

typescript 复制代码
class QueryBuilder {
  private predicates: relationalStore.RdbPredicates;
  
  constructor(tableName: string) {
    this.predicates = new relationalStore.RdbPredicates(tableName);
  }
  
  where(column: string, value: ValueType): this {
    this.predicates.equalTo(column, value);
    return this;
  }
  
  orderBy(column: string, isAsc: boolean = true): this {
    this.predicates.orderBy(column, isAsc);
    return this;
  }
  
  limit(limit: number, offset?: number): this {
    this.predicates.limit(limit, offset);
    return this;
  }
  
  groupBy(columns: string[]): this {
    this.predicates.groupBy(columns);
    return this;
  }
  
  build(): relationalStore.RdbPredicates {
    return this.predicates;
  }
}

// 使用示例
const query = new QueryBuilder('User')
  .where('age', '>', 18)
  .orderBy('name', true)
  .limit(10)
  .build();

const users = await userRepo.query(query);

三、高级特性实战

3.1 分布式数据同步

typescript 复制代码
// 配置分布式同步
const config: relationalStore.SyncConfig = {
  mode: relationalStore.SyncMode.SYNC_MODE_PUSH, // 推送模式
  devices: ['123456789012345'], // 目标设备ID
};

try {
  await rdbStore.sync(config);
  Logger.info('Data sync completed');
} catch (err) {
  const error = err as BusinessError;
  Logger.error(`Sync failed: ${error.message}`);
}

3.2 数据库加密与备份

typescript 复制代码
// 更改加密密钥
async changeEncryptionKey(newKey: Uint8Array): Promise<void> {
  try {
    await this.rdbStore.changeEncryptKey(newKey);
    Logger.info('Encryption key changed');
  } catch (err) {
    const error = err as BusinessError;
    Logger.error(`Change key failed: ${error.message}`);
    throw error;
  }
}

// 数据库备份
async backup(backupPath: string): Promise<void> {
  try {
    await this.rdbStore.backup(backupPath);
    Logger.info(`Database backed up to ${backupPath}`);
  } catch (err) {
    const error = err as BusinessError;
    Logger.error(`Backup failed: ${error.message}`);
    throw error;
  }
}

四、ORM高级封装库

4.1 实体类定义(装饰器方案)

typescript 复制代码
import { Entity, Column, PrimaryKey } from './decorators';

@Entity('User')
class User {
  @PrimaryKey({ autoIncrement: true })
  id: number = 0;
  
  @Column('TEXT', { notNull: true })
  name: string = '';
  
  @Column('INTEGER')
  age: number = 0;
  
  @Column('BOOLEAN', { default: false })
  isVip: boolean = false;
}

4.2 数据仓库封装

typescript 复制代码
class BaseRepository<T> {
  constructor(private entityClass: new () => T) {}
  
  async save(entity: T): Promise<number> {
    // 自动处理插入或更新
  }
  
  async findById(id: number): Promise<T | null> {
    // 根据ID查询
  }
  
  async findAll(): Promise<T[]> {
    // 查询所有记录
  }
  
  async delete(entity: T): Promise<boolean> {
    // 根据主键删除
  }
}

// 使用示例
const userRepo = new BaseRepository(User);
const newUser = new User();
newUser.name = 'Bob';
newUser.age = 30;
await userRepo.save(newUser);

五、性能优化实践

5.1 数据库索引优化

typescript 复制代码
// 创建索引
async createIndex(table: string, column: string): Promise<void> {
  const sql = `CREATE INDEX IF NOT EXISTS idx_${table}_${column} ON ${table}(${column})`;
  await this.rdbStore.executeSql(sql);
}

// 索引使用场景
// 1. WHERE条件中的字段
// 2. ORDER BY排序字段
// 3. JOIN操作字段

5.2 批处理操作

typescript 复制代码
async batchInsert(table: string, entities: Object[]): Promise<number> {
  await this.rdbStore.beginTransaction();
  
  try {
    let count = 0;
    for (const entity of entities) {
      await this.rdbStore.insert(table, entity);
      count++;
    }
    
    await this.rdbStore.commit();
    return count;
  } catch (err) {
    await this.rdbStore.rollback();
    throw err;
  }
}

六、完整封装库使用示例

typescript 复制代码
// 初始化数据库
const dbManager = DatabaseManager.getInstance(context);
await dbManager.init({
  name: 'MyAppData.db'
});

// 创建表
await dbManager.createTable('Product', `
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL,
  price REAL,
  stock INTEGER DEFAULT 0,
  createdAt INTEGER
`);

// 创建数据仓库
const productRepo = new DataRepository<Product>(dbManager.rdbStore!, 'Product');

// 插入数据
const newProduct = {
  name: 'HarmonyOS开发指南',
  price: 99.9,
  stock: 100
};
await productRepo.insert(newProduct);

// 查询数据
const query = new QueryBuilder('Product')
  .where('price', '<', 100)
  .orderBy('name')
  .build();
  
const products = await productRepo.query(query);

// 分布式同步
await dbManager.syncToDevice('目标设备ID');

七、资源与开源

  1. 官方文档

  2. 开源项目

原创声明:本文内容及封装类均为原创,转载请注明出处。更多鸿蒙开发技巧请关注专栏 #HarmonyOS进阶实战

相关推荐
li理2 小时前
鸿蒙应用本地数据库导出与查看指南
harmonyos
xo198820113 小时前
鸿蒙Des 加密解密 C++版本
c++·华为·harmonyos
HarmonyOS小助手4 小时前
【上新啦】HarmonyOS官方模板优秀案例 (第2期:新闻行业 · 综合新闻)
harmonyos·鸿蒙·鸿蒙生态
HarmonyOS_SDK4 小时前
HarmonyOS SDK助力高德地图创新,带来便捷出行新体验
harmonyos
whysqwhw6 小时前
鸿蒙freezeWhenInactive性能优化
harmonyos
何阿苗1 天前
开发者技术支持-鸿蒙弹窗开发技术问题总结
harmonyos
zhanshuo1 天前
跨设备开发不再难:HarmonyOS 分布式任务管理应用全解析
harmonyos
zhanshuo1 天前
鸿蒙本地与云端数据双向同步实战:从原理到可运行 Demo 的全流程指南
harmonyos
张风捷特烈1 天前
鸿蒙纪·Flutter卷#02 | 已有 Flutter 项目鸿蒙化 · 3.27.4 版
android·flutter·harmonyos