Ehcache缓存和Redis缓存数据
JVM缓存和使用Redis缓存数据
一、本地缓存Ehcache
Ehcache是纯java的开源缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。它主要面向通用缓存、Java EE和轻量级容器,具有内存和磁盘存储、缓存加载器、缓存扩展、缓存异常处理程序。
Ehcache最初由Greg Luck于2003年开始开发。2009年,该项目被Terracotta购买。软件仍然开源,但一些新的主要功能(例如,快速可重启性之间的一致性的)只能在商业产品中使用。
Ehcache 被广泛用于在Hibernate、Spring、Cocoon等其他开源系统。
1. Ehcache的主要特性
- 快速;
- 简单;
- 多种缓存策略;
- 缓存数据有两级:内存和磁盘,因此无需担心容量问题;
- 缓存数据会在虚拟机重启的过程中写入磁盘;
- 可以通过 RMI、可插入 API 等方式进行分布式缓存;
- 具有缓存和缓存管理器的侦听接口;
- 支持多缓存管理器实例,以及一个实例的多个缓存区域;
- 提供 Hibernate 的缓存实现;
2. Ehcache缓存过期策略
当缓存需要被清理时(比如空间占用已经接近临界值了),需要使用某种淘汰算法来决定清理掉哪些数据。常用的淘汰算法有下面几种:
- FIFO:First In First Out,先进先出。判断被存储的时间,离目前最远的数据优先被淘汰。
- LRU:Least Recently Used,最近最少使用。判断最近被使用的时间,目前最远的数据优先被淘汰。
- LFU:Least Frequently Used,最不经常使用。在一段时间内,数据被使用次数最少的,优先被淘汰。
3. 主要注解
@CachePut 是将数据加入到redis缓存中
@Cacheable 在获取数据的时候会先查询缓存,如果缓存中存在,则不执行查询数据库的方法,如果不存在则查询数据库,并加入到缓存中。
@CacheEvict 一般注解到删除数据的操作上,会将一条或多条数据从缓存中删除。
4. SpringBoot中使用Ehcache
- pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- application.yml
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/db1
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
cache:
type: ehcache
ehcache:
config: classpath:ehcache.xml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="java.io.tmpdir/Tmp_EhCache" />
<defaultCache maxElementsInMemory="5000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120"
memoryStoreEvictionPolicy="LRU" overflowToDisk="false" />
<cache name="userCache" maxElementsInMemory="1000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
<bootstrapCacheLoaderFactory
class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" />
</cache>
</ehcache>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 启动
@EnableCaching
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 使用
@CacheConfig(cacheNames = "userCache")
public interface UserMapper {
@Select("select * from users where name=#{name}")
@Cacheable
UserEntity findName(@Param("name") String name);
}
- 1
- 2
- 3
- 4
- 5
- 6
@CacheConfig(cacheNames = "transitoryCache")
@RestController
public class TestController {
@GetMapping("/GetTest/{id}/{param}")
@Cacheable(key = "#id.toString()")
public String getTest(@PathVariable("id")String id,@PathVariable("param")String param){
return "参数->"+param;
}
@GetMapping("/UpdateDate/{id}/{param}")
@CachePut(key = "#id.toString()")
public String updateDate(@PathVariable("id")String id,@PathVariable("param")String param){
return "参数->"+param;
}
@GetMapping("/DeleteDate/{id}")
@CacheEvict(key = "#id.toString()")
public String deleteDate(@PathVariable("id")String id){
return "success";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
清楚缓存
@Autowired
private CacheManager cacheManager;
@RequestMapping("/remoKey")
public void remoKey() {
cacheManager.getCache("userCache").clear();
}
- 1
- 2
- 3
- 4
- 5
- 6
二、Redis缓存
springboot已经集成了redis缓存,只需要在pom.xml中加载redis,然后通过注解即可完成配置。
springboot 集成
- pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- application.yml 修改
server:
port: 8080
spring:
cache:
type: redis
- 1
- 2
- 3
- 4
- 5
- 6
- 启动类
@SpringBootApplication
@EnableCaching
@MapperScan(value = {"com.bxc.rediscaching.Mapper"})
public class RediscachingApplication {
public static void main(String[] args) {
SpringApplication.run(RediscachingApplication.class, args);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- service
@Service
public class UserService {
@Autowired
UserMapper userMapper;
@Cacheable(key = "#root.methodName",value = "userCache")
public List<UserEntity> getAllUser(){
System.out.println();
List<UserEntity> list = userMapper.selectList(null);
return list;
}
//@Cacheable 表示可缓存,如果缓存中存在,就从缓存中查询,不存在,就走数据库
//其中缓存库位userCache,key表示使用缓存的key(为当前的传递的id.toString())
@Cacheable(key = "#id.toString()", value = "userCache")
public UserEntity findUserById(Integer id) {
System.out.println("从数据库中查询编号为:"+id);
return userData.get(id);;
return null;
}
//表示向缓存中直接添加数据,添加的库为当前的value,添加的key为当前的key(user的id.toString())
@CachePut(key = "#user.id.toString()", value = "userCache")
public void addUser(UserEntity user) {
userData.put(user.getId(), user);
}
//表示向缓存中直接添加数据,添加的库为当前的value,添加的key为当前的key(user的id.toString())
@CachePut(key = "#user.id.toString()", value = "userCache")
public void updateUser(UserEntity user) {
userData.put(user.getId(), user);
}
//用来删除数据,指定key表示删除缓存库中的key的字段的内容,value表示删除的缓存的库
@CacheEvict(key = "#id.toString()", value = "userCache")
public void deleteUserById(Integer id) {
userData.remove(id);
}
//用来删除数据,指定allEntries = true表示删除所有的缓存,value表示删除的缓存的库
@CacheEvict(allEntries = true, value = "userCache")
public void clearCache() {
System.out.println("清空缓存");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
三、补充
1. @Cacheable 和 @CachePut注解属性说明
- keyGenerator:缓存数据key生成策略;
- CacheManager:缓存管理器,管理缓存组件;
- CacheResolver:缓存解析器,根据实际情况动态解析决定使用哪个缓存实例;
- value:缓存实例(一个缓存实例可以存储多个缓存KV对)的名称,至少需要设置一个;
- key:缓存的 key,如果不为空需要要按照 SpEL 表达式编写;如果不为空6. 则缺省按照方法的所有参数进行组合;
- condition:缓存条件,使用 SpEL 编写;若不为空,只在条件结果为 true 时才进行缓存;
- unless:缓存排除条件,当条件结果为TRUE时不会缓存;
- sync:是否同步操作,如为true,那么多个线程访问同一条记录时,会同步执行调用的方法。
2. @CacheEvict注解属性说明
@CacheEvict注解的属性大致同 @Cacheable一致,不过 @CacheEvict还有两个独有的属性:
- allEntries:是否清空所有缓存内容,缺省为 false;如果指定为 true,则方法调用后将立即清空所有缓存;
- beforeInvocation:是否在方法执行前就清空,缺省为 false;如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存。
3. @CacheConfig注解属性说明
@CacheConfig注解的属性 @Cacheable都有。因为 @CacheConfig注解的作用本来就是统一管理相同类下所有方法的缓存配置。
需要提一下的就是在spring4.1之前是没有 @CacheConfig注解的,那时候需要在每个方法的 @Cacheable注解中设置cacheNames属性。
4. SpEL表达式
名称 | 位置 | 描述 | 示例 |
---|---|---|---|
methodName | root对象 | 当前被调用的方法名 | #root.methodname |
method | root对象 | 当前被调用的方法 | #root.method.name |
target | root对象 | 当前被调用的目标对象实例 | #root.target |
targetClass | root对象 | 当前被调用的目标对象的类 | #root.targetClass |
args | root对象 | 当前被调用的方法的参数列表 | #root.args[0] |
caches | root对象 | 当前方法调用使用的缓存列表 | #root.caches[0].name |
Argument Name | 执行上下文 | 当前被调用的方法的参数,如findArtisan(Artisan artisan),可以通过#artsian.id获得参数 | #artsian.id |
result | 执行上下文 | 方法执行后的返回值(仅当方法执行后的判断有效,如 unless cacheEvict的beforeInvocation=false) | #result |
注意事项:
- 当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性, 如 @Cacheable(key = “targetClass + methodName +#p0”);
- 使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”,如: @Cacheable(value=“users”, key="#id")和 @Cacheable(value=“users”, key="#p0")。
文章来源: blog.csdn.net,作者:小毕超,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_43692950/article/details/107443007
- 点赞
- 收藏
- 关注作者
评论(0)