RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

HarmonyOS開發(fā)案例:【關系型數(shù)據(jù)庫】

jf_46214456 ? 來源:jf_46214456 ? 作者:jf_46214456 ? 2024-04-22 14:58 ? 次閱讀

介紹

本Codelab以記賬為例,使用關系型數(shù)據(jù)庫的相關接口實現(xiàn)了對賬單的增、刪、改、查操作。實現(xiàn)效果如圖所示:

相關概念

  • [關系型數(shù)據(jù)庫]:基于關系模型來管理數(shù)據(jù)的數(shù)據(jù)庫,提供了增、刪、改、查等接口,也可運行輸入的SQL語句滿足復雜場景需要。

環(huán)境搭建

軟件要求

  • [DevEco Studio]版本:DevEco Studio 3.1 Release。
  • OpenHarmony SDK版本:API version 9。

硬件要求

  • 開發(fā)板類型:[潤和RK3568開發(fā)板]。
  • OpenHarmony系統(tǒng):3.2 Release。

環(huán)境搭建

完成本篇Codelab我們首先要完成開發(fā)環(huán)境的搭建,本示例以RK3568開發(fā)板為例,參照以下步驟進行:

  1. [獲取OpenHarmony系統(tǒng)版本]:標準系統(tǒng)解決方案(二進制)。以3.2 Release版本為例:
  2. 搭建燒錄環(huán)境。
    1. [完成DevEco Device Tool的安裝]
    2. [完成RK3568開發(fā)板的燒錄]
    3. 鴻蒙開發(fā)指導文檔:[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md]
  3. 搭建開發(fā)環(huán)境。
    1. 開始前請參考[工具準備],完成DevEco Studio的安裝和開發(fā)環(huán)境配置。
    2. 開發(fā)環(huán)境配置完成后,請參考[使用工程向?qū)創(chuàng)建工程(模板選擇“Empty Ability”),選擇JS或者eTS語言開發(fā)。
    3. 工程創(chuàng)建完成后,選擇使用[真機進行調(diào)測]。

代碼結(jié)構(gòu)解讀

本篇只對核心代碼進行講解,完整代碼可以直接從gitee獲取。

搜狗高速瀏覽器截圖20240326151450.png

├──entry/src/main/ets               // 代碼區(qū)
│  ├──common
│  │  ├──constants
│  │  │  └──CommonConstants.ets     // 公共常量
│  │  ├──database
│  │  │  ├──tables
│  │  │  │  └──AccountTable.ets     // 賬目數(shù)據(jù)表
│  │  │  └──Rdb.ets                 // RDB數(shù)據(jù)庫
│  │  └──utils                      // 日志類
│  │     ├──ConsoleLogger.ets
│  │     ├──HiLogger.ets
│  │     ├──ILogger.ets
│  │     └──Logger.ets
│  ├──entryability
│  │  └──EntryAbility.ts            // 程序入口類
│  ├──pages
│  │  └──MainPage.ets               // 應用首頁
│  ├──view
│  │  └──DialogComponent.ets        // 自定義彈窗
│  └──viewmodel
│     ├──AccountData.ets            // 賬目類接口
│     ├──AccountItem.ets            // 賬目資源類接口
│     ├──AccountList.ets            // 賬目類型model
│     └──ConstantsInterface.ets     // 常量接口
└──entry/src/main/resources         // 資源文件夾

創(chuàng)建數(shù)據(jù)庫

要使用關系型數(shù)據(jù)庫存儲用戶數(shù)據(jù),首先要進行數(shù)據(jù)庫的創(chuàng)建,并提供基本的增、刪、改、查接口。

導入關系型數(shù)據(jù)庫模塊:

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

關系型數(shù)據(jù)庫提供以下兩個基本功能:

首先要獲取一個RdbStore實例來操作關系型數(shù)據(jù)庫,代碼如下:

// Rdb.ets
getRdbStore(callback: Function = () = > {
}) {
  // 如果已經(jīng)獲取到RdbStore則不做操作
  if (!callback || typeof callback == 'undefined' || callback == undefined) {
    Logger.verbose(`${CommonConstants.RDB_TAG}`, 'getRdbStore() has no callback!');
    return;
  }
  

  // 應用上下文,本Codelab使用API9 Stage模型的Context
  let context: Context = getContext(this) as Context;
  relationalStore.getRdbStore(context, CommonConstants.STORE_CONFIG, (err, rdb) = > {
    if (err) {
      Logger.error(`${RDB_TAG}`, 'gerRdbStore() failed, err: ' + err);
      return;
    }
    this.rdbStore = rdb;

    // 獲取到RdbStore后,需使用executeSql接口初始化數(shù)據(jù)庫表結(jié)構(gòu)和相關數(shù)據(jù)
    this.rdbStore.executeSql(this.sqlCreateTable);          
    Logger.verbose(`${RDB_TAG}`, 'getRdbStore() finished.');
    callback();
  });
}

