select查询标签的两个属性:
resultType:用于指定返回结果集的类型
resultMap:在查询的结果集不便于封装,或者多表关联查询时,替代resultType自定义返回结果类型。
一.ResultType示例
Employee【员工表】
对应的实体类【注意last_name并未开启驼峰命名,无法直接映射】
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;
private Department dept;
constructor...
getter and setter...
}
查询语句mapper以及对应的接口方法:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tt.mybatis.dao.EmployeeMapper">
<!-- public Employee getEmpById(Integer id); -->
<select id="getEmpById" resultType="com.tt.mybatis.bean.Employee">
select id,last_name lastName from tbl_employee where id=#{id}
</select>
<!-- public List<Employee> getEmps(); -->
<select id="getEmps" resultType="com.tt.mybatis.bean.Employee">
select id,last_name lastName from tbl_employee
</select>
<!--public Map<String, Object> getEmpByIdReturnMap(Integer id); -->
<select id="getEmpByIdReturnMap" resultType="map">
select id,last_name lastName from tbl_employee where id=#{id}
</select>
<!--
@MapKey("id")
public Map<Integer, Employee> getEmpsReturnMap();
-->
<select id="getEmpsReturnMap" resultType="com.tt.mybatis.bean.Employee">
select id,last_name lastName from tbl_employee
</select>
</mapper>
总结
1、resultType指定pojo或者map,可以将查询结果自动封装成pojo或者map。
注意:在未开启驼峰命名规则时,查询的列名与实体类的属性名完全一致才能自动封装。
2、如果返回的是List,resultType只需指定集合中元素的类型。
3、如果需要返回Map<Integer,Employee>这种格式,resultType指定map中value的值,map中key的值由mapper接口方法@MapKey()来指定。
二.ResultMap示例
Employee【员工表d_id外键关联部门表id主键】
Department【部门表】
对应的实体类
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;
private Department dept;
constructor...
getter and setter...
}
public class Department {
private Integer id;
private String departmentName;
private List<Employee> emps;
constructor...
getter and setter...
}
对应的mapper接口:
public interface EmployeeMapperPlus {
public Employee getEmpById(Integer id);
public Employee getEmpAndDept(Integer id);
public Employee getEmpByIdStep(Integer id);
public List<Employee> getEmpsByDeptId(Integer deptId);
}
public interface DepartmentMapper {
public Department getDeptById(Integer id);
public Department getDeptByIdPlus(Integer id);
public Department getDeptByIdStep(Integer id);
}
场景一:使用resultMap封装列名与属性名不一致时的结果类
<!--
id: 指定主键列的封装规则
column:指定哪一列
property:指定对应的javaBean属性
result: 指定普通列的封装规则
-->
<resultMap type="com.tt.mybatis.bean.Employee" id="MySimpleEmp">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
</resultMap>
<!-- public Employee getEmpById(Integer id); -->
<select id="getEmpById" resultMap="MySimpleEmp">
select * from tbl_employee where id=#{id}
</select>
场景二:查询Employee的同时查询员工对应的部门
1、级联属性封装结果集
<resultMap type="com.atguigu.mybatis.bean.Employee" id="MyDifEmp">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="gender" property="gender"/>
<result column="did" property="dept.id"/>
<result column="departmentName " property="dept.departmentName"/>
</resultMap>
<!-- public Employee getEmpAndDept(Integer id);-->
<select id="getEmpAndDept" resultMap="MyDifEmp">
SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,
d.id did,d.departmentName departmentName
FROM tbl_employee e,tbl_dept d
WHERE e.d_id=d.id AND e.id=#{id}
</select>
2、使用association定义关联对象封装规则
<!--
association定:义关联对象的封装规则
property:指定哪个属性是关联的对象
javaType:指定这个属性对象的类型[不能省略]
-->
<resultMap type="com.tt.mybatis.bean.Employee" id="MyDifEmp2">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="gender" property="gender"/>
<association property="dept" javaType="com.tt.mybatis.bean.Department">
<id column="did" property="id"/>
<result column="departmentName" property="departmentName"/>
</association>
</resultMap>
<!-- public Employee getEmpAndDept(Integer id);-->
<select id="getEmpAndDept" resultMap="MyDifEmp">
SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,
d.id did,d.departmentName departmentName
FROM tbl_employee e,tbl_dept d
WHERE e.d_id=d.id AND e.id=#{id}
</select>
3、使用association分步查询
<!--
association定义关联对象的封装规则
select:表明当前属性是调用select指定的方法查出的结果
column:指定将哪一列的值传给这个方法
-->
<resultMap type="com.tt.mybatis.bean.Employee" id="MyEmpByStep">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
<association property="dept"
select="com.tt.mybatis.dao.DepartmentMapper.getDeptById"
column="d_id">
</association>
</resultMap>
<!-- public Employee getEmpByIdStep(Integer id);-->
<select id="getEmpByIdStep" resultMap="MyEmpByStep">
select * from tbl_employee where id=#{id}
</select>
场景三:查询Department的同时查询部门下的员工
1.使用collection定义关联集合封装规则
<!--
collection定义关联集合类型的属性的封装规则
ofType:指定集合里面元素的类型
-->
<resultMap type="com.tt.mybatis.bean.Department" id="MyDept">
<id column="did" property="id"/>
<result column="departmentName" property="departmentName"/>
<collection property="emps" ofType="com.tt.mybatis.bean.Employee">
<!-- 定义这个集合中元素的封装规则 -->
<id column="eid" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
</collection>
</resultMap>
<!-- public Department getDeptByIdPlus(Integer id); -->
<select id="getDeptByIdPlus" resultMap="MyDept">
SELECT d.id did,d.departmentName departmentName,
e.id eid,e.last_name last_name,e.email email,e.gender gender
FROM tbl_dept d LEFT JOIN tbl_employee e
ON d.id=e.d_id
WHERE d.id=#{id}
</select>
2.使用collection分步查询
<resultMap type="com.tt.mybatis.bean.Department" id="MyDeptStep">
<id column="id" property="id"/>
<id column="dept_name" property="departmentName"/>
<collection property="emps"
select="com.tt.mybatis.dao.EmployeeMapperPlus.getEmpsByDeptId"
column="id" fetchType="lazy"></collection>
</resultMap>
<!-- public Department getDeptByIdStep(Integer id); -->
<select id="getDeptByIdStep" resultMap="MyDeptStep">
select id,dept_name from tbl_dept where id=#{id}
</select>
总结
1.通过级联查询和association/collection定义关联对象/集合封装规则,这两种方式是直接发送一条sql,查询两张表得到所有数据。
而利用association/collection分步查询是发送两条sql,先查询主表得到关联外键后再查询从表。
如果全局配置文件中设置了懒加载,只有在使用到从表数据才会进行查询。
2.懒加载的设置:在mybatis全局配置文件中设置。
<settings>
<!-- 驼峰命名默认false关闭 -->
<setting name="mapUnderscoreToCamelCase" value="false"/>
<!-- 开启懒加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
当全局配置文件中开启懒加载设置时,想设置某个查询语句立即加载。
在association和collection标签中有fetchType属性默认为lazy,可以设置为eager设置该查询语句立即加载。