目錄
概述
云數據庫開發
一、創建云數據庫的對象類型。
二、預置數據(為對象類型添加數據條目)。
三、部署云數據庫
云函數實現業務邏輯
一、創建云函數
二、云函數目錄講解
三、創建resources目錄
四、獲取云端憑據
五、導出之前創建的元數據庫對象信息
六、為實現操作數據庫創建一個類CloudDBZoneProvinceDao
七、在云函數入口文件中進行地區數據庫的查詢操作。
八、調試云函數
九、部署云函數
????????實現效果:
概述
????????通過本次課程,我們將學習怎么使用云端一體化開發模板來創建云開發工程,以及如何使用云工程進行云數據庫創建、云函數創建和調用。
那下面我們直接進入本次課程的學習。
使用云端一體化開發模板創建項目工程
這塊內容,在上一篇文章《【鴻蒙應用ArkTS開發系列】- 云開發入門簡介》中已經進行了講解,這塊這里就不在過多贅述,沒有看過的同學可以點擊這里: 鏈接 查閱
創建完畢,整體的工程目錄結構如下:
接下來,我們展開CloudProgram 這個項目,開始進行云數據開發
云數據庫開發
本次Demo將創建三個對象類型來維護查詢地理位置信息,這三個對象類型分別是
- provinces? 省份表
- cities 城市表
- districts 區/縣表
provinces的信息和預置數據如下表:
cities?的信息和預置數據如下表:
districts 的信息和預置數據如下表:
首先我們先創建云數據庫的對象類型。
這里由于篇幅原因,我們這里以provinces 為例,來講解數據表的創建以及對應預置數據的實現,其他兩個表的操作是一樣的,這里就不多提。
一、創建云數據庫的對象類型。
1、右擊“CloudProgram -> clouddb -> objecttype”目錄,選擇“New > Cloud DB Object Type”,命名為“provinces”,生成一個provinces.json文件。
2、打開provinces.json文件,配置字段、索引、以及角色與權限。
參數 | 說明 |
---|---|
fieldName | 字段名稱。 字段的名稱長度必須大于等于1個字符,小于等于30個字符,只能包含以下3種類型,并且至少包含“字母”類型:
說明
|
fieldType | 字段的數據類型。 當前支持的數據類型:String、Boolean、Byte、Short、Integer、Long、Float、Double、ByteArray、Text、Date、IntAutoIncrement和LongAutoIncrement。 |
belongPrimaryKey | 設置該字段是否為對象類型的主鍵。
|
notNull | 設置字段值是否為非空。
|
isNeedEncrypt | 設置字段是否需要加密。 開啟全程加密數據管理功能。選擇加密后,該字段對應的數據會加密存儲在存儲區中。
|
【fields】provinces 配置三個字段,自增主鍵“id”和 省份編碼 code 、省份名稱label。
【indexes】配置索引信息,本Demo不設置。
【permissions】本Demo 針對不同用戶配置不同的權限,配置如下:
role(用戶) | 描述 | rights(權限) |
World | 所有用戶,包含認證和非認證用戶。默認且最多僅可以擁有Read權限。 | 只開放讀取權限
|
Authenticated | 經過AppGallery Connect登錄認證的用戶,包含隱式登錄的匿名用戶。 | 開放讀取跟插入更新權限
|
Creator | 經過認證的數據創建用戶,每條記錄都有其對應的數據創建人。 | 開放讀取、插入更新、刪除權限
|
Administrator | 應用開發者。 | 開放讀取、插入更新、刪除權限
|
注:上面的權限只是針對Demo演示,具體配置開發者可以自行配置。
下面是provinces.json文件完整數據:
{"fields": [{"belongPrimaryKey": true,"fieldName": "id","fieldType": "IntAutoIncrement","isNeedEncrypt": false,"notNull": true},{"belongPrimaryKey": false,"fieldName": "code","fieldType": "Text","isNeedEncrypt": false,"notNull": false},{"belongPrimaryKey": false,"fieldName": "label","fieldType": "Text","isNeedEncrypt": false,"notNull": false}],"indexes": [],"objectTypeName": "provinces","permissions": [{"rights": ["Read"],"role": "World"},{"rights": ["Read","Upsert"],"role": "Authenticated"},{"rights": ["Read","Upsert","Delete"],"role": "Creator"},{"rights": ["Read","Upsert","Delete"],"role": "Administrator"}]
}
二、預置數據(為對象類型添加數據條目)。
1、右擊“CloudProgram -> clouddb -> dataentry”目錄,選擇“New > Cloud DB Data Entry”。
2、“Object Type”選擇之前創建的對象類型“provinces”,填寫數據條目名稱后,點擊“OK”。
3、在dataentry文件夾下生成了以數據條目名稱為名的json文件:provinces.json。
4、打開provinces.json文件,預置數據。
-
cloudDBZoneName:數據條目所在存儲區。
-
objectTypeName:數據條目所在對象類型。
-
objects:每個object即為一條數據。
{"cloudDBZoneName": "cloudDBOfArea","objectTypeName": "provinces","objects": [{"id": 1,"code": "110000","label": "北京市"},{"id": 2,"code": "120000","label": "天津市"},{"id": 3,"code": "130000","label": "河北省"},{"id": 4,"code": "140000","label": "山西省"},{"id": 5,"code": "150000","label": "內蒙古自治區"},{"id": 6,"code": "210000","label": "遼寧省"},{"id": 7,"code": "220000","label": "吉林省"},{"id": 8,"code": "230000","label": "黑龍江省"},{"id": 9,"code": "310000","label": "上海市"},{"id": 10,"code": "320000","label": "江蘇省"},{"id": 11,"code": "330000","label": "浙江省"},{"id": 12,"code": "340000","label": "安徽省"},{"id": 13,"code": "350000","label": "福建省"},{"id": 14,"code": "360000","label": "江西省"},{"id": 15,"code": "370000","label": "山東省"},{"id": 16,"code": "410000","label": "河南省"},{"id": 17,"code": "420000","label": "湖北省"},{"id": 18,"code": "430000","label": "湖南省"},{"id": 19,"code": "440000","label": "廣東省"},{"id": 20,"code": "450000","label": "廣西壯族自治區"},{"id": 21,"code": "460000","label": "海南省"},{"id": 22,"code": "500000","label": "重慶市"},{"id": 23,"code": "510000","label": "四川省"},{"id": 24,"code": "520000","label": "貴州省"},{"id": 25,"code": "530000","label": "云南省"},{"id": 26,"code": "540000","label": "西藏自治區"},{"id": 27,"code": "610000","label": "陜西省"},{"id": 28,"code": "620000","label": "甘肅省"},{"id": 29,"code": "630000","label": "青海省"},{"id": 30,"code": "640000","label": "寧夏回族自治區"},{"id": 31,"code": "650000","label": "新疆維吾爾自治區"},{"id": 32,"code": "710000","label": "臺灣省"},{"id": 33,"code": "810000","label": "香港特別行政區"},{"id": 34,"code": "820000","label": "澳門特別行政區"}]
}
注意:由于篇幅原因,這里步驟一、步驟二只演示了provinces 的對象類型創建跟數據預置,cities跟districts 需要按上面步驟自行創建。
三、部署云數據庫
數據配置完成,右擊“CloudProgram -> clouddb”目錄,選擇“Deploy Cloud DB”,DevEco Studio將自動把配置的信息同步至AppGallery Connect云數據庫中。
同步完成,在IDE的右下角會有如下截圖:
友情提示:對象類型,字段 如果是 IntAutoIncrement 自增,初始值為1,不可從0開始,否則部署云數據的時候會報錯。
我們可以在AppGallery Connect 對應項目中的云數據庫中找到我們部署的數據存儲區跟對象類型(表),以及對應預置的數據。
1、存儲區
2、對象類型
3、數據
接下來我們繼續講下一章節的內容,講講我們如何開發云函數,利用云函數查詢云數據庫數據的功能。
云函數實現業務邏輯
一、創建云函數
1、右擊“CloudProgram -> cloudfunctions”目錄,選擇“New > Cloud Function”,例如命名為“province-query”。
點擊OK之后,在“cloudfunctions”目錄下會生成一個province-query的函數目錄,如下圖所示:
二、云函數目錄講解
? ? ? ? 1、provinceQuery.ts:函數入口文件(此處以“provinceQuery.ts”為例,請以實際名稱為準)。請參考鴻蒙官網開發函數編寫函數代碼,這里不對函數入口文件做過多闡述。
let myHandler = async function (event, context, callback, logger) {logger.info(event);// do something herecallback({code: 0,desc: "Success."});
};export { myHandler };
- myHandler:入口方法名稱。
- event:調用方傳遞的事件對象,JSON格式。具體內容請參見event對象。
- context:函數運行時上下文對象,封裝了日志接口、回調接口、環境變量env對象等。
- callback:事件處理結果。
- logger:記錄日志。
????????函數必須通過顯示調用callback(object)將事件處理結果返回給AGC,結果可以是任意對象,但必須與JSON.stringify兼容,AGC會將結果轉換成JSON字符串后,返回給調用方。callback執行完成,函數即執行結束。
????????2、function-config.json:函數的配置文件,可配置觸發器,通過觸發器暴露的觸發條件來實現函數調用。
????????在“triggers”下配置觸發器,云函數目前支持以下5種觸發器。
???????注意:如您需在函數部署完成后更新觸發器,請先刪除之前的觸發器配置,再添加新的觸發器配置,否則您的更新將不生效。
觸發器 | 描述 |
HTTP觸發器 | 函數部署到云端后會自動生成觸發URL,在您向該URL發起HTTP請求時觸發函數。 請參見官網通過HTTP觸發器調用函數 |
CLOUDDB觸發器 | 當云數據庫發生插入或者更新數據、刪除數據、清空數據等變更操作時將觸發云函數。 請參見官網云數據庫調用函數 |
AUTH觸發器 | 為函數配置AUTH觸發器來接收用戶的注冊、登錄等關鍵事件。例如,若添加了“用戶注冊”事件類型的AUTH觸發器,當認證服務檢測到用戶注冊事件發生時將觸發函數。 請參見認證服務調用函數官網認證服務調用函數 |
CLOUDSTORAGE觸發器 | 當AGC云存儲服務中發生文件或者文件夾上傳或刪除操作時,將觸發函數并執行您想要實現的功能。 請參見官網云存儲調用函數 |
CRON觸發器 | CRON觸發器即定時任務觸發器,用于在指定的時間點觸發云函數。 請參見官網通過定時任務觸發器調用函數 |
?
觸發器的具體知識這里我們不講,大家可以查閱鴻蒙官網,會比我講的詳細,本次Demo我們會使用到HTTP觸發器。
? ?3、package.json:包含了當前函數的名稱、版本等函數元數據。package.json內自動引入了云數據庫的最新版本Node.js Server SDK,您也可以在“dependencies”下添加其他需要的依賴。
????????我這邊版本的IDE實際操作創建云函數時,函數目錄下只生成了如上面截圖所示的provinceQuery.ts、function-config.json、package.json這三個文件,package.json 文件中也沒有自動引入云數據庫依賴,實際上完整的云函數目錄結構應該是下面這樣的。
那我們只需要在package.json 文件中下增加如下云數據庫依賴, 點擊Run npm install即可 。
? ?4、node_modules:自動為該函數引入依賴包。
? ?5、package-lock.json:保存了node_modules中所有包的信息,如版本、下載地址等。
????????
三、創建resources目錄
·????????在“province-query”下新建一個"resources"目錄。
????????
注意:由于篇幅原因,這里步驟一、步驟三只演示了provinces-query 云函數的創建和配置,cities跟districts 對應的云函數需要按上面步驟自行創建。
四、獲取云端憑據
????????1、進入AppGallery Connect,點擊“我的項目”。
????????2、點擊應用或者元服務所屬的項目,進入“項目設置”頁面。
? ? ? ? 3、選中“Server SDK”頁簽,點擊“下載認證憑據”。
? ? ? ? 4、將獲取的云端憑據文件放置在云函數中新建的"resources"目錄下。d
五、導出之前創建的元數據庫對象信息
????????1、進入AppGallery Connect,點擊“我的項目”。
? ? ? ? 2、點擊元服務所屬的項目,進入“項目設置”頁面。
? ? ? ? 3、左側導航選擇“Serverless > 云數據庫”,選中“provinces”、“cities”、“districts”對象類型,點擊“導出”。
? ? ? ? 4、“導出文件格式”選擇“js格式”,“js文件類型”選擇“serverSDK”,點擊“確定”,導出壓縮包文件,解壓后得到?provinces.js、cities.js、districts.js文件。
? ? ? ? 5、將導出的provinces.js、cities.js、districts.js文件放置云函數的根目錄。
????????
六、為實現操作數據庫創建一個類CloudDBZoneProvinceDao
? ? ? ? 1、右擊province-query云函數,選擇“New > File”,文件名填寫CloudDBZoneProvinceDao.ts。
? ? ? ? 2、在文件中補充如下完整代碼,其中credentialPath中agc-apiclient-1172400184764681664-7241544512647644597.json需替換為第四步獲取的云端憑證名稱。
import {AGConnectCloudDB,CloudDBZone,CloudDBZoneConfig,CloudDBZoneQuery,CloudDBZoneSnapshot
} from "@agconnect/database-server/dist/index.js"
import { AGCClient, CredentialParser } from "@agconnect/common-server"
import path from 'path'
import { provinces } from "./provinces"let mProvincesObject = new provinces();let loggerlet mCloudDBZone: CloudDBZoneclass CloudDBZoneProvinceDao {// AGC & 數據庫初始化constructor(log) {let agcClient;const credentialPath = "/resources/gc-apiclient-1172400184764681664-7241544512647644597.json";try {agcClient = AGCClient.getInstance();} catch (error) {AGCClient.initialize(CredentialParser.toCredential(path.join(__dirname, credentialPath)));agcClient = AGCClient.getInstance();}AGConnectCloudDB.initialize(agcClient)const cloudDBZoneConfig = new CloudDBZoneConfig("cloudDBOfArea");const agconnectCloudDB = AGConnectCloudDB.getInstance(agcClient);mCloudDBZone = agconnectCloudDB.openCloudDBZone(cloudDBZoneConfig);}// 查詢省份列表數據async executeQueryProvince(): Promise<provinces[]> {if (!mCloudDBZone) {console.log("CloudDBClient is null, try re-initialize it");return;}try {const query = CloudDBZoneQuery.where(provinces).orderByAsc('code');const resp: CloudDBZoneSnapshot<provinces> = await mCloudDBZone.executeQuery(query);console.log("CloudDB Success")return resp.getSnapshotObjects();} catch (error) {console.log("CloudDB error: " + error);}}
}export default CloudDBZoneProvinceDao;
注意:這里只提供了CloudDBZoneProvinceDao作為例子,另外兩個對象類型操作類請自行創建,也可在文章隨附的Demo中拷貝。
在數據庫對象類型操作類中,我們定義了幾個數據庫表操作方法:
- executeQueryProvince? 查詢所有省份列表數據
- executeQueryCitiesByPCode 根據省份編碼查詢城市列表數據
- executeQueryDistrictByCCode 根據城市編碼查詢區/縣列表數據
在下一步云函數觸發器中,我們將使用這幾個數據庫對象類型操作類進行云數據數據查詢操作。
七、在云函數入口文件中進行地區數據庫的查詢操作。
????????這里依舊以province-query 云函數為例,拷貝如下代碼到provinceQuery.ts文件中,完整示例代碼如下:
import CloudDBZoneProvinceDao from "./CloudDBZoneProvinceDao"
import {provinces} from "./provinces"let myHandler = async function (event, context, callback, logger) {logger.info(event);var res = new context.HTTPResponse(context.env, {"res-type":"context.env","faas-content-type":"json",},"application/json", "200");const cloudDBZoneProvinceDao = new CloudDBZoneProvinceDao(logger);let data: provinces[] = await cloudDBZoneProvinceDao.executeQueryProvince();var body = {result: data};res.body = body;callback(res);
};
export { myHandler };
????????這里在myHandler中接收請求,可以獲取請求參數進行處理,然后返回一個HttpResponse,使用CloudDBZoneProvinceDao 對象操作云數據庫將省份列表數據從數據庫中查詢出來并作為請求響應body使用callback返回給客戶端。
八、調試云函數
? ? ? ? 省份列表數據云函數開發完畢,我們需要對函數進行調試,確保函數功能正常可用。
????????1、右擊“CloudProgram -> cloudfunctions”目錄,選擇“Run Cloud Functions”。
????????
? ? ? ? 如下截圖,說明云函數本地運行成功。
????????2、待DevEco Studio運行完成后,菜單選擇“Tools > CloudDev > Cloud Functions Requestor”。
? ? ? ? 3、在右側“Cloud Functions Requestor”面板,對云函數進行調試。????????
- ????????Environment:選擇“Local”。
- ????????Cloud Function:選擇“province-query”。
- ????????Event:輸入函數的參數,為JSON格式的請求體數據。
? ? ? ? 4、點擊“Trigger”,執行云函數,查看Result內容和日志信息。
九、部署云函數
????????云函數調試正常后,右擊“CloudProgram -> cloudfunctions”目錄,選擇“Deploy Cloud Functions”,DevEco Studio將自動把內容同步至AppGallery Connect云函數中。
????????將函數部署到AGC控制臺,支持單個部署和批量部署。這里我先演示一下單個部署。
????????1、單個部署。右擊需部署的函數目錄,選擇“Deploy Function”。??
? ? ? ?
????????2、“底部狀態欄右側將展示函數打包與部署進度。請耐心等待,直至出現“Deploy successfully”消息,表示函數已成功部署。
? ? ? ? 3、在AppGallery Connect 云函數面板可以查到我們部署上去的云函數。
? ? ? ? 4、上面我們完成了省份查詢 province-query云函數 中provinceQuery.js 云函數邏輯的編寫,并將單個函數部署完成。那就一次到位,將城市查詢云函數以及區縣查詢云函數的邏輯開發完畢,再進行批量云函數部署。
cityQuery.ts ,完整代碼如下:
import CloudDBZoneCityDao from "./CloudDBZoneCityDao"
import {cities} from "./cities"let myHandler = async function (event, context, callback, logger) {logger.info(event);var res = new context.HTTPResponse(context.env, {"res-type":"context.env","faas-content-type":"json",},"application/json", "200");let provinceCode ;if (event.body) {var _body = JSON.parse(event.body);provinceCode = _body.code;} else {provinceCode = event.code;};if (!provinceCode) {provinceCode = '';}const cloudDBZoneCityDao = new CloudDBZoneCityDao(logger);let data: cities[] = await cloudDBZoneCityDao.executeQueryCitiesByPCode(provinceCode);var body = {result: data};res.body = body;callback(res);
};
export { myHandler };
?districtsQuery.js?,完整代碼如下:
import CloudDBZoneDistrictDao from "./CloudDBZoneDistrictDao"
import {districts} from "./districts"let myHandler = async function (event, context, callback, logger) {logger.info(event);var res = new context.HTTPResponse(context.env, {"res-type":"context.env","faas-content-type":"json",},"application/json", "200");let cityCode;if (event.body) {var _body = JSON.parse(event.body);cityCode = _body.code;} else {cityCode = event.code;};if (!cityCode) {cityCode = '';}const cloudDBZoneDistrictDao = new CloudDBZoneDistrictDao(logger);let data: districts[] = await cloudDBZoneDistrictDao.executeQueryDistrictByCCode(cityCode);var body = {result: data};res.body = body;callback(res);
};
export { myHandler };
注意:
? ? ? ? 這里有一個點需要留意下:
這里為什么要做這個處理的呢,只是因為方便直接在Cloud Functions Requestor面板中貼body中的JSON,比如客戶端調用云函數時實際的報文是這樣的,我們設置的json的時候是調用
functionCallable.call(params)
這個params 是??{"code":"110000"} ,后端接收到的是
{"body": "{\"code\":\"110000\"}"
}
body節點下的json需要進行轉義。為了方便我們在Cloud Functions Requestor 中event框中直接貼
{"code":"110000"}
這里取請求報文做了下處理。
? ? ? ? 5、批量部署函數。
????????批量部署指將整個云函數目錄下創建的所有函數同時部署到AGC控制臺。
????????
????????到這里,關于云函數開發跟部署的流程我們就講解完畢了,客戶端關于地址聯動涉及的三個接口我們都開發并完成部署,接下來我們開發客戶端UI,介紹客戶端如何調用云函數,并進行數據展示。
? ? ? ? 由于篇幅原因,本篇文章數字已經到1W+,為了提高讀者可讀性,減少單次閱讀疲勞感,我將另外寫一篇《云開發入門實戰二 實現城市多級聯動Demo(下)》,對客戶端調用云函數進行服務端數據獲取展示功能進行講解。
? ? ? ? 這里對本篇文章進行一個回顧,做個總結
- 創建云數據庫對象類型
- 預置數據
- 部署云數據庫
- 創建云函數
- 獲取云端憑證
- 導出元數據庫對象信息拷貝到云函數根目錄中
- 創建云數據庫對象類型操作類(Dao)
- 云函數入口JS文件邏輯開發
- 調試并部署云函數
? ? ? ? 謝謝大家的閱讀。
? ? ? ? ?這里附上本文源碼(只提供相關云數據庫(對象類型、預置數據)、云函數核心類)源碼下載地址
????????