HarmonyOS worker或者taskpool更新列表数据源?

当从数据库查询了一个数据列表之后,用list进行展示。这时候在worker或者taskpool里面更新了某些数据库的数据,要实时快速的更新list列表应该如何做?

阅读 602
1 个回答

参考如下代码:

//rdb.ets
import relationalStore from '@ohos.data.relationalStore';
import { BusinessError, Callback } from '@ohos.base';
import { ValuesBucket } from '@ohos.data.ValuesBucket';
import { Student } from './student';

export default class Rdb {
  rdbStore?: relationalStore.RdbStore;

  constructor(storeName: string, context: Context) {
    // 数据库配置
    const STORE_CONFIG: relationalStore.StoreConfig = {
      name: storeName, securityLevel: relationalStore.SecurityLevel.S1,
    };
    // 获取数据库Store
    relationalStore.getRdbStore(context, STORE_CONFIG, (err: BusinessError, rdbStore: relationalStore.RdbStore) => {
      this.rdbStore = rdbStore;
      if (err) {
        console.error(`Get RdbStore failed, code is ${err.code},message is ${err.message}`);
        return;
      }
      console.info(`Get ${storeName} RdbStore successfully.`);
    })
  }

  CreateTable() {
    const SQL_CREATE_TABLE =
      'CREATE TABLE IF NOT EXISTS STUDENT (ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT,AGE INTEGER,SALARY INTEGER)';
    if (this.rdbStore) {
      this.rdbStore.executeSql(SQL_CREATE_TABLE);
      console.info(`CreateTable successfully.`);
    }
  }

  InsertData(name: string, age: number, salary: number) {
    // 插入数据
    const valueBucket: ValuesBucket = {
      'NAME': name, 'AGE': age, 'SALARY': salary
    };
    setTimeout(() => {
      if (this.rdbStore) {
        this.rdbStore.insert('STUDENT', valueBucket, (err, rowId) => {
          if (err) {
            console.error(`Failed to insert data. Code:${err.code}, message:${err.message}`);
            return;
          }
          console.info(`Succeeded in inserting data. rowId:${rowId}`);
        })
      }
    }, 10)
  }

  async InsertAsync(name: string, age: number, salary: number) {
    let start = Date.now();
    const valueBucket:
      ValuesBucket = {
      'NAME': name, 'AGE': age, 'SALARY': salary
    };
    /* while (Date.now() - start <1000) { continue; } console.log('延时结束');*/
    if (this.rdbStore) {
      await this.rdbStore.insert('STUDENT', valueBucket, (err, rowId) => {
        if (err) {
          console.error(`Failed to insert data. Code:${err.code}, message:${err.message}`);
          return;
        }
        console.info(`Succeeded in inserting data. rowId:${rowId}`);
      })
    }
  }

  DeleteData() {
    let predicates = new relationalStore.RdbPredicates("STUDENT");
    predicates.equalTo("NAME", "Lisa");
    if (this.rdbStore != undefined) {
      (this.rdbStore as relationalStore.RdbStore).delete(predicates, (err, rows) => {
        if (err) {
          console.error(`Delete failed, code is ${err.code},message is ${err.message}`);
          return;
        }
        console.info(`Delete rows: ${rows}`);
      })
    }
  }

  queryData() {
    let predicates =
      new relationalStore.RdbPredicates("STUDENT").notEqualTo('name', 'li').orderByAsc('age').orderByAsc('salary')
    if (this.rdbStore) {
      this.rdbStore.query(predicates, ["ID", 'NAME', 'AGE', 'SALARY'], (err, resultSet) => {
        if (err) {
          console.error(`Failed to query data. Code:${err.code}, message:${err.message}`);
          return;
        }
        console.info(`ResultSet column names: ${resultSet.columnNames}, row count: ${resultSet.rowCount}`);
        if (resultSet.rowCount == -1) {
          console.info("rowCount=-1")
        }
        // 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();
      })
    }
  }

  querySyncData() {
    let predicates =
      new relationalStore.RdbPredicates("STUDENT").notEqualTo('name', 'li').orderByAsc('age').orderByAsc('salary')
    try {
      if (this.rdbStore) {
        let resultSet = this.rdbStore.querySync(predicates, ["ID", 'NAME', 'AGE', 'SALARY']);
        console.info(`ResultSet column names: ${resultSet.columnNames}, row count: ${resultSet.rowCount}`);
        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) {
      console.error(`Failed to query data. Code:${err.code}, message:${err.message}`);
      return;
    }
  }

  UpdateData(name: string, age: number, salary: number) {
    const valueBucket: ValuesBucket = {
      'NAME': name, 'AGE': age, 'SALARY': salary
    };
    let predicates = new relationalStore.RdbPredicates("EMPLOYEE");
    predicates.equalTo("NAME", "Lisa");
    if (this.rdbStore != undefined) {
      (this.rdbStore as relationalStore.RdbStore).update(valueBucket, predicates,
        relationalStore.ConflictResolution.ON_CONFLICT_REPLACE, (err, rows) => {
          if (err) {
            console.error(`Updated failed, code is ${err.code},message is ${err.message}`);
            return;
          }
          console.info(`Updated row count: ${rows}`);
        })
    }
  }

  QueryData(callback: Callback<string>) {
    // 配置谓词
    let predicates = new relationalStore.RdbPredicates("STUDENT");
    let jsonData: Array<ValuesBucket> = new Array<ValuesBucket>()
    if (this.rdbStore) {
      this.rdbStore.query(predicates, ["ID", 'NAME', 'AGE', 'SALARY'], (err, resultSet) => {
        if (err) {
          console.error(`Failed to query data. Code:${err.code}, message:${err.message}`);
          return;
        }
        console.info(`ResultSet column names: ${resultSet.columnNames}, row count: ${resultSet.rowCount}`);
        if (resultSet.rowCount == -1) {
          console.info("rowCount=-1")
        }
        // 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}`);
          const valueBucket: ValuesBucket = {
            'ID': id,
            'NAME': name,
            'AGE': age,
            'SALARY': salary
          };
          jsonData.push(valueBucket)
        }
        // 释放数据集的内存
        resultSet.close();
        // console.info("JSON: " + JSON.stringify(jsonData)) callback(JSON.stringify(jsonData))
      })
    }
  }

