本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1.二级缓存
-
为什么需要缓存
拉高程序的性能
-
什么样的数据需要缓存
很少被修改或根本不改的数据
业务场景比如:耗时较高的统计分析sql、电话账单查询sql等
-
ehcache是什么
Ehcache 是现在最流行的纯Java开源缓存框架,配置简单、结构清晰、功能强大
注1:本章介绍的是2.X版本,3.x的版本和2.x的版本API差异比较大
-
ehcache的特点
4.1 够快
Ehcache的发行有一段时长了,经过几年的努力和不计其数的性能测试,Ehcache终被设计于large, high concurrency systems.
4.2 够简单
开发者提供的接口非常简单明了,从Ehcache的搭建到运用运行仅仅需要的是你宝贵的几分钟。其实很多开发者都不知道自己用在用Ehcache,Ehcache被广泛的运用于其他的开源项目
4.3 够袖珍
关于这点的特性,官方给了一个很可爱的名字small foot print ,一般Ehcache的发布版本不会到2M,V 2.2.3 才 668KB。
4.4 够轻量
核心程序仅仅依赖slf4j这一个包,没有之一!
4.5 好扩展
Ehcache提供了对大数据的内存和硬盘的存储,最近版本允许多实例、保存对象高灵活性、提供LRU、LFU、FIFO淘汰算法,基础属性支持热配置、支持的插件多
4.6 监听器
缓存管理器监听器 (CacheManagerListener)和 缓存监听器(CacheEvenListener),做一些统计或数据一致性广播挺好用的
4.7 分布式缓存
从Ehcache 1.2开始,支持高性能的分布式缓存,兼具灵活性和扩展性
3. ehcache的使用
3.1 导入相关依赖
3.2 核心接口
CacheManager:缓存管理器
Cache:缓存对象,缓存管理器内可以放置若干cache,存放数据的实质,所有cache都实现了Ehcache接口
Element:单条缓存数据的组成单位
它指的是Mybatis中SqlsessionFactory对象的缓存,由同一个SqlSessionFactory对象创建,其中创建的SqlSession共享其缓存
二级缓存的使用步骤:
- 1.让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
- 2.让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
- 3.让当前的操作支持二级缓存(在select标签中配置)
<?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属性:用于指定配置文件的位置,是按照类路径的写法来写平且必须存在与类路径下
-->
<properties resource="jdbcConfig.properties">
</properties>
<!--配置参数延迟加载-->
<settings>
<!--开启mybatis支持延迟加载-->
<setting name="cacheEnabled" value="true"/><!--开启二级缓存-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境-->
<environment id="mysql">
<!--配置事物类型-->
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<!--配置连接数据库的4个信息-->
<property name="driver" value="${jdbc.driver}"/>
<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/mybatisD/dao/IUserDao.xml"/>
<mapper resource="com/mybatisD/dao/IAccountDao.xml"/>
</mappers>-->
<!--如果要是用注解来配置的话,此处应该使用class属性指定被注解的dao全限定类名-->
<!--<mappers>
<mapper class="com.mybatisD.dao.IUserDao"/>
</mappers>-->
<mappers >
<!--package标签用于指定doa接口所在的包,当指定了之后就不需要在写mapper以及resource或者class了-->
<package name="com.mybatisD.dao"/>
</mappers>
</configuration>
配置IUserDao.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.mybatisD.dao.IUserDao">
<!--开启User支持二级缓存-->
<cache/>
<!--配置查询所有-->
<select id="findAll" resultType="com.mybatisD.domain.User" useCache="true">
select * from user
</select>
<!--根据ID查询用户-->
<select id="findById" parameterType="INT" resultType="com.mybatisD.domain.User">
select * from user where id=#{userid}
</select>
</mapper>
测试方法
package com.mybatisJ.test;
import com.mybatisD.dao.IUserDao;
import com.mybatisD.domain.User;
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.InputStream;
import java.util.Date;
import com.mybatisD.dao.IAccountDao;
import com.mybatisD.dao.IUserDao;
import com.mybatisD.domain.Account;
import com.mybatisD.domain.AccountUser;
import com.mybatisD.domain.User;
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.InputStream;
import java.util.Date;
import java.util.List;
/**
* @author :程序员徐大大
* @description:TODO
* @date :2022-01-23 14:11
*/
public class SecondLeaveCatcheTest {
private InputStream in;
private SqlSessionFactory factory;
@Before//用于在测试方法执行之前执行
public void init()throws Exception{
in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
factory = builder.build(in);
}
@After//用于在测试方法之后执行
public void destory() throws Exception{
in.close();
}
//一级缓存
@Test
public void tesSecondChatch() throws Exception {
SqlSession sqlSession1 = factory.openSession();
IUserDao dao1 =sqlSession1.getMapper(IUserDao.class);
User user1 = dao1.findById(2);
System.out.println(user1);
sqlSession1.close(); //一级缓存消失
SqlSession sqlSession2 = factory.openSession();
IUserDao dao2 =sqlSession2.getMapper(IUserDao.class);
User user2 = dao2.findById(2);
System.out.println(user2);
sqlSession2.close();
System.out.println( user1 == user2);
}
}
结果
其中的
System.out.println( user1 == user2);
输出的是false