数据模型——饮食记录

数据模型——饮食记录

本次实验完成饮食记录的数据模型,如下图所示

在这里插入图片描述

该饮食记录模型与上次的记录项数据模式定义处理方式相同,我们首先分析其数据结构,我们发现首先有早餐、午餐、晚餐等记录类型数据模型,其包括了id、类型名称、类型图标、类型推荐最小和最大卡路里等。在每个类型中又可以添加记录项,记录项也有id、类型id、卡路里总数、和上节课定义的记录项相同的数据项和食品数量或运动时长等组成的记录项数据模型。

记录类型数据模型

export default class RecordType{/*** 类型id*/id: number/*** 类型名称*/name: ResourceStr/*** 类型图标*/icon: ResourceStr/*** 类型推荐最小卡路里*/min: number/*** 类型推荐最大卡路里*/max: numberconstructor(id: number, name: ResourceStr, icon: ResourceStr, min: number = 0, max: number = 0) {this.id = idthis.name = namethis.icon = iconthis.min = minthis.max = max}
}

可以看出min和max设置了默认可选值,因为当类型为运动时,没有类型推荐最小卡路里、类型推荐最大卡路里

import RecordType from '../viewmodel/RecordType'enum RecordTypeEnum {/*** 早餐*/BREAKFAST,/*** 午餐*/LUNCH,/*** 晚餐*/DINNER,/*** 加餐*/EXTRA_MEAL,/*** 运动*/WORKOUT
}/*** 记录类型常量*/
const RecordTypes: RecordType[] = [new RecordType(0, $r("app.string.breakfast"), $r("app.media.ic_breakfast"), 423, 592),new RecordType(1, $r("app.string.lunch"), $r("app.media.ic_lunch"), 592, 761),new RecordType(2, $r("app.string.dinner"), $r("app.media.ic_dinner"), 423, 592),new RecordType(3, $r("app.string.extra_meal"), $r("app.media.ic_extra_m"), 0, 169),new RecordType(4, $r("app.string.workout"), $r("app.media.ic_workout")),
]export {RecordTypes, RecordTypeEnum}

这里设置RecordTypeEnum枚举的作用与上次相同,有助于每一项数据项能方便的找到其所在的类型。

记录项数据模型

import RecordItem from './RecordItem'/*** 饮食记录的页面数据模型*/
export default class RecordVO {/*** 记录id*/id: number/*** 饮食记录类型*/typeId: number/*** 卡路里总数*/calorie: number/*** 记录中的食物或运动信息*/recordItem: RecordItem/*** 食物数量或运动时长,如果是运动信息则无*/amount: number = 0
}

在其中recordItem的类型是上次我们定义的RecordItem数据模型,方便我们直接使用上次定义的数据模型中的数据。

在这里插入图片描述

如图所示,RecordModel我们采用了关系型数据库来保存记录项的数据,通过关系型数据库来进行数据操作,这样做的原因是因为,这部分数据是可以根据日期进行查询的,还可以执行删除操作,所以不能像其他数据一样保存在内存中,必须保存在关系型数据库中才能进行

持久化保存。

为了操作数据库方便,我们定义了数据库通用工具类

