参考视频:https://www.bilibili.com/video/BV1VP4y1c7j7?p=66&vd_source=510ec700814c4e5dc4c4fda8f06c10e8
代码地址:https://gitee.com/empirefree/SpringBoot-summarize/tree/尚硅谷-mybatis篇/
1. 基本概念
1.1. Mybatis基本概念
1.1.1 名词
Mybatis是个半自动ORM框架的持久化框架
1.1.2 ${}、#{}
${}:字符串拼接
{}:占位符赋值
1.1.3 @Param
类似于Map存储
xml分为命名空间和使用函数,就是包 + select,在进入mapper语句源码时会使用到
1.1.4 ResultMap
<!-- 通用查询映射结果 第一个是id 后面是result字段 -->
<resultMap id="BaseResultMap" type="">
<id column="id" property="id" />
<result column="external_userid" property="externalUserid" />
</resultMap>
1.1.5 association
association多对一查询,强制多对多也只会查询出第一条记录
1.1.6 collection
collection 一对多、多对多查询
1.1.7 分步查询、延迟加载
分步查询:查询一个员工SQL之后另外去调用另一个部门SQL,在assocation, collection的select 属性实现
延迟加载:只加载需要的部分,需要开启mybatis的lazyloadingEnabled=true,这样上面分步查询如果只查员工就不会查询部门
(感觉目前用不到,现在都讲究高速,而且分成2条SQL查询效率也比较低)
1.2 动态SQL
1.2.1 基本概念
为了解决拼接SQL中字符串的语法问题
1.2.2 If
<!-- if判断不查询null, '', size()为空的值 -->
<if test="XXX != null and XXX.size() > 0">
and
</if>
1.2.3 where
<!--<where> 可以去掉前置的and, or标签, 若内部条件都不满足,则失效,与where 1=1 一样-->
<select id="selectWhere" resultType="com.empirefree.mybatisplus.entity.Dept">
select * from dept
<where>
<if test="did != null and did != '' ">
and did = #{did}
</if>
<if test="did != null and did != '' ">
or did = #{did}
</if>
</where>
</select>
1.2.4 trim
prefix, suffix:为整条语句前置后置添加指定字符,可用于select 的where、and、or,insert的分隔符
<trim prefix="where" prefixOverrides="and" suffixOverrides="and | or">
<if test="did != null and did != '' ">
and did = #{did}
</if>
<if test="did != null and did != '' ">
or did = #{did} or
</if>
</trim>
1.2.5 choose|when|otherwise
/*when: 类似于else if 可以有一个或多个,而otherwise最多只能有一个,也可以放在select条件中 */
<choose>
<when test="did != null and did != '' ">
did = #{did}
</when>
<otherwise>
did = 2
</otherwise>
</choose>
1.2.6 foreach
<foreach collection="e" item="eid" separator="or" open="(" close=")"></foreach>
1.2.7 SQL标签
<!--字段拼接成SQL片段 -->
<sql id="Base_Column_List">
id, name
</sql>
select <include refid="Base_Column_List"/> from table
2.Mybatis缓存
2.1. 基本概念
2.1.1 一级缓存
默认开启,为SQLSession
2.1.1.1 四种失效情况
1、不同SQLSession对应不同一级缓存(springboot中若没开启事务,则每次CRUD都会重新创建一个SQLSession)
2、同一个SQLSession查询条件不同
3、同一个SQLSession2个查询中执行了任何CUD操作
4、同一个SQLSession2个查询中手动清空了缓存
2.1.2 二级缓存
2.1.2.1 开启条件
二级缓存内部有SqlSessionFactory,开启后每次会重新创建SqlSessioin,但是内部会复用cache的SQL
1、核销配置文件设置cacheEnabled=true 默认开心
2、映射mapper文件设置标签
3、二级缓存必须在SQLSession提交或关闭后有效
4、查询的实体类必须实现序列化接口Serializable
(个人博客链接:https://www.cnblogs.com/meditation5201314/p/14854788.html)
2.1.2.2 失效情况
2次查询之间执行了任何增删改之后,一二级缓存都会失效
2.1.2.3 缓存配置
- eviction:缓存回收策略
- LRU:默认
- FIFO
- FlushInterval:刷新间隔,仅在增删改时刷新
- size: 引用数目,缓存多少个对象
- readOnly: 默认false,设置成true就不能修改,就会出现和数据库里数据不一致情况,但是设置成true确实可以增加查询效率
2.1.3 查询顺序
- 先查二级缓存
- 二级缓存没有,查一级缓存
- 一级缓存也没有,查数据库
- SQLSession关闭后,一级缓存写入二级缓存
(程序->底层servelt 数据库实现类-> JDBC)