目录
第四章 Mybatis映射文件详解
4.1 映射文件概述
-
MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。
-
如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。
4.2 映射文件根标签
-
mapper标签
-
mapper中的namespace要求与接口的全类名一致
4.3 映射文件子标签
子标签共有9个,注意学习其中8大子标签
-
insert标签:定义添加SQL
-
delete标签:定义删除SQL
-
update标签:定义修改SQL
-
select标签:定义查询SQL
-
sql标签:定义可重用的SQL语句块
-
cache标签:设置当前命名空间的缓存配置
-
cache-ref标签:设置其他命名空间的缓存配置
-
resultMap标签:描述如何从数据库结果集中加载对象
-
resultType解决不了的问题,交个resultMap。
-
4.4 映射文件中常用属性
-
resultType:设置期望结果集返回类型【全类名或别名】
-
注意:如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。
-
resultType 和 resultMap 之间只能同时使用一个。
-
day03
4.5 获取主键自增数据
-
useGeneratedKeys:启用主键生成策略
-
keyProperty:设置存储属性值
4.6 获取数据库受影响行数
-
直接将接口中方法的返回值设置为int或boolean即可
-
int:代表受影响行数
-
boolean
-
true:表示对数据库有影响
-
false:表示对数据库无影响
-
-
第五章 Mybatis中参数传递问题
5.1 单个普通参数
-
可以任意使用:参数数据类型、参数名称不用考虑
5.2 多个普通参数
-
Mybatis底层封装Map结构,封装key为param1、param2....【支持:arg0、arg1、...】
5.3 命名参数
-
语法:
-
@Param(value="参数名")
-
@Param("参数名")
-
-
位置:参数前面
-
注意:
-
底层封装Map结构
-
命名参数,依然支持参数【param1,param2,...】
-
-
示例代码
/** * 通过员工姓名及薪资查询员工信息【命名参数】 * @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参数
-
Mybatis支持POJO【JavaBean】入参,参数key是POJO中属性
5.5 Map参数
-
Mybatis支持直接Map入参,map的key=参数key
5.6 Collection|List|Array等参数
-
参数名:collection、list、array
第六章 Mybatis参数传递【#与$区别】
6.1 回顾JDBC
-
DriverManager
-
Connection
-
Statement:执行SQL语句,入参使用SQL【String】拼接方式
-
PreparedStatement执行SQL语句【预编译SQL】,入参使用占位符方式
-
ResultSet
6.2 #与$区别
-
【#】底层执行SQL语句的对象,使用PreparedStatementd,预编译SQL,防止SQL注入安全隐患,相对比较安全。
-
【$】底层执行SQL语句的对象使用Statement对象,未解决SQL注入安全隐患,相对不安全。
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>
第七章 Mybatis查询中返回值四种情况
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的key,查询结果作为Map的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>
-
对象的id作为key
-
对象作为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>
第八章 Mybatis中自动映射与自定义映射
自动映射【resultType】
自定义映射【resultMap】
8.1 自动映射与自定义映射
-
自动映射【resultType】:指的是自动将表中的字段与类中的属性进行关联映射
-
自动映射解决不了两类问题
-
多表连接查询时,需要返回多张表的结果集
-
单表查询时,不支持驼峰式自动映射【不想为字段定义别名】
-
-
-
自定义映射【resultMap】:自动映射解决不了问题,交给自定义映射
-
注意:resultType与resultMap只能同时使用一个
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相关标签及属性
-
resultMap标签:自定义映射标签
-
id属性:定义唯一标识
-
type属性:设置映射类型
-
-
resultMap子标签
-
id标签:定义主键字段与属性关联关系
-
result标签:定义非主键字段与属性关联关系
-
column属性:定义表中字段名称
-
property属性:定义类中属性名称
-
-
association标签:定义一对一的关联关系
-
property:定义关联关系属性
-
javaType:定义关联关系属性的类型
-
select:设置分步查询SQL全路径
-
colunm:设置分步查询SQL中需要参数
-
fetchType:设置局部延迟加载【懒加载】是否开启
-
-
collection标签:定义一对多的关联关系
-
property:定义一对一关联关系属性
-
ofType:定义一对一关联关系属性类型
-
fetchType:设置局部延迟加载【懒加载】是否开启
-
-
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
-
eager:关闭局部延迟加载
-
lazy:开启局部延迟加载
-
-
示例代码
<association property="dept" select="com.atguigu.mybatis.mapper.DeptMapper.selectDeptByDeptId" column="dept_id" fetchType="eager"> </association>
-
-
8.8 扩展
-
如果分步查询时,需要传递给调用的查询中多个参数,则需要将多个参数封装成
Map来进行传递,语法如下: {k1=v1, k2=v2....}