HarmonyOS 鸿蒙Next 第三方数据库的使用问题

发布于 1周前 作者 eggper 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 第三方数据库的使用问题

目前我在测试使用的是https://gitee.com/openharmony-sig/dataORM这个数据库,麻烦帮我用这个数据库,写个关于增删改查这几个数据库操作的小demo吧。 增删改查请帮忙使用同步和异步调用的有回调的两种方式,谢谢。  

目前遇到的问题,ability设置daosession,在第一个加载的page页面aboutToAppear函数中获取的daosession为undefined。

2 回复

demo问题,需要给undefined对象赋值。 bean/Student.ets

import { Columns, ColumnType, Entity, Id } from '@ohos/dataorm';

@Entity('Student',[{value:'name',unique:true}])

export class Student {

  // @Id({autoincrement:false})

  @Columns({ columnName: 'ID', types: ColumnType.num })

  // id: number|undefined

  id: number

  @Columns({ columnName: 'NAME', types: ColumnType.str })

  name: string

  // name: string|undefined

  @Columns({ columnName: 'AGE', types: ColumnType.num })

  // age: number|undefined

  age: number

  @Columns({ columnName: 'CLASSNAME', types: ColumnType.str })

  // className: string|undefined

  className: string

  @Columns({columnName:'COMMENT',types:ColumnType.str})

  // comment:string|undefined

  comment:string

  constructor(id:number,name: string, age: number, className: string, comment: string) {

    this.id = id;

    this.name = name;

    this.age = age;

    this.className = className;

    this.comment = comment;

  }

}

EntryAbility.ets

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';

import { hilog } from '@kit.PerformanceAnalysisKit';

import { window } from '@kit.ArkUI';

import { ExampleOpenHelper } from '../utlis/ExampleOpenHelper';

import { Student } from '../bean/Student';

import { DaoMaster, DaoSession, Database, GlobalContext } from '@ohos/dataorm';

export default class EntryAbility extends UIAbility {

  async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {

    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');

    let newVersion = 1;

    console.debug('测试daosession3333')

    let helper: ExampleOpenHelper = new ExampleOpenHelper(this.context, "iceTest.db");

    // 设定数据加密密钥,加密后不可变更,加密和非加密库暂不能切换(普通数据库不能在设定为加密库,加密库不能变更为普通库,一经生成不可变更)

    helper.setEncrypt(false);

    // 设置新的数据库版本,如果新版本中包含表更新实例将在这调用onUpgradeDatabase进行表更新

    await helper.setVersion(newVersion)

    // 将所有的表(新增,修改,已存在)加到全局

    helper.setEntities(Student);

    // Migration为表更新实例,也可调用Migration.backupDB对当前数据库进行备份

    // let migration = new Migration("notes.db", "NOTE", newVersion).addColumn("MONEYS", ColumnType.realValue);

    // 将所有表更新实例放到ExampleOpenHelper的父级中

    // helper.setMigration(migration);

    console.debug('测试daosession44444')

    let db: Database = await helper.getWritableDb();

    db.name = "iceTest.db";

    GlobalContext.getContext().setValue("daoSession", new DaoMaster(db).newSession());

    let daoSession: DaoSession = GlobalContext.getContext().getValue("daoSession") as DaoSession;

    console.debug('测试daosession111--'+daoSession)

  }

  onDestroy(): void {

    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');

  }

  onWindowStageCreate(windowStage: window.WindowStage): void {

    // Main window is created, set main page for this ability

    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/Index', (err) => {

      if (err.code) {

        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');

        return;

      }

      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');

    });

  }

  onWindowStageDestroy(): void {

    // Main window is destroyed, release UI related resources

    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');

  }

  onForeground(): void {

    // Ability has brought to foreground

    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');

  }

  onBackground(): void {

    // Ability has back to background

    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');

  }

}

pages/Index.ets

import {

  BaseDao,

  DaoSession,

  GlobalContext,

  OnTableChangedListener,

  Property,

  Query,

  TableAction

} from '@ohos/dataorm';

import { Student } from '../bean/Student';

import dataRdb from '@ohos.data.relationalStore';

import { router } from '@kit.ArkUI';

let daoSession: DaoSession | null = null;

@Entry

@Component

struct Index {

  @State message: string = 'Hello World';

  // private daoSession: DaoSession | null = null;

