JetCache是一个基于Java的缓存系统封装,提供统一的API和注解来简化缓存的使用。 JetCache提供了比SpringCache更加强大的注解,可以原生的支持TTL、两级缓存、分布式自动刷新,还提供了Cache接口用于手工缓存操作。 当前有四个实现,RedisCache、TairCache(此部分未在github开源)、CaffeineCache(in memory)和一个简易的LinkedHashMapCache(in memory),要添加新的实现也是非常简单的。
开源地址:https://github.com/alibaba/jetcache
中文Wiki:https://github.com/alibaba/jetcache/wiki/Home_CN
有多种集成方式,此处使用 jetcache-starter-redis-lettuce
思路:本地缓存做为一级缓存,redis为二级缓存和数据源存储,数据不存储在DB了
<dependency>
<groupId>com.alicp.jetcache</groupId>
<artifactId>jetcache-starter-redis-lettuce</artifactId>
<version>2.6.0</version>
</dependency>
jetcache:
statIntervalMinutes: 15
areaInCacheName: false
hidePackages: com.alibaba
local:
default:
type: caffeine
limit: 300
keyConvertor: fastjson
expireAfterWriteInMillis: 100000
remote:
default:
type: redis.lettuce
keyConvertor: fastjson
valueEncoder: java
valueDecoder: java
poolConfig:
minIdle: 5
maxIdle: 20
maxTotal: 50
uri: redis://127.0.0.1:6379/
@EnableMethodCache(basePackages = "com.zypcy.multicache")
@EnableCreateCacheAnnotation
@SpringBootApplication
public class MultiCacheApplication {
public static void main(String[] args) {
SpringApplication.run(MultiCacheApplication.class, args);
}
}
public interface IndexService {
void addUser(User user);
//配置一级缓存
@Cached(name="userCache-", key="#userId", expire = 60)
//缓存30秒钟自动刷新,从getUserById方法取一次,如果key在600秒内没有访问则不再自动刷新
@CacheRefresh(refresh = 30, stopRefreshAfterLastAccess = 600, timeUnit = TimeUnit.SECONDS)
//当缓存访问未命中的情况下,对并发进行的加载行为进行保护,同一个JVM中同一个key只有一个线程去加载,其它线程等待结果
@CachePenetrationProtect
User getUserById(long userId);
//更新缓存
@CacheUpdate(name="userCache-", key="#user.userId", value="#user")
void updateUser(User user);
//删除缓存
@CacheInvalidate(name="userCache-", key="#userId")
void deleteUser(long userId);
}
@Service
public class IndexServiceImpl implements IndexService {
private static final String key = "user";
@Autowired
StringRedisTemplate redisTemplate;
@Override
public void addUser(User user) {
redisTemplate.opsForHash().put(key , String.valueOf(user.getUserId()) , JSON.toJSONString(user));
}
@Override
public User getUserById(long userId) {
User user = null;
Object result = redisTemplate.opsForHash().get(key , String.valueOf(userId));
if(result != null){
user = JSON.parseObject(result.toString() , User.class);
}
return user;
}
@Override
public void updateUser(User user) {
User dbUser = getUserById(user.getUserId());
if(dbUser != null){
if(!StringUtils.isEmpty(user.getName())){
dbUser.setName(user.getName());
}
if(!StringUtils.isEmpty(user.getAddress())){
dbUser.setAddress(user.getAddress());
}
if(user.getAge() > 0){
dbUser.setAge(user.getAge());
}
addUser(dbUser);
}
}
@Override
public void deleteUser(long userId) {
redisTemplate.opsForHash().delete(key , String.valueOf(userId));
}
}
public class User implements Serializable {
private long userId;
private String name;
private int age;
private String address;
//getter setter 略
}
@RestController
@RequestMapping("/index")
public class IndexController {
@Autowired
IndexService indexService;
@PostMapping("/add")
public String addUser(User user) {
indexService.addUser(user);
return "success";
}
@GetMapping("/get")
public User getUserById(long userId) {
return indexService.getUserById(userId);
}
@PostMapping("/update")
public String updateUser(User user) {
indexService.updateUser(user);
return "success";
}
@GetMapping("/delete")
public String deleteUser(long userId) {
indexService.deleteUser(userId);
return "success";
}
}