HarmonyOS Next 入門實戰 - 關係型資料庫、smartdb

睡精灵s發表於2024-12-24

SQLite資料庫

HarmonyOS的關係型資料庫基於SQLite
匯入模組

import { relationalStore } from '@kit.ArkData';

實現步驟:

  1. 獲取RdbStore物件,用於建立資料庫,資料表,以及資料庫升級等操作
let storeConfig = {
  name: 'Poetry.db',  //資料庫檔名
  securityLevel: relationalStore.SecurityLevel.S1,  //安全級別
  encrypt: false, //是否加密,可選,預設不加密
  customDir: '', 	//自定義路徑,可選,目錄:context.databaseDir + '/rdb/' + customDir
  isReadOnly: false, //是否已只讀方式開啟,可選,預設false
}

relationalStore.getRdbStore(this.context, this.storeConfig)
  .then(store => {
    //建立表
    store.executeSql('sql')
    //判斷版本
    store.version
  })
  .catch((err: Error) => {
    
  })
  1. 插入資料
let data :ValuesBucket={
  name:"zhangsan",
  age: 23,
}
store.insert("tableName",data).then((rowId)=>{
  //操作成功返回rowId,否則返回-1
})

store.batchInsert() //用於插入批次資料
  1. 修改,刪除資料:透過元件提供的謂詞(Predicates)修改或刪除元件
let data :ValuesBucket={
  name:"zhangsan",
  age: 26,
}
let predicates = new relationalStore.RdbPredicates("tableName")
predicates.equalTo("name","zhangsan")
//更新資料
store.update(data,predicates).then((value)=>{

})

//刪除資料
store.delete(predicates).then((value)=>{

})
  1. 查詢資料
let predicates = new relationalStore.RdbPredicates("tableName")
predicates.equalTo("name","zhangsan")
store.query(predicates).then((resultSet)=>{
  while (resultSet.goToNextRow()){
    const name = resultSet.getString(resultSet.getColumnIndex("name"))
    const age = resultSet.getLong(resultSet.getColumnIndex("age"))
  }
  resultSet.close()
})
//也可以透過下面介面使用sql查詢
store.querySql(sql: string, bindArgs?: Array<ValueType>): Promise<ResultSet>;
  1. 備份資料和恢復資料
//備份資料
store.backup("backup.db")
//恢復資料
store.restore("backup.db")

SmartDB

SmartDB與Android中的room元件類似,可以簡化我們資料庫操作的步驟,使程式碼更易維護。
安裝和匯入模組

//安裝模組
ohpm install @liushengyi/smartdb
//匯入模組
import sql from "@liushengyi/smartdb"

定義資料結構:

export class Poetry {
  @sql.SqlColumn(sql.ColumnType.TEXT)
  uuid?: string
  @sql.SqlColumn(sql.ColumnType.TEXT)
  title?: string
  @sql.SqlColumn(sql.ColumnType.TEXT)
  dynasty?: string
  @sql.SqlColumn(sql.ColumnType.TEXT)
  author?: string
  @sql.SqlColumn(sql.ColumnType.TEXT)
  introduction?: string
  @sql.SqlColumn(sql.ColumnType.TEXT)
  text?: string
  @sql.SqlColumn(sql.ColumnType.TEXT)
  textAlign?: string
  @sql.SqlColumn(sql.ColumnType.TEXT)
  translation?: string
  @sql.SqlColumn(sql.ColumnType.TEXT)
  rectify?: string
  @sql.SqlColumn(sql.ColumnType.TEXT)
  searchKey?: string
}

執行資料庫操作:進行增刪改查、事務操作

export class PoetryDao {
  public static TABLE_NAME = "Poetry"
  public static SQL_CREATE_TABLE =
    "CREATE TABLE IF NOT EXISTS `Poetry` (`uuid` TEXT NOT NULL, `title` TEXT, `dynasty` TEXT, `author` TEXT, `introduction` TEXT, `text` TEXT, `textAlign` TEXT, `translation` TEXT, `rectify` TEXT, `searchKey` TEXT, PRIMARY KEY(`uuid`))"

  @sql.SqlQuery(`select * from ${PoetryDao.TABLE_NAME} where uuid=#{uuid}`)
  @sql.ReturnType(Poetry)
  queryOne(@sql.Param('uuid') uuid: string): Promise<Poetry> {
    return sql.PromiseNull()
  }

  @sql.SqlQuery(`select count(*) from ${PoetryDao.TABLE_NAME} `)
  @sql.ReturnType(Number)
  queryCount(): Promise<Number> {
    return sql.PromiseNull()
  }

  @sql.SqlInsert(`insert into ${PoetryDao.TABLE_NAME} values (#{data.uuid},#{data.title},#{data.dynasty},#{data.author},#{data.introduction},#{data.text},#{data.textAlign},#{data.translation},#{data.rectify},#{data.searchKey})`)
  insert(@sql.Param('data') data: Poetry): Promise<void> {
    return sql.PromiseNull()
  }
  
  @sql.Transactional()
  async insertPoetryAll(list: Poetry[]) {
    for (let item of list) {
      await this.insert(item)
    }
  }
}

資料庫管理:建立資料庫、資料庫升級

export class DatabaseManager {
  static readonly DATABASE_VERSION = 1
  static readonly DATABASE_NAME = 'poetry.db'

  static init(context: Context) {
    sql.dbHelper.initDb(context,
      DatabaseManager.DATABASE_NAME,
      DatabaseManager.DATABASE_VERSION,
      new DbOpenHelperImpl()
    )
  }
}

class DbOpenHelperImpl extends sql.DbOpenHelper {
  //建立資料庫
  onCreate(db: relationalStore.RdbStore): void {
    db.executeSql(PoetryDao.SQL_CREATE_TABLE)
  }

  //升級資料
  onUpgrade(db: relationalStore.RdbStore, oldVersion: number, newVersion: number): void {

  }
}

最後在app啟動的時候呼叫初始化方法

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
    DatabaseManager.init(this.context)
  }
}

資料初始化和使用

將json格式的資料插入到資料庫中

poetryDao: PoetryDao = new PoetryDao()

new Promise<boolean>(async (resolve, reject) => {
  try {
    let count = await this.poetryDao.queryCount()
    if (!count) {
      let list = await (await import("resources/rawfile/poetry.json")).default
      let poetryArray: Array<Poetry> = []
      for (let item of list) {
        let poetry = item as Poetry
        poetry.uuid = util.generateRandomUUID()
        if (poetry.rectify) {
          poetry.rectify = JSON.stringify(poetry.rectify)
        }
        poetryArray.push(poetry)
      }
      this.poetryDao.insertPoetryAll(poetryArray)
      resolve(true)
    } else {
      resolve(false)
    }
  } catch (e) {
    reject(e)
  }
})

讀取資料

//讀取所有資料
new PoetryDao().queryList()
  .then((value) => {

  })
//讀取一條資料
new PoetryDao().queryOne("id")
  .then((value) => {

  })

本文的技術設計和實現都是基於作者工作中的經驗總結,如有錯誤,請留言指正,謝謝。

相關文章