文章摘自:b站2022版MyBatis教程
MyBatis的查询- 查询一个实体类对象
select * from t_user where id = #{id}
- 查询一个List集合
- 查询单个数据
- 查询一条数据为map集合
5. 查询多条数据为map
第一种方式:
第二种方式
@MapKey("id")
Map getAllUser();
自定义sql的执行
- 模糊查询
- 批量删除
delete from t_user where id in (${ids})
- 动态设置表名
- 添加功能获取自增的主键
insert into t_user values(null,#{username},#{password},#{age},#{sex})
User user = new User(-1, "admin", "123456", 18, "女", "111@qq.com"); userMapper.insertUser(user); System.out.println(user);
- 添加功能获取uuid的主键
属性和字段名不一致select uuid() insert into t_user values(#{id},#{username},#{password},#{age},#{sex})
- mybatis-config.xml添加
数据库字段为 emp_name,属性就为 empName
- 通过sql起别名
- resultMap处理字段和属性的映射关系
多对一映射处理
- 级联方式处理映射关系
Emp.java
public class Emp {
private int eid;
private String empName;
private Dept dept;
}
- association处理映射关系
- 分步查询
EmpMapper.xml(员工)
DeptMapper.xml(部门)
延迟加载
lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。
注:例如上边分步查询中,调用了 emp.getDepe()才会去查询关联的对象,不调用默认只查询emp对象
aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个属性会按需加载此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。
此时可通过 association 和 collection 中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy(延迟加载)|eager(立即加载)”
一对多映射处理- collection
结果
2. 分步查询
DeptMapper.xml(部门)
EmpMapper.xml(员工)
动态SQL
- if
- where
where 和 if 一般结合使用:
若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字
若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的and去掉
注意:where标签不能去掉条件最后多余的and
- trim
trim用于去掉或添加标签中的内容
常用属性:
prefix:在trim标签中的内容的前面添加某些内容
prefixOverrides:在trim标签中的内容的前面去掉某些内容
suffix:在trim标签中的内容的后面添加某些内容
suffixOverrides:在trim标签中的内容的后面去掉某些内容
- choose、when、otherwise
choose、when、otherwise相当于if…else if…else
- foreach
插入多个
insert into t_emp values (null,#{emp.ename},#{emp.age},#{emp.sex},#{emp.email},null)
删除多条
delete from t_emp where eid = #{eid}
delete from t_emp where eid in #{eid}
属性:
collection:设置要循环的数组或集合
item:表示集合或数组中的每一个数据
separator:设置循环体之间的分隔符
open:设置foreach标签中的内容的开始符
close:设置foreach标签中的内容的结束符
- SQL片段
MyBatis的缓存eid,ename,age,sex,did selectfrom t_emp
- MyBatis的一级缓存
一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就
会从缓存中直接获取,不会从数据库重新访问
使一级缓存失效的四种情况:
1) 不同的SqlSession对应不同的一级缓存 2) 同一个SqlSession但是查询条件不同 3) 同一个SqlSession两次查询期间执行了任何一次增删改操作 4) 同一个SqlSession两次查询期间手动清空了缓存
- MyBatis的二级缓存
二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取
二级缓存开启的条件:
a>在核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置
b>在映射文件中设置标签
c>二级缓存必须在SqlSession关闭或提交之后有效
d>查询的数据所转换的实体类类型必须实现序列化的接口
使二级缓存失效的情况:
两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效
- 二级缓存的相关配置
在 mapper 配置文件中添加的 cache 标签可以设置一些属性:
eviction属性:缓存回收策略
LRU(Least Recently Used) – 最近最少使用的:移除最长时间不被使用的对象。
FIFO(First in First out) – 先进先出:按对象进入缓存的顺序来移除它们。
SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
默认的是 LRU。flushInterval属性:刷新间隔,单位毫秒
默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新size属性:引用数目,正整数
代表缓存最多可以存储多少个对象,太大容易导致内存溢出readOnly属性:只读,true/false
true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。
false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
- MyBatis缓存查询的顺序
先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。如果二级缓存没有命中,再查询一级缓存如果一级缓存也没有命中,则查询数据库SqlSession关闭之后,一级缓存中的数据会写入二级缓存
整合第三方缓存EHCache
a>添加依赖
org.mybatis.caches mybatis-ehcache 1.2.1 ch.qos.logback logback-classic 1.2.3
b>各jar包功能
c>创建EHCache的配置文件ehcache.xml
d>xxxMapper.xml设置二级缓存的类型
e>加入logback日志
存在SLF4J时,作为简易日志的log4j将失效,此时我们需要借助SLF4J的具体实现logback来打印日志。
创建logback的配置文件logback.xml
[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n



