mybatis中的resultMap,结果映射,将返回的数据进行更加高级的自定义规则设置,resultMap
结果映射中还可以使用resultType,它可以指定返回的数据类型,如map
<select id="getEmp" resultType="map">
select * from emp
</select>
映射到map中并不是很好的结果,因为我们不是很清晰的知道map中的数据,所有我们一般指定javabean类型返回,如上面的例子中,查询的emp数据,
我们写一个Emp类来进行参数的封窗。
@Data
public class Emp {
private Long id;
private String name;
private String gender;
private String email;
}
我们的xml就可以这样写:
<select id="getEmp" resultType="com.mybatis.bean.Emp">
select id,name,gender,emailfrom emp
</select>
上面使用resultType的做法,我们可以使用resultMap,实现相同的结果
<!--id 唯一标识-->
<resultMap id="myEmp" type="com.mybatis.bean.Emp">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="gender" property="gender"></result>
<result column="email" property="email"></result>
</resultMap>
<select id="getEmp" resultMap="myEmp">
select id,name,gender,email from emp
</select>
resultType和resultMap不能同时使用,如果Emp中有一个对象的属性,那么直接使用resultType返回 com.mybatis.bean.Emp将会有问题;
如:Emp中有一个属性dept
@Data
public class Emp {
private Long id;
private String name;
private String gender;
private String email;
private Dept dept;
Dept:
@Data
public class Dept {
private Long deptId;
private String deptName;
xml:
<select id="getEmpAndDept" resultType="com.mybatis.bean.Emp">
SELECT e.id,e.name,e.gender,e.email,d.dept_id,d.dept_name FROM emp e, dept d where e.dept_id = d.dept_id and e.id = #{id}
</select>
这时候我们发现返回的数据中dept是null,所以这时候我们就可以使用resultMap自定义的映射规则了
第一种方式:
<!--id 唯一标识-->
<resultMap id="myEmpDept" type="com.mybatis.bean.Emp">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="gender" property="gender"></result>
<result column="email" property="email"></result>
<result column="dept_id" property="dept.deptId"></result>
<result column="dept_name" property="dept.deptName"></result>
</resultMap>
第二种方式:使用association
<resultMap id="myEmpDept" type="com.mybatis.bean.Emp">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="gender" property="gender"></result>
<result column="email" property="email"></result>
<!--指定javabean对象,emp的属性dept
property:指定emp的属性dept
javaType:指定属性的类型com.mybatis.bean.Dept
-->
<association property="dept" javaType="com.mybatis.bean.Dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></result>
</association>
</resultMap>
SQL这里的resultMap指定上面的id属性
<select id="getEmpAndDept" resultMap="myEmpDept">
SELECT e.id,e.name,e.gender,e.email,d.dept_id,d.dept_name FROM emp e, dept d where e.dept_id = d.dept_id and e.id = #{id}
</select>
这样就可以返回的dept就有数据了。
如果Dept中定义的类型是集合:一个部门对应多个员工
@Data
public class Dept {
private Long deptId;
private String deptName;
private List<Emp> emp;
这时候使用association就不行了,需要使用collection
<resultMap id="myDepts" type="com.mybatis.bean.Dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></result>
<!--property:Dept中的emp属性
ofType:集合里面元素的类型
-->
<collection property="emp" ofType="com.mybatis.bean.Emp">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="gender" property="gender"></result>
<result column="email" property="email"></result>
</collection>
</resultMap>
<select id="getDept" resultMap="myDepts">
select d.dept_id,d.dept_name ,e.id,e.name,e.gender,e.email from dept d
LEFT JOIN emp e ON d.dept_id = e.dept_id where d.dept_id = #{dept_id}
</select>
关联的嵌套 Select 查询(分步查询):
同样的需求:查询一个部门中的多个员工
mapper中的接口:
//通过部门的id查询员工
public List<Emp> selectEmps(Integer dept_id);
//通过部门id查询部门
public Dept selectDept(Integer dept_id);
DeptMapper.xml;
<!--分步查询-->
<resultMap id="myDept" type="com.mybatis.bean.Dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></result>
<!--property:Dept的属性名,column:传入的dept_id,select:查询的语句,fetchType有效值为 lazy 和 eager。 指定属性后,将在映射中忽略全局配置参数 lazyLoadingEnabled,使用属性的值->
<collection property="emp" column="dept_id" select="com.mybatis.mapper.EmpMapper.selectEmpsStep"/>
</resultMap>
<select id="selectDept" resultMap="myDept">
SELECT dept_id,dept_name FROM dept WHERE dept_id = #{dept_id}
</select>
EmpMapper.xml:
<select id="selectEmps" resultType="com.mybatis.bean.Emp">
SELECT id,name,gender,email FROM emp WHERE dept_id = #{dept_id}
</select>
mybatis全局配置:
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
最终实现分步查询和延迟加载,当我们访问只dept时,就不会去执行emp的SQL语句
Dept dept = mapper.selectDept(10000);
System.out.println(dept.getDeptName());
System.out.println(dept.getEmp());
当我们去访问emp时,就会执行emp的SQL语句。
不过官方说分步查询和延迟加载会有性能问题