HarmonyOS 鸿蒙Next 第三方数据库的使用问题
HarmonyOS 鸿蒙Next 第三方数据库的使用问题
目前我在测试使用的是https://gitee.com/openharmony-sig/dataORM这个数据库,麻烦帮我用这个数据库,写个关于增删改查这几个数据库操作的小demo吧。 增删改查请帮忙使用同步和异步调用的有回调的两种方式,谢谢。
目前遇到的问题,ability设置daosession,在第一个加载的page页面aboutToAppear函数中获取的daosession为undefined。
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异步变同步,等待数据库初始化完成再进行下一步操作,
数据库建库操作本身就是一个异步方法,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 。