HarmonyOS 怎么把数据库的relationalStore.RdbPredicates传参传入taskpool的function里,因为这个传参无法序列化,而且taskpool里也获取不到已初始化的单例,该怎么解决这个问题?

HarmonyOS
2天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zxjiu

taskpool数据传递需要序列化,relationalStore又不支持Sendable跨线程传递。所以单例是无法实现的。但是可以在线程里面单独初始化数据库,然后操作,不过需要传入context,一下demo可以参考一下:

EntryAbility.ets

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import Dbutil from '../common/DbUtil';

const TABLE_NAME: string = "EMPLOYEE"
const CREATE_TABLE_SQL: string = `
 CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (
   ID INTEGER PRIMARY KEY AUTOINCREMENT,
   NAME TEXT NOT NULL,
   AGE INTEGER NOT NULL,
   SALARY DOUBLE NOT NULL
 )

export default class EntryAbility extends UIAbility {
  async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
    await Dbutil.initDB(this.context)
    Dbutil.createTable(CREATE_TABLE_SQL)
  }

  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/Index5', (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');
  }
}

DbUtil.ets

import relationalStore from '@ohos.data.relationalStore'
import { ColumnInfo, ColumnType } from '../common/ColumnInfo'
import { BusinessError } from '@kit.BasicServicesKit'
import { ValuesBucket, ValueType } from '@kit.ArkData'

const DB_FILENAME: string = 'testMySql.db'

class DbUtil {
  rdbStore: relationalStore.RdbStore | undefined = undefined

  initDB(context: Context): Promise<void> {
    let config: relationalStore.StoreConfig = {
      name: DB_FILENAME,
      securityLevel: relationalStore.SecurityLevel.S1
    }
    return new Promise((resolve, reject) => {
      relationalStore.getRdbStore(context, config)
        .then(rdbStore => {
          this.rdbStore = rdbStore
          console.debug('rdbStore 初始化完成!')
          resolve()
        })
        .catch((err:BusinessError) => {
          console.error('rdbStore 初始化异常', JSON.stringify(err))
          reject(err)
        })
    })
  }

  isInited() {
    return !!this.rdbStore
  }

  createTable(sql: string): Promise<void> {
    return new Promise((resolve, reject) => {
      if (this.rdbStore){
        this.rdbStore.executeSql(sql)
          .then(() => {
            console.debug('创建成功', sql)
            resolve()
          })
          .catch((err:BusinessError) => {
            console.error('创建失败,' + err.message, JSON.stringify(err))
          })
      }
    })
  }


  async insertTest(tableName: string, value: ValuesBucket): Promise<number> {
    return await new Promise((resolve, reject) => {
      console.debug('insertTest1111')
      if (!this.rdbStore) return
      console.debug('insertTest2222')
      this.rdbStore.insert(tableName, value, (err, id) => {
        if (err) {
          console.error('新增失败!', JSON.stringify(err))
          reject(err)
        } else {
          console.debug('新增成功!新增id:', id.toString())
          resolve(id)
        }
      })
    })
  }

  queryForListPrint(tableName: string){
    let predicates = new relationalStore.RdbPredicates(tableName);
    predicates.equalTo("NAME", "Rose");
    if(this.rdbStore != undefined) {
      (this.rdbStore as relationalStore.RdbStore).query(predicates, ["ID", "NAME", "AGE", "SALARY"]).then((resultSet: relationalStore.ResultSet) => {
        console.info(`ResultSet column names: ${resultSet.columnNames}, column count: ${resultSet.columnCount}`);
        // resultSet是一个数据集合的游标,默认指向第-1个记录,有效的数据从0开始。
        while (resultSet.goToNextRow()) {
          const id = resultSet.getLong(resultSet.getColumnIndex("ID"));
          const name = resultSet.getString(resultSet.getColumnIndex("NAME"));
          const age = resultSet.getLong(resultSet.getColumnIndex("AGE"));
          const salary = resultSet.getDouble(resultSet.getColumnIndex("SALARY"));
          console.info(`id=${id}, name=${name}, age=${age}, salary=${salary}`);
        }
        // 释放数据集的内存
        resultSet.close();
      }).catch((err: BusinessError) => {
        console.error(`Query failed, code is ${err.code},message is ${err.message}`);
      })
    }
  }
}

const dbUtil: DbUtil = new DbUtil()
export default dbUtil as DbUtil

Index5 .ets

import { taskpool } from '@kit.ArkTS';
import { ValuesBucket } from '@kit.ArkData';
import DbUtil from '../common/DbUtil';

@Concurrent
async function insertInfo(context:Context) {
  console.debug('insertInfo')
  let value1 = "Lisa";
  let value2 = 18;
  let value3 = 100.5;
  const valueBucket1: ValuesBucket = {
    'NAME': value1,
    'AGE': value2,
    'SALARY': value3
  };
  await DbUtil.initDB(context)
  DbUtil.insertTest("EMPLOYEE",valueBucket1)
}

@Concurrent
async function insertInfo2(context:Context) {
  let value1 = "Rose";
  let value2 = 16;
  let value3 = 99.5;
  const valueBucket1: ValuesBucket = {
    'NAME': value1,
    'AGE': value2,
    'SALARY': value3
  };
  console.debug('insertInfo2')
  await DbUtil.initDB(context)
  DbUtil.insertTest("EMPLOYEE",valueBucket1)
}


@Concurrent
async function queryListPrintInfo(context:Context) {
  await DbUtil.initDB(context)
  DbUtil.queryForListPrint("EMPLOYEE")
}
@Entry
@Component
struct Index5 {
  @State message: string = 'Hello World';

  @Styles ButtonStyle(){
    .width(180)
    .height(45)
    .margin({ top: 20 })
  }

  build() {
    Row() {
      Column() {
        Button("插入数据1").ButtonStyle()
          .onClick(async () => {
            const task = new taskpool.Task(insertInfo,getContext(this) );
            taskpool.execute(task);

          })

        Button("插入数据2").ButtonStyle()
          .onClick(async () => {
            const task = new taskpool.Task(insertInfo2,getContext(this) );
            taskpool.execute(task);

          })
        Button("查询数据").ButtonStyle()
          .onClick(async () => {
            const task = new taskpool.Task(queryListPrintInfo,getContext(this) );
            taskpool.execute(task);

          })

      }
      .width('100%')
    }
    .height('100%')
  }
}
分享
微博
QQ
微信
回复
2天前
相关问题
HarmonyOS 自动测试问题
57浏览 • 1回复 待解决
HarmonyOS 类被反复初始化问题
42浏览 • 1回复 待解决
求教一个sql语句怎么写?
3383浏览 • 1回复 待解决
HarmonyOS Context在taskpool怎么获取
71浏览 • 1回复 待解决
HarmonyOS router获取问题
565浏览 • 1回复 待解决
HarmonyOS 页面问题
415浏览 • 1回复 待解决
HarmonyOS 参数问题
113浏览 • 1回复 待解决
HarmonyOS Navigation问题
79浏览 • 1回复 待解决
HarmonyOS Map 序列化问题
16浏览 • 1回复 待解决
HarmonyOS 本地html问题
315浏览 • 1回复 待解决
没法调试“初始化”分支
272浏览 • 1回复 待解决
JS跳转Java问题
4878浏览 • 1回复 待解决
HarmonyOS @Builder Params问题
27浏览 • 1回复 待解决