  private stDao: BaseDao<Student, number> | null = null;

  private stQuery: Query<Student> | null = null;

  aboutToAppear() {

    // this.getDBData()

    // console.debug('测试daosession222')

  }

  getDBData() {

    daoSession = GlobalContext.getContext().getValue("daoSession") as DaoSession;

    this.stDao = daoSession.getBaseDao(Student);

    // console.debug('测试daosession222' + JSON.stringify(this.stDao))

    if (!this.stDao) {

      return;

    }

    this.stDao.addTableChangedListener(this.tabListener())

    let entityClass = GlobalContext.getContext().getValue(GlobalContext.KEY_CLS) as Record<string, Object>;

    let properties = entityClass.Student as Record<string, Property>;

    // this.stQuery = this.stDao.queryBuilder().orderAsc(properties.text).build();

    this.stQuery = this.stDao.queryBuilder().build();

  }

  tabListener(): OnTableChangedListener<dataRdb.ResultSet> {

    let that = this;

    return {

      async onTableChanged(t: dataRdb.ResultSet, action: TableAction) {

        if (action == TableAction.INSERT) {

          console.info('--------insert--------')

          // await that.updateNotes();

        } else if (action == TableAction.UPDATE) {

          console.info('--------edit--------')

          // await that.updateNotes();

        } else if (action == TableAction.DELETE) {

          console.info('--------delete--------')

          // await that.updateNotes();

        } else if (action == TableAction.QUERY) {

          console.info('--------query-------- any:' + JSON.stringify(t))

        }

      }

    }

  }

  build() {

    Column() {

      Button("11")

        .onClick(()=>{

          this.getDBData()

          console.debug('测试daosession222')

        })

      Text('插入数据').fontSize(20)

        .onClick(() => {

          router.pushUrl({

            url: 'pages/SecondPage'

          })

          // console.debug('执行数据库插入操作---11111')

          // // this.addNote()

          // this.myAsyncFunction()

          // console.debug('执行数据库插入操作---44444--'+this.myAsyncFunction())

        })

    }

  }

  async myAsyncFunction(): Promise<string> {

    const result: string = await new Promise((resolve: Function) => {

      setTimeout(() => {

        resolve('Hello, world!');

      }, 3000);

    });

    console.debug('执行数据库插入操作---555' + result)

    return result

  }

  async addNote() {

    if (!this.stDao) {

      return;

    }

    console.debug('执行数据库插入操作---22222')

    let st = new Student(1,"yiger",1,"yigeren","yigeren");

    st.name = '王国强'

    st.age = 18

    st.className = '高中'

    await this.stDao.insert(st);

    console.debug('执行数据库插入操作---33333')

  }

}

pages/SecondPage.ets

import {

  BaseDao,

  DaoSession,

  GlobalContext,

  OnTableChangedListener,

  Property,

  Query,

  TableAction

} from '@ohos/dataorm';

import { Student } from '../bean/Student';

import dataRdb from '@ohos.data.relationalStore';

import { BusinessError } from '@kit.BasicServicesKit';

@Entry

@Component

struct SecondPage {

  @State message: string = 'Hello World';

  private daoSession: DaoSession | null = null;

  private stDao: BaseDao<Student, number> | null = null;

  private stQuery: Query<Student> | null = null;

  private arr: Array<Student> = new Array<Student>()

  private ids: number = 1

  aboutToAppear(): void {

    this.getDBData()

  }

  getDBData() {

    this.daoSession = GlobalContext.getContext().getValue("daoSession") as DaoSession;

    this.stDao = this.daoSession.getBaseDao(Student);

    // console.debug('测试daosession222'+JSON.stringify(this.stDao))

    if (!this.stDao) {

      return;

    }

    this.stDao.addTableChangedListener(this.tabListener())

    // let entityClass = GlobalContext.getContext().getValue(GlobalContext.KEY_CLS) as Record<string, Object>;

    // let properties = entityClass.Student as Record<string, Property>;

    // this.stQuery = this.stDao.queryBuilder().orderAsc(properties.name).build();

  }

