CGB2107-Day05-Mybatis高级
1. Mybatis高级用法
1.1 一对一案例
1.1.1 编辑测试案例
/**
* 完成一对一映射.
* 规定: 一个员工对应一个部门.
* 选取方向: 员工方
* 需求: 需要在员工中 完成部门对象的封装.
*/
@Test
public void testOneToOne(){
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> list = empMapper.findAll();
System.out.println(list);
sqlSession.close();
}
1.1.2 编辑业务接口
1.1.3 编辑xml映射文件
<?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.jt.mapper.EmpMapper">
<select id="findAll" resultMap="empRM">
select e.id,e.name,e.age,d.dept_id,d.dept_name
from emp e,dept d
where e.dept_id = d.dept_id
</select>
<!--
规则:
1.如果映射的字段与对象的属性一致,则可以省略不写.
2.最好保留主键的字段信息.
3.如果需要封装单个对象则使用association标签
3.1 property 代表封装对象的属性
3.2 javaType 指定属性的类型 注意路径
4.如果遇到关联封装,必须全部配置映射关系. 如果属性与字段名称一致
则可以使用autoMapping="true"实现自动映射
-->
<resultMap id="empRM" type="Emp" autoMapping="true">
<id column="id" property="id"/>
<!--完成Dept对象的封装-->
<association property="dept" javaType="Dept">
<id column="dept_id" property="deptId"/>
<result column="dept_name" property="deptName"/>
</association>
</resultMap>
</mapper>
1.2 关联查询和子查询的说明
- 关联查询: 通过大量的sql语句 实现数据的关联查询. 其中Sql语句相对复杂. 但是数据封装简单.
- 子查询: 可以通过子查询的方式实现复杂的数据封装. 其中Sql几乎都是单表查询,Sql简单, 但是数据封装复杂.
1.3 子查询实现一对一封装
1.3.1 编辑测试方法
/*一对一查询 方式2 where 条件子查询 */
@Test
public void testOneToOne2(){
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> list = empMapper.findAllWhere();
System.out.println(list);
sqlSession.close();
}
1.3.2 编辑业务接口
1.3.3 编辑xml映射文件
<!--where条件的子查询-->
<select id="findAllWhere" resultMap="empRM2">
select * from emp
</select>
<!--
子查询的说明:
1.column="子查询的字段信息"
2.select= "sql的ID" 作用:根据column中的数据 实现子查询!!!
-->
<resultMap id="empRM2" type="Emp" autoMapping="true">
<id column="id" property="id"></id>
<association property="dept" javaType="Dept"
column="dept_id" select="findDept"/>
</resultMap>
<select id="findDept" resultMap="deptRM">
select * from dept where dept_id = #{dept_id}
</select>
<resultMap id="deptRM" type="Dept">
<id column="dept_id" property="deptId"/>
<result column="dept_name" property="deptName"/>
</resultMap>
1.3.4 子查询的调用逻辑图
2.1 一对多
2.1.1 业务逻辑
业务说明: 一个部门对应多个员工.
2.1.2 一对多Sql语句
/*利用左连接 实现数据查询 */
SELECT d.dept_id,d.dept_name,e.id,e.name,e.age FROM
dept d
LEFT JOIN
emp e
ON
d.dept_id = e.dept_id
1234567
2.1.3 编辑测试类
/**
* 一对多的测试 一个部门下有多个用户信息
*/
@Test
public void testOneToMore(){
SqlSession sqlSession = sqlSessionFactory.openSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
List<Dept> list = deptMapper.findDept();
System.out.println(list);
sqlSession.close();
}
1234567891011
2.1.4 编辑业务接口
2.1.5 编辑xml映射文件
<select id="findDept" resultMap="listRM">
SELECT d.dept_id,d.dept_name,e.id,e.name,e.age FROM
dept d
LEFT JOIN
emp e
ON
d.dept_id = e.dept_id
</select>
<!--
关于一对多 数据封装说明:
collection: 封装集合的固定写法.
property: 指定属性
ofType: 封装List集合的泛型对象
-->
<resultMap id="listRM" type="Dept">
<id column="dept_id" property="deptId"/>
<result column="dept_name" property="deptName"/>
<collection property="emps" ofType="Emp" autoMapping="true">
<id column="id" property="id"/>
</collection>
</resultMap>
1.3 驼峰规则映射
说明: 在mybatis映射数据时,经常出现字段名称与属性名称不一致的现象. 但是其中一部分可以采用驼峰规则的方式完成自动映射. 所以有如下的配置.
1.3.1 编辑mybatis-config.xml
官网API:
配置信息写在configuration 配置标签之下.
<!--Mybatis的核心配置-->
<settings>
<!--开启了驼峰映射规则 dept_id 自动映射到 deptId -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
1.3.2 编辑xml 映射文件
<!--
关于一对多 数据封装说明:
1.collection: 封装集合的固定写法.
property: 指定属性
ofType: 封装List集合的泛型对象
2.如果开启驼峰映射规则,可以简化赋值过程
3.autoMapping="true" 自动实现映射
4.一般最好保留主键,为后续扩展提供方便.
-->
<resultMap id="listRM" type="Dept" autoMapping="true">
<id column="dept_id" property="deptId"/>
<!--<result column="dept_name" property="deptName"/>-->
<collection property="emps" ofType="Emp" autoMapping="true">
<id column="id" property="id"/>
</collection>
</resultMap>
12345678910111213141516
1.4 Mybatis中的缓存机制
1.4.1 什么是缓存机制
说明: 引入缓存可以有效降低用户访问物理设备的频次.提高用户响应速度.
扩展:
1.mybatis自身缓存 一级缓存/二级缓存
2.Redis缓存 读取10万次/秒, 写 8.6万次/秒
1.4.2 一级缓存
概念说明: Mybatis默认开启一级缓存, 一级缓存可以在同一个SqlSession对象中查询相同的数据,可以实现数据的共享(缓存操作).
一级缓存测试:
/**
* Mybatis一级缓存: 默认开启
* 规则: 同一个SqlSession内部有效.
*/
@Test
public void cache1(){
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
List<DemoUser> list1 = demoUserMapper.findAll();
List<DemoUser> list2 =demoUserMapper.findAll();
List<DemoUser> list3 =demoUserMapper.findAll();
System.out.println(list1 == list2);
sqlSession.close();
}
1.4.3 二级缓存
说明: 二级缓存mybatis中默认也是开启的.但是需要手动标识. 二级缓存可以在同一个SqlSessionFactory内部有效.
全局配置:
二级缓存的使用
/**
* 二级缓存说明:
* sqlSession查询数据之后,会将缓存信息保存到一级缓存中.但是不会立即将
* 缓存交给二级缓存保管.如果需要使用二级缓存,则必须将sqlSession业务逻辑执行成功之后关闭.
*/
@Test
public void cache2(){
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
demoUserMapper.findAll();
//关闭一级缓存
sqlSession.close();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper2 = sqlSession2.getMapper(DemoUserMapper.class);
demoUserMapper2.findAll();
sqlSession2.close();
}
2. Mybatis框架总结
2.1 ORM思想
概括: 利用对象的方式封装数据库
核心规则:
对象与表一一映射.
对象的属性与表中的字段一一映射.
2.2 Mybaits框架介绍
小结: Mybatis是一个优秀的持久层框架,基于ORM设计思想,实现了以对象的方式操作数据库.
2.3 Mybaits使用步骤
2.3.1 导入jar包
课堂使用的是springboot整合mybatis的版本.但是使用其中的依赖包 3.5.7的版本.
2). mysql的驱动版本 mysql:mysql-connector-java:8.0.22
3). 驱动的配置: com.mysql.cj.jdbc.Driver
4). 高版本应该使用高版本数据库
2.3.2 编辑核心配置文件
- 数据库环境的配置
- Mapper接口与xml映射文件的绑定关系.
2.3.3 创建接口/xml映射文件
说明: 接口与xml映射文件 一对一映射.
2.3.4 入门案例步骤
- 指定mybatis-config.xml的路径
- 读取指定的核心配置文件.
- 通过SelSessionFactoryBuilder.buid方法创建SqlSessionFactory.
- 获取SqlSession
- 获取Mapper的接口
- 从mapper接口文件中获取业务数据.
- 调用xml文件的Sql语句实现数据获取.
- mybatis自动封装为对象返回 交给用户处理.
2.4 简化mybatis操作
注解: @BeforeEach 在执行@Test注解之前执行.
2.5 Mybatis的参数封装
1. 封装为实体对象 user对象
2. 更为常用的方式 Map集合
3. 如果传递的数据有多个,则可以使用注解@Param("sex") String sex 封装为Map.
123
2.6 #号 $符用法
- 使用#{} 获取数据时,默认有预编译的效果.防止sql注入攻击.
- mybatis使用#{}获取数据时,默认为数据添加一对""号.
- 当以字段名称为参数时,一般使用${},但是这样的sql慎用. 可能出现sql注入攻击问题.
小结: 一般条件下能用#{}号,不用${}
2.7 mybatis转义字符
xml文件中的转义字符.
> > 大于
< < 小于
& & 号
说明:如果sql中有大量的转义字符 建议使用转义标签体
语法: <![CDATA[ xxx内容 报文 ]]>
123456
2.8 Mybatis集合写法
- array
- list
- map
<!--
需求: 批量删除多个数据
难点: 如果使用#{集合}获取的是集合对象的整体.删除无效.
思路: 将数组拆分为单个数据. 可以通过遍历的方式操作
语法: mybatis为了参数取值方便,特意封装了遍历的标签 foreach
关于标签参数说明:
<foreach collection=""></foreach>
1.如果传递的参数是数组, 则collection="array"
2.如果传递的参数是list集合, 则collection="list"
3.如果传递的参数是Map集合, 则collection="map中的key"
标签属性说明:
1.collection 集合的名称
2.item 每次遍历的数据的形参变量
3.open 循环的开始标签
4.close 循环的结束标签
5.index 循环遍历下标 一般不用
6.separator 循环遍历的分割符
-->
2.9 mybatis特殊查询
模糊查询: “%” #{属性}"%" 或者 xxxx.setName("%精%")
2.10 Mybatis优化
1.指定具体的类型的别名
2.别名包
3.别名注解 一般不常用
4.Sql标签 将通用的Sql进行抽取. 通过ID进行引用
5.mybatis的驼峰映射规则 可以自动将下划线去除,映射到属性中.
2.11 动态Sql
- if-where where去除多余的and / or
- set标签 去除多余的,号
- choose when otherwise 用法上和java中的switch类型.
2.12 resultMap用法
当结果集中的字段与属性名不一致时使用. 可以使用驼峰映射规则优化.
2.13 关联关系
2.13.1 一对一
逻辑: 一个员工对应一个部门
表示: 在对象中封装其他对象 对一 封装单个对象 对多封装List集合
一对一映射标签:
2.13.2 一对多
2.14 mybatis中的缓存机制
- 一级缓存 默认开启 SqlSession内共享数据.
- 二级缓存 默认开启 需要标识 SqlSessionFactory内共享数据.