Mybatis 自定义映射和分布查询:
自定义映射
- 自定义resultMap,实现高级结果集映射
- id :用于完成主键值的映射
- result :用于完成普通列的映射
- association :一个复杂的类型关联;许多结果将包成这种类型
- collection : 复杂类型的集
项目结构
数据准备
项目结构
Department
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.hph.mybatis.beans;
import java.util.List;
public class Department {
private Integer id; private String departmentName ;
private List<Employee> emps ;
public List<Employee> getEmps() { return emps; } public void setEmps(List<Employee> emps) { this.emps = emps; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getDepartmentName() { return departmentName; } public void setDepartmentName(String departmentName) { this.departmentName = departmentName; } @Override public String toString() { return "Department [id=" + id + ", departmentName=" + departmentName + "]"; } }
|
Employee
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| package com.hph.mybatis.beans;
public class Employee {
private Integer id; private String lastName; private String email; private Integer gender;
private Department dept;
public void setDept(Department dept) { this.dept = dept; }
public Department getDept() { return dept; }
public Employee() { }
public Employee(Integer id, String lastName, String email, Integer gender, Department dept) { this.id = id; this.lastName = lastName; this.email = email; this.gender = gender; this.dept = dept; }
public Employee(Integer id, String lastName, String email, Integer gender) { super(); this.id = id; this.lastName = lastName; this.email = email; this.gender = gender; }
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Integer getGender() { return gender; }
public void setGender(Integer gender) { this.gender = gender; }
@Override public String toString() { return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + "]"; }
}
|
EmployeeMapperResultMap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.hph.mybatis.dao;
import com.hph.mybatis.beans.Employee;
import java.util.List;
public interface EmployeeMapperResultMap {
public Employee getEmployeeById(Integer id);
public Employee getEmpAndDept(Integer id);
public Employee getEmpAndDeptStep(Integer id);
public List<Employee> getEmpsByDid(Integer did);
}
|
EmployeeMapperResultMap.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| <?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.hph.mybatis.dao.EmployeeMapperResultMap">
<select id="getEmployeeById" resultMap="MyEmp"> select id ,last_name, email,gender from tbl_employee where id = #{id} </select> <resultMap type="com.hph.mybatis.beans.Employee" id="MyEmp"> <id column="id" property="id"/> <result column="last_name" property="lastName"/> <result column="email" property="email"/> <result column="gender" property="gender"/> </resultMap>
<select id="getEmpAndDept" resultMap="myEmpAndDept"> SELECT e.id eid , e.last_name, e.email,e.gender , d.id did , d.dept_name FROM tbl_employee e , tbl_dept d WHERE e.d_id = d.id AND e.id = #{id} </select> <resultMap type="com.hph.mybatis.beans.Employee" id="myEmpAndDept"> <id column="eid" property="id"/> <result column="last_name" property="lastName"/> <result column="email" property="email"/> <result column="gender" property="gender"/> <result column="did" property="dept.id"/> <result column="dept_name" property="dept.departmentName"/> </resultMap>
<select id="getEmpAndDeptStep" resultMap="myEmpAndDeptStep"> select id, last_name, email,gender ,d_id from tbl_employee where id = #{id} </select> <resultMap type="com.hph.mybatis.beans.Employee" id="myEmpAndDeptStep"> <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.hph.mybatis.dao.DepartmentMapperResultMap.getDeptById" column="{did=d_id}" fetchType="eager"> </association> </resultMap>
<select id="getEmpsByDid" resultType="com.hph.mybatis.beans.Employee"> select id,last_name,email,gender from tbl_employee where d_id = #{did} </select> </mapper>
|
TestMapbatisResultMap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| package com.hph.mybatis.test;
import com.hph.mybatis.beans.Department; import com.hph.mybatis.beans.Employee; import com.hph.mybatis.dao.DepartmentMapperResultMap; import com.hph.mybatis.dao.EmployeeMapperResultMap; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test;
import java.io.IOException; import java.io.InputStream;
public class TestMapbatisResultMap {
public SqlSessionFactory getsqlSessionFactory() throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; }
@Test public void testResultMap() throws IOException { SqlSessionFactory ssf = getsqlSessionFactory(); SqlSession session = ssf.openSession(); try { EmployeeMapperResultMap mapper = session.getMapper(EmployeeMapperResultMap.class); Employee employee = mapper.getEmployeeById(1001); System.out.println(employee); } finally { session.close(); } }
@Test public void testResultMapCascade() throws IOException { SqlSessionFactory ssf = getsqlSessionFactory(); SqlSession session = ssf.openSession(); try { EmployeeMapperResultMap mapper = session.getMapper(EmployeeMapperResultMap.class);
Employee employee = mapper.getEmpAndDept(1001); System.out.println(employee); System.out.println(employee.getDept());
} finally { session.close(); } }
@Test public void testResultMapAssociation() throws IOException { SqlSessionFactory ssf = getsqlSessionFactory(); SqlSession session = ssf.openSession(); try { EmployeeMapperResultMap mapper = session.getMapper(EmployeeMapperResultMap.class); Employee employee = mapper.getEmpAndDeptStep(1001); System.out.println(employee); System.out.println(employee.getDept()); } finally { session.close(); } }
@Test public void testResultMapCollectionStep() throws IOException { SqlSessionFactory ssf = getsqlSessionFactory(); SqlSession session = ssf.openSession(); try { DepartmentMapperResultMap mapper = session.getMapper(DepartmentMapperResultMap.class); Department dept = mapper.getDeptAndEmpsStep(1); System.out.println(dept.getDepartmentName()); System.out.println(dept.getEmps()); }finally { session.close(); } } }
|
association
级联
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
<select id="getEmployeeById" resultMap="MyEmp"> select id ,last_name, email,gender from tbl_employee where id = #{id} </select> <resultMap type="com.hph.mybatis.beans.Employee" id="MyEmp"> <id column="id" property="id"/> <result column="last_name" property="lastName"/> <result column="email" property="email"/> <result column="gender" property="gender"/> </resultMap>
|
testResultMap结果
Association
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <select id="getEmpAndDept" resultMap="myEmpAndDept"> SELECT e.id eid , e.last_name, e.email,e.gender , d.id did , d.dept_name FROM tbl_employee e , tbl_dept d WHERE e.d_id = d.id AND e.id = #{id} </select> <resultMap type="com.hph.mybatis.beans.Employee" id="myEmpAndDept"> <id column="eid" property="id"/> <result column="last_name" property="lastName"/> <result column="email" property="email"/> <result column="gender" property="gender"/> <result column="did" property="dept.id"/> <result column="dept_name" property="dept.departmentName"/> </resultMap>
|
getEmpAndDept的结果
分步查询
实际的开发中,对于每个实体类都应该有具体的增删改查方法,也就是DAO层, 因此对于查询员工信息并且将对应的部门信息也查询出来的需求,就可以通过分步的方式完成查询。
① 先通过员工的id查询员工信息
② 再通过查询出来的员工信息中的外键(部门id)查询对应的部门信息.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <select id="getEmpAndDeptStep" resultMap="myEmpAndDeptStep"> select id, last_name, email,gender ,d_id from tbl_employee where id = #{id} </select> <resultMap type="com.hph.mybatis.beans.Employee" id="myEmpAndDeptStep"> <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.hph.mybatis.dao.DepartmentMapperResultMap.getDeptById" column="{did=d_id}" fetchType="eager"> </association> </resultMap>
<select id="getEmpsByDid" resultType="com.hph.mybatis.beans.Employee"> select id,last_name,email,gender from tbl_employee where d_id = #{did} </select>
|
延迟加载
在分步查询的基础上,可以使用延迟加载来提升查询的效率,只需要在全局(mybatis-config.xml)的Settings中进行如下的配置:
1 2 3 4
| <setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
|
collection
POJO中的属性可能会是一个集合对象,我们可以使用联合查询,并以级联属性的方式封装对象.使用collection标签定义对象的封装规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <select id="getDeptAndEmpsById" resultMap="myDeptAndEmps"> SELECT d.id did ,d.dept_name, e.id eid, e.last_name, e.email,e.gender FROM tbl_dept d LEFT OUTER JOIN tbl_employee e ON d.id = e.d_id WHERE d.id = #{id} </select> <resultMap type="com.hph.mybatis.beans.Department" id="myDeptAndEmps"> <id column="did" property="id"/> <result column="dept_name" property="departmentName"/>
<collection property="emps" ofType="com.hph.mybatis.beans.Employee" > <id column="eid" property="id"/> <result column="last_name" property="lastName"/> <result column="email" property="email"/> <result column="gender" property="gender"/> </collection> </resultMap>
|
分步查询
实际的开发中,对于每个实体类都应该有具体的增删改查方法,也就是DAO层, 因此对于查询部门信息并且将对应的所有的员工信息也查询出来的需求,就可以通过分步的方式完成查询。
① 先通过部门的id查询部门信息
② 再通过部门id作为员工的外键查询对应的部门信息.
1 2 3 4 5 6 7 8 9 10 11 12
| <select id="getDeptAndEmpsStep" resultMap="myDeptAndEmpsStep"> select id , dept_name from tbl_dept where id = #{id} </select>
<resultMap id="myDeptAndEmpsStep" type="com.hph.mybatis.beans.Department"> <id column="id" property="id"/> <result column="dept_name" property="departmentName"/> <collection property="emps" select="com.hph.mybatis.dao.EmployeeMapperResultMap.getEmpsByDid" column="id"> </collection> </resultMap>
|
分步查询多列值的传递
如果分步查询时,需要传递给调用的查询中多个参数,则需要将多个参数封装成Map来进行传递,语法如下: {k1=v1, k2=v2….}
在所调用的查询方,取值时就要参考Map的取值方式,需要严格的按照封装map时所用的key来取值.
column=”{key1=column1,key2=column2}”
fetchType属性
在<association> 和<collection>标签中都可以设置fetchType,指定本次查询是否要使用延迟加载。默认为 fetchType=”lazy” ,如果本次的查询不想使用延迟加载,则可设置为fetchType=”eager”.
fetchType可以灵活的设置查询是否需要使用延迟加载,而不需要因为某个查询不想使用延迟加载将全局的延迟加载设置关闭..