開發了Java這麼久,有的時候會偷懶寫一些代碼,影響性能。 比如 消息列表裡面,查詢用戶信息。 這樣就會造成一個N+1的問題,有多少條消息就查詢了多少次用戶信息。hibernate 裡面有個很不錯的功能 left outer join fetch。可以解決N+1的問題,但是現在已經沒有人用hibernate了,用mybatis的人比較多,所以得手動寫代碼進行查詢優化了。
開始寫代碼想著完成功能,在後來就要考慮優化,使用高效的查詢方式,這樣的才能提高用戶體驗。
比如數據表為:
<select id="selectByIdBatch" parameterType="java.util.List" resultMap="userInfo">
SELECT
id,name,sex,phone
FROM
user_info
<where>
id in
<foreach item="id" collection="list" separator="," open="(" close=")" index="">
#{id, jdbcType=NUMERIC}
</foreach>
</where>
</select>
然後使用在循環裡面,找到多個id,然後用in查詢將user_info數據查詢出來,在放到msg的對象裡面。
比如兩個類
public class Message{
private Long id;
private String content;
private Date createTime;
private Long uid;
priavte UserInfo userInfo;
}
public class UserInfo{
private Long id;
private String name;
private String phone;
}
//示意代碼:用作代碼展示,沒有編譯過。
List<Message> msgList = msgMapper.selectPage(0,10);
//示意Set存儲,保證Id不重復。
Set<Long> msgIds = new HashSet<Long>();
//循環Message消息,找到所有Id。
for(Message msg:msgList){
if(msg != null && msg.getId() != null){
msgIds.add(msg.getId());
}
}
//批量查詢用戶信息。
List<UserInfo> userList = userMapper.selectByIdBatch(new ArrayList<Long>(msgIds));
//將用戶List轉換成Map
Map<Long,List<UserInfo>> userMap = new HashMap<Long,List<UserInfo>>();
for(UserInfo userInfo:userList){
if(userInfo != null && userInfo.getId() != null){
//轉換map。
userMap.add(userInfo.getId(),userInfo);
}
}
//循環消息再把UserInfo對象放回去。
for(Message msg : msgList){
if(msg != null && msg.getUid() != null){
UserInfo userInfo = userMap.get(msg.getUid());
//設置用戶
msg.setUserInfo(userInfo);
}
}
//最後再顯示。
.....
雖然代碼寫的比較多,但是性能得到了提供,查詢數據庫的次數減少了。
優化了查詢效率,提高了用戶體驗,減少了用戶等待時間。
這裡有個小技巧,mybatis不支持Set,只能用List。Set保持id不重復。
使用new ArrayList(msgIds) 可以將Set轉換成List。
查詢完成之後放到Map數組裡面,減少循環次數。
這樣就完成優化了,效率得到了提高。
MyBatis入門學習教程 http://www.linuxidc.com/Linux/2015-02/113771.htm
Java實戰應用:Mybatis實現單表的增刪改 http://www.linuxidc.com/Linux/2014-06/103456.htm
[Java][Mybatis]物理分頁實現 http://www.linuxidc.com/Linux/2014-04/99889.htm
Mybatis快速入門教程 http://www.linuxidc.com/Linux/2013-06/85762.htm
Mybatis的關於批量數據操作的測試 http://www.linuxidc.com/Linux/2012-05/60863.htm
Mybatis中對List<Object> 對象List的批處理插入操作 http://www.linuxidc.com/Linux/2014-02/96916.htm
MyBatis 的詳細介紹:請點這裡
MyBatis 的下載地址:請點這裡