一、使用关系型数据库实现数据持久化,需要获取一个RdbStore,其中包括建库、建表、升降级等操作。

   const STORE_CONFIG: relationalStore.StoreConfig = {
      name: 'AnyOffice.db', // 数据库文件名
      securityLevel: relationalStore.SecurityLevel.S1, // 数据库安全级别
      encrypt: false, // 可选参数,指定数据库是否加密,默认不加密
      isReadOnly: false // 可选参数,指定数据库是否以只读方式打开。该参数默认为false,表示数据库可读可写。该参数为true时,只允许从数据库读取数据,不允许对数据库进行写操作,否则会返回错误码801。
    };
    relationalStore.getRdbStore(this.context, STORE_CONFIG, (err, store) => {
      if (err) {
        console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
        return;
      }
      APPDataBaseHelper.getInstance().initialStore(store)
      APPDataBaseHelper.getInstance().initialize()
    })
  }

二、获取到RdbStore,完成数据表创建后,进行表的操作

import { relationalStore } from '@kit.ArkData';
import { BusinessError } from '@kit.BasicServicesKit';
import { IAppData } from '../pages/AppStore/AppStoreM';

const TAG = 'APPDataBaseHelper:'
// 表名和字段定义
const TABLE_NAME = 'AnyOfficeApps';
const COLUMN_USER = 'user'
const COLUMN_APK_URL = 'apk'
const COLUMN_ID = 'appId'
const COLUMN_ICON_URL = 'iconURL'
const COLUMN_APP_NAME = 'appName'
const COLUMN_APP_VERSION = 'appVersion'
const COLUMN_APP_SIZE = 'appSize'
const COLUMN_APP_PACKAGE_NAME = 'packageName'
const COLUMN_APP_STATE = 'appState'


const SQL_CREATE_TABLE =
  `CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (ID INTEGER PRIMARY KEY AUTOINCREMENT,${COLUMN_USER} TEXT,${COLUMN_APK_URL} TEXT,${COLUMN_ID} INTEGER NOT NULL,${COLUMN_ICON_URL} TEXT,${COLUMN_APP_NAME} TEXT UNIQUE NOT NULL,${COLUMN_APP_VERSION} TEXT,${COLUMN_APP_SIZE} INTEGER,${COLUMN_APP_PACKAGE_NAME} TEXT NOT NULL,${COLUMN_APP_STATE} INTEGER NOT NULL)`

export class APPDataBaseHelper {
  private static instance: APPDataBaseHelper
  private rdbStore: relationalStore.RdbStore | null = null;

  private constructor() {
  }

  public static getInstance() {
    if (!APPDataBaseHelper.instance) {
      APPDataBaseHelper.instance = new APPDataBaseHelper()
    }
    return APPDataBaseHelper.instance
  }

  async initialStore(store: relationalStore.RdbStore): Promise<void> {
    this.rdbStore = store
  }

  //初始化表
  async initialize(): Promise<void> {
    if (!this.rdbStore) {
      return
    }
    if (this.rdbStore.version === 0) {
      // 创建表
      await this.rdbStore.executeSql(SQL_CREATE_TABLE).catch((err: BusinessError) => {
        console.error(`Database initialization failed. Code: ${err.code}, Message: ${err.message}`);
        return
      });
      console.info(`${TAG}Table created successfully.`);
    }
  }

  /**
   * 批量插入数据
   * @param apps
   * @returns
   */
  async batchInsertApps(apps: IAppData[]): Promise<void> {
    if (!this.rdbStore || this.rdbStore === undefined) {
      throw new Error('Database not initialized. Call initialize() first.');
    }
    try {
      let userName = AppStorage.get<string>('userName')
      //开启事务
      this.rdbStore.beginTransaction()
      for (const app of apps) {
        const valueBucket: relationalStore.ValuesBucket = {
          user: userName ?? '',
          apk: app.apk,
          appId: app.id,
          iconURL: app.iconURL,
          appName: app.appName,
          appVersion: app.appVersion,
          appSize: app.appSize,
          packageName: app.packageName,
          appState: 0
        }
        const checkAppExist = await this.checkAppExist(app.packageName)
        if (!checkAppExist) {
          await this.rdbStore.insert(TABLE_NAME, valueBucket)
        }
      }
      //提交事务
      this.rdbStore.commit()
      console.info(`${TAG}Batch insert succeeded.`);
    } catch (err) {
      // 回滚事务
      this.rdbStore.rollBack();
      const error = err as BusinessError;
      console.error(`${TAG}Batch insert failed. Code: ${error.code}, Message: ${error.message}`);
    }

  }

  /**
   * 更新应用状态
   * @param id
   * @param state 0 未安装 1 已安装 2 待更新
   * @returns
   */
  async updateAppState(id: number, state: number): Promise<boolean> {
    if (!this.rdbStore || this.rdbStore === undefined) {
      console.info(`${TAG}Database not initialized. Call initialize() first.`);
      return false
    }
    const valueBucket: relationalStore.ValuesBucket = {
      appState: state
    }
    let userName = AppStorage.get<string>('userName')
    const predicates = new relationalStore.RdbPredicates(TABLE_NAME);
    predicates.equalTo(`${COLUMN_ID}`, id).and().equalTo(`${COLUMN_USER}`, userName)
    const result = await this.rdbStore.update(valueBucket, predicates)
    console.info(`${TAG}updateAppState is ${result}`)
    return result > 0
  }


  /**
   * 查询所有app数据
   * @returns
   */
  async queryAllApp(): Promise<IAppData[]> {
    if (!this.rdbStore || this.rdbStore === undefined) {
      console.info(`${TAG}Database not initialized. Call initialize() first.`);
      return []
    }
    let userName = AppStorage.get<string>('userName')
    const predicates = new relationalStore.RdbPredicates(TABLE_NAME);
    predicates.equalTo(`${COLUMN_USER}`, userName)
    const COLUMNS = [COLUMN_APK_URL, COLUMN_ID, COLUMN_ICON_URL, COLUMN_APP_NAME, COLUMN_APP_VERSION, COLUMN_APP_SIZE,
      COLUMN_APP_PACKAGE_NAME]
    try {
      const result = await this.rdbStore.query(predicates, COLUMNS)
      const apps: IAppData[] = []
      while (result.goToNextRow()) {
        const app: IAppData = {
          iconURL: result.getString(result.getColumnIndex(`${COLUMN_ICON_URL}`)),
          appName: result.getString(result.getColumnIndex(`${COLUMN_APP_NAME}`)),
          appVersion: result.getString(result.getColumnIndex(`${COLUMN_APP_VERSION}`)),
          appSize: result.getLong(result.getColumnIndex(`${COLUMN_APP_SIZE}`)),
          id: result.getLong(result.getColumnIndex(`${COLUMN_ID}`)),
          apk: result.getString(result.getColumnIndex(`${COLUMN_APK_URL}`)),
          packageName: result.getString(result.getColumnIndex(`${COLUMN_APP_PACKAGE_NAME}`))
        }
        apps.push(app)
      }
      result.close()
      return apps
    } catch (err) {
      const error = err as BusinessError;
      console.error(`Query failed. Code: ${error.code}, Message: ${error.message}`);
      return []
    }
  }

  /**
   * 获取所有已经安装的app
   * @returns
   */
  async queryAllInstalledApp(): Promise<IAppData[]> {
    if (!this.rdbStore || this.rdbStore === undefined) {
      console.info('Database not initialized. Call initialize() first.');
      return []
    }
    let userName = AppStorage.get<string>('userName')
    const predicates = new relationalStore.RdbPredicates(TABLE_NAME);
    predicates.equalTo(`${COLUMN_APP_STATE}`, 1).and().equalTo(`${COLUMN_USER}`, userName)
    const COLUMNS = [COLUMN_APK_URL, COLUMN_ID, COLUMN_ICON_URL, COLUMN_APP_NAME, COLUMN_APP_VERSION, COLUMN_APP_SIZE,
      COLUMN_APP_PACKAGE_NAME]
    try {
      const result = await this.rdbStore.query(predicates, COLUMNS)
      const apps: IAppData[] = []
      while (result.goToNextRow()) {
        const app: IAppData = {
          iconURL: result.getString(result.getColumnIndex(`${COLUMN_ICON_URL}`)),
          appName: result.getString(result.getColumnIndex(`${COLUMN_APP_NAME}`)),
          appVersion: result.getString(result.getColumnIndex(`${COLUMN_APP_VERSION}`)),
          appSize: result.getLong(result.getColumnIndex(`${COLUMN_APP_SIZE}`)),
          id: result.getLong(result.getColumnIndex(`${COLUMN_ID}`)),
          apk: result.getString(result.getColumnIndex(`${COLUMN_APK_URL}`)),
          packageName: result.getString(result.getColumnIndex(`${COLUMN_APP_PACKAGE_NAME}`))
        }
        apps.push(app)
      }
      result.close()
      return apps
    } catch (err) {
      const error = err as BusinessError;
      console.error(`Query failed. Code: ${error.code}, Message: ${error.message}`);
      return []
    }
  }

   /**
   * 检查数据是否已存在
   * @param packageName
   * @returns
   */
  async checkAppExist(packageName: string): Promise<boolean> {
    if (!this.rdbStore) {
      return false
    }
    let userName = AppStorage.get<string>('userName')
    const predicates = new relationalStore.RdbPredicates(TABLE_NAME);
    predicates.equalTo(`${COLUMN_APP_PACKAGE_NAME}`, packageName).and().equalTo(`${COLUMN_USER}`, userName);
    const resultSet = await this.rdbStore.query(predicates, [`${COLUMN_APP_PACKAGE_NAME}`])
    let exist=resultSet.rowCount>0
    resultSet.close()
    return exist
  }
}

三、官网文档连接

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