Skip to main content

缓存服务

缓存配置#

框架原生支持caffeine、redis缓存,集群状态时自动添加ignite支持,非集群状态时,caffeine是默认缓存。下面是配置实例:

# configuration for dev environment
---
readyWork:
server:
# This is the default binding address.
ip: 0.0.0.0
# dynamic port is used for containerization
dynamicPort: false
# Http port if enableHttp is true.
httpPort: 8080
database:
sqlDebug: true
dataSource:
main:
type: mysql
jdbcUrl: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useSSL=false&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull
username: root
password: 12345678
cache:
# 主缓存,默认是caffeine类型,这里可以指定为redis类型,如果指定redis类型,下面的redis配置项需要进行配置
cacheType: redis # main cache, caffeine by default, redis is an option
# 数据库查询缓存,只用于DAO层查询缓存,默认是caffeine,不建议修改
#dbCacheType: caffeine # caffeine by default
# AOP缓存,只用于AOP层动态缓存,默认是caffeine,不建议修改
#aopCacheType: caffeine # caffeine by default
# AOP缓存的生命周期,0为永久,即JVM生命周期
#aopCacheLiveSeconds: 0 # seconds, 0 = forever by default
redis:
# redis服务IP地址
host: 127.0.0.1
# redis服务端口
port: 6379
# redis服务的登陆密码
#password: 123456
#database: 0
#timeout: 2000

缓存应用#

通用缓存#

框架对缓存操作进行了统一封装,不管是caffeine、redis都可以通过一套接口进行操作,透明切换缓存类型。通过Ready.cacheManager().getCache()可以获得当前主缓存实例,然后就可以进行各种缓存操作,见下面的实例:

@Service
public class CacheService {
// 获得主缓存实例
private final Cache cache = Ready.cacheManager().getCache();
private final String cacheName = "DefaultCache";
// 添加缓存
public <T> void putCache(String key, T value) {
cache.put(cacheName, key, value);
}
// 添加缓存并设定缓存的过期时间
public <T> void putCache(String key, T value, int liveSeconds) {
cache.put(cacheName, key, value, liveSeconds);
}
// 获取缓存
public <T> T getCache(String key) {
return cache.get(cacheName, key);
}
// 删除缓存
public void removeCache(String key) {
cache.remove(cacheName, key);
}
// 获取缓存清单
public List getKeys() {
return cache.getKeys(cacheName);
}
}

当然,一般不需要像上面这样封装,直接利用缓存实例进行操作即可,这里只是把演示内容放在一起而已。如果主缓存是redis类型,需要redis的高级功能,可以通过以下方式获得:

  • ((RedisCache)cache).getJedis();
  • ((RedisCache)cache).getJedisCluster();

AOP缓存#

AOP缓存是一套建立在AOP技术基础上的动态缓存机制。通过@Cacheable、@CacheEvict、@CachesEvict、@CachePut几个注解即可动态进行缓存操作。出于性能考虑,默认使用的是caffeine缓存。见下面的实例:

@Service
public class AopCacheDemo extends ModelService<Demo> {
@CacheEvict(name = "testCache",key = "*") // 插入数据时清除缓存
@Auto("insert into _TABLE_(name, gender, age) value(?,?,?)")
public Boolean addRecord(String name, int gender, int age) {
return IfFailure.get(null);
}
@Auto
@CacheEvict(name = "testCache",key = "*") // 修改数据时清除缓存
public int updateByName(String name, Map<String, Object> map) {
return IfFailure.get(0);
}
@Auto
@CacheEvict(name = "testCache",key = "*") // 删除数据时清除缓存
public Boolean deleteByName(String name) {
return IfFailure.get(false);
}
// 查询数据时对结果集合进行缓存
@Cacheable(name = "testCache", key = "page:#(page)-#(size)-#(age)")
@Auto("select * from _TABLE_ where age > ?")
public Page<Record> getByAge(int page, int size, int age) {
return IfFailure.get(null);
}
}

通过AOP缓存可以大幅度对提高系统性能。但需要注意的是,如果缓存对象的数据在多个不同的类中进行了修改时,这些地方都需要@CacheEvict进行缓存清理。所以,通过ModeService层统一对单表进行增删改查就会很方便。

数据库缓存#

数据库缓存对一些基本上不做变更的数据表很有用,查询一次后就会自动缓存,大幅度提高查询性能。出于性能考虑,默认使用的是caffeine缓存。见下面的实例:

@Service
public class DbCacheDemo {
private final Db db = Ready.dbManager().getDb();
public List<Record> findByGender(int gender) {
// 按gender进行查询和缓存demo表的数据
return db.findByCache("DbCache", "all-gender-" + gender, "select * from demo where gender = ?", gender);
}
public Record findByName(String name) {
// 按name进行查询和缓存demo表的单条数据
return db.findFirstByCache("DbCache", "one-name-" + name, "select * from demo where name = ? limit 1", name);
}
// 还可以通过db.paginateByCache进行翻页查询缓存,但并不推荐这样使用
}

数据库缓存不会自动清理,所以缓存结果不会因为数据库变更而变更,只适合对数据不会变动的表进行缓存。

更多文档#

以上为本框架提供的常用缓存方式介绍,还有更多缓存方面的文档将在后续不断完善,重点内容将以专题形式提供。