  async QueryDataArr(): Promise<Student[]> {
    // 配置谓词
    let predicates = new relationalStore.RdbPredicates("STUDENT");
    let jsonData: Array<Student> = new Array<Student>()
    if (this.rdbStore) {
      let resultSet = await this.rdbStore.query(predicates, ["ID", 'NAME', 'AGE', 'SALARY'])
      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}`);
        const valueBucket: Student = new Student();
        valueBucket.id = id
        valueBucket.name = name
        valueBucket.age = age
        valueBucket.salary = salary
        jsonData.push(valueBucket)
      }

      // 释放数据集的内存
      resultSet.close();
      // console.info("JSON: " + JSON.stringify(jsonData)) callback(JSON.stringify(jsonData))
    }
    return jsonData
  }

  queryKeySync() {
    let predicates = new relationalStore.RdbPredicates("STUDENT");
    predicates.equalTo("NAME", "Lisa");
    if (this.rdbStore != undefined) {
      try {
        let resultSet: relationalStore.ResultSet =
          (this.rdbStore as relationalStore.RdbStore).querySync(predicates, ["ID", "NAME", "AGE", "SALARY"]);
        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) {
        console.error(`Query failed, code is ${err.code},message is ${err.message}`);
      }
    }
  }
}
//student.ets
export class Student {
  id: number = 0
  name: string = ''
  age: number = 1
  salary: number = 0
}
//Worker.ets
import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
import Rdb from '../database/rdb'
import { Student } from '../database/student';

const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
let rdbTest: Rdb;

workerPort.onmessage = async (e: MessageEvents) => {
  console.log('testtag onmessage' + JSON.stringify(e))
  if (e.data.code == 1) {
    rdbTest.CreateTable(); //建表
  } else if (e.data.code == 2) {
    let student = e.data.data as Student
    await rdbTest.InsertData(student.name, student.age, student.salary); //添加数据
    //添加新数据收立马查询,然后同时主线程
    let studentArr = await rdbTest.QueryDataArr();
    //将处理结果返回主线程
    workerPort.postMessage({ code: 101, data: studentArr })
  } else if (e.data.code == 3) {
    let studentArr = await rdbTest.QueryDataArr();
    //将处理结果返回主线程
    workerPort.postMessage({ code: 101, data: studentArr })
  } else {
    rdbTest = await new Rdb('Student.db', e.data.data) //创建数据库
  }
  console.log('testtag onmessage end')
}

workerPort.onmessageerror = (e: MessageEvents) => {
  console.log('testtag onmessageerror' + e)
}

workerPort.onerror = (e: ErrorEvent) => {

}
//Index.ets
import worker, { MessageEvents } from '@ohos.worker';
import { Student } from '../database/student';
import { util } from '@kit.ArkTS';

const workerInstance = new worker.ThreadWorker("entry/ets/workers/Worker.ets");
let context = getContext()
let nameArr = ['jack', 'tom', 'anlay', 'jany', 'lili', 'Aaron', 'Ben', 'Brandon', 'Cody', 'Mason']

@Entry
@Component
struct Index {
  @State list: Student[] = [];

  aboutToAppear(): void {
    workerInstance.postMessage({ code: 99, data: context });
    workerInstance.onmessage = (e: MessageEvents): void => {
      if (e.data.code == 101) {
        this.list = e.data.data
      }
    }
  }

  build() {
    Row() {
      Column() {
        Row() {
          Button('建表')
            .onClick(() => {
              workerInstance.postMessage({ code: 1, data: context });
            })
          Button('插入数据')
            .onClick(() => {
              let student: Student = new Student()
              let index = Math.ceil(Math.random() * 10) % 10
              student.name = nameArr[index]
              student.age = Math.ceil(Math.random() * 100) % 18
              student.salary = 2000 + Math.ceil(Math.random() * 10000) % 10000
              workerInstance.postMessage({ code: 2, data: student });
            })
          Button('查询数据')
            .onClick(() => {
              workerInstance.postMessage({ code: 3, data: {} });
            })
        }
        .width('100%')
        .margin({ top: 10 })
        .justifyContent(FlexAlign.SpaceAround)

        ForEach(this.list, (item: Student, index: number) => {
          ViewA({ student: item })
        })
      }
      .height('100%')
      .width('100%')
    }
  }
}

@Component
export struct ViewA {
  student: Student = new Student();

  build() {
    Row() {
      Text("姓名:" + this.student.name)
      Text("年龄:" + this.student.age.toString())
      Text("费用:" + this.student.salary.toString())
    }.width('100%').margin({ top: 10 }).justifyContent(FlexAlign.SpaceEvenly)
  }
}