import common from '@ohos.app.ability.common';
import relationalStore from '@ohos.data.relationalStore';
import { ColumnInfo, ColumnType } from '../bean/ColumnInfo';
import Logger from './Logger';const DB_FILENAME: string = 'HeiMaHealthy.db'class DbUtil {rdbStore: relationalStore.RdbStoreinitDB(context: common.UIAbilityContext): Promise<void> {let config: relationalStore.StoreConfig = {name: DB_FILENAME,securityLevel: relationalStore.SecurityLevel.S1}return new Promise<void>((resolve, reject) => {relationalStore.getRdbStore(context, config).then(rdbStore => {this.rdbStore = rdbStoreLogger.debug('rdbStore 初始化完成!')resolve()}).catch(reason => {Logger.debug('rdbStore 初始化异常', JSON.stringify(reason))reject(reason)})})}createTable(createSQL: string): Promise<void> {return new Promise((resolve, reject) => {this.rdbStore.executeSql(createSQL).then(() => {Logger.debug('创建表成功', createSQL)resolve()}).catch(err => {Logger.error('创建表失败,' + err.message, JSON.stringify(err))reject(err)})})}
//添加通用新增方法insert(tableName:string,obj:any,columns:ColumnInfo[]){return new Promise((resolve,reject)=>{//1.构建新增的数据let value=this.buildValueBucket(obj,columns)//2.新增this.rdbStore.insert(tableName,value,(err,id)=>{if (err) {Logger.debug('新增失败!',JSON.stringify(err))reject(err)}else {Logger.debug('新增成功!新增id:',id.toString())resolve(id)}})})}//通用删除delete(predicates:relationalStore.RdbPredicates){return new Promise((resolve,reject)=>{//1.删除this.rdbStore.delete(predicates,(err,rows)=>{if (err) {Logger.debug('删除失败!',JSON.stringify(err))reject(err)}else {Logger.debug('删除成功!删除行数:',rows.toString())resolve(rows)}})})}//批量查询queryForList<T>(predicates:relationalStore.RdbPredicates,columns:ColumnInfo[]):Promise<T[]>{return new Promise((resolve,reject)=>{//1.删除this.rdbStore.query(predicates,columns.map(info=>info.columnName),(err,result)=>{if (err) {Logger.debug('查询失败!',JSON.stringify(err))reject(err)}else {Logger.debug('查询成功!查询行数:',result.rowCount.toString())resolve(this.parseResultSet(result,columns))}})})}//解析resultSETparseResultSet<T>(result:relationalStore.ResultSet,columns:ColumnInfo[]):T[]{//1.声明最终返回结果let arr=[]//2.判断是否有结果if (result.rowCount<=0) {return arr;}//3.处理结果while (!result.isAtLastRow) {//3.1 去下一行result.goToNextRow()//3.2 解析该行数据,转为结果对象格式let obj={}columns.forEach(info=>{let val=nullswitch (info.type){case ColumnType.LONG:val=result.getLong(result.getColumnIndex(info.columnName))break;case ColumnType.DOUBLE:val=result.getDouble(result.getColumnIndex(info.columnName))break;case ColumnType.STRING:val=result.getString(result.getColumnIndex(info.columnName))break;case ColumnType.BLOB:val=result.getBlob(result.getColumnIndex(info.columnName))break;}obj[info.name]=val;})//3.3 将对象填充到数组arr.push(obj)}return arr;}buildValueBucket(obj:any,columns:ColumnInfo[]):relationalStore.ValuesBucket{//1.构建数据let value={}columns.forEach(info=>{let val=obj[info.name]if (typeof val !=='undefined') {value[info.columnName]=val}})return value
}}let dbUtil: DbUtil = new DbUtil();export default dbUtil as DbUtil

可以看出,我们只需要提供DBUtil中所需方法的参数,即可进行增删改查操作,适用于所有数据库。但是想要实现该功能,需要在EntryAbility中初始化RDB工具和数据库中表的建立:

