Mybatis中的collection、association来处理结果映射
最近几天闲下来,主动把之前的代码优化了一下:)
原处理
1 String eventId = "";2 String aTime = "";3 for (UserEvent event : userEventList) {4 eventId = event.getEventId();5 6 // 获取业务B信息7 List<EntityB> listB = mapperB.selectBInfoByEventId(eventId);8 event.setListB(listB);9 10 // 获取业务C信息 11 List<EntityC> listC = mapperC.selectCInfoByEventId(eventId); 12 event.setListC(listC); 13 14 // 查看是否有业务B处理 15 EntityB entityB = mapperB.selectBInfoByPrimary(phone, eventId); 16 event.setIsActionB(null == entityB ? "false" : "true"); 17 18 // 获取业务A和用户信息 19 User userInfo = mapperA.selectEventUserInfoByEventId(eventId); 20 if(null != userInfo){ 21 aTime = userInfo.getTime(); 22 event.setTime(aTime == null ? "" : sdfMd.format(sdfYmd.parse(aTime))); 23 event.setUserInfo(userInfo); 24 } 25 }
1 <select id="selectBInfoByEventId" parameterType="String" resultType="EntityA">2 SELECT3 B.phone AS phone,4 B.time AS time,5 U.name AS userName6 FROM table_b B7 LEFT JOIN user U ON U.phone = B.phone8 WHERE B.event_id = #{eventId}9 ORDER BY B.time ASC 10 </select> 11 <select id="selectCInfoByEventId" parameterType="String" resultType="EntityC"> 12 SELECT 13 C.cmtId, 14 C.referId, 15 C.time, 16 U.name AS userName 17 ( SELECT TU.name FROM table_c TC 18 LEFT JOIN user TU ON TU.phone = TC.phone 19 WHERE TC.cmt_id = TC.refer_id 20 ) AS referName 21 FROM table_c C 22 LEFT JOIN user U ON C.phone = U.phone 23 WHERE C.event_id = #{eventId} 24 ORDER BY C.time ASC 25 <select id="selectEventUserInfoByEventId" parameterType="java.lang.String" resultType="User"> 26 SELECT 27 U.name, 28 U.picId, 29 A.time 30 FROM table_a A 31 LEFT JOIN user U ON U.phone = A.phone 32 WHERE A.event_id = #{eventId} 33 </select>
优化分析
- 在代码结构上,要避免在for循环中作查询处理。考虑将查询参数evenId从for循环中提取出来,做批量查询,然后再将查询结果设定到对应的实体类中。
- 在业务上,对于每一个UserEvent中的eventId,业务表A中必定对应有一条记录,而在业务表B和业务表C中则未必有与这个eventId关联的数据。因此,可以将业务表A作为主表,通过eventId与另外几个表关联查询。查询次数也由原来的至少四次减少为一次查询。
- 对于联合查询的结果,以UserEvent作为查询结果的实体类,使用Mybatis中的collection、association来处理结果映射。
- 另外,各业务表的查询中都有与用户表User的关联,考虑将各业务信息的查询处理创建为视图。这样不仅能简化联合查询中SQL语句,也可以隔离基础表的数据。
优化后的代码
int eventSize = userEventList.size();List<String> eventIds = new ArrayList<String>(); // 如果考虑去掉重复数据,可以使用集合Set,但是作为Mybatis的输入参数,最后还是需要将Set转化为List。 // 此处直接使用List,因为在业务上排除了重复数据的可能性。for (int i = 0; i < eventSize; i++) {eventIds.add(userEventList.get(i).getEventId());}Map<String, Object> paramsMap = new HashMap<String, Object>();paramsMap.put("eventIds", eventIds);paramsMap.put("phone", phone);List<UserEvent> eventInfoList = eventMapper.selectUserEventInfo(paramsMap);// 将查询结果转化为Map存储,方便调用Map<String, UserEvent> eventInfoMap = new HashMap<String, UserEvent>();for(UserEvent event : eventInfoList){eventInfoMap.put(event.getEventId(), event);}UserEvent newEvent = null;String aTime = null;for(UserEvent event : roadEventList){ // 从查询结果Map中取出补充信息,保存到原UserEvent对象中newEvent =eventInfoMap.get(event.getEventId());if(null != newEvent ){aTime = newEvent.getTime();event.setTime(aTime == null ? "" : sdfMd.format(sdfYmd.parse(aTime )));event.setIsActionB(newEvent.getIsActionB() == null ? "false" : newEvent.getIsActionB());event.setUserInfo(newEvent.getUserInfo());event.setListB(newEvent.getListB());event.setListC(newEvent.getListC());}}
<resultMap id="UserMap" type="User"><result column="name" property="name" /><result column="picId" property="picId" /><result column="time" property="time" /></resultMap><resultMap id="BMap" type="EntityB"><id column="bPhone" property="phone" /><result column="bUserName" property="userName" /><result column="bTime" property="time" /></resultMap><resultMap id="CMap" type="EntityC"><id column="cmtId" property="cmtId" /><result column="referId" property="referId" /><result column="cUserName" property="userName" /><result column="referName" property="referName" /><result column="cTime" property="time" /></resultMap><resultMap id="EventResultMap" type="com.xxxx.bean.UserEvent"><id column="eventId" property="eventId" /><result column="time" property="time" /><result column="isActionB" property="isActionB" /><association property="userInfo" resultMap="UserMap" /><collection property="listB" resultMap="BMap" /><collection property="listC" resultMap="CMap" /></resultMap><select id="selectUserEventInfo" resultMap="EventResultMap">SELECTA.eventId,A.time,A.name,A.picId,CASE WHEN B.phone = #{phone} THEN "true" ELSE "false" END AS isActionB,B.phone AS bPhone,B.userName AS bUserName,B.time AS bTime,C.cmtId,C.referId,C.userName AS cUserName,C.referName AS referName,C.time AS cTimeFROM v_table_a ALEFT JOIN v_table_b B ON B.eventId = A.eventIdLEFT JOIN v_table_c C ON C.eventId = A.eventId<where>A.event_id in<foreach collection="eventIds" index="" item="eventId" open="(" separator="," close=")">#{eventId}</foreach></where>;</select>
编码时需要注意的几个地方
1. 复杂对象的映射解析
<!-- spring-mybatis.xml文件 --><!-- 配置sqlSessionFactory --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource" /> <!-- 将各Java类的简写别名单独放到文件mybatis.xml中,方便修改和管理 --><property name="configLocation" value="classpath:xml/mybatis.xml" /> <property name="mapperLocations" value="classpath:sql/*.xml" /></bean>
<!-- mybatis.xml文件 --><configuration><typeAliases><typeAlias alias="EntityA" type="com.xxxx.model.EntityA" /><typeAlias alias="EntityB" type="com.xxxx.model.EntityB" /><typeAlias alias="EntityC" type="com.xxxx.model.EntityC" /><typeAlias alias="User" type="com.xxxx.model.User" /></typeAliases></configuration>
2. foreach标签的使用
处理时间对比
http://www.cnblogs.com/quiet-snowy-day/p/6166340.html
Mybatis中的collection、association来处理结果映射相关推荐
- Mybatis中的collection和association一关系
collection 一对多和association的多对一关系 学生和班级的一对多的例子 班级类: package com.glj.pojo;import java.io.Serializable; ...
- mybatis 中 foreach collection的三种用法
oreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合. foreach元素的属性主要有 item,index,collection,open,separator,close. i ...
- mybatis中,collection配置后查询只显示一条记录
描述一下问题: 已知有两个表,一个是user表,一个是address,一(user)对多(address)的关系,在user的实体类里面写属性: private List<Address> ...
- MyBatis中的collection使用方法
demo: 实体:Position @TableName("tb_position") public class Position {private static final lo ...
- mybatis collection标签_一对多的关系,在MyBatis中如何映射?
# 使用collection标签 需求:根据用户id查询用户信息的同时获取用户拥有的角色,一个用户可以拥有1个或多个角色. 一般情况下,不建议直接修改数据库表对应的实体类. 所以这里我们延用之前博客中 ...
- Mybatis中Collection集合标签的使用
mybatis简单的CURD就不用多说了,网上相关博客文档一大堆.分析一下Mybatis里面的collection聚集查询. 假设一个班级有多名学生为例,通过班级号查询出该班级的信息,和班级里面的所 ...
- MyBatis中resultMap详解
MyBatis 中 resultMap 详解 resultMap 是 Mybatis 最强大的元素之一,它可以将查询到的复杂数据(比如查询到几个表中数据)映射到一个结果集当中.如在实际应用中,有一个表 ...
- mybatis中的ResultMap使用
mybatis中的ResultMap使用 文章目录 mybatis中的ResultMap使用 一.自动映射 二.手动映射 1.返回值类型为resultMap 2.编写resultMap,实现手动映射! ...
- MyBatis之输入与输出(resultType、resultMap)映射
2019独角兽企业重金招聘Python工程师标准>>> 在MyBatis中,我们通过parameterType完成输入映射(指将值映射到sql语句的占位符中,值的类型与dao层响应方 ...
最新文章
- Word中的图片显示出不来的解决办法
- 计算机java语言答案_【计算机二级Java语言】卷019
- hisi mmz内存管理
- CF1594F-Ideal Farm【构造】
- Java使用者的延期执行
- 类支付宝微信密码输入框
- ORACLE--Connect By、Level、Start With的使用(Hierarchical query-层次查询)
- (转)MTK softkey流程 必看
- Flutter TextField设置默认值默认值和光标位置
- Matlab中的逻辑运算与,||与|的区别
- 红外测试操作步骤_红外分光测油仪操作步骤及注意事项
- 华为云学院-人人学loT学习笔记- 第四章 物联网关 汇聚回传
- 护眼软件Linux,四个 Linux 下的“护眼”软件解析
- 珍重了,我亲爱的朋友们
- MySQL设计一张学生表选择的数据类型保存学号,姓名,性别,出生日期,入学日期,家庭住址信息。
- 综合素质能力测试软件,儿童综合素质体检测评系统
- 北京航空航天大学计算机考研推免比例,2021考研报考人数公布!今年人数暴增了吗?...
- 爬虫抓取京东、苏宁、唯品会商品价格
- 一文读懂阿里云挑战 AWS 的底气 | 2018•大复盘
- 2017年总结-我的学习之路
热门文章
- python电影名称词云_python-词云
- PHP怎样防止小数点精度不丢失,javascript小数精度丢失的完美解决方法
- python3.6安装包多大_win10下Python3.6安装、配置以及pip安装包教程
- dict格式转字符串两种方法的区别
- git只添加指定类型的文件的.gitignore规则
- Java竞赛目的_ACM竞赛 Java编程小结
- 程序员送女朋友的礼物:域名和祝福视频
- 第11章:项目风险管理—章节重点
- ElementUI中的el-form怎样格式化显示1和0为是和否
- Android中使用getDrawable时提示:Call requires API level 21(current min is 15)