  tabListener(): OnTableChangedListener<dataRdb.ResultSet> {

    let that = this;

    return {

      async onTableChanged(t: dataRdb.ResultSet, action: TableAction) {

        if (action == TableAction.INSERT) {

          console.info('--------insert--------')

          // await that.updateNotes();

        } else if (action == TableAction.UPDATE) {

          console.info('--------edit--------')

          // await that.updateNotes();

        } else if (action == TableAction.DELETE) {

          console.info('--------delete--------')

          // await that.updateNotes();

        } else if (action == TableAction.QUERY) {

          console.info('--------query-------- any:' + JSON.stringify(t))

        }

      }

    }

  }

  async addNote() {

    if (!this.stDao) {

      return;

    }

    let date = new Date()

    let comment = "Added on " + date.toLocaleString();

    let st = new Student();

    st.name = '王国强1121'

    st.age = 12

    // st.className = '高中'

    st.comment = comment

    try {

      await this.stDao.insert(st)

    } catch (error) {

      console.debug('执行数据库插入操作---error---' + JSON.stringify(error))

    }

    // this.stDao.insert(st)

    console.debug('执行数据库插入操作---33333')

    this.query()

  }

  async updateNotes() {

    if (this.stQuery) {

      this.arr = await this.stQuery.list();

    }

  }

  build() {

    Column() {

      Text('插入数据')

        .id('SecondPageHelloWorld')

        .fontSize(50)

        .fontWeight(FontWeight.Bold)

        .onClick(() => {

          this.ids++

          this.addNote()

        })

      Text('查询数据').fontSize(40)

        .onClick(() => {

          this.query()

        })

      Text('删除清空表数据').fontSize(40)

        .onClick(() => {

          this.deleteTable()

        })

    }

  }

  deleteTable() {

    //删除

    if (!this.stDao) {

      return;

    }

    let entityClass = GlobalContext.getContext().getValue(GlobalContext.KEY_CLS) as Record<string, Object>;

    let properties = entityClass.Student as Record<string, Property>;

    let deleteQuery = this.stDao.queryBuilder().where(properties.name.eq("王国强111"))

      .buildDelete();

    deleteQuery.executeDeleteWithoutDetachingEntities()

    console.debug('执行数据库删除操作---888--delete-')

  }

  async query() {

    if (!this.stDao) {

      return;

    }

    let entityClass = GlobalContext.getContext().getValue(GlobalContext.KEY_CLS) as Record<string, Object>;

    let properties = entityClass.Student as Record<string, Property>;

    let query = this.stDao.queryBuilder().orderAsc(properties.name).buildCursor();

    let a = await query.list();

    if (!a) {

      a = [];

    }

    this.arr = a;

    console.debug('执行数据库查询操作---888--quary-' + this.arr.length + '===' + JSON.stringify(this.arr))

  }

}

可能存在时序问题,app启动的时候,数据库还未初始化完成,导致调用数据库接口会报错,使用定时器,等待一段时间,这个时候,数据库初始化完成了。

参考代码

//替换aboutToAppear函数

aboutToAppear() {

setTimeout(() => {

console.log('delay 1s');

this.getDBData()

console.debug('测试daosession222')

}, 5000);

}

在写数据库的逻辑那里,加await异步变同步,等待数据库初始化完成再进行下一步操作,

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/async-concurrency-overview-V13#asyncawait

数据库建库操作本身就是一个异步方法,daosession需要完成建库建表操作后才能获取。

这里有个demo,有基本增删改查的基本样例,可以参考下,https://gitee.com/openharmony-sig/dataORM

针对HarmonyOS 鸿蒙Next 第三方数据库的使用问题,以下是一些专业的解答:

首先,确保已安装ohpm-cli工具,该工具是安装HarmonyOS第三方库的必要工具。之后,可以通过ohpm install命令后跟数据库库名来安装所需的第三方数据库库。

在安装过程中,可能会遇到版本不匹配的问题。此时,应前往OpenHarmony三方库中心仓库查看最新的版本号,并尝试更换不同的版本以确保兼容性。同时,在oh-package.json5文件中,应避免使用“^”来指定版本号,而应使用具体的版本号以确保精确性。

此外,如果安装的是Native工程的数据库库,可能需要将编译好的so库放到Native工程的指定目录下,并在CMakeLists.txt文件中链入so库,同时在Native侧的.cpp文件中引入头文件。

最后,如果在使用过程中遇到任何问题,可以仔细分析报错信息,定位问题源头。HarmonyOS的官方文档和API参考也是解决问题的重要资源。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部