async  onCreate(want, launchParam) {//1.加载用户首选项PreferenceUtil.loadPreference(this.context)//2.初始化日期AppStorage.SetOrCreate(CommonConstants.RECORD_DATE,DateUtil.beginTimeOfDay(new Date()))//3.初始化RDB工具await DbUtil.initDB(this.context)//4.创建record表的创建DbUtil.createTable(RecordModel.getCreateTableSql())hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');}

在完成这样后我们便可以在RecordModel中调用DBUtil所提供的方法,进行record数据表的增删改查操作,从而完成各种业务逻辑。

观察下面的代码,const CREATE_TABLE_SQL提供给了EntryAbility进行数据库中record表的建立,而且只有列名与数据库列名的映射正确,才能使自己定义的数据模型能正确使用数据库。

/*** 数据库建表语句*/
import relationalStore from '@ohos.data.relationalStore'
import { ColumnInfo, ColumnType } from '../common/bean/ColumnInfo'
import RecordPO from '../common/bean/RecordPO'
import DbUtil from '../common/utils/DbUtil'
const CREATE_TABLE_SQL: string = `CREATE TABLE IF NOT EXISTS record (id INTEGER PRIMARY KEY AUTOINCREMENT,type_id INTEGER NOT NULL,item_id INTEGER NOT NULL,amount DOUBLE NOT NULL,create_time INTEGER NOT NULL)`
//列名与数据库列名的映射
const COLUMNS: ColumnInfo[] = [{name: 'id', columnName: 'id', type: ColumnType.LONG},{name: 'typeId', columnName: 'type_id', type: ColumnType.LONG},{name: 'itemId', columnName: 'item_id', type: ColumnType.LONG},{name: 'amount', columnName: 'amount', type: ColumnType.DOUBLE},{name: 'createTime', columnName: 'create_time', type: ColumnType.LONG}
]const TABLE_NAME = 'record'
const ID_COLUMN = 'id'
const DATE_COLUMN = 'create_time'class RecordModel {getCreateTableSql(): string {return CREATE_TABLE_SQL}
//插入insert(record:RecordPO){return DbUtil.insert(TABLE_NAME,record,COLUMNS)}
//删除deleteById(id:number){//1.删除条件let predicates=new relationalStore.RdbPredicates(TABLE_NAME)predicates.equalTo(ID_COLUMN,id)//2.删除return DbUtil.delete(predicates)}//查找(按日期)listByDate(date:number){//1.查询条件let predicates=new relationalStore.RdbPredicates(TABLE_NAME)predicates.equalTo(DATE_COLUMN,date)//2.查询DbUtil.queryForList(predicates,COLUMNS)}
}let recordModel = new RecordModel()export default recordModel as RecordModel

下次课我们将完成利用此数据模型,实现保存不同日期的饮食记录的数据保存功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/30208.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI人工智能产品经理,就该这么学!

前言 想入行AI人工智能产品经理&#xff0c;该如何学习呢&#xff1f; 随时AI的兴起&#xff0c;AI产品经理开始爆火&#xff0c;很多功能性产品经理想转行做AI产品经理。转行的原因&#xff0c;这个仁者见仁智者见智。唯一的共同点就是&#xff0c;大家都看好AI行业的发展前景…

Java 诊断神器 Arthas使用笔记

Arthas 是一款开源在线 Java 诊断工具&#xff0c;采用命令行交互模式&#xff0c;支持 web 端在线诊断&#xff0c;同时提供丰富的 Tab 自动补全功能&#xff0c;进一步方便进行问题的定位和诊断。得益于 Arthas 强大且丰富的功能。 1.JDK原生定位工具 平时开发中会用到JDK中…

edge如何找包已经安装的插件。

我的目录&#xff1a;C:\Users\Administrator\AppData\Local\Microsoft\Edge\User Data\Default\Extensions 如图&#xff1a; 如何我要打包如下图 注意iD的名字 多次操作选择到ID的目录&#xff0c;再向下。 如上图之后。打包。 显示成功 并提供地址。 找到相应地址&#x…

监控员工上网软件有哪些|4款好用的员工上网行为管理软件推荐

在当今数字化办公环境中&#xff0c;确保网络安全、提升工作效率、以及规范员工上网行为成为企业管理的重要组成部分。 为此&#xff0c;一套高效的员工上网行为管理软件显得尤为关键。 本文将为您推荐五款市场上广受好评的员工上网行为管理软件&#xff0c;帮助您有效监控与管…

linux离线安装chrony服务校准时间

基础环境 Linux forlinx 5.10.35 #53 SMP PREEMPT Thu Mar 30 01:04:19 CST 2023 aarch64 aarch64 aarch64 GNU/Linux chrony源码包 下载地址&#xff1a;https://download.tuxfamily.org/chrony/ 以chrony-4.5.tar.gz举例说明 详细步骤 1.解压chrony tar zxvf chrony-4.…

【Spine学习14】之 裁剪

1、新建裁剪 2、在页面中随便点几下 圈出对应位置 3、点编辑裁剪 或者按空格键 退出编辑模式&#xff0c; 页面就只剩下对应区域&#xff0c;这个区域可以任意拖动 放大缩小显示。 tips&#xff1a; 如果手动选择区域描绘不准确&#xff0c;可以启用对应图片的网格 然后复制…

无监督学习:从理论到实践的全面指南

本文深入讲解了无监督学习中的K-means、层次聚类、密度聚类、PCA、t-SNE和自编码器算法&#xff0c;涵盖其原理、数学基础、实现步骤及应用实例&#xff0c;并提供了详细的代码示例。 关注作者&#xff0c;复旦AI博士&#xff0c;分享AI领域全维度知识与研究。拥有10年AI领域研…

axios二次封装

导读&#xff1a;axios用于网络请求、在开发时常常进行二次封装便于前端请求接口时&#xff0c;在网络请求和响应拦截器中做统一处理 1、创建axios实例 配置接口基地址baseURL&#xff0c;接口超时时间timeout 等等 VITE_BASE_URL 在.env文件中配置, 可查看上一篇.env文件详解…

药物+蚊子=疟疾疫苗?

药物蚊子疟疾疫苗&#xff1f; 编译 李升伟 疟原虫的天然暴露和抗生素的组合使用是否可以支持病人的天然免疫力。 顶复合小体靶向药 几十年来&#xff0c;科学家们一直在苦苦寻求一种防御疟疾的疫苗&#xff0c;但是这种疾病的致病性寄生虫——疟原虫――却是一种难以对付的…

外链应该怎么做才有效?

做有效的外链&#xff0c;关键在于策略和执行&#xff0c;高质量的独立站外链就是一个不错的选择&#xff0c;确保是dofollow&#xff0c;每一条都被谷歌收录&#xff0c;并保证长期留存&#xff0c;至少一年以上&#xff0c;这种外链就是能发挥最大效果的外链&#xff0c;名为…

pytest框架中的pytest.ini配置文件

pytest.ini是pytest的主配置文件&#xff0c;主要用于全局配置pytest的行为&#xff0c;如指定测试收集的规则、插件配置、路径忽略等。它允许我们定制pytest的运行方式&#xff0c;而不必在代码中硬编码这些配置。 目录 1、基本结构 2、常见配置项及使用方法 1.addopts 2…

2024年已过半,靠独立站赚钱行得通吗?

中国跨境出口电商行业近年来展现了显著的增长势头&#xff0c;在2017至2021年间&#xff0c;行业规模持续保持20%以上的同比增速。特别是在2021年&#xff0c;受疫情加速全球消费线上化的影响&#xff0c;行业规模已经突破6万亿元人民币。到了2022年&#xff0c;尽管面临局部封…

云原生重大事件保障预案与执行结果

一、背景 随着云计算技术的快速发展&#xff0c;云原生架构已成为企业数字化转型的关键驱动力。然而&#xff0c;云原生环境的高度动态性和复杂性使得其面临着一系列挑战&#xff0c;如服务稳定性、安全性以及性能优化等。为了确保云原生环境的稳定运行&#xff0c;并应对可能…

全新防关联技术出炉:亚马逊测评环境优化,下单成功率大提升

在竞争激烈的测评行业中&#xff0c;构建一个稳定且高效的环境系统成为了制胜的关键。然而&#xff0c;市场上现有的环境方案如虚拟机、模拟机、GCS、云手机、VPS等不仅成本高昂&#xff0c;而且面临着在风控严格的平台上如亚马逊难以逃脱检测的挑战&#xff0c;进而影响了测评…

Memory use report提示信息

Memory use report: Heap dump has been created at C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2021.3\tmp\hprof-temp\heapDump-idea-1718785956302.hprof. It will be analyzed next time you start IntelliJ IDEA.Memory use report提示信息 Memory use…

【两数之和】

两数之和 一、题目二、暴力解法三、哈希表四、map字典1.基本方法.set()添加键值对.get()通过键获取值.has()判断map是否有这个键 2.map和set的联系和区别共同点共同点MapSet 一、题目 二、暴力解法 三、哈希表 解题思路&#xff1a;将nums的元素依次以键值对的方式存储在map字典…

在MySQL中添加索引

在添加之前可以做下备份 mysqldump -u 用户名 -p 数据库名 表名 > 备份文件.sql在 MySQL 中&#xff0c;虽然可以同时执行多个 ALTER TABLE 语句&#xff0c;但需要注意的是&#xff0c;MySQL 对 ALTER TABLE 操作的并行执行有一些限制。具体来说&#xff0c;MySQL 在执行 …

【Linux】如何创建yum 组(yum groups)

如何创建yum 组(yum groups) 在 yum 中创建组信息需要手动编辑并创建一个组文件&#xff0c;然后使用 createrepo 工具生成组信息。以下是一个详细的步骤指南&#xff1a; 1. 创建组信息文件 首先&#xff0c;创建一个 XML 文件来定义组信息。例如&#xff0c;创建一个名为 …

HTML语言笔记

结构 C/S结构 ClientSever 客户端服务器端 需要在电脑上安装的重终端&#xff0c;或一个特定的客户端才能运行。 B/S结构 BrowserServer 浏览器服务器 JAVA主要后端语言&#xff0c;用于开发服务器端程序。 网页开发 学习内容&#xff1a; 语言&#xff1a; html cs…

java基础·小白入门(二)

目录 Java数组、字符串、正则表达式数组基本知识二维数组 字符串初始化基本用法 正则表达式相关知识点Java语言的内存分配Java的增强for循环 类和对象基本概念定义与创建应用 Java数组、字符串、正则表达式 数组 基本知识 Java中&#xff0c;数组元素可以为简单数据类型&…