mybatis有缓存机制,且有两级缓存机制,默认是一级缓存,二级缓存需要手动开启.
一级缓存是sqlsession级别的缓存
二级缓存是mapper级别的缓存
缓存的目的: 提供查询效率.
一级缓存
一级缓存是默认开启.是sqlsession级别
** 原理:**
原理:
一级缓存,在每个SqlSession内部有个Map结构用于存储查询到的结果.将查询的方法名、参数名等信息组合成一个map的key;查询到的结果,当成map的value。
演示命中缓存:
演示不命中缓存:
// 3 创建出sqlsession
SqlSession sqlSession1 = sqlSessionFactory.openSession( );
SqlSession sqlSession2 = sqlSessionFactory.openSession( );
// 4.1 获得代理对象
UserMapper mapper = sqlSession1.getMapper(UserMapper.class);
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
// 4.2 执行
User user = mapper.findUserById(1);
System.out.println(user );
System.out.println("--------------" );
User user2 = mapper2.findUserById(1);
System.out.println(user2 );
sqlSession1.close();
sqlSession2.close();
清空缓存
增删改时会将缓存清空:
@Test
public void selectOne2() throws IOException {
String path = "sqlmapfconfig.xml";
// 1 加载配置文件
InputStream stream = Resources.getResourceAsStream(path);
// 2 通过配置文件,创建sqlsession工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder( ).build(stream);
// 3 创建出sqlsession
SqlSession sqlSession1 = sqlSessionFactory.openSession( );
// 4.1 获得代理对象
UserMapper mapper = sqlSession1.getMapper(UserMapper.class);
// 4.2 执行
User user = mapper.findUserById(1);
System.out.println(user );
System.out.println("--------------" );
mapper.update2("李思思",3);
sqlSession1.commit();
System.out.println("--------------" );
User user2 = mapper.findUserById(1);
System.out.println(user2 );
sqlSession1.close();
}
二级缓存:
二级缓存是mapper级别.
原理:
开启二级缓存:
1.需要在全局配置文件,设置开启二级缓存:
2.在需要二级缓存的mapper.xml文件开启二级缓存
创建实体类:
package com.zzx.model;
import java.io.Serializable;
import java.util.Date;
/**
* @auther ZhengZiXuan
* @date 2021/3/9 14:59
* @desc
*/
public class Student implements Serializable {
private Integer sid;
private String sname;
private Float score;
private Integer cid;
private Date sbirthday;
private Integer zid;
private Class aclass;
public Student(Integer sid, String sname, Float score, Integer cid, Date sbirthday, Integer zid, Class aclass) {
this.sid = sid;
this.sname = sname;
this.score = score;
this.cid = cid;
this.sbirthday = sbirthday;
this.zid = zid;
this.aclass = aclass;
}
public Student() {
}
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Float getScore() {
return score;
}
public void setScore(Float score) {
this.score = score;
}
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public Date getSbirthday() {
return sbirthday;
}
public void setSbirthday(Date sbirthday) {
this.sbirthday = sbirthday;
}
public Integer getZid() {
return zid;
}
public void setZid(Integer zid) {
this.zid = zid;
}
public Class getAclass() {
return aclass;
}
public void setAclass(Class aclass) {
this.aclass = aclass;
}
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", sname='" + sname + '\'' +
", score=" + score +
", cid=" + cid +
", sbirthday=" + sbirthday +
", zid=" + zid +
", aclass=" + aclass +
'}';
}
}
package com.zzx.model;
/**
* @auther ZhengZiXuan
* @date 2021/3/9 15:03
* @desc
*/
public class Class {
private Integer cid;
private String cname;
private Student student;
public Class(Integer cid, String cname, Student student) {
this.cid = cid;
this.cname = cname;
this.student = student;
}
public Class() {
}
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
@Override
public String toString() {
return "Class{" +
"cid=" + cid +
", cname='" + cname + '\'' +
", student=" + student +
'}';
}
}
创建db.properties:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/dog
jdbc.username=root
jdbc.password=123456
创建sqlconfigtion.xml
<?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>
<!--加载配置文件-->
<properties resource="db.properties"></properties>
<!--添加缓存-->
<settings>
<setting name="cacheEnabled" value="true"/>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
<!--开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
<!--类型别名-->
<typeAliases>
<!--每个单独的类取别名-->
<!--<typeAlias type=""alias=""/>-->
<!--给包下的所有类起别名-->
<package name="com.zzx"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--第一种写法-加载包下指定是映射文件 -->
<!--<mapper resource="com/zzx/mapper/UserMapper.xml"/>-->
<!--第二种写法-加载包下的所有的映射文件 -->
<package name="com.zzx.mapper"/>
</mappers>
</configuration>
创建StudentMapper接口:
package com.zzx.mapper;
import com.zzx.model.Class;
import com.zzx.model.Student;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @auther ZhengZiXuan
* @date 2021/3/8 11:41
* @desc
*/
public interface StudentMapper {
List<Student> findById(int id);
void update(@Param("sname") String name, @Param("sid") int id);
}
创建StudentMapper.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.zzx.mapper.StudentMapper">
<!--开启当前mapper的二级缓存
默认使用的是mybatis自己提供的缓存处理类perpetualcache-->
<cache></cache>
<select id="findById" parameterType="int" resultType="Student">
select * from student where sid =#{id}
</select>
<update id="update" parameterType="Map" >
update student set sname=#{sname} where sid=#{sid}
</update>
</mapper>
创建测试类测试:
package com.zzx.test;
import com.zzx.mapper.StudentMapper;
import com.zzx.model.Class;
import com.zzx.model.Student;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @auther ZhengZiXuan
* @date 2021/3/9 15:21
* @desc
*/
public class MainClass1 {
@Test
public void 二级缓存() throws IOException {
String path = "sqlconfigtion.xml";
// 1 加载配置文件
InputStream stream = Resources.getResourceAsStream(path);
// 2 通过配置文件,创建sqlsession工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder( ).build(stream);
// 3 创建出sqlsession
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
SqlSession sqlSession3 = sqlSessionFactory.openSession();
SqlSession sqlSession4 = sqlSessionFactory.openSession();
//4.1 获得代理对象
StudentMapper mapper1 = sqlSession1.getMapper(StudentMapper.class);
StudentMapper mapper2 = sqlSession2.getMapper(StudentMapper.class);
StudentMapper mapper3 = sqlSession3.getMapper(StudentMapper.class);
StudentMapper mapper4 = sqlSession4.getMapper(StudentMapper.class);
//4.2 执行
List<Student> stu1 = mapper1.findById(10);
System.out.println(stu1);
sqlSession1.close();
System.err.println("-------------------------第一次查询出来的-----------------------------------");
List<Student> stu2 = mapper2.findById(10);
System.out.println(stu2);
sqlSession2.close();
System.err.println("-------------------------第二次查询出来的-----------------------------------");
mapper3.update("风马",10);
sqlSession3.commit();
System.err.println("-------------------------第三次查询出来的-----------------------------------");
List<Student> stu4 = mapper4.findById(10);
System.out.println(stu4);
sqlSession4.close();
System.err.println("-------------------------第四次查询出来的-----------------------------------");
}
}
ps:由于中间调用修改方法,所以会再次使用查询方法,但是再次查询的时候,就不会再调用SQL查询了,会直接在缓存中取数据