第四章 Mybatis映射文件详解
4.1 映射文件概述
4.2 映射文件根标签
4.3 映射文件子标签
子标签共有9个,注意学习其中8大子标签
4.4 映射文件中常用属性
4.5 获取主键自增数据
4.6 获取数据库受影响行数
5.1 单个普通参数
5.2 多个普通参数
5.3 命名参数
语法:
位置:参数前面
注意:
示例代码
/**
* 通过员工姓名及薪资查询员工信息【命名参数】
* @return
*/
public List<Employee> selectEmpByNamed(@Param("lName")String lastName,
@Param("salary") double salary);
<select id="selectEmpByNamed" resultType="employee">
SELECT
id,
last_name,
email,
salary
FROM
tbl_employee
WHERE
last_name=#{param1}
AND
salary=#{param2}
</select>
源码分析
MapperMethod对象:142行代码【命名参数底层代码入口】
命名参数底层封装map为ParamMap,ParamMap继承HashMap
ParamNameResolver对象:130行代码,命名参数底层实现逻辑
//130行
final Map<String, Object> param = new ParamMap<>();
int i = 0;
for (Map.Entry<Integer, String> entry : names.entrySet()) {
param.put(entry.getValue(), args[entry.getKey()]);
// add generic param names (param1, param2, ...)
final String genericParamName = GENERIC_NAME_PREFIX + (i + 1);
// ensure not to overwrite parameter named with @Param
if (!names.containsValue(genericParamName)) {
param.put(genericParamName, args[entry.getKey()]);
}
i++;
}
return param;
5.4 POJO参数
5.5 Map参数
5.6 Collection|List|Array等参数
6.1 回顾JDBC
6.2 #与$区别
6.3 #与$使用场景
查询SQL:select col,col2 from table1 where col=? and col2=? group by ?, order by ? limit ?,?
#使用场景,sql占位符位置均可以使用#
使用场景,#解决不了的参数传递问题,均可以交给处理【如:form 动态化表名】
/**
* 测试$使用场景
*/
public List<Employee> selectEmpByDynamitTable(@Param("tblName") String tblName);
<select id="selectEmpByDynamitTable" resultType="employee">
SELECT
id,
last_name,
email,
salary
FROM
${tblName}
</select>
7.1 查询单行数据返回单个对象
/**
* 通过id获取员工信息
*/
public Employee selectEmpById(int empId);
<select id="selectEmpById" resultType="employee">
SELECT
id,
last_name,
email,
salary
FROM
tbl_employee
WHERE
id=#{empId}
</select>
7.2 查询多行数据返回对象的集合
/**
* 查询所有员工信息
*/
public List<Employee> selectAllEmps();
<select id="selectAllEmps" resultType="employee">
SELECT
id,
last_name,
email,
salary
FROM
tbl_employee
</select>
7.3 查询单行数据返回Map集合
Map<String key,Object value>
示例代码
/**
* 查询单行数据返回Map集合
* @return
*/
public Map<String,Object> selectEmpReturnMap(int empId);
<!-- 查询单行数据返回Map集合-->
<select id="selectEmpReturnMap" resultType="map">
SELECT
id,
last_name,
email,
salary
FROM
tbl_employee
WHERE
id=#{empId}
</select>
7.4 查询多行数据返回Map集合
Map<Integer key,Employee value>
示例代码
/**
* 查询多行数据返回Map
* Map<Integer,Object>
* Map<Integer,Employee>
* 对象Id作为:key
* 对象作为:value
* @return
*/
@MapKey("id")
public Map<Integer,Employee> selectEmpsReturnMap();
<select id="selectEmpsReturnMap" resultType="map">
SELECT
id,
last_name,
email,
salary
FROM
tbl_employee
</select>
自动映射【resultType】 自定义映射【resultMap】
8.1 自动映射与自定义映射
8.2 自定义映射-级联映射
<!-- 自定义映射 【员工与部门关系】-->
<resultMap id="empAndDeptResultMap" type="employee">
<!-- 定义主键字段与属性关联关系 -->
<id column="id" property="id"></id>
<!-- 定义非主键字段与属性关联关系-->
<result column="last_name" property="lastName"></result>
<result column="email" property="email"></result>
<result column="salary" property="salary"></result>
<!-- 为员工中所属部门,自定义关联关系-->
<result column="dept_id" property="dept.deptId"></result>
<result column="dept_name" property="dept.deptName"></result>
</resultMap>
<select id="selectEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">
SELECT
e.`id`,
e.`email`,
e.`last_name`,
e.`salary`,
d.`dept_id`,
d.`dept_name`
FROM
tbl_employee e,
tbl_dept d
WHERE
e.`dept_id` = d.`dept_id`
AND
e.`id` = #{empId}
</select>
8.3 自定义映射-association映射
特点:解决一对一映射关系【多对一】
示例代码
<!-- 自定义映射 【员工与部门关系】-->
<resultMap id="empAndDeptResultMapAssociation" type="employee">
<!-- 定义主键字段与属性关联关系 -->
<id column="id" property="id"></id>
<!-- 定义非主键字段与属性关联关系-->
<result column="last_name" property="lastName"></result>
<result column="email" property="email"></result>
<result column="salary" property="salary"></result>
<!-- 为员工中所属部门,自定义关联关系-->
<association property="dept"
javaType="com.atguigu.mybatis.pojo.Dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></result>
</association>
</resultMap>
8.4 自定义映射-collection映射
示例代码
/**
* 通过部门id获取部门信息,及部门所属员工信息
*/
public Dept selectDeptAndEmpByDeptId(int deptId);
<resultMap id="deptAndempResultMap" type="dept">
<id property="deptId" column="dept_id"></id>
<result property="deptName" column="dept_name"></result>
<collection property="empList"
ofType="com.atguigu.mybatis.pojo.Employee">
<id column="id" property="id"></id>
<result column="last_name" property="lastName"></result>
<result column="email" property="email"></result>
<result column="salary" property="salary"></result>
</collection>
</resultMap>
<select id="selectDeptAndEmpByDeptId" resultMap="deptAndempResultMap">
SELECT
e.`id`,
e.`email`,
e.`last_name`,
e.`salary`,
d.`dept_id`,
d.`dept_name`
FROM
tbl_employee e,
tbl_dept d
WHERE
e.`dept_id` = d.`dept_id`
AND
d.dept_id = #{deptId}
</select>
8.5 ResultMap相关标签及属性
8.6 Mybatis中分步查询
为什么使用分步查询【分步查询优势】?
示例代码
一对一
/**
* 通过员工id获取员工信息及员工所属的部门信息【分步查询】
1. 先通过员工id获取员工信息【id、last_name、email、salary、dept_id】
2. 再通过部门id获取部门信息【dept_id、dept_name】
*/
public Employee selectEmpAndDeptByEmpIdAssociationStep(int empId);
<select id="selectEmpAndDeptByEmpIdAssociationStep" resultMap="empAndDeptResultMapAssocationStep">
select
id,
last_name,
email,
salary,
dept_id
from
tbl_employee
where
id=#{empId}
</select>
/**
* 通过部门id获取部门信息
*/
public Dept selectDeptByDeptId(int deptId);
<select id="selectDeptByDeptId" resultType="dept">
select
dept_id,
dept_name
from
tbl_dept
where
dept_id=#{deptId}
</select>
一对多
/**
* 通过部门id获取部门信息,及部门所属员工信息【分步查询】
1. 通过部门id获取部门信息
2. 通过部门id获取员工信息
*/
public Dept selectDeptAndEmpByDeptIdStep(int deptId);
<!-- 通过部门id获取部门信息,及部门所属员工信息【分步查询】-->
<!-- 1. 通过部门id获取部门信息-->
<!-- 2. 通过部门id获取员工信息-->
<select id="selectDeptAndEmpByDeptIdStep" resultMap="deptAndEmpResultMapStep">
select
dept_id,
dept_name
from
tbl_dept
where
dept_id=#{deptId}
</select>
/**
* 通过部门Id获取员工信息
* @param deptId
* @return
*/
public List<Employee> selectEmpByDeptId(int deptId);
<select id="selectEmpByDeptId" resultType="employee">
select
id,
last_name,
email,
salary,
dept_id
from
tbl_employee
where
dept_id=#{deptId}
</select>
8.7 Mybatis延迟加载【懒加载】
需要时加载,不需要暂时不加载
优势:提升程序运行效率
语法
全局设置
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 设置加载的数据是按需加载3.4.2及以后的版本该步骤可省略-->
<setting name="aggressiveLazyLoading" value="false"/>
局部设置
fetchType
示例代码
<association property="dept"
select="com.atguigu.mybatis.mapper.DeptMapper.selectDeptByDeptId"
column="dept_id"
fetchType="eager">
</association>
8.8 扩展