Mybatis之使用
一、Mybatis是什么?
Mybatis是一个基于Java的持久层框架,内部封装类JDBC,让开发人员只需要关注sql语句本身,不需要花费精力在驱动的加载、连接的创建、Statement的创建等复杂的过程。Mybatis通过XML或注解的方式将要执行的各种statement配置起来,并通过Java对象和statement中的sql动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql语句,并将结果直接映射为Java对象。
Mybatis采用ORM(对象关系映射)思想解决了实体类和数据库表映射的问题。对JDBC进行了封装,屏蔽了JDBC API底层的访问细节。
二、小试牛刀
1.创建表
CREATE TABLE `student` (
`studentid` int NOT NULL AUTO_INCREMENT,
`studentname` varchar(10) NOT NULL,
`studentsex` varchar(5) NOT NULL,
`studentage` int(5) NOT NULL,
`studenttel` varchar(20) NOT NULL,
PRIMARY KEY (`studentid`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
2.新建maven项目并导入依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
3.编写mybaitis的配置文件
配置文件头可以在Mybatis参考文档查找
Mybatis参考文档
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--配置mybatis的环境-->
<environments default="dev">
<environment id="dev">
<!--事务类型-->
<transactionManager type="JDBC"></transactionManager>
<!--使用连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/dm?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
</configuration>
4.编写实体类
实体类中属性需要和表的列名保持一致
public class Student {
private Integer studentId;
private String studentName;
private String studentSex;
private Integer studentAge;
private String studentTel;
//setter、getter、toString
}
5.编写ORM映射文件
<?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.dmlll.pojo.Student">
<!--MappedStatement
id:MappedStatement名称
resultType:返回值类型
parameterType:参数类型
-->
<select id="selectAll" parameterType="int" resultType="com.dmlll.pojo.Student">
select * from student
</select>
</mapper>
6.在mybatis配置文件注册映射文件
<!--environments下方-->
<mappers>
<mapper resource="com/dmlll/pojo/Student.xml"></mapper>
</mappers>
6.1映射文件放置在哪
- Student.xml可以放在与实体类同一目录,但是此时需要在pom.xml中添加一段配置
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include><!--正常maven项目只在resources下加载配置文件,如果想要放在main下,则需让他加载-->
</includes>
</resource>
</resources>
</build>
2. 可以放在resources目录下与Java目录相同
- 也可以直接放在resources目录下
此时在mybatis配置文件配置时resource需要改变
<mappers>
<mapper resource="Student.xml"></mapper>
</mappers>
7.编写测试方法
@Test
public void test() throws IOException {
Reader reader = Resources.getResourceAsReader("mybatis.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sessionFactory.openSession();
//命名空间+MappedStatement名称
List<Student> students = session.selectList("com.dmlll.pojo.Student.selectAll");
students.forEach(student -> System.out.println(student));
}
添条数据测试
三、对象分析
1.Resources
读取资源文件
2.SqlSessionFactoryBuilder
创建SqlSessionFactory,使用他的build()方法。
3.SqlSessionFactory
SqlSessionFactory接口对象是一个重量级对象,是线程安全的,所以一个应用只需要一个该对象即可。创建SqlSession需要使用SqlsessionFactory接口的openSession()方法
4.SqlSession
SqlSession接口对象用于执行持久化操作。一个SqlSession对应着一次数据库会话,一次会话以SqlSession对象的创建开始,以SqlSession对象的关闭结束。
SqlSession接口对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其close()方法,将其关闭。再次需要会话,再次创建。
5.执行过程
- Mybatis.xml文件是mybatis的全局配置文件,配置了mybatis框架运行的环境等信息。
映射文件配置了所有操作数据库的sql语句,这些文件也会随着配置文件中加载 - 通过mybatis环境等配置信息构建SqlSessionFactory,相当于产生了连接池
- 由会话工厂创建SqlSession即会话,操作数据库需要通过SqlSession进行
- Mybatis底层自定义了Executor执行器的接口操作数据库,Executor接口有两个实现,一个是基本的执行器,一个是缓存的执行器
- MappedStatement也是mybatis框架一个底层的封装对象,他包装了mybaits配置信息以及sql的映射信息。Mapper.xml文件是一个文件中一个sql语句对应一个MappedStatement对象,sql的id就是MappedStatement的id
- MappedStatement对sql执行输入参数的定义,输入参数包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql语句前将输入java对象映射到sql语句中,执行sql完毕后,输出映射就是JDBC编码中的对preparedStatement执行结果的定义
四、配置日志文件
1.添加jar依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2.添加日志配置文件
<!--environments之前-->
<settings>
<setting name="logImpl" value="log4j"/>
</settings>
3.结果展示
五、使用Mapper的接口编写Mybatis项目
1.编写StudentMapper.java
public interface StudentMapper {
List<Student> selectAll();
}
2.编写StudentMapper.xml
注意:此时的命名空间跟Student.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.dmlll.mapper.StudentMapper">
<select id="selectAll" resultType="com.dmlll.pojo.Student">
select * from student
</select>
</mapper>
3.在mybatis.xml中配置映射文件
<mappers>
<mapper resource="StudentMapper.xml"></mapper>
</mappers>
4.编写测试类
public class Tests2 {
SqlSession sqlSession = null;
@Before
public void init() throws IOException {
Reader reader = Resources.getResourceAsReader("mybatis.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(reader);
sqlSession = build.openSession();
}
@Test
public void test1(){
//通过SqlSession获得mapper,动态代理获得一个接口的实现类
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//调用实现类方法
List<Student> students = mapper.selectAll();
students.forEach(student -> System.out.println(student));
sqlSession.close();
}
}
5.展示结果
6.getMapper实现原理
六、映射文件编写
1.获取自增主键
前提:主键自增
1.1正常返回
实体类就使用之前的Student
1.1.1向StudentMapper.java添加方法
int add(Student student);
1.1.2向StudentMapper.xml添加sql语句
<insert id="add" parameterType="com.dmlll.pojo.Student">
INSERT INTO `dm`.`student` (`studentname`, `studentsex`, `studentage`, `studenttel`)
VALUES (#{studentName}, #{studentSex}, #{studentAge}, #{studentTel});
</insert>
1.1.3编写测试方法
@Test
public void test2(){
//通过SqlSession获得mapper,动态代理获得一个接口的实现类
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//调用实现类方法
Student student = new Student();
student.setStudentAge(18);
student.setStudentName("红孩儿");
student.setStudentSex("男");
student.setStudentTel("123456");
int res = mapper.add(student);
sqlSession.commit();
System.out.println(res);
}
1.1.4展示结果
主键依旧为空
1.2主键为数字自增1
1.2.1修改StudentMapper.xml
<!--
useGeneratedKeys:表示生成主键
keyProperty:主键填充到pojo的哪个字段
-->
<insert id="add" parameterType="com.dmlll.pojo.Student" useGeneratedKeys="true" keyProperty="studentId">
INSERT INTO `dm`.`student` (`studentname`, `studentsex`, `studentage`, `studenttel`)
VALUES (#{studentName}, #{studentSex}, #{studentAge}, #{studentTel});
</insert>
1.2.2展示结果
其他不变,只改变mapper,可以看到主键被填充了
1.3主键为数字自增2
1.3.1修改StudentMapper.xml
<!--
selectKey:声明在添加语句执行前后查询最后插入的id,返回到哪
keyProperty:返回到pojo的studentId
order:在插入语句之后执行(Mysql是先插入在生成主键)
last_insert_id():mysql内置函数,查询最后插入的主键
-->
<insert id="add" parameterType="com.dmlll.pojo.Student">
<selectKey keyProperty="studentId" order="AFTER" resultType="java.lang.Integer">
select last_insert_id()
</selectKey>
INSERT INTO `dm`.`student` (`studentname`, `studentsex`, `studentage`, `studenttel`)
VALUES (#{studentName}, #{studentSex}, #{studentAge}, #{studentTel});
1.2.3展示结果
1.4主键为varchar类型获取
1.4.1 新建表
CREATE TABLE `student2` (
`studentid` varchar(40) NOT NULL ,
`studentname` varchar(10) NOT NULL,
`studentsex` varchar(5) NOT NULL,
`studentage` int(5) NOT NULL,
`studenttel` varchar(20) NOT NULL,
PRIMARY KEY (`studentid`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
1.4.2 复制Student.java并修改
public class Student2 {
private String studentId;
private String studentName;
private String studentSex;
private Integer studentAge;
private String studentTel;
//setter、getter、toString
}
1.4.3 向StudentMapper.java添加方法
一般一个Mapper对一个pojo操作,这里偷点懒在一个Mapper进行操作
int add2(Student2 student2);
1.4.3 修改StudentMapper.xml
<!--
插入之前先获取36位字符串存在studentId
因为主键不是数字自增,所以需要先获取主键,然后添加
-->
<insert id="add2" parameterType="com.dmlll.pojo.Student2">
<selectKey keyProperty="studentId" order="BEFORE" resultType="java.lang.String">
select uuid()
</selectKey>
INSERT INTO `dm`.`student2` (`studentid`,`studentname`, `studentsex`, `studentage`, `studenttel`)
VALUES (#{studentId}, #{studentName}, #{studentSex}, #{studentAge}, #{studentTel});
</insert>
1.4.4 添加测试方法
@Test
public void test3(){
//通过SqlSession获得mapper,动态代理获得一个接口的实现类
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//调用实现类方法
Student2 student = new Student2();
student.setStudentAge(18);
student.setStudentName("红孩儿");
student.setStudentSex("男");
student.setStudentTel("123456");
int res = mapper.add2(student);
sqlSession.commit();
System.out.println("结果条数:"+res);
System.out.println("student:"+student);
}
1.4.5 展示结果
七、映射
1. 输入映射parameterType
parameterType:接口中方法参数的类型,类型必须是完全限定名或者别名。该属性非必须,因为Mybatis能够自行推断出传入参数的类型
1.1 单个参数
单个参数直接指定参数即可
Student selectById(Integer id);
mapper中parameterType可省略,传递的参数名随便写也可以
<select id="selectById" resultType="com.dmlll.pojo.Student">
select * from student where studentid = #{abc}
</select>
编写测试方法
@Test
public void test4() {
//通过SqlSession获得mapper,动态代理获得一个接口的实现类
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = mapper.selectById(1);
System.out.println(student);
}
查看结果
1.2 多个参数指定参数名
多个参数如果要指定参数名则需要使用@Param注解
List<Student> selectByNameAndAge(@Param("name") String name,@Param("age") Integer age);
<!--concat连接字符串-->
<select id="selectByNameAndAge" resultType="com.dmlll.pojo.Student">
select * from student where studentname like concat('%',#{name},'%') and studentage> #{age};
</select>
@Test
public void test5() {
//通过SqlSession获得mapper,动态代理获得一个接口的实现类
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.selectByNameAndAge("红", 10);
for (Student student : students) {
System.out.println(student);
}
}
1.2 多个参数不指定参数名
List<Student> selectByNameAndAge2(String name,Integer age);
此时在使用之前指定的名称则会报错
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.apache.ibatis.binding.BindingException: Parameter 'name' not found. Available parameters are [arg1, arg0, param1, param2]
### Cause: org.apache.ibatis.binding.BindingException: Parameter 'name' not found. Available parameters are [arg1, arg0, param1, param2]
报错信息告诉我们可以使用[arg1, arg0, param1, param2]表示。
尝试一下
<select id="selectByNameAndAge2" resultType="com.dmlll.pojo.Student">
select * from student where studentname like concat('%',#{arg0},'%') and studentage > #{arg1};
</select>
可以得到正确的结果
<select id="selectByNameAndAge2" resultType="com.dmlll.pojo.Student">
select * from student where studentname like concat('%',#{param1},'%') and studentage > #{param2};
</select>
这种的也可以
2.输出映射
1.1resultType
resultType:执行sql得到ResultSet转换的类型,使用类型的完全限定名或者别名。如果返回的是集合,设置集合元素的类型,而不是集合本身。
1.1.1输出基本类型
int selectCount();
<select id="selectCount" resultType="java.lang.Integer">
select count(studentid) from student
</select>
@Test
public void test8() {
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
int students = mapper.selectCount();
System.out.println(students);
}
1.1.2输出pojo类型
之前已经演示,这里不在赘述
1.1.3输出Map类型
Map<String,Object> selectStudentAll();
<!--查一条-->
<select id="selectStudentAll" resultType="java.util.HashMap">
select * from student limit 1
</select>
@Test
public void test9() {
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Map<String, Object> students = mapper.selectStudentAll();
System.out.println(students);
}
1.2数据库与列名不一致
1.1.1使用别名
1.1.2使用resultMap
1.3resultMap
CREATE TABLE `student` (
`student_id` int NOT NULL,
`student_name` varchar(10) NOT NULL,
`student_sex` varchar(5) NOT NULL,
`student_age` int(5) NOT NULL,
`student_tel` varchar(20) NOT NULL,
PRIMARY KEY (`studentid`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
<select id="selectStudentAll" resultMap="base">
select * from student limit 1
</select>
<resultMap id="base" type="com.dmlll.pojo.Student">
<id property="studentId" column="student_id" />
<result property="studentName" column="student_name"/>
.....
</resultMap>
3. #{} 和 ${}的区别
1.1 #{}
#{}:表示一个占位符,通知mybatis使用实际的值代替。并使用PreparedStatement对象执行sql语句。#{}代替了?。这个是mybatis的首选做法,安全迅速,避免sql注入。
1.2${}
${}:表示字符串原样替换,通知mybatis替换使用$包含的字符串,一般用在替换表名,列名,不同列排序等
List<Student> selectByColumn(@Param("columnName") String columnName,@Param("columnValue") String columnValue);
<select id="selectByColumn" resultType="com.dmlll.pojo.Student">
select * from student where ${columnName} like concat('%',#{columnValue},'%')
</select>
@Test
public void test7() {
//通过SqlSession获得mapper,动态代理获得一个接口的实现类
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.selectByColumn("studentname", "红");
for (Student student : students) {
System.out.println(student);
}
}
八、全局配置文件
1.文件头部约束
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
2.配置文件内容
configuration(配置)
properties--属性:加载外部的配置文件,例如加载数据库的连接信息
Settings--全局配置参数:例如日志配置
typeAliases--类型别名
typeHandlers----类型处理器
objectFactory-----对象工厂
Plugins------插件:例如分页插件
Environments----环境集合属性对象
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
Mappers---映射器:注册映射文件用
3.自定义别名
<!--自定义类型别名-->
<typeAliases>
<!--对单个的实体类定义别名-->
<typeAlias type="com.dmlll.pojo.Student" alias="Student"/>
<!--推荐写法:批量定义别名:扫描指定包下的所有类,同时别名定义为类名,别名的首字母大小写都可以-->
<package name="com.dmlll.pojo"/>
</typeAliases>
4.Mappers
1.使用相对于类路径的资源引用
语法:<mapper resource=""/>
使用相对于类路径的资源,从 classpath 路径查找文件
例如:<mapper resource="com/kkb/mapper/TeamMapper.xml" />
2.使用映射器接口实现类的完全限定类名
语法:<mapper class=""/>
使用的mapper接口的完全限定名
要求:接口和映射文件同包同名
例如<mapper class="com.kkb.mapper.GameRecordMapper"/>
3.将包内的映射器接口实现全部注册为映射器
语法:<package name=""/>
指定包下的所有Mapper接口
如:<package name="com.kkb.mapper"/>
注意:此种方法要求 Mapper接口名称和 mapper 映射文件名称相同,且在同一个目录中。
5.事务
Mybatis默认事务手动提交,如果自动提交可以在获取SqlSession是指定参数
sqlSessionFactory.openSession(true)
九、映射关系
CREATE TABLE `class` (
`classid` varchar(10) NOT NULL,
`classname` varchar(20) NOT NULL,
PRIMARY KEY (`classid`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
INSERT INTO `dm`.`class` (`classid`, `classname`) VALUES ('1', '西游一班');
CREATE TABLE `student` (
`studentid` varchar(10) NOT NULL,
`studentname` varchar(10) NOT NULL,
`studentsex` varchar(5) NOT NULL,
`studentage` int(5) NOT NULL,
`studenttel` varchar(20) NOT NULL,
`studentclass` varchar(10) NOT NULL,
PRIMARY KEY (`studentid`) USING BTREE,
KEY `studentclass` (`studentclass`) USING BTREE,
CONSTRAINT `student_ibfk_1` FOREIGN KEY (`studentclass`) REFERENCES `class` (`classid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
INSERT INTO `dm`.`student` (`studentid`, `studentname`, `studentsex`, `studentage`, `studenttel`, `studentclass`) VALUES ('1', '孙悟空', '男', '1', '1', '1');
public class Student {
private Integer studentId;
private String studentName;
private String studentSex;
private Integer studentAge;
private String studentTel;
private Integer studentClass;
private Clazz clazz;//多对一
}
public class Clazz {
private String classId;
private String className;
private List<Student> students;
}
1.多对一
Student selectById(Integer id);
<select id="selectById" resultMap="baseEntity">
<!--两表连接找出字段-->
select * from student,class where studentclass = classid and studentid = #{abc}
</select>
<resultMap id="baseEntity" type="com.dmlll.pojo.Student">
<id property="studentId" column="studentId" />
<result property="studentName" column="studentName"/>
<result property="studentSex" column="studentSex"/>
<result property="studentAge" column="studentAge"/>
<result property="studentTel" column="studentTel"/>
<result property="studentClass" column="studentClass"/>
<!--
如果有Clazz的resultMap也可以使用
<association property="clazz" resultMap="clazz的resultMap路径">
-->
<association property="clazz" javaType="com.dmlll.pojo.Clazz" column="studentClass" >
<id property="classId" column="classId" />
<result property="className" column="className"/>
</association>
</resultMap>
2.一对多
Clazz selectById(Integer id);
<select id="selectById" resultMap="baseEntity">
select * from student,class where studentclass = classid and classid = #{abc}
</select>
<resultMap id="baseEntity" type="com.dmlll.pojo.Clazz">
<id property="classId" column="classId" />
<result property="className" column="className"/>
<collection property="students" ofType="com.dmlll.pojo.Student">
<id property="studentId" column="studentId" />
<result property="studentName" column="studentName"/>
<result property="studentSex" column="studentSex"/>
<result property="studentAge" column="studentAge"/>
<result property="studentTel" column="studentTel"/>
<result property="studentClass" column="studentClass"/>
</collection>
</resultMap>
十、动态SQL
偷个懒,直接贴mapper
1.where
<select id="queryByVO" parameterType="QueryVO" resultMap="baseResultMap">
select * from team
<where>
<!-- 如果用户输入了名称,就模糊查询 and teamName like '%?%'-->
<if test="name!=null ">
and teamName like concat(concat('%',#{name}),'%')
</if>
<if test="beginTime!=null ">
and createTime>=#{beginTime}
</if>
<if test="endTime!=null ">
and createTime<=#{endTime}
</if>
<if test="location!=null ">
and location=#{location}
</if>
</where>
</select>
2.set
<update id="update1" parameterType="com.kkb.pojo.Team">
update team
<set>
<if test="teamName!=null">
teamName=#{teamName},
</if>
<if test="location!=null">
location=#{location},
</if>
<if test="createTime!=null">
createTime=#{createTime},
</if>
</set>
where teamId=#{teamId}
</update>
3. forEach
<insert id="addList" parameterType="arraylist">
INSERT INTO team (teamName,location) VALUES
<!--collection:要遍历的集合;参数是集合类型,直接写list
item:遍历的集合中的每一个数据
separator:将遍历的结果用,分割-->
<foreach collection="list" item="t" separator=",">
(#{t.teamName},#{t.location})
</foreach>
</insert
十一、分页插件
1.引入依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
2.配置插件
<!--environments之前-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
3.测试方法
@Test
public void test10() {
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
PageHelper.startPage(1,2);//查询语句之前
List<Student> students = mapper.selectAll();
PageInfo pageInfo = new PageInfo(students);//查询语句之后
System.out.println("总数:"+pageInfo.getTotal());
for (Student student : students) {
System.out.println(student);
}
}
十二、Mybatis缓存简介
1.作用
提升查询的效率和减少数据库的压力。将经常查询的数据存在缓存(内存)中,用户查询该数据的时候不需要从磁盘(关系型数据库文件)上查询,而是直接从缓存中查询,提高查询效率,解决高并发问题。
2.一级缓存
自动开启,SqlSession级别的缓存
读取的数据写入缓存,下次查询相同的数据不需要在查询数据库,如果发生增删改或提交回滚或sqlSession关闭都会清空缓存
清空缓存:
1、 session.clearCache( ) ;
2、 execute update(增删改) ;
3、 session.close( );
4、 xml配置 flushCache=“true” ;
5、 rollback;
6、 commit。
3.二级缓存
默认关闭,Mapper级别
多个SqlSession去操作一个Mapper的sql语句,得到的数据会存放在二级缓存,多个SqlSession共享二级缓存。
二级缓存是多个SqlSession共享的,其作用域是mapper的同一namespace。
不同的sqlSession两次执行相同namespace下的sql语句参数相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。
开启二级缓存
//mybatis.xml
<setting name="cacheEnabled" value="true"/>
//需要开启缓存的mapper.xml
<cache></cache>
mapper中的statement想要禁用
useCache=false
缓存的属性配置
<cache>
<property name="eviction" value="LRU"/><!--回收策略为LRU-->
<property name="flushInterval" value="60000"/><!--自动刷新时间间隔为60S-->
<property name="size" value="1024"/><!--最多缓存1024个引用对象-->
<property name="readOnly" value="true"/><!--只读-->
</cache>
没时间了,草草收尾,抱歉