iBatis双向一对多映射中解决N+1查询问题

为了方便,用一个小例子说明问题。有两个实体类,Department和Employee。
Department为一,Employee为多。


package cn.com.legendapl.ibatis.domain;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

public class Employee implements java.io.Serializable {

private static final long serialVersionUID = 8830655291098555343L;

private Integer id;
private String name;
private String title;
private Department department;

// getter and setter and constrctor
}


package cn.com.legendapl.ibatis.domain;

import java.util.Set;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

public class Department implements java.io.Serializable {

private static final long serialVersionUID = 133006271347210670L;

private Integer id;
private String name;
private String location;
private Set<Employee> employees;

// getter and setter and constrctor
}


两个实体类分别对应数据库的两张表
[code]
mysql> desc t_dep;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| _id | int(11) | NO | PRI | NULL | auto_increment |
| _name | varchar(30) | NO | | NULL | |
| _location | varchar(50) | YES | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

mysql> desc t_emp;
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| _id | int(11) | NO | PRI | NULL | auto_increment |
| _name | varchar(30) | NO | | NULL | |
| _title | varchar(5) | YES | | NULL | |
| _dep_id | int(11) | YES | | NULL | |
+---------+-------------+------+-----+---------+----------------+
[/code]

在“一”的一方配置时映射时

<resultMap class="Department" id="dep" groupBy="id">
<result property="id" column="_id"/>
<result property="name" column="_name"/>
<result property="location" column="_location"/>
<result property="employees" resultMap="department.emp"/>
</resultMap>

<resultMap class="cn.com.legendapl.ibatis.domain.Employee" id="emp">
<result property="id" column="e_id"/>
<result property="name" column="e_name"/>
<result property="title" column="e_title"/>
</resultMap>

<select id="query" parameterClass="java.util.Map" resultMap="dep">
select
d._id,
d._name,
d._location,
e._id as e_id,
e._name as e_name,
e._title as e_title
from
t_dep as d
left join
t_emp as e
on
d._id = e._dep_id
<dynamic prepend="where">
<isNotEmpty property="id" prepend="and"> d._id = #id# </isNotEmpty>
</dynamic>
</select>


在名为dep的resultMap中配置一项groupBy="id",这样,ibatis在处理结果集时,把id相同的几项“看成”一项来处理。
[color=red]注意:groupBy属性的配置,是指的映射到的模型的property name 而不是查询的结果集的列名。[/color]

dao 实现中

@Repository("departmentDao")
public class DepartmentDaoIbatisImpl implements DepartmentDao {

@Resource(name="sqlMapClientTemplate")
private SqlMapClientTemplate sqlMapClientTemplate;

public Department findDepartmentById(Integer id) {
Map<String, Object> map = new HashMap<String, Object>(1);
map.put("id", id);
Department dep = (Department) sqlMapClientTemplate.queryForObject("department.query", map);
for (Employee emp : dep.getEmployees()) {
emp.setDepartment(dep);
}
return dep;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值