Mybatis项目创建
中文文档:https://mybatis.org/mybatis-3/zh/getting-started.html
Github: https://github.com/mybatis/mybatis-3/releases
Maven: http://maven.apache.org/
一、入门:
新建空Maven工程,删掉src
新建Module子工程
1. 父工程pom.xml文件
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--在 build 中配置 resource,来防止资源导出失败的问题-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
* 设置Maven 的路径
* 测试连接数据库:database + Data Source > mysql
问题1:连接不上
Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property manually.
解决:进入数据库:mysql -u root -p123456
设置时区:set global time_zone='+8:00';
2. Mybatis-config :MyBatis 核心配置文件
```java
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!---->
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true
&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--每一个Mapper.xml 都需要在 MyBatis 核心配置文件中注册-->
<mappers>
<mapper resource="com/fei/dao/UserMapper.xml"/>
</mappers>
</configuration>
```
3. 编写mybatis工具类
```java
// sqlSessionFactory ---> sqlSession
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
// 使用Mybatis第一步:获取 sqlSessionFactory 对象
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
// sqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
}
```
4. 编写代码 – 实体类,DAO接口
5. 接口实现类 ----Mapper配置文件
```java
<?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">
<!--namespace 绑定一个对应的Dao/Mapper接口-->
<mapper namespace="org.mybatis.example.BlogMapper">
<!--select 查询语句-->
<select id="getUserList" resultType="ocm.fei.pojo.User">
select * from mybatis.user
</select>
</mapper>
<!--
sql映射文件:sql语句,mybatis会执行这些sql
1、指定约束文件 mybatis-3-mapper.dtd
2、mapper:当前文件的根标签,必须的
namespace:命名空间,唯一值,可以是自定义的字符串,要求使用dao接口的全限定名称
3、select: 表示执行查询
update: 表示更新数据库的操作
insert: 表示插入
delete: 表示删除
-->
```
6. 测试类
```java
public class UserDaoTest {
@Test
public void test(){
// 1 获取 SqlSession 对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
// 2 方式一:getMapper
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.getUserList();
for (User user:userList){
System.out.println(user);
}
sqlSession.close();
}
}
```
7. 问题解决
错误1:
java.lang.ExceptionInInitializerError Error building SqlSession.
target/classes 中缺少 Mybatis-config
解决:<!--在 build 中配置 resource,来防止资源导出失败的问题-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
错误2:连接数据库错误
Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
Communications link failure
解决:
更换JDBC驱动:使用:com.mysql.cj.jdbc.Driver (需注意:需要指定时区serverTimezone:)
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true
&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/>
并且更换了连接驱动的版本 ,之前为 5.1的
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
原文链接:https://blog.csdn.net/L_it123/article/details/106845391
错误3:Caused by: com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException:
1 字节的 UTF-8 序列的字节 1 无效。
解决:UserMapper.xml 和 mybatis-config.xml 中 UTF-8 改为 UTF8
<?xml version="1.0" encoding="UTF8" ?>
-
增删改查
<mapper namespace="com.fei.dao.UserDao"> <!--select 查询语句--> <select id="getUserList" resultType="com.fei.pojo.User"> select * from mybatis.user </select> <!--查询--> <select id="getUserById" parameterType="int" resultType="com.fei.pojo.User"> select * from mybatis.user where id = #{id} </select> <!--插入, 对象中的属性,可以直接取出来--> <insert id="addUser" parameterType="com.fei.pojo.User"> insert into mybatis.user(id, name, pwd) values (#{id},#{name},#{pwd}) </insert> <!--修改--> <update id="updateUser" parameterType="com.fei.pojo.User"> update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id} </update> <!--删除--> <delete id="deleteUser" parameterType="int"> delete from mybatis.user where id=#{id} </delete> </mapper>
/** *@描述 增删改需要提交事务才能成功提交 *@参数 sqlSession.commit(); *@返回值 */ @Test public void addUser(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserDao mapper = sqlSession.getMapper(UserDao.class); int result = mapper.addUser(new User(4, "gg", "565")); if(result> 0){ System.out.println("提交成功"); } // 提交事务 sqlSession.commit(); sqlSession.close(); }
9. 万能的 Map
```java
int addUser2(Map<String,Object> map);
<!--万能的 Map :传递 Map 的 Key-->
<insert id="addUser2" parameterType="map">
insert into mybatis.user(id,name) values(#{userid},#{username})
</insert>
@Test
public void addUser2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
Map<String, Object> map = new HashMap<String, Object>();
map.put("userid",5);
map.put("username","dd"); // 可为空
int result = mapper.addUser2(map);
if(result>0){
System.out.println("提交成功");
}
sqlSession.commit();
sqlSession.close();
}
```
10. 模糊查询
1.java 代码执行的时候,传递通配符 %%
List<User> userList = mapper.getUserLike("%d%");
2.在 sql 拼接中使用通配符
select * from mybatis.user where name like "%"#{value}"%"
二、配置解析
1. mybatis-config.xml
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
2. 环境配置
事务管理器(transactionManager) 默认 JDBC
在 MyBatis 中有两种类型的事务管理器(也就是 type="[JDBC|MANAGED]"):
JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
数据源(dataSource)默认 POOLED
3. 属性
db.properties 优先使用
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true
&characterEncoding=UTF-8&serverTimezone=UTC
username=root
password=123456
在核心配置文件中引入
<properties resource="org/mybatis/example/config.properties">
<property name="username" value="root"/>
<property name="password" value="123456"/>
</properties>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
4. 类型别名
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
</typeAliases>
<typeAliases>
<package name="domain.blog"/>
</typeAliases>
@Alias("author")
public class Author {
...
}
5. 设置
6.映射器 (mappers)
方式一:
<!--每一个Mapper.xml 都需要在 MyBatis 核心配置文件中注册-->
<mappers>
<mapper resource="com/fei/dao/UserMapper.xml"/>
</mappers>
方式二:使用class文件绑定注册
<mappers>
<mapper class="com.fei.dao.UserMapper"/>
</mappers>
注意点:
1.接口和它的Mapper配置文件必须同名
2.接口和它的Mapper配置文件必须在同一个包下
方式三:使用扫描包进行注入绑定
<mappers>
<package name="com.fei.dao" />
</mappers>
注意点:
1.接口和它的Mapper配置文件必须同名
2.接口和它的Mapper配置文件必须在同一个包下
7. 生命周期和作用域
不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。
提示 对象生命周期和依赖注入框架
依赖注入框架可以创建线程安全的、基于事务的 SqlSession 和映射器,并将它们直接
注入到你的 bean 中,因此可以直接忽略它们的生命周期。
SqlSessionFactoryBuilder
这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。
因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)
SqlSessionFactory
可以理解为:数据库连接池
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。
因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。
SqlSession
连接到连接池的一个请求
每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域
使用完必须关闭
Mapper 代表一个具体的业务
8. 解决属性名和字段名不一致的问题
![null](https://img-blog.csdnimg.cn/2021063010210843.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81OTc3NDYyMA==,size_16,color_FFFFFF,t_70#pic_center)
解决:
1.起别名
```java
<select id="getUserById" parameterType="int" resultType="com.fei.pojo.User">
select id,name,pwd as password from mybatis.user where id = #{id}
</select>
```
2.resultMap
```java
<!--结果集映射-->
<resultMap id="userMap" type="user" >
<!--column 数据库中的字段,property 实体类中的属性
字段名相同的不需用显示地声明
-->
<!-- <result column="id" property="id" />-->
<!-- <result column="name" property="name" />-->
<result column="pwd" property="password" />
</resultMap>
<select id="getUserById" parameterType="int" resultMap="userMap">
select * from mybatis.user where id = #{id}
</select>
```
9. 日志
Mybatis 通过使用内置的日志工厂提供日志功能。内置日志工厂将会把日志工作委托给下面的实现之一:
SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING
掌握: LOG4J :
STDOUT_LOGGING :标准日志输出
<!--在主配置文件中设置-->
```java
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
```
LOG4J
导包:
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
```java
### 设置###
log4j.rootLogger = debug,stdout,D,E
### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = C://JAVA/log.log
log4j.appender.D.Append = true
log4j.appender.D.Encoding=UTF8
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} - [ %p ] %l %c %t - %m %n
### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =C://JAVA/error.log
log4j.appender.E.Append = true
log4j.appender.E.Encoding=UTF8
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} - [ %p ] %l %c %t - %m %n
```
简单使用
导包 import org.apache.log4j.Logger;
static Logger logger = Logger.getLogger(UserDaoTest.class);
日志级别
public void testLog4j(){
logger.info("info");
logger.debug("debug");
logger.error("error");
}
10. Limit分页
```java
List<User> getUserByLimit(Map<String,Integer> map);
<select id="getUserByLimit" parameterType="map" resultMap="userMap">
select * from mybatis.user limit #{startIndex},#{pageSize}
</select>
@Test
public void getUserByLimit(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("startIndex",0);
map.put("pageSize",3);
List<User> userList = mapper.getUserByLimit(map);
for(User user:userList){
System.out.println(user);
}
```
11. RowBounds分页
```java
List<User> getUserByRowBounds();
<select id="getUserByRowBounds" resultMap="userMap">
select * from mybatis.user
</select>
@Test
public void getUserByRowBounds(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
RowBounds rowBounds = new RowBounds(1, 2);
List<User> userList = sqlSession.selectList(
"com.fei.dao.UserMapper.getUserByRowBounds",null,rowBounds);
for(User user:userList){
System.out.println(user);
}
sqlSession.close();
}
```
12. 使用注解开发
```java
@Select("select * from user")
List<User> getUsers();
<!--绑定接口-->
<mappers>
<mapper class="com.fei.dao.UserMapper" />
</mappers>
```
13. Mybatis执行流程剖析
Resources获取加载全局配置文件
实例化SqlSessionFactoryBuilder构造器
解析文件流XMLConfigBuilder
Configuration所有的配置信息
SqlSessionFactory实例化
transactional事务管理器
创建executor执行器
创建sqlSession
实现CRUD
提交事务
关闭流
14. 增删改查
核心配置文件中绑定接口
设置自动提交事务
```java
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
```
编写接口,增加注解
```java
@Select("select * from user")
List<User> getUsers();
// 方法存在多个参数,使用 @Param
@Select("select * from user where id =#{id1}")
User getUserById(@Param("id1") int id,@Param("pwd") String password);
@Insert("insert into user(id,name,pwd) values (#{id},#{name},#{password})")
int addUser(User user);
@Update("update user set name=#{name},pwd=#{password} where id=#{id}")
int updateUser(User user);
@Delete("delete from user where id=#{id}")
int deleteUser(int id);
```
@Param()注解
基本数据类型的参数或String类型,需要加上
如果只有一个基本数据类型,可以省略
引用数据类型不用加
SQL中引用的就是Param()中设定的属性名
15.Lombok
在IDEA中安装Lombok插件
配置文件
```java
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
```
@Getter and @Setter
@FieldNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor
@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
@Data
@Builder
@SuperBuilder
@Singular
@Delegate
@Value
@Accessors
@Wither
@With
@SneakyThrows
@val
@var
experimental @var
实体类
@UtilityClass
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
三、多对一处理
1.核心配置文件
```java
<mappers>
<mapper class="com.fei.dao.StudentMapper"/>
<mapper class="com.fei.dao.TeacherMapper"/>
</mappers>
Student 属性
private int id;
private String name;
// 学生需要关联一个老师
private Teacher teacherS;
```
2.按照查询嵌套处理 子查询
```java
<!--方式一 按照查询嵌套处理 子查询-->
<select id="getStudent" resultMap="studentT">
select * from mybatis.student
</select>
<resultMap id="studentT" type="student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--复杂的属性:对象 association, 集合 collection-->
<association property="teacherS" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from mybatis.teacher where id =#{tid}
</select>
```
3.按照结果嵌套处理
```java
<!--方式二 按照结果嵌套处理-->
<select id="getStudent2" resultMap="studentT2">
select s.id sid,s.name sname,t.id tid,t.name tname
from student s,teacher t
where s.tid = t.id
</select>
<resultMap id="studentT2" type="student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacherS" javaType="teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
</association>
</resultMap>
```
四、一对多处理
1、接口
Teacher属性
private int id;
private String name;
// 一个老师有多个学生
private List<Student> Tstudents;
2、按照查询嵌套处理 子查询
```java
<!-- 按照查询嵌套处理 子查询-->
<select id="getTeacher2" resultMap="teacherS2">
select * from mybatis.teacher where id= #{id}
</select>
<resultMap id="teacherS2" type="teacher">
<result property="id" column="id"/>
<result property="name" column="name"/>
<collection property="Tstudents" javaType="ArrayList" ofType="Student"
select="stu" column="id"/>
</resultMap>
<select id="stu" resultType="student">
select * from mybatis.student where tid= #{id}
</select>
```
3.按照结果嵌套处理
```java
<!--方式一 按照结果嵌套处理-->
<select id="getTeacher" resultMap="teacherS">
select s.id sid,s.name sname,t.name tname,t.id tid
from student s,teacher t
where s.tid = t.id and t.id = #{id}
</select>
<resultMap id="teacherS" type="teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="Tstudents" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
```
4、总结
1、关联: association 多对一
2、集合: collection 一对多
3、javaType 用来指定实体类中的属性
ofType 用来指定泛型中的约束类型
五、动态SQL
```java
<!--namespace 绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.fei.dao.BlogMapper">
<!--插入数据-->
<insert id="addBlog" parameterType="blog">
insert into mybatis.blog(id, title, author, create_time, views) values (
#{id},#{title}, #{author}, #{createTime}, #{views})
</insert>
1、if
<!--if-->
<select id="queryBlogIf" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
2、choose、when、otherwise
<!--choose-->
<select id="queryBlogChoose" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
and author = #{author}
</when>
<otherwise>
and views = #{views}
</otherwise>
</choose>
</where>
</select>
3、trim、where、set
<!--set-->
<update id="updateBlog" parameterType="map">
update mybatis.blog
<set>
<if test="title != null">title=#{title},</if>
<if test="author != null">author=#{author}</if>
</set>
where id = #{id}
</update>
<!--trim 实现where set-->
<select id="queryBlogIf" parameterType="map" resultType="blog">
select * from mybatis.blog
<trim prefix="where" prefixOverrides="and |or">
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</trim>
<trim prefix="set" suffixOverrides=",">
...
</trim>
</select>
</mapper>
```
4、sql 片段
```java
<!--sql 片段-->
<sql id="if-title-author">
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>
<!--if-->
<select id="queryBlogIf" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<include refid="if-title-author"></include>
</where>
</select>
```
注意事项:
最好基于单表来定义sql片段
不要存在where标签
5、foreach
```java
<!--Foreach-->
<select id="queryBlogForeach" parameterType="map" resultType="Blog">
select * from mybatis.blog
<where>
<foreach collection="ids" item="id" open="(" separator="or" close=")">
id = #{id}
</foreach>
</where>
</select>
```
面试高频
MySQL引擎
InnoDB底层原理
索引
索引优化
六、缓存
1、一级缓存
缓存失效的情况:
1、查询不同的东西
2、增删改操作,可能会改变原来的数据,所以必定会刷新缓存
3、查询不同的Mapper.xml
4、手动清理缓存
```java
public void queryBlogIf(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
System.out.println("--------------------");
sqlSession.clearCache();
User user1 = mapper.queryUserById(1);
System.out.println(user1 == user);
sqlSession.close();
}
```
小结:
2、二级缓存
1.开启全局缓存
<!--显示的开启全局缓存-->
<setting name="cacheEnabled" value="true"/>
2.在要使用二级缓存的Mapper中开启
<!--在当前xml中使用二级缓存-->
<!-- <cache/>-->
<cache eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
3、注意
使用 <cache/> 需要序列化实体类
Caused by: java.io.NotSerializableException: com.fei.pojo.User
3、自定义缓存 ehcache
导包:
<!--ehcache-->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.0</version>
</dependency>