springboot注解开发如何映射对象型数据

创作灵感

最近在帮学校写一款小程序时,有这样一个数据需要展示:一条申请记录,里面包含了申请时间、申请状态、申请所提供的六条活动记录等待,其中,申请所提供的六条活动记录为一个数组,数组中的每个元素又为一个对象。

那么,对于这样的一个对象,我们又该如何将其从数据库中映射为一个java对象呢?这里需要注意的是,数据库的表设计与java中的实体类其实是有着非常大的差距的,例如,我们的数据库因为需要满足一些范式需求;在我的数据库内,上面这个对象信息主要存放在三个表内,一个是申请表,其中包含了用户id,六次活动记录的id与申请时间等、一个是用户表,存放了用户的基本信息、一个是活动记录表,这个表内包含了哪个用户参加了哪次活动(其实就是用户id和活动id)。

但是在java实体类对象内,我们要的可不是这条申请记录里面的六次活动记录的id

第一种写法(错误示例)

之所以将第一种写法视为错误示例,并不是说第一种写法会出现BUG,而是说第一种写法违背了我们分层的思想,下面先分享一下我的第一种写法:

@Overridepublic ApplyRecord[] getApplyRecords() {ApplyRecord[] applyRecords=applyRecordMapper.getApplyRecords();for (ApplyRecord applyRecord : applyRecords) {User user= userMapper.getAllById(applyRecord.getUserId());applyRecord.setName(user.getName());ActivityRecord[] activityRecords = new ActivityRecord[6];ActivityRecord activityRecordOne=activityRecordMapper.getActivityRecordById(applyRecord.getActivityRecordIdOne());//获取申请素拓记录中提交的六次活动记录ActivityRecord activityRecordTwo=activityRecordMapper.getActivityRecordById(applyRecord.getActivityRecordIdTwo());//获取申请素拓记录中提交的六次活动记录ActivityRecord activityRecordThree=activityRecordMapper.getActivityRecordById(applyRecord.getActivityRecordIdThree());//获取申请素拓记录中提交的六次活动记录ActivityRecord activityRecordFour=activityRecordMapper.getActivityRecordById(applyRecord.getActivityRecordIdFour());//获取申请素拓记录中提交的六次活动记录ActivityRecord activityRecordFive=activityRecordMapper.getActivityRecordById(applyRecord.getActivityRecordIdFive());//获取申请素拓记录中提交的六次活动记录ActivityRecord activityRecordSix=activityRecordMapper.getActivityRecordById(applyRecord.getActivityRecordIdSix());//获取申请素拓记录中提交的六次活动记录Activity activityOne=activityMapper.getAllById(activityRecordOne.getActivityId());activityRecordOne.setName(activityOne.getName());activityRecordOne.setDate(activityOne.getDate());Activity activityTwo=activityMapper.getAllById(activityRecordTwo.getActivityId());activityRecordTwo.setName(activityTwo.getName());activityRecordTwo.setDate(activityTwo.getDate());Activity activityThree=activityMapper.getAllById(activityRecordThree.getActivityId());activityRecordThree.setName(activityThree.getName());activityRecordThree.setDate(activityThree.getDate());Activity activityFour=activityMapper.getAllById(activityRecordFour.getActivityId());activityRecordFour.setName(activityFour.getName());activityRecordFour.setDate(activityFour.getDate());Activity activityFive=activityMapper.getAllById(activityRecordFive.getActivityId());activityRecordFive.setName(activityFive.getName());activityRecordFive.setDate(activityFive.getDate());Activity activitySix=activityMapper.getAllById(activityRecordSix.getActivityId());activityRecordSix.setName(activitySix.getName());activityRecordSix.setDate(activitySix.getDate());activityRecords[0]=activityRecordOne;activityRecords[1]=activityRecordTwo;activityRecords[2]=activityRecordThree;activityRecords[3]=activityRecordFour;activityRecords[4]=activityRecordFive;activityRecords[5]=activityRecordSix;applyRecord.setActivityRecords(activityRecords);}return applyRecords;}

相信大家看到这段代码的时候,眼睛都花了,这里我并没有将DAO层的操作展现给大家,但是大家在看到我的调用应该基本都明白。无非就是拿到了指定活动的id然后去获取该活动的信息等等。但是,这种事情不应该是在DAO层要全部完成的吗?这就是我吃了没文化的亏!

在最近上课时,听到了老师说到了关于这样的对象,我们在设计java实体类时,应该存放的是具体的对象,而非这个对象的id。

在升级这个小程序时,我遇到了一个类似的功能,也是查询这样的一系列数据,下面向大家展示一下正确的做法

第二种写法(正确示例)

如果要将上述对象进行一个完整的映射,那么我们就需要用到结果集映射了。因为我使用的是注解开发,下面为我的DAO层操作:

@Select("SELECT * FROM applyRecord WHERE userId=#{userId} ORDER BY date DESC LIMIT #{start},10")@Results({@Result(column = "date",property = "date"),//申请时间@Result(column = "status",property = "status"),//申请状态@Result(column = "userId",property = "user",javaType= User.class,one = @One(select="org.example.Mapper.UserMapper.getAllById")),@Result(column = "activityRecordIdOne,activityRecordIdOne,activityRecordIdTwo,activityRecordIdTwo," +"activityRecordIdThree,activityRecordIdThree,activityRecordIdFour,activityRecordIdFour," +"activityRecordIdFive,activityRecordIdFive,activityRecordIdSix,activityRecordIdSix",property = "activityRecords",javaType = ActivityRecord[].class,many = @Many(select = "org.example.Mapper.ActivityRecordMapper.getActivityRecordsInIds"))})ApplyRecord[] getApplyRecordsByUserId(@Param("userId") Integer userId,@Param("start") Integer start);

ApplyRecordMapper文件

@Select("SELECT * FROM (activityRecord,activity) WHERE activityRecord.id IN (#{activityRecordIdOne}," +"#{activityRecordIdTwo},#{activityRecordIdThree},#{activityRecordIdFour},#{activityRecordIdFive}," +"#{activityRecordIdSix}) AND activity.id=activityRecord.activityId")ActivityRecord[] getActivityRecordsInIds(@Param("activityRecordIdOne") Integer activityRecordIdOne,@Param("activityRecordIdTwo") Integer activityRecordIdTwo,@Param("activityRecordIdThree") Integer activityRecordIdThree,@Param("activityRecordIdFour") Integer activityRecordIdFour,@Param("activityRecordIdFive") Integer activityRecordIdFive,@Param("activityRecordIdSix") Integer activityRecordIdSix);

ActivityRecordMapper文件

上面的两个文件,是不是感觉比第一种方法更加易懂?我们主要需要看懂的就是第一个文件,其中,普通类型的映射只需要column与property两个属性映射就好了,但如果碰上了需要映射一个对象,我们就需要用到@One这个注解,这个注解后面的select是一个方法的地址。同时需要注意的是,javaType表示的是这个属性的类,下面的@Maney类似,但不同的是,这个注解查询出来的是多个值。

难点解释

相信大家在看我的代码还看到了我在many的那个result中,传递column参数时,传递了不止一个参数,但是每个参数都传递了两边?其实我并没有传递两边,这就好像我们在使用get方法传递参数一样,时以键值对的方式进行传递的。只不过我的键与值都是同样的名字而已。

下面给大家展示一下我的最终效果吧!

 这就是一条申请记录,里面包含了学生信息,以及六条活动记录信息!

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

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

相关文章

【BUG】Hexo|GET _MG_0001.JPG 404 (Not Found),hexo博客搭建过程图片路径正确却找不到图片

我的问题 我查了好多资料,结果原因是图片名称开头是_则该文件会被忽略。。。我注意到网上并没有提到这个问题,遂补了一下这篇博客并且汇总了我找到的所有解决办法。 具体检查方式: hexo生成一下静态资源: hexo g会发现这张图片…

二维码门楼牌管理应用平台建设:网格化管理的新篇章

文章目录 前言一、二维码门楼牌管理应用平台的建设背景二、二维码门楼牌管理应用平台的功能特点三、二维码门楼牌管理应用平台的实际应用四、二维码门楼牌管理应用平台的前景展望 前言 随着信息技术的飞速发展,二维码门楼牌管理应用平台的建设已成为城市网格化管理…

李廉洋:4.20国际黄金,原油本周行情分析及下周一走势分析。

荷兰国际银行表示,所谓的美国国债期限溢价的回升,将为10年期国债收益率重返5%的关键水平铺平道路。从理论上来说,可将10年期美债收益率拆解为未来短端利率的期望期限溢价(term premium)。所谓期限溢价,是对投资者持有长期债券的风…

第十四届蓝桥杯省赛C/C++大学B组真题-飞机降落

思路&#xff1a;根据数据范围N<10猜测用DFS剪枝&#xff0c;因为菜狗不会状压dp。根据题目&#xff0c;一般这种飞机的题都会用到贪心的思想。思想是每架飞机都要卡极限最早降落时间&#xff0c;从而保证后面的飞机能够有充足时间降落。 代码参考博客MQy大佬有详细解答 #i…

深度学习之CNN

目录 我们为什么要用CNN&#xff0c;或者说究竟是因为什么我们要用CNN 卷积操作的实现原理 补充知识 torch.nn.Conv2d&#xff08;&#xff09; 注意 torch.nn.functional.conv2d&#xff08;&#xff09; torch.nn.functional.conv2d&#xff08;&#xff09;和torch.nn.…

前端-每天一道面试题(2)-localStorage/sessionStorage/cookie的区别

都是本地缓存数据的方式。 cookie:类型为小型文本文件&#xff0c;是某些网站为了辨别用户身份而储存在用户本地终端上的数据。是为了解决HTTP无状态导致的问题。最大为4KB,由一个名称&#xff0c;一个值&#xff0c;和其它几个用于控制cookie有效期&#xff0c;安全性&#x…

Fannel和Calico

一 1、路由器下面每一个端口都是一个vlan,隔离了广播包 192.168.1.0和192.168.2.0他们属于不同的vlan,没有三层交换机或者路由器,他们通不了信 不在同一个vlan,也就是子网,包就会走向网关(也就是路由器那里,路由器有路由表。查看目的地192.168.2.0在b口,从b口出去vlan…

模块与包及json模块学习

【一】模块与包介绍 【1】什么是模块 在Python中&#xff0c;一个py文件其实就是一个模块 文件名 knight.py中 py就是模块名 【2】模块的优点 有了模块以后可以增加程序的可读性&#xff0c;提高开发效率 【3】模块的来源 &#xff08;1&#xff09;在Python解释器内部内…

oCPC实践录 | 低转化场景下的智能出价设计

有读者私聊问笔者一个问题&#xff1a;低转化场景下怎么做智能出价。特别是对于电商、线索类行业&#xff0c;每个广告下转化量普遍非常低。 笔者也没有给出很完善的答案&#xff0c;也咨询了行业内资深的出价产品专家&#xff0c;下面尝试总结一下常见的思路&#xff0c;供大…

太多模型了!

多少个 AI 模型才算太多?这需要看你的角度。但每周 10 个可能有点过头了。在过去几天里,我们大概就看到了这么多新模型的推出,要说这些模型彼此之间有何对比,甚至一开始就能比较,都变得越来越难。那么这到底有什么意义呢? 我们正处于 AI 发展的一个奇怪时期,尽管整个过程一直…

MacOS 文件句柄数不够 Error: EMFILE: too many open files

MacOS 文件句柄数不够 Error: EMFILE: too many open files 直奔主题-解决方案 启动项目发现报错&#xff1a;Error: EMFILE: too many open files&#xff1b;经排查是因为单个微应用项目较大&#xff0c;发布过程中已经超过了mac默认的文件监听上限对文件系统进行大量并发调用…

互联网技术知识点总览——算法和数据结构

简介 本文对算法和数据结构的知识点整体框架进行梳理和分享如下&#xff1a;

Ubuntu无法安装向日癸15.2.0.63062_amd64.deb最新版

Ubuntu安装向日葵远程控制 安装包下载 安装方式 方式一&#xff1a;运行安装包安装 方式二&#xff1a;终端命令安装 通过以下教程可以快速的安装向日葵远程控制&#xff0c;本教程适用于Ubuntu18.04/20.04/22.04 安装包下载 进入向日葵远程控制下载官网下载向日葵远程控制Lin…

黑马程序员Linux简单入门学习笔记

Linux介绍 内核提供系统最核心的功能&#xff0c;如: 调度CPU、调度内存、调度文件系统、调度网络通讯、调度等系统级应用程序&#xff0c;可以理解为出厂自带程序&#xff0c;可供用户快速上手操作系统&#xff0c;如:文件管理器、任务管理器、图片查看、音乐播放等 目录结构 …

GlobalRouting - FastRoute布线算法运行流程(二)

文章目录 1. 运行步骤 FT::run 1. 运行步骤 首先生成2D的布线&#xff0c;然后进行层分配以及生成3D的布线&#xff0c;最后计算结果并返回。具体流程如下&#xff1a; 读取查找表flut, POST9.dat, POWV9.dat使用查找表生成RSMT&#xff0c;将多pin线网拆分为2pin线网进行第…

深度学习--CNN卷积神经网络(附图)

框架 让我们先看一下CNN的框架 卷积层中后是ReLu激活函数 &#xff0c;然后是深化池&#xff0c;之后是全连接&#xff0c;最后进行Softmax进行归一化。 所以&#xff0c;我们先逐一了解一下它们各个部分 全连接层 全连接层也称感知机&#xff0c;BP神经网络 全连接层&…

cpp中的右值引用()及其相关拓展知识

cpp中的右值引用 右值引用&#xff08;rvalue reference&#xff09;是 C11 引入的一个新特性&#xff0c;用于表示对临时对象&#xff08;右值&#xff09;的引用。右值是指那些无法被修改的临时对象&#xff0c;比如函数返回的临时对象、移动语义中的源对象等。右值引用的语…

机器学习常用评价指标的公式和含义

在机器学习中&#xff0c;特别是在分类任务中&#xff0c;评价模型性能常用以下指标。这些指标主要基于混淆矩阵&#xff0c;该矩阵记录了实际类别与模型预测类别的对应情况。下面是这些指标的定义和计算公式&#xff1a; 1. TP&#xff08;True Positives&#xff09;: - …

seatable部署之后network error【seatable】

这里写自定义目录标题 问题汇总 问题汇总 seatable服务部署后&#xff0c;组件显示正常运行&#xff0c;创建表单&#xff0c;显示Network error 点击错误信息&#xff0c;查看其跳转至另一个页面

最大子数组和(贪心)

53. 最大子数组和 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个连续部分。 样例输入 示例…