關系型數(shù)據(jù)庫接口提供的增、刪、改、查操作均有callback和Promise兩種異步回調(diào)方式,本Codelab使用了callback異步回調(diào),其中插入數(shù)據(jù)使用了insert()接口,實現(xiàn)代碼如下:

// Rdb.ets
insertData(data: relationalStore.ValuesBucket, callback: Function = () = > {
}) {
  if (!callback || typeof callback == 'undefined' || callback == undefined) {
    Logger.verbose(`${CommonConstants.RDB_TAG}`, 'insertData() has no callback!');
    return;
  }
  let resFlag: boolean = false;
  const valueBucket: relationalStore.ValuesBucket = data;
  if (this.rdbStore) {
    this.rdbStore.insert(this.tableName, valueBucket, (err, ret) = > {
      if (err) {
        Logger.error(`${CommonConstants.RDB_TAG}`, 'insertData() failed, err: ' + err);
        callback(resFlag);
        return;
      }
      Logger.verbose(`${CommonConstants.RDB_TAG}`, 'insertData() finished: ' + ret);
      callback(ret);
    });
  }
}

刪除數(shù)據(jù)使用了delete()接口,實現(xiàn)代碼如下:

// Rdb.ets
deleteData(predicates: relationalStore.RdbPredicates, callback: Function = () = > {
}) {
  if (!callback || typeof callback == 'undefined' || callback == undefined) {
    Logger.verbose(`${CommonConstants.RDB_TAG}`, 'deleteData() has no callback!');
    return;
  }
  let resFlag: boolean = false;
  if (this.rdbStore) {
    this.rdbStore.delete(predicates, (err, ret) = > {
      if (err) {
        Logger.error(`${CommonConstants.RDB_TAG}`, 'deleteData() failed, err: ' + err);
        callback(resFlag);
        return;
      }
      Logger.verbose(`${CommonConstants.RDB_TAG}`, 'deleteData() finished: ' + ret);
      callback(!resFlag);
    });
  }
}

更新數(shù)據(jù)使用了update()接口,實現(xiàn)代碼如下:

// Rdb.ets
updateData(predicates: relationalStore.RdbPredicates, data: relationalStore.ValuesBucket, callback: Function = () = > {
}) {
  if (!callback || typeof callback == 'undefined' || callback == undefined) {
    Logger.verbose(`${CommonConstants.RDB_TAG}`, 'updateDate() has no callback!');
    return;
  }
  let resFlag: boolean = false;
  const valueBucket: relationalStore.ValuesBucket = data;
  if (this.rdbStore) {
    this.rdbStore.update(valueBucket, predicates, (err, ret) = > {
      if (err) {
        Logger.error(`${CommonConstants.RDB_TAG}`, 'updateData() failed, err: ' + err);
        callback(resFlag);
        return;
      }
      Logger.verbose(`${CommonConstants.RDB_TAG}`, 'updateData() finished: ' + ret);
      callback(!resFlag);
    });
  }
}

查找數(shù)據(jù)使用了query()接口,實現(xiàn)代碼如下:

// Rdb.ets
query(predicates: relationalStore.RdbPredicates, callback: Function = () = > {
}) {
  if (!callback || typeof callback == 'undefined' || callback == undefined) {
    Logger.verbose(`${CommonConstants.RDB_TAG}`, 'query() has no callback!');
    return;
  }
  if (this.rdbStore) {
    this.rdbStore.query(predicates, this.columns, (err, resultSet) = > {
      if (err) {
        Logger.error(`${CommonConstants.RDB_TAG}`, 'query() failed, err: ' + err);
        return;
      }
      Logger.verbose(`${CommonConstants.RDB_TAG}`, 'query() finished.');
      callback(resultSet);
      resultSet.close();
    });
  }
}

本Codelab需要記錄賬目的類型(收入/支出)、具體類別和金額,因此需要創(chuàng)建一張存儲賬目信息的表,表頭如下:

創(chuàng)建該表的SQL語句為:

