端侧调用云数据库
·
1、一键生成目标对象类型类文件
云数据库支持从端侧或者云侧云函数访问数据库,代码涉及调用云数据库时,需要引入对应云数据库对象类型的类文件。DevEco当前支持为对象类型一键生成类文件,供开发者在端侧或云侧云函数开发时引用,以下为生成端侧对象类型类文件。
-
在云侧工程中,右击目标对象类型(以Feeding为例),选择“Generate Client Model”。
-
选择生成的Client Model文件存放的端侧目录。
-
点击“OK”。指定目录下生成对应对象类型的Client Model文件,后续开发者便可以在端侧代码中方便地引用该Client Model。
import { Feeding } from '../model/Feeding';
2、在端侧工程操作云数据库
云开发服务能力为开发者提供了直接操作云数据库的模块,该模块可以对云数据库进行数据写入、查询、删除等操作。
端侧工程查询云数据库数据分为三步,第一步引入云数据库模块组件;第二步构建查询条件;第三步从存储区获取满足查询条件的数据。
1)引入云数据库模块组件和端侧模型类Feeding。
import { cloudDatabase } from '@kit.CloudFoundationKit';
import { Feeding } from '../model/Feeding';
2)构建查询条件
云数据库模块提供了丰富的谓词查询来构建查询条件,包括以下谓词:
方法 | 说明 |
---|---|
equalTo(fieldName: string, value: FieldType) |
添加实体类中某个字段的值等于指定值的查询条件 |
notEqualTo(fieldName: string, value: FieldType) |
添加实体类中某个字段的值不等于指定值的查询条件 |
beginsWith(fieldName: string, value: FieldType) |
添加实体类中string类型字段值以指定子串开头的查询条件。 |
endsWith(fieldName: string, value: FieldType) |
添加实体类中string类型字段值以指定子串结尾的查询条件。 |
contains(fieldName: string, value: FieldType) |
添加实体类中字符串类型字段值包含指定子字符串的查询条件。 |
greaterThan(fieldName: string, value: FieldType) |
添加实体类字段值大于指定值的查询条件。 |
greaterThanOrEqualTo(fieldName: string, value: FieldType) |
添加实体类字段值大于或等于指定值的查询条件。 |
lessThan(fieldName: string, value: FieldType) |
添加实体类字段值小于指定值的查询条件。 |
lessThanOrEqualTo(fieldName: string, value: FieldType) |
添加实体类字段值小于或等于指定值的查询条件。 |
in(fieldName: string, values: FieldType[]) |
添加实体类字段值包含在指定数组中的查询条件。 |
isNull(fieldName: string) |
添加实体类某字段值为空的查询条件。 |
isNotNull(fieldName: string) |
添加实体类某字段值不为空的查询条件。 |
orderByAsc(fieldName: string) |
按指定字段升序对查询结果进行排序。 |
orderByDesc(fieldName: string) |
按指定字段降序对查询结果进行排序。 |
limit(count: number, offset?: number) |
指定返回的查询结果集中的数据记录条数。如果不设置offset,则默认从首个对象开始获取前count个对象。 |
beginGroup() |
调用此方法是为了放置左括号“(”附加到任何查询条件并将右括号“)”与相同的查询连接起来组合使用。 |
endGroup() |
调用此方法是为了放置右括号“)”附加到任何查询条件并将左括号“(”与相同的查询连接起来组合使用。 |
or() |
使用or运算组合两个条件并返回两个查询结果的并集。 |
and() |
使用and运算组合两个条件并返回两个查询结果的交集。 |
我们以查询当前宝宝喂养记录为例,需要用到greaterThanOrEqualTo
、lessThanOrEqualTo
两个属性来获取当天喂养记录。
condition: cloudDatabase.DatabaseQuery<Feeding> = new cloudDatabase.DatabaseQuery(Feeding);
condition
.greaterThanOrEqualTo("startTime", this.currentDateTime.setHours(0, 0, 0, 0))
.and()
.lessThanOrEqualTo("startTime", this.currentDateTime.setHours(23, 59, 59, 999));
3)查询数据
构建符合业务逻辑的查询条件之后,调用云数据库模块提供通过存储区名称初始化云数据库实例。云数据库实例具备以下能力:
方法 | 说明 |
---|---|
query<T extends DatabaseObject>(condition: DatabaseQuery<T>) |
通过查询条件查询数据 |
calculateQuery<T extends DatabaseObject>(condition: DatabaseQuery<T>, fieldName: string, calculate: QueryCalculate) |
从数据库中查询符合条件的数据,并对指定字段进行算术计算。 |
upsert<T extends DatabaseObject>(objectList: T[] | T) |
向数据库更新数据,可以更新一条或多条对象数据。 |
delete<T extends DatabaseObject>(objectList: T[] | T) |
在数据库中删除一条或者多条数据,可以删除一条或多条对象数据。 |
// 构建查询条件
const queryCondition = this.condition
.greaterThanOrEqualTo("startTime", this.currentDateTime.setHours(0, 0, 0, 0))
.and()
.lessThanOrEqualTo("startTime", this.currentDateTime.setHours(23, 59, 59, 999));
const result = await this.databaseZone.query(queryCondition);
完成的代码:
currentDateTime: Date = new Date();
condition: cloudDatabase.DatabaseQuery<Feeding> = new cloudDatabase.DatabaseQuery(Feeding);
private databaseZone = cloudDatabase.zone("default");
@State allFeedingList: Feeding[] = [];
// 查询当前喂养记录信息
async queryAllFeeding() {
try {
// 构建查询条件
const queryCondition = this.condition
.greaterThanOrEqualTo("startTime", this.currentDateTime.setHours(0, 0, 0, 0))
.and()
.lessThanOrEqualTo("startTime", this.currentDateTime.setHours(23, 59, 59, 999));
const result = await this.databaseZone.query(queryCondition);
if (result.length > 0) {
this.allFeedingList = result;
}
} catch (error) {
// 异常处理
this.allFeedingList = [];
}
}
async aboutToAppear(): Promise<void> {
this.queryAllFeeding();
}
// 页面
if (this.allFeedingList.length > 0) {
List() {
ForEach(this.allFeedingList, (item: Feeding) => {
ListItem() {
Column({ space: 8 }) {
Row() {
Text(`${item.type}喂养`)
Text(`${item.startTime.toLocaleDateString()}`)
}
.width('100%')
.height(32)
.justifyContent(FlexAlign.SpaceBetween)
if (item.type === '母乳') {
Row() {
Text(`左边喂养时长:${item.leftDuration}m`)
Text(`右边喂养时长:${item.rightDuration}m`)
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
Text(`总喂养时长:${item.totalDuration}m`)
.width('100%')
.height(32)
}
.backgroundColor(0xf2f2f2)
.padding(12)
.borderRadius(8)
}
})
}
.width('90%')
.divider({
strokeWidth: 2,
color: Color.White
})
}
4)新增数据
// 新增喂养记录
async insertFeeding(feeding: Feeding) {
await this.databaseZone.upsert(feeding);
}
5)删除数据
// 删除数据
async deleteFeeding(feeding: Feeding) {
await this.databaseZone.delete(feeding);
}
完整代码:
import { cloudFunction, cloudDatabase } from '@kit.CloudFoundationKit';
import { BusinessError, request } from '@kit.BasicServicesKit';
import { SymbolGlyphModifier } from '@kit.ArkUI';
import { Feeding } from '../model/Feeding';
interface BabyAge {
years: number;
months: number;
days: number;
totalDays: number;
}
interface ResponseBody {
code: number;
desc: string;
data: BabyAge
}
@Entry
@Component
struct Index {
controller: SearchController = new SearchController();
@State birthday: string = "";
@State callFunctionResult: BabyAge | undefined = undefined;
currentDateTime: Date = new Date();
condition: cloudDatabase.DatabaseQuery<Feeding> = new cloudDatabase.DatabaseQuery(Feeding);
private databaseZone = cloudDatabase.zone("default");
@State allFeedingList: Feeding[] = [];
@State feeding: Feeding = new Feeding();
@State isFeeding: boolean = false;
@State startTime: Date = new Date();
// 查询当前喂养记录信息
async queryAllFeeding() {
try {
// 构建查询条件
const queryCondition = this.condition
.greaterThanOrEqualTo("startTime", this.currentDateTime.setHours(0, 0, 0, 0))
.and()
.lessThanOrEqualTo("startTime", this.currentDateTime.setHours(23, 59, 59, 999));
const result = await this.databaseZone.query(queryCondition);
if (result.length > 0) {
this.allFeedingList = result;
}
} catch (error) {
// 异常处理
this.allFeedingList = [];
}
}
// 新增喂养记录
async insertFeeding(feeding: Feeding) {
await this.databaseZone.upsert(feeding);
await this.queryAllFeeding();
}
// 删除数据
async deleteFeeding(feeding: Feeding) {
try {
await this.databaseZone.delete(feeding);
await this.queryAllFeeding();
} catch (error) {
const err: BusinessError = error;
this.getUIContext().getPromptAction().showToast({
message: err.message
})
}
}
async aboutToAppear(): Promise<void> {
this.queryAllFeeding();
}
build() {
Column({ space: 10 }) {
Text("请先设置宝宝出生日期")
.fontColor(Color.Grey)
.height(54)
Search({ controller: this.controller, value: this.birthday })
.width('90%')
.height('54vp')
.searchIcon(
new SymbolGlyphModifier($r('sys.symbol.calendar_badge_play'))
.fontColor([Color.Grey])
.fontSize('30fp')
)
.cancelButton({
style: CancelButtonStyle.INVISIBLE
})
.borderRadius('8vp')
.onClick(() => {
CalendarPickerDialog.show({
selected: new Date(this.birthday),
acceptButtonStyle: {
style: ButtonStyleMode.EMPHASIZED
},
cancelButtonStyle: {
fontColor: Color.Grey
},
onAccept: async (value) => {
this.birthday = value.toLocaleDateString();
console.info("calendar onAccept:" + JSON.stringify(value))
let result: cloudFunction.FunctionResult = await cloudFunction.call({
name: 'calculate-baby-age',
version: '$latest',
timeout: 10 * 1000,
data: {
birthday: this.birthday
}
});
let body = result.result as ResponseBody;
this.callFunctionResult = body.data;
}
})
})
if (this.callFunctionResult !== undefined) {
Row() {
Column({ space: 8 }) {
Text(`我已经${this.callFunctionResult.years}岁了 ${this.callFunctionResult.months}月 ${this.callFunctionResult.days}天了~`)
Text(`我已经出生${this.callFunctionResult.totalDays}天了~`)
}
.width('100%')
}
.width('90%')
Button(`${this.isFeeding ? '停止喂养' : '开始喂养'}`)
.backgroundColor(this.isFeeding ? Color.Orange : Color.Green)
.onClick(async () => {
this.isFeeding = !this.isFeeding;
if (this.isFeeding) {
this.startTime = new Date();
this.feeding.id = this.allFeedingList.length + 1;
this.feeding.startTime = this.startTime;
} else {
this.feeding.totalDuration = new Date().getTime() - this.startTime.getTime();
await this.insertFeeding(this.feeding);
}
})
if (this.allFeedingList.length > 0) {
List() {
ForEach(this.allFeedingList, (item: Feeding) => {
ListItem() {
Column({ space: 8 }) {
Row() {
Text(`${item.type}喂养`)
Text(`${item.startTime.toLocaleDateString()}`)
}
.width('100%')
.height(32)
.justifyContent(FlexAlign.SpaceBetween)
Text(`总喂养时长:${item.totalDuration >= (60 * 1000) ? (item.totalDuration / (60 * 1000)) + 'm' : (item.totalDuration / 1000) + 's'}`)
.width('100%')
.height(32)
Row() {
Button("删除")
.onClick(async () => {
this.getUIContext().getPromptAction().showDialog({
title: '温馨提示',
message: '确定要删除该喂养记录吗?',
buttons: [
{
text: '取消',
color: '#D3D3D3'
},
{
text: '确定',
color: '#FF5277'
}
],
})
.then(async data => {
console.info('showDialog success, click button: ' + data.index);
if (data.index === 1) {
await this.deleteFeeding(item);
}
})
.catch((err: Error) => {
console.info('showDialog error: ' + err);
})
})
}
.width('100%')
}
.backgroundColor(0xf2f2f2)
.padding(12)
.borderRadius(8)
}
})
}
.width('90%')
.height(450)
.divider({
strokeWidth: 2,
color: Color.White
})
}
}
}.width('100%').height('100%')
}
}
更多推荐
所有评论(0)