<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
創作中心

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

3天內不再提示

HarmonyOS開發案例:【關系型數據庫】

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

介紹

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

相關概念

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

環境搭建

軟件要求

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

硬件要求

  • 開發板類型:[潤和RK3568開發板]。
  • OpenHarmony系統:3.2 Release。

環境搭建

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

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

代碼結構解讀

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

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

├──entry/src/main/ets               // 代碼區
│  ├──common
│  │  ├──constants
│  │  │  └──CommonConstants.ets     // 公共常量
│  │  ├──database
│  │  │  ├──tables
│  │  │  │  └──AccountTable.ets     // 賬目數據表
│  │  │  └──Rdb.ets                 // RDB數據庫
│  │  └──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         // 資源文件夾

創建數據庫

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

導入關系型數據庫模塊:

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

關系型數據庫提供以下兩個基本功能:

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

// Rdb.ets
getRdbStore(callback: Function = () = > {
}) {
  // 如果已經獲取到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接口初始化數據庫表結構和相關數據
    this.rdbStore.executeSql(this.sqlCreateTable);          
    Logger.verbose(`${RDB_TAG}`, 'getRdbStore() finished.');
    callback();
  });
}

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

// 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);
    });
  }
}

刪除數據使用了delete()接口,實現代碼如下:

// 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);
    });
  }
}

更新數據使用了update()接口,實現代碼如下:

// 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);
    });
  }
}

查找數據使用了query()接口,實現代碼如下:

// 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需要記錄賬目的類型(收入/支出)、具體類別和金額,因此需要創建一張存儲賬目信息的表,表頭如下:

創建該表的SQL語句為:

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

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

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

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

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

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

// 查找數據
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);
    }
  });
}

功能實現

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

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

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

點擊右上角的“編輯”圖標,主頁面變為如下效果:

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

// 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;
}

搜索欄在鍵入文本并回車時,實現搜索功能:

// 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組件創建的賬目類別、使用TextInput組件創建的輸入欄和確定按鈕組成,如下圖所示:

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

// Mainpage.ets
accept(isInsert: boolean, newAccount: AccountData): void {
  if (isInsert) {  // 插入模式,往數據庫插入一個新賬目
    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 {  // 編輯模式,更新當前選中的賬目并寫入數據庫,刷新頁面的賬目清單
    this.AccountTable.updateData(newAccount, () = > {});
    let list = this.accounts;
    this.accounts = [];
    list[this.index] = newAccount;
    this.accounts = list;
    this.index = -1;
  }
}

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據庫
    +關注

    關注

    7

    文章

    3591

    瀏覽量

    63374
  • HarmonyOS
    +關注

    關注

    79

    文章

    1853

    瀏覽量

    29267
  • OpenHarmony
    +關注

    關注

    23

    文章

    3311

    瀏覽量

    15159
收藏 人收藏

    評論

    相關推薦

    數據庫連接

    在利用 LabVIEW數據庫工具包操作數據庫之前,需要先連接數據庫,這就像操作文件之前,先要打開文件一樣。在這里我們利用UDL連接數據庫。Microsoft設計的ODBC標準只能訪問
    發表于 06-29 21:29

    建立與數據庫的連接

    在利用 LabVIEW數據庫工具包操作數據庫之前,需要先連接數據庫,這就像操作文件之前,先要打開文件一樣。在這里我們利用UDL連接數據庫。Microsoft設計的ODBC標準只能訪問
    發表于 07-01 21:24

    使用NoSQL數據庫的原因

    阻抗失衡 關系模型和內存中的數據結構不匹配 采用更為方便的數據交互方式提升開發效率待處理的數據量很大
    發表于 05-27 06:43

    關系數據庫與非關系數據庫的區別淺析

    關系數據庫的一個劣勢就是 阻抗失諧(impedance mismatch):關系模型和內存中的數據結構之間存在差異
    發表于 06-03 06:03

    Hbase分布式非關系數據庫安裝部署步驟

    Hbase分布式非關系數據庫安裝與部署
    發表于 09-19 08:50

    HarmonyOS應用開發數據交互--關系數據庫完整流程練習

    名稱使用默認配置創建數據庫配置。 private RdbStore rdbStore;//提供管理關系數據庫 (RDB) 的方法。 //RdbOpenCallback 管理數據庫創建、升級和降級
    發表于 09-13 15:05

    基于Data Ability的關系數據庫數據管理能力,實現數據庫相關應用服務的快速開發

    1. 基于Data Ability的關系數據庫操作方法介紹HarmonyOS支持應用以Ability為單位進行部署,Ability可以分為FA(Feature Ability)和PA
    發表于 09-26 16:43

    一款基于Java實現的小巧而強大的關系數據庫

    H2 是一款基于 Java 實現的小巧而強大的關系數據庫,支持嵌入式、客戶端/服務器以及混合部署模式。H2 數據庫適合嵌入小型應用程序、元數據
    發表于 10-27 06:12

    HarmonyOS數據庫的相關資料下載

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

    怎樣使用Harmony Developer提供的關系數據庫的相關API去讀取sqlite文件內容呢

    Developer提供的關系數據庫的相關API去讀取之前放入的sqlite文件的內容,然后展示出來最后的效果如下:該demo中操作關系
    發表于 03-28 11:21

    HarmonyOS關系數據庫和對象關系數據庫的使用方法

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

    請問HarmonyOS是如何解決數據存儲問題的?

    背景描述:現在任何一款成熟的APP應用,如淘寶,將海量信息均是存儲在遠端服務器上,前端(如:web端、手機APP端)通過調用接口來展示商品數據。而在HarmonyOS提供的文檔中:不管是關系
    發表于 03-31 15:31

    求助,Android和HarmonyOS都使用SQLite數據庫,能在兩個環境組合訪問數據庫嗎?

    開發一個APP,同時支持Android和HarmonyOS;Android 和HarmonyOS 都使用SQLite 數據庫,能在兩個環境組合訪問
    發表于 06-17 09:39

    如何在HarmonyOS數據庫進行備份,恢復與加密

    數據庫恢復至可用狀態。 鍵值數據庫關系數據庫均支持對
    發表于 11-07 08:57

    數據庫設計開發案例教程之數據庫設計的資料介紹

    本文檔的主要內容詳細介紹的是數據庫設計開發案例教程之數據庫設計的資料介紹主要內容包括了:1 數據庫設計概述,2 需求分析,3 概念結構設計,4 邏輯結構設計,5
    發表于 01-11 11:20 ?17次下載
    <b class='flag-5'>數據庫</b>設計<b class='flag-5'>開發案</b>例教程之<b class='flag-5'>數據庫</b>設計的資料介紹
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>