- resultMap
- 分步查询
- 懒加载
- 关联查询
- 一对一
- 一对多
一、resultMap自定义结果映射规则
1、在
xxxMapper.xml
文件中自定义一个javaBean的封装规则<!--自定义某个javaBean的封装规则 type:自定义规则的Java类型 id:唯一id方便引用 --> <resultMap type="com.fc.mybatis.bean.Employee" id="MySimpleEmp"> <!--指定主键列的封装规则,id定义主键会底层有优化; column:指定哪一列 property:指定对应的javaBean属性 --> <id column="id" property="id"/> <!-- 定义普通列封装规则 --> <result column="last_name" property="lastName"/> <!-- 其他不指定的列会自动封装:我们只要写resultMap就把全部的映射规则都写上。即下面的可省略 --> <result column="email" property="email"/> <result column="gender" property="gender"/> </resultMap> <!-- resultMap:自定义结果集映射规则; --> <!-- 对应EmployeeMapper.java接口的public Employee getEmpById(Integer id); --> <select id="getEmpById" resultMap="MySimpleEmp"> select * from tbl_employee where id=#{id} </select>
总结:
- 1、property对应javabean上的属性名
- 2、column和查询数据库的列名一致(重命名后,要和重命名的名字一致)
二、数据库增改以满足关联查询
一、场景一:
查询Employee的同时查询员工对应的部门,每个员工有与之对应的部门信息;
id last_name gender d_id did dept_name (private Department dept;)
- 1、创建部门表
tbl_dept
- 2、在
tbl_employee
员工表上增加部门id列d_id
3、对
tbl_employee
员工表增加约束;d_id
列关联上tbl_dept
部门表的id
列
- 1、创建部门表
三、一对一查询
- 1、联合查询:级联属性封装结果集
<!-- dept对应Employee中javabean的部门
private Department dept;
-->
<resultMap type="com.fc.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="dept_name" property="dept.departmentName"/>
</resultMap>
- 2、使用
association
定义关联的单个javaBean对象的封装规则
property="dept"
:指定哪个属性是联合的对象javaType
:指定这个属性对象的类型【不能省略】
<!--
使用association定义关联的单个对象的封装规则;
-->
<resultMap type="com.fc.mybatis.bean.Employee" id="MyDifEmp2">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="gender" property="gender"/>
<!-- association可以指定联合的javaBean对象
property="dept":指定哪个属性是联合的对象
javaType:指定这个属性对象的类型[不能省略]
-->
<association property="dept" javaType="com.fc.mybatis.bean.Department">
<id column="did" property="id"/>
<result column="dept_name" property="departmentName"/>
</association>
</resultMap>
- 3、xxxMapper.xml数据库语句
<!-- public Employee getEmpAndDept(Integer id);
MyDifEmp / MyDifEmp2
-->
<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.dept_name dept_name FROM tbl_employee e,tbl_dept d
WHERE e.d_id=d.id AND e.id=#{id}
</select>
- 4、测试单元类
// 获取接口的实现类对象
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
System.out.println(mapper.getEmpAndDept(1));
System.out.println(mapper.getEmpAndDept(1).getDept());
5、使用association进行分步查询
- 1)、先按照员工id查询员工信息
- 2)、根据查询员工信息中的d_id值去部门表查出部门信息
- 3)、部门设置到员工中;
实现步骤
- 1、在
mybatis-config
配置中注册部门DepartmentMapper接口
<mapper class="com.fc.mybatis.dao.DepartmentMapper"/>
- 2、
DepartmentMapper.xml
实现select查询部门信息
<!--public Department getDeptById(Integer id); -->
<select id="getDeptById" resultType="com.fc.mybatis.bean.Department">
select id,dept_name departmentName from tbl_dept where id=#{id}
</select>
- 3、
EmployeeMapper.xml
流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性
- select: 表明当前属性是调用select指定的方法查出的结果
- column: 指定将员工表哪一列的值传到部门表中查询
- d_id 是 tbl_employee员工表的关联部门表id的列
<!-- id last_name email gender d_id -->
<resultMap type="com.fc.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定义关联对象的封装规则
select:表明当前属性是调用select指定的方法查出的结果
column:指定将哪一列的值传给这个方法
流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性
d_id是tbl_employee员工表的关联部门表id的列
-->
<association property="dept"
select="com.fc.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>
- 分步查询的日志如下:
DEBUG 06-23 15:13:09,306 ==> Preparing: select * from tbl_employee where id=? (BaseJdbcLogger.java:159)
DEBUG 06-23 15:13:09,343 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:159)
DEBUG 06-23 15:13:09,365 ====> Preparing: select id,dept_name departmentName from tbl_dept where id=? (BaseJdbcLogger.java:159)
DEBUG 06-23 15:13:09,366 ====> Parameters: 1(Integer) (BaseJdbcLogger.java:159)
DEBUG 06-23 15:13:09,368 <==== Total: 1 (BaseJdbcLogger.java:159)
DEBUG 06-23 15:13:09,369 <== Total: 1 (BaseJdbcLogger.java:159)
Employee [id=1, lastName=111, email=aa@qq.com, gender=0]
Department [id=1, departmentName=ha]
- 6、在分步查询基础上实现懒加载
在mybatis-config.xml
中配置
<!-- 懒加载;显示的指定每个我们需要更改的配置的值,即使他是默认的。防止版本更新带来的问题 -->
<setting name="lazyLoadingEnabled" value="true"></setting>
<setting name="aggressiveLazyLoading" value="false"></setting>
测试类
// 获取接口的实现类对象
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
Employee employee = mapper.getEmpByIdStep(1);
System.out.println(employee.getLastName());
System.out.println(employee.getDept());
打印出的日志, 即调用getDept()方法才去查询数据库
DEBUG 06-23 15:59:31,908 ==> Preparing: select * from tbl_employee where id=? (BaseJdbcLogger.java:159)
DEBUG 06-23 15:59:31,947 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:159)
DEBUG 06-23 15:59:32,027 <== Total: 1 (BaseJdbcLogger.java:159)
111
DEBUG 06-23 15:59:32,028 ==> Preparing: select id,dept_name departmentName from tbl_dept where id=? (BaseJdbcLogger.java:159)
DEBUG 06-23 15:59:32,028 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:159)
DEBUG 06-23 15:59:32,030 <== Total: 1 (BaseJdbcLogger.java:159)
Department [id=1, departmentName=ha]
四、一对多查询
场景二:
查询部门的时候将部门对应的所有员工信息也查询出来:注释在DepartmentMapper.xml中
- 1、数据库操作,左拼接查询
- 2、
department.java
的javabean中添加emps, 并添加get/set方法
private List<Employee> emps;
- 3、在
DepartmentMapper.java
中添加接口方法
// 查询出一个部门中所有员工
public Department getDeptByIdPlus(Integer id);
- 4、
DepartmentMapper.xml
中使用collection标签定义关联的集合类型的属性封装规则
- collection定义关联集合类型的属性的封装规则
- ofType:指定集合里面元素的类型
<!--嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则 -->
<resultMap type="com.fc.mybatis.bean.Department" id="MyDept">
<id column="did" property="id"/>
<result column="dept_name" property="departmentName"/>
<!--
collection定义关联集合类型的属性的封装规则
ofType:指定集合里面元素的类型
-->
<collection property="emps" ofType="com.fc.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.dept_name dept_name,
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>
- 5、一对多下的分步查询和一对一分步查询的异同点
- 1、将单个关联对象
association
换成集合关联对象collection
- 2、 同样
property="dept"
对应上javabean
的名字dept - 3、将多列的值封装map传递;比如:
column="{deptId=id}"
- 4、column表示传到下一步操作的列
- 5、select指向下一步操作的方法
- 6、fetchType=”lazy”:表示使用延迟加载;
- lazy:延迟
- eager:立即
- 1、将单个关联对象
问题
- 1、Mybatis Generator代码不报错,但是没有生成文件
解决方案:
此种情况一般都是设置的路径有误,将从\
换成/
比如:./src/main/java