对于iBATIS一对多/多对多的问题,传统的办法是在一对多/多对多关联的属性上再做一次子查询,这个解决办法很简单易懂,但是有个缺点,会导致N+1 selects,导致查询的性能瓶颈,更好的解决办法是sql做一个表连接,然后主表的resultMap配置上加“groupBy='...'”属性,这样一次查询就搞定,避免了N+1问题,下面请看代码:
com.cuishen.sqlmaptest.vo.Menu如下:
- package com.cuishen.sqlmaptest.vo;
-
- import java.util.List;
-
-
-
-
-
- public class Menu implements java.io.Serializable {
- private static final long serialVersionUID = 7172793340860021199L;
-
- private Long id;
- private String name;
- private String url;
- private Short layer;
- private Short grade;
- private Short position;
- private Long parentId;
- private List subMenus;
-
- public Menu() { }
-
- public Long getId() {
- return this.id;
- }
-
- public void setId(Long id) {
- this.id = id;
- }
-
-
-
-
-
- public List getSubMenus() {
- return subMenus;
- }
-
- public void setSubMenus(List subMenus) {
- this.subMenus = subMenus;
- }
- }
测试类如下:
- package com.cuishen.sqlmaptest;
-
- import java.sql.SQLException;
- import java.util.List;
-
- import com.ibatis.sqlmap.client.SqlMapClient;
-
- import com.cuishen.sqlmaptest.vo.Menu;
-
-
-
-
-
- public class Test {
- public static void main(String args[]) throws SQLException {
- SqlMapClient sqlMapClient = SqlMapClientFactory.getSqlMapClient();
- List topMenus = sqlMapClient.queryForList("getTopMenu", null);
- for(int i = 0; i < topMenus.size(); i++) {
- Menu menu = (Menu)topMenus.get(i);
- List subMenus = (List)menu.getSubMenus();
- System.out.println("top menu name >> " + menu.getName());
- for(int j = 0; j < subMenus.size(); j++) {
- Menu subMenu = (Menu)subMenus.get(j);
- System.out.println(">> sub menu name >> " + subMenu.getName());
- }
- }
- }
- }
是不是很简单,但是有三点需要注意:
1. 注意这个配置:<result property="subMenus" resultMap="sys.sub-menu-map" />,resultMap是sys.sub-menu-map,要加命名空间sys,而不是sub-menu-map,否则iBATIS可能会报错!
2. 一对多/多对多映射的集合属性subMenus必须用简单的getter/setter,不能在getter/setter里做其他处理,否则会导致iBATIS报错!!
3. 在iBATIS2.3.0.677上测试通过,更老旧的版本可能不支持该解决方案!!
从iBATIS3.0开始该解决方案的配置改为:
- <resultMap id="blogResult" type="Blog">
- <id property=”id” column="blog_id" />
- <result property="title" column="blog_title"/>
- <collection property="posts" ofType="Post">
- <id property="id" column="post_id"/>
- <result property="subject" column="post_subject"/>
- <result property="body" column="post_body"/>
- </collection>
- </resultMap>
更详细的信息请参阅iBATIS-3-User-Guide
转载: