前言:我们的App加载数据很多都是采用本地化数据,数据都是存在数据库中的,本地有个小型数据库,所有的主数据都存在本地,用来支持业务数据的展示,业务逻辑处理。之前在安卓系统和ios系统上都是得心应手的,网上的方法也比力多,但是到了鸿蒙系统,只有官方资料可查,大概开源的demo可参考,本人基于同事以及本身开辟中发现的问题,鸿蒙系统的数据库操作整理一份博客,一起记录问题,并解决问题。
相关类先容:
DatabaseHelp类,重要是创建数据库,创建表
DatabaseSqlUtil类,重要是创建表的语句
ParseServerDataManager类,重要是插入数据,以及数据解析,数据整理,数据插入、删除操作
DatabaseManager类,数据库操作,增删改查
class:DatabaseSqlUtil类
- export class DatabaseSqlUtil {
- // 数据库配置
- public static STORE_CONFIG :relationalStore.StoreConfig= {
- name: 'test.db', // 数据库文件名
- securityLevel: relationalStore.SecurityLevel.S1, // 数据库安全级别
- encrypt: false, // 可选参数,指定数据库是否加密,默认不加密
- customDir: 'winchannel' // 可选参数,数据库自定义路径。数据库将在如下的目录结构中被创建:context.databaseDir + '/rdb/' + customDir,其中context.databaseDir是应用沙箱对应的路径,'/rdb/'表示创建的是关系型数据库,customDir表示自定义的路径。当此参数不填时,默认在本应用沙箱目录下创建RdbStore实例。
- };
- //建表语句
- public static CREATE_BASE_STORE_TABLE:string = 'CREATE TABLE IF NOT EXISTS base_store (_id INTEGER PRIMARY KEY AUTOINCREMENT,id TEXT, name TEXT, cod TEXT, styp TEXT, addr TEXT )'
- }
复制代码 代码中的解释已经很清楚了。
class:DatabaseHelper
- export class DatabaseHelper{
- constructor(context:Context) {
- // 获取数据库Store
- relationalStore.getRdbStore(context, DatabaseSqlUtil.STORE_CONFIG, (err, rdbStore) => {
- if (err) {
- conslog.info(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
- return;
- }
- WinLog.info('WINLOG Succeeded in getting RdbStore.');
- this.createTable(rdbStore)
- });
- }
- /**
- * 创建表.
- */
- private createTable(rdbStore: relationalStore.RdbStore):void {
- // 判断数据库版本,如果不匹配则需进行升降级操作
- if (rdbStore == undefined){
- conslog.info('WINLOG rdbStore undefined');
- return
- }
- conslog.info('WINLOG store.version--->' + rdbStore.version);
- // 当数据库创建时,数据库默认版本为0
- if (rdbStore.version === 0) {
- rdbStore.executeSql(DatabaseSqlUtil.CREATE_BASE_STORE_TABLE);
- // 设置数据库的版本,入参为大于0的整数
- rdbStore.version = 1;
- conslog.info('WINLOG version 0 action');
- }
- // 如果数据库版本不为0且和当前数据库版本不匹配,需要进行升降级操作
- // 当数据库存在并假定版本为1时,例应用从某一版本升级到当前版本,数据库需要从1版本升级到2版本
- if (rdbStore.version === 1) {
- // version = 1:表结构:EMPLOYEE (NAME, SALARY, CODES, ADDRESS) => version = 2:表结构:EMPLOYEE (NAME, AGE, SALARY, CODES, ADDRESS)
- if (rdbStore !== undefined) {
- (rdbStore as relationalStore.RdbStore).executeSql(DatabaseSqlUtil.ALTER_BASE_ACVT_QST_COLUMN_memo);
- rdbStore.version = 2;
- }
- conslog.info('WINLOG version 1 action');
- }
- }
- }
复制代码 建数据库的时候有个版本控制,后续可以更新版本用来控制数据库的更新表的列,新增表操作
//表操作类:DatabaseManager
//批量数据插入,整个数组一次性插入
- export class DatabaseManager{
- static batchInsertTableData(context:Context, tableName:string, bucketArray:ValuesBucket[] ){
- // 获取数据库Store
- relationalStore.getRdbStore(context, DatabaseSqlUtil.STORE_CONFIG, (err, rdbStore) => {
- if (err) {
- conslog.info(`batchInsertTableData ${tableName} Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
- return;
- }
- conslog.info('batchInsertTableData Succeeded in getting RdbStore.');
- if(rdbStore != undefined) {
- (rdbStore as relationalStore.RdbStore).batchInsert(tableName, bucketArray, (err, insertNum) => {
- if (err) {
- conslog.error(`${tableName}batchInsert is failed, code is ${err.code},message is ${err.message}`);
- return;
- }
- conslog.info(`${tableName}batchInsert is successful, the number of values that were inserted = ${insertNum}`);
- })
- }
- });
- }
- }
复制代码 我们这里的数据比力多,用的批量插入,你的数据少的话,可以一条插入:
语法:
- (rdbStore as relationalStore.RdbStore).insert(tableName, bucketArray, (err, insertNum) => {
- if (err) {
- conslog.error(`${tableName}batchInsert is failed, code is ${err.code},message is ${err.message}`);
- return;
- }
- conslog.info(`${tableName}batchInsert is successful, the number of values that were inserted = ${insertNum}`);
- })
复制代码 删除操作:
- static deleteTableDataByTabName(context:Context, tableName:string){
- // 获取数据库Store
- relationalStore.getRdbStore(context, DatabaseSqlUtil.STORE_CONFIG, (err, rdbStore) => {
- if (err) {
- conslog.info(`${tableName} deleteTableData Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
- return;
- }
- conslog.info(`deleteTableData ${tableName} Succeeded in getting RdbStore.`);
- if(rdbStore != undefined) {
- //创建谓词,进行删除
- let rdbPredicates = new relationalStore.RdbPredicates(tableName);
- (rdbStore as relationalStore.RdbStore).delete(rdbPredicates, (err, rows) => {
- if (err) {
- conslog.info(`${tableName} Delete failed, code is ${err.code},message is ${err.message}`);
- return;
- }
- conslog.info(`${tableName} Delete rows: ${rows}`);
- })
- }
- });
- }
复制代码 数据处理类:ParseServerDataManager
- function parseBaseStoreData(context: Context, jsonData: string, serverNode:string){
- //先删后插
- DatabaseManager.deleteTableDataByTabName(context,"base_store")
- let parseStoreList: ValuesBucket[] = []
- let storesList: BaseStore[] = JSON.parse(jsonData)[serverNode]
- if (storesList == undefined) {
- WinLog.info("stores is null")
- return
- }
- storesList.forEach((item) => {
- item.server_node = serverNode
- let storeFilter:string[] = ['id','name','empId','cod','lat','lon','addr'];
- let storeValuesBucket: ValuesBucket = JSON.parse(JSON.stringify(item, storeFilter),replacer)
- parseStoreList.push(storeValuesBucket)
- })
- DatabaseManager.batchInsertTableData(context, "base_store", parseStoreList);
- }
- function replacer(key: string, value: Object): Object {
- if (key != '_id' && typeof value == 'number') {
- value = value.toString()
- }
- if (key == 'opt') {
- value = value.toString()
- }
- return value
- }
复制代码 这里遇到一个问题,假如你解析的数据,有object类型的,插入数据的时候,会在表里显示【object object】,JSON.parse在解析json到对象的时候,就会将object类型数据解析成object,插入数据的时候也就插入object了,这不是我想要的,我想插入的是string类型数据,
- parse(text: string, reviver?: Transformer, options?: ParseOptions): Object | null
复制代码 此方法就有用了,
官方解释:reviver Transformer 否 转换函数,传入该参数,可以用来修改解析天生的原始值。默认值是undefined。
传入次参数,可以指定key值不解析成object,保持原来的类型值,这个有时候开辟很难留意到,希望有帮到你们。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |