【Java】记录一次代码优化
最近几天闲下来,主动把之前的代码优化了一下:)
原处理
String eventId = "";
String aTime = "";
for (UserEvent event : userEventList) {
eventId = event.getEventId(); // 获取业务B信息
List<EntityB> listB = mapperB.selectBInfoByEventId(eventId);
event.setListB(listB); // 获取业务C信息
List<EntityC> listC = mapperC.selectCInfoByEventId(eventId);
event.setListC(listC); // 查看是否有业务B处理
EntityB entityB = mapperB.selectBInfoByPrimary(phone, eventId);
event.setIsActionB(null == entityB ? "false" : "true"); // 获取业务A和用户信息
User userInfo = mapperA.selectEventUserInfoByEventId(eventId);
if(null != userInfo){
aTime = userInfo.getTime();
event.setTime(aTime == null ? "" : sdfMd.format(sdfYmd.parse(aTime)));
event.setUserInfo(userInfo);
}
}
<select id="selectBInfoByEventId" parameterType="String" resultType="EntityA">
SELECT
B.phone AS phone,
B.time AS time,
U.name AS userName
FROM table_b B
LEFT JOIN user U ON U.phone = B.phone
WHERE B.event_id = #{eventId}
ORDER BY B.time ASC
</select>
<select id="selectCInfoByEventId" parameterType="String" resultType="EntityC">
SELECT
C.cmtId,
C.referId,
C.time,
U.name AS userName
( SELECT TU.name FROM table_c TC
LEFT JOIN user TU ON TU.phone = TC.phone
WHERE TC.cmt_id = TC.refer_id
) AS referName
FROM table_c C
LEFT JOIN user U ON C.phone = U.phone
WHERE C.event_id = #{eventId}
ORDER BY C.time ASC
<select id="selectEventUserInfoByEventId" parameterType="java.lang.String" resultType="User">
SELECT
U.name,
U.picId,
A.time
FROM table_a A
LEFT JOIN user U ON U.phone = A.phone
WHERE A.event_id = #{eventId}
</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">
SELECT
A.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 cTime
FROM v_table_a A
LEFT JOIN v_table_b B ON B.eventId = A.eventId
LEFT 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标签的使用
处理时间对比
【Java】记录一次代码优化的更多相关文章
- JAVA记录-java代码优化策略
java代码优化策略 1.生成对象时,合理分配空间和大小:new ArrayList(100); 2.优化for循环: Vector vect = new Vector(1000); For(int ...
- java记录在线人数小案例
文件目录: web.xml: <?xml version="1.0" encoding="UTF-8"?> <web-app version= ...
- JAVA记录-Servlet介绍
1.什么是Servlet Servlet是sun公司提供的一门用于开发动态web资源的技术.Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...
- JAVA记录-Mybatis介绍
1.什么是 MyBatis ? MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyB ...
- JAVA记录-JSP内容
JSP(JavaServer Pages )是什么? JavaServer Pages(JSP)是一种支持动态内容开发的网页技术它可以帮助开发人员通过利用特殊的JSP标签,其中大部分以<%开始并 ...
- java 记录对象前后修改的内容(工具类)
有时候业务需要,需记录一条记录的修改历史,但是不能为完成任务而硬编码,不靠谱 这种情况可以使用java反射来完成 对对象属性的描述可以通过自定义注解来完成,读取里面的属性进而记录修改历史. 在对象的属 ...
- java基础一(阅读Head First Java记录)
写在前面的话 在实际应用java中,因为没有系统去看过书或者学习过,所以基础薄弱,刚好这本书是比较入门级的一些书,记录一下下面的一些基本概念,以方便自己来学习.当然如果对大家有帮助也是很好的. 因为书 ...
- java记录linux top命令信息
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...
- 初学java记录
记录一: if语句: if(x < y) System.out.println("x is less than y"); 记录二: 强制转换字符类型赋值的方法: num2= ...
随机推荐
- TCP三次握手四次挥手
看到一篇总结很好的TCP三次握手,学习一下,原文链接. 建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,S ...
- 程序员眼中的 SQL Server-执行计划教会我如何创建索引?
先说点废话 以前有 DBA 在身边的时候,从来不曾考虑过数据库性能的问题,但是,当一个应用程序从头到脚都由自己完成,而且数据库面对的是接近百万的数据,看着一个页面加载速度像乌龟一样,自己心里真是有种挫 ...
- Step by step 如何创建一个新森林
原创地址:http://www.cnblogs.com/jfzhu/p/4006118.html 转载请注明出处 创建一个新森林就是在一台计算机上安装AD DS,并将这台计算机提升为域控制器. 演示环 ...
- Socket programing(make a chat software) summary 1:How to accsess LAN from WAN
First we should know some basic conceptions about network: 1.Every PC is supposed to have its own IP ...
- struts2 标签怪事
<s:if test="4 ge 3">111</s:if><s:else>222</s:else> 结果竟然是222 难道不是 4 ...
- Polynomial Library in OpenCascade
Polynomial Library in OpenCascade eryar@163.com 摘要Abstract:分析幂基曲线即多项式曲线在OpenCascade中的计算方法,以及利用OpenSc ...
- Memory Management in Open Cascade
Open Cascade中的内存管理 Memory Management in Open Cascade eryar@163.com 一.C++中的内存管理 Memory Management in ...
- Unity基础知识学习笔记一
1,Unity 4.5.4这个版本,在打包ios应用程序的时候.会生成一个xcode工程,但是这个工程无法在xcode6上变异,无法生成ios8上发布.所以unity在ios8发布3天内就发了4. ...
- java.util.NoSuchElementException: Timeout waiting for idle object
出现这个问题第一个想法就是连接池的参数设置问题,把最大连接数量设置大一些就行了,但是我就一个客服端访问服务器,连接池连接数量不可能会不够用.我的项目架构是spring mvc+hibernate,用s ...
- Android仿qq聊天记录长按删除功能效果
最近项目在做IM即时通讯开发,在删除聊天列表的时候跟删除聊天详细信息的时候,产品经理想要跟ios一样,在当前选中行上方弹出一个删除窗口.于是先从网上找demo,找了一个发现是Dialog做的,我感觉没 ...