CREATE TABLE IF NOT EXISTS accountTable(
    id INTEGER PRIMARY KEY AUTOINCREMENT, 
    accountType INTEGER, 
    typeText TEXT, 
    amount INTEGER
)

該表需要封裝增、刪、改、查接口,代碼如下:

// AccountTable.ets
// 插入數(shù)據(jù)
insertData(account: AccountData, callback: Function) {
  // 根據(jù)輸入數(shù)據(jù)創(chuàng)建待插入的數(shù)據(jù)行
  const valueBucket: relationalStore.ValuesBucket = generateBucket(account);
  this.accountTable.insertData(valueBucket, callback);
}

// 刪除數(shù)據(jù)
deleteData(account: AccountData, callback: Function) {
  let predicates = new relationalStore.RdbPredicates(CommonConstants.ACCOUNT_TABLE.tableName);
  
  // 根據(jù)id匹配待刪除的數(shù)據(jù)行
  predicates.equalTo('id', account.id);
  this.accountTable.deleteData(predicates, callback);
}

// 修改數(shù)據(jù)
updateData(account: AccountData, callback: Function) {
  const valueBucket: relationalStore.ValuesBucket = generateBucket(account);
  let predicates = new relationalStore.RdbPredicates(CommonConstants.ACCOUNT_TABLE.tableName);

  // 根據(jù)id匹配待刪除的數(shù)據(jù)行
  predicates.equalTo('id', account.id);
  this.accountTable.updateData(predicates, valueBucket, callback);
}

// 查找數(shù)據(jù)
query(amount: number, callback: Function, isAll: boolean = true) {
  let predicates = new relationalStore.RdbPredicates(CommonConstants.ACCOUNT_TABLE.tableName);
  if (!isAll) {
    predicates.equalTo('amount', amount);
  }
  this.accountTable.query(predicates, (resultSet: relationalStore.ResultSet) = > {
    let count: number = resultSet.rowCount;
    if (count === 0 || typeof count === 'string') {
      console.log(`${CommonConstants.TABLE_TAG}` + 'Query no results!');
      callback([]);
    } else {
      resultSet.goToFirstRow();
      const result: AccountData[] = [];
      for (let i = 0; i < count; i++) {
        let tmp: AccountData = { id: 0, accountType: 0, typeText: '', amount: 0 };
        tmp.id = resultSet.getDouble(resultSet.getColumnIndex('id'));
        tmp.accountType = resultSet.getDouble(resultSet.getColumnIndex('accountType'));
        tmp.typeText = resultSet.getString(resultSet.getColumnIndex('typeText'));
        tmp.amount = resultSet.getDouble(resultSet.getColumnIndex('amount'));
        result[i] = tmp;
        resultSet.goToNextRow();
      }
      callback(result);
    }
  });
}

功能實現(xiàn)

首先創(chuàng)建應用主頁面,主要包括使用Search組件創(chuàng)建的搜索欄和使用List組件創(chuàng)建的賬目清單,如下圖所示:

在打開應用時,需要查詢數(shù)據(jù)庫中存儲的賬目并顯示在主頁面,因此生命周期函數(shù)aboutToAppear()應寫為:

// Mainpage.ets
aboutToAppear() {
  this.AccountTable.getRdbStore(() = > {  // 獲取數(shù)據(jù)庫
    this.AccountTable.query(0, (result: AccountData[]) = > {  // 查詢數(shù)據(jù)庫中的全部賬目
      this.accounts = result;
    }, true);
  });
}

點擊右上角的“編輯”圖標,主頁面變?yōu)槿缦滦Ч?/p>

可以選中需要刪除的賬目,點擊下方“刪除”圖標后刪除對應賬目,對應代碼如下:

// Mainpage.ets
deleteListItem() {
  for (let i = 0; i < this.deleteList.length; i++) {  // 刪除每一項選中的賬目并更新頁面上的賬目清單
    let index = this.accounts.indexOf(this.deleteList[i]);
    this.accounts.splice(index, 1);
    this.AccountTable.deleteData(this.deleteList[i], () = > {});
  }
  this.deleteList = [];
  this.isEdit = false;
}

搜索欄在鍵入文本并回車時,實現(xiàn)搜索功能:

// Mainpage.ets
.onSubmit((searchValue: string) = > {
  if (searchValue === '') {  // 如果搜索欄為空,查找全部賬目
    this.AccountTable.query(0, (result: AccountData[]) = > {
      this.accounts = result;
    }, true);
  } else {
    this.AccountTable.query(Number(searchValue), (result: AccountData[]) = > {  // 查找金額為val的賬目
      this.accounts = result;
    }, false);
  }
})

右下角的“添加”按鈕可以打開一個自定義彈窗,并在彈窗里新建賬目信息:

// Mainpage.ets
.onClick(() = > {
  this.isInsert = true;  // 插入模式
  this.newAccount = { id: 0, accountType: 0, typeText: '', amount: 0 };
  this.dialogController.open();
})

點擊賬目清單中的某個賬目,也可以打開自定義彈窗,并修改賬目信息:

// Mainpage.ets
selectListItem(item: AccountData) {
  this.isInsert = false;  // 編輯模式
  this.index = this.accounts.indexOf(item);
  this.newAccount = {
    id: item.id,
    accountType: item.accountType,
    typeText: item.typeText,
    amount: item.amount
  };
}

自定義彈窗由使用Tabs組件創(chuàng)建的賬目類別、使用TextInput組件創(chuàng)建的輸入欄和確定按鈕組成,如下圖所示:

點擊“確定”按鈕會調(diào)用accept()函數(shù),根據(jù)isInsert的值來進行賬目的添加或修改,代碼如下:

// Mainpage.ets
accept(isInsert: boolean, newAccount: AccountData): void {
  if (isInsert) {  // 插入模式,往數(shù)據(jù)庫插入一個新賬目
    Logger.verbose(`${CommonConstants.INDEX_TAG}`, 'The account inserted is: ' + JSON.stringify(newAccount));
    this.AccountTable.insertData(newAccount, (id: number) = > {
      newAccount.id = id;
      this.accounts.push(newAccount);
    });
  } else {  // 編輯模式,更新當前選中的賬目并寫入數(shù)據(jù)庫,刷新頁面的賬目清單
    this.AccountTable.updateData(newAccount, () = > {});
    let list = this.accounts;
    this.accounts = [];
    list[this.index] = newAccount;
    this.accounts = list;
    this.index = -1;
  }
}

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 數(shù)據(jù)庫

    關注

    7

    文章

    3794

    瀏覽量

    64360
  • HarmonyOS
    +關注

    關注

    79

    文章

    1973

    瀏覽量

    30143
  • OpenHarmony
    +關注

    關注

    25

    文章

    3713

    瀏覽量

    16254
收藏 人收藏

    評論

    相關推薦

    HarmonyOS開發(fā)案例:【搭建關系數(shù)據(jù)庫】(4)

    本節(jié)將介紹如何調(diào)用關系數(shù)據(jù)庫接口在本地搭建數(shù)據(jù)庫,并讀寫相應的用戶數(shù)據(jù)
    的頭像 發(fā)表于 05-11 10:27 ?869次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開發(fā)案</b>例:【搭建<b class='flag-5'>關系</b><b class='flag-5'>型</b><b class='flag-5'>數(shù)據(jù)庫</b>】(4)

    關系數(shù)據(jù)庫與非關系數(shù)據(jù)庫的區(qū)別淺析

    關系數(shù)據(jù)庫的一個劣勢就是 阻抗失諧(impedance mismatch):關系模型和內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)之間存在差異
    發(fā)表于 06-03 06:03

    HarmonyOS數(shù)據(jù)庫的相關資料下載

    1、HarmonyOS數(shù)據(jù)庫篇之輕量級數(shù)據(jù)存儲HarmonyOS中的數(shù)據(jù)庫存儲主要分為3種形式:1. 輕量級
    發(fā)表于 03-28 11:13

    HarmonyOS關系數(shù)據(jù)庫和對象關系數(shù)據(jù)庫的使用方法

    extends OrmDatabase { }2.表:被開發(fā)者用@Entity注解的實體類,且繼承了OrmObject的類,對應關系數(shù)據(jù)庫中的表。// 定義了一個實體類User.j
    發(fā)表于 03-29 14:10

    DCS仿真系統(tǒng)的內(nèi)存-關系數(shù)據(jù)庫系統(tǒng)的構(gòu)成

    對內(nèi)存數(shù)據(jù)庫關系數(shù)據(jù)庫進行分析,設計完成內(nèi)存—關系數(shù)據(jù)庫系統(tǒng),并在實際的DCS 仿真系統(tǒng)中進行使用。本文介紹了所
    發(fā)表于 09-07 15:39 ?15次下載

    什么是關系數(shù)據(jù)庫

    什么是關系數(shù)據(jù)庫 關系數(shù)據(jù)庫簡介   關系
    發(fā)表于 06-17 07:38 ?9123次閱讀

    什么是非關系數(shù)據(jù)庫

    什么是非關系數(shù)據(jù)庫 談到非關系數(shù)據(jù)庫設計的難點,朱海峰說:“我們可以從一些場景來看這個問題
    發(fā)表于 06-17 15:49 ?3131次閱讀

    hbase和關系數(shù)據(jù)庫的區(qū)別

    hbase和關系數(shù)據(jù)庫的區(qū)別就是對于傳統(tǒng)數(shù)據(jù)庫,增加列對于一個項目來講,改變是非常大的。但是對于nosql,插入列和刪除列,跟傳統(tǒng)數(shù)據(jù)庫
    發(fā)表于 12-27 15:51 ?1.1w次閱讀
    hbase和<b class='flag-5'>關系</b><b class='flag-5'>型</b><b class='flag-5'>數(shù)據(jù)庫</b>的區(qū)別

    數(shù)據(jù)庫設計開發(fā)案例教程之數(shù)據(jù)庫設計的資料介紹

    本文檔的主要內(nèi)容詳細介紹的是數(shù)據(jù)庫設計開發(fā)案例教程之數(shù)據(jù)庫設計的資料介紹主要內(nèi)容包括了:1 數(shù)據(jù)庫設計概述,2 需求分析,3 概念結(jié)構(gòu)設計,4 邏輯結(jié)構(gòu)設計,5
    發(fā)表于 01-11 11:20 ?17次下載
    <b class='flag-5'>數(shù)據(jù)庫</b>設計<b class='flag-5'>開發(fā)案</b>例教程之<b class='flag-5'>數(shù)據(jù)庫</b>設計的資料介紹

    基于SQLite的鴻蒙的關系數(shù)據(jù)庫使用

    HarmonyOS關系數(shù)據(jù)庫基于SQLite組件提供了一套完整的對本地數(shù)據(jù)庫進行管理的機制,對外提供了一系列的增、刪、改、查接口,也可以直
    的頭像 發(fā)表于 01-20 11:48 ?4137次閱讀
    基于SQLite的鴻蒙的<b class='flag-5'>關系</b><b class='flag-5'>型</b><b class='flag-5'>數(shù)據(jù)庫</b>使用

    輕松設計關系數(shù)據(jù)庫教程

    本文討論關系數(shù)據(jù)庫設計相關的一些內(nèi)容,涉及關系模型,表結(jié)構(gòu)設計等內(nèi)容,以學生選修課程講述設計過程,在盡量講清楚設計要領的前提下,簡化設計內(nèi)容。 本文基于MySQL數(shù)據(jù)庫為基礎,適合有一定關系
    的頭像 發(fā)表于 07-13 09:13 ?1724次閱讀

    OpenHarmony關系數(shù)據(jù)庫概述

    關系數(shù)據(jù)庫(Relational Database, 以下簡稱RDB)是一種基于關系模型來管理數(shù)據(jù)數(shù)
    的頭像 發(fā)表于 03-28 18:08 ?1043次閱讀
    OpenHarmony<b class='flag-5'>關系</b><b class='flag-5'>型</b><b class='flag-5'>數(shù)據(jù)庫</b>概述

    關系數(shù)據(jù)庫的基本原理(什么是關系數(shù)據(jù)庫

    什么是關系數(shù)據(jù)庫?關系數(shù)據(jù)庫,簡稱 RDBMS是由許多數(shù)
    的頭像 發(fā)表于 07-10 09:06 ?1417次閱讀

    鴻蒙HarmonyOS開發(fā)實例:【分布式關系數(shù)據(jù)庫

    使用[@ohos.data.relationalStore]接口和[@ohos.distributedDeviceManager]?接口展示了在eTS中分布式關系數(shù)據(jù)庫的使用,在增、刪、改、查的基本操作外,還包括分布式
    的頭像 發(fā)表于 04-11 09:52 ?920次閱讀
    鴻蒙<b class='flag-5'>HarmonyOS</b><b class='flag-5'>開發(fā)</b>實例:【分布式<b class='flag-5'>關系</b><b class='flag-5'>型</b><b class='flag-5'>數(shù)據(jù)庫</b>】

    鴻蒙開發(fā)接口數(shù)據(jù)管理:【@ohos.data.rdb (關系數(shù)據(jù)庫)】

    關系數(shù)據(jù)庫(Relational Database,RDB)是一種基于關系模型來管理數(shù)據(jù)數(shù)據(jù)庫
    的頭像 發(fā)表于 06-10 18:35 ?1300次閱讀
    RM新时代网站-首页