缓存的出现目的就是减少于数据库之间频繁的连接操作,当数据成千上万的时候这样的操作会极大的浪费时间,所以缓存的出现解决了这个问题。
mybatis中有一级缓存和二级缓存,一级缓存就是本地的会话缓存,其是自动开启的,它存在于一个sqlSession的运行中,即当sqlSession.close()时就结束了。
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>
<properties resource="db.properties"></properties>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="com.li.pojo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.li.dao"/>
</mappers>
</configuration>
我们利用一个user来进行简单的验证缓存
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
private int id;
private String name;
private String pwd;
}
//UserMapper.java
public interface UserMapper {
User getUserById(@Param("id") int id);
int updateUser(User user);
}
这是UserMapper.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.li.dao.UserMapper">
<select id="getUserById" resultType="user">
select * from user where id=#{id};
</select>
<update id="updateUser" parameterType="user" >
update user set name=#{name},pwd=#{pwd} where id=#{id};
</update>
</mapper>
我们现在来测试一下
@Test
public void qq(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = mapper.getUserById(1);
System.out.println(user1);
System.out.println("============");
User user2 = mapper.getUserById(1);
System.out.println(user2);
sqlSession.close();
}
得到的结果
可以从结果看到,第一次执行的时候进行了查表,而第二次没有,这是因为第一次查出来之后就放入了缓存。
那么什么时候缓存会发生变化呢?
1.进行了增删改之后,因为这时缓存中的数据在数据库中是可能变化的,我们进行一个updateUser的操作来进行验证。
@Test
public void qq(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = mapper.getUserById(1);
System.out.println(user1);
System.out.println("==========update");
mapper.updateUser(new User(2,"2号","1233"));
System.out.println("============");
User user2 = mapper.getUserById(1);
System.out.println(user2);
sqlSession.close();
}
一张图没放下,就截了两次
从日志中可以看出,进行了修改操作之后,当我们再次查询时又进行了连表操作。
2.第二种当然就是进行清楚缓存的操作了
@Test
public void qq(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = mapper.getUserById(1);
System.out.println(user1);
sqlSession.clearCache();
System.out.println("============");
User user2 = mapper.getUserById(1);
System.out.println(user2);
sqlSession.close();
}
如图所示,便是如此。
二级缓存的话需要手动开启,一共是两步
第一步是在核心配置文件中
<setting name="cacheEnabled" value="true"/>
第二步是在mapper的xml文件中加上
<mapper namespace="com.li.dao.UserMapper">
<cache/>
如此就开启了二级缓存,二级缓存就是说当一级缓存完蛋或者说你将sqlSession关闭之后,其中的数据会放到二级缓存中。
@Test
public void qq1(){
SqlSession sqlSession1 = MybatisUtils.getSqlSession();
SqlSession sqlSession2 = MybatisUtils.getSqlSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.getUserById(1);
System.out.println(user1);
System.out.println("============");
sqlSession1.close();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.getUserById(1);
System.out.println(user2);
sqlSession2.close();
}
运行之后:
这个错误是因为没有对实体类进行序列化,所以一般尽量将pojo序列化,原因建议百度。
如图,只进行了一次查表操作。