springboot使用redis注解做緩存的基本操作方式
springboot使用redis注解做緩存
在springboot中,我們可以很方便地使用注解來讓redis為我們的數(shù)據(jù)庫作緩存
以下為基本步驟
數(shù)據(jù)庫中的用戶表(主鍵id自增)

在,創(chuàng)建springboot項目時,我們選中非關(guān)系型數(shù)據(jù)庫中的redis

項目結(jié)構(gòu):

首先添加連接池的依賴
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.9.0</version>
</dependency>在配置文件中添加有關(guān)redis的配置:
# redis配置 spring.redis.host=192.168.134.128 spring.redis.port=6379 spring.redis.password=123456 spring.redis.lettuce.pool.min-idle=3 spring.redis.lettuce.pool.max-idle=8
之后我們在啟動類上添加@EnableCaching注解,表示開啟redis緩存托管

現(xiàn)在我們著手來改造service層
我們準(zhǔn)備五個方法用于測試,增刪改查,以及全部查詢,方法的返回值不能隨便寫,由于我們要添加緩存,添加到緩存中的數(shù)據(jù)是根據(jù)方法的返回值來操作的,所以除了刪除的操作,方法的返回值都要給定成相應(yīng)的對象
public interface UserService extends IService<User> {
User saveUser(User user);
int removeUser(Integer id);
User updateUser(User user);
User findById(Integer id);
List<User> findAll();
}之后我們在service實現(xiàn)類上添加@CacheConfig注解,并給定cacheNames屬性,用于區(qū)分各個service中間的緩存內(nèi)容,一般建議使用該類的全限定名

之后我們來到具體的方法上
首先是添加方法,我們需要在方法上添加@CachePut注解,此注解用在添加以及更新的方法上,其中的key屬性,是為了給redis中的key賦值,內(nèi)容自定義,但一般為了key的唯一性,都取參數(shù)對象的id作為值,此處#user.id表示取方法闡述中的user的id屬性作為值
@CachePut(key = "#user.id")
@Override
public User saveUser(User user) {
userMapper.insert(user);
return user;
}接下來是刪除方法,我們需要在方法上添加@CacheEvict注解,此注解一般用在刪除方法上作緩存,key屬性作用與以上相同
@CacheEvict(key = "#id")
@Override
public int removeUser(Integer id) {
return userMapper.deleteById(id);
}修改(更新)方法,使用@CachePut注解
@CachePut(key = "#user.id")
@Override
public User updateUser(User user) {
userMapper.updateById(user);
return user;
}查詢方法,使用@Cacheable注解
@Cacheable(key = "#id")
@Override
public User findById(Integer id) {
return userMapper.selectById(id);
}接下來是查詢?nèi)康淖⒔?,此處要注意@Cacheable注解中的key值,我們自定義該值為userAll,但是如果直接寫進去,會被當(dāng)做是變量進行識別。
而我們則希望這個值是一個字符串類型,所以我們還需要添加一層單引號,也可以用雙引號加上轉(zhuǎn)義字符來實現(xiàn)
@Cacheable(key = "'userAll'")
@Override
public List<User> findAll() {
return userMapper.selectList(new QueryWrapper<User>());
}但是到此,我們發(fā)現(xiàn)邏輯上出現(xiàn)了問題,一旦我們執(zhí)行了增刪改操作,redis中的userAll就會和數(shù)據(jù)庫中的不匹配,此時我們就需要移除redis中的userAll,所以我們在執(zhí)行增刪改方法時,就需要用到多次redis的緩存操作,此時我們就需要用到@Caching注解,這里先以增加方法為例
// @CachePut(key = "#user.id")
@Caching(
put = @CachePut(key = "#user.id"),
evict = @CacheEvict(key = "'userAll'")
)
@Override
public User saveUser(User user) {
userMapper.insert(user);
return user;
}此處@Caching中的內(nèi)容表示,在先執(zhí)行了往redis中添加操作后,就立即刪除掉redis中userAll這個key,這里的put和evict屬性的值都是數(shù)組,所以我們可以添加多個增加(更新)和刪除方法(查詢方法也可以,使用cacheable屬性)
類似得,我們將其他方法也做改造(查詢方法不需要),最終service實現(xiàn)類的方法如下
// @CachePut(key = "#user.id")// 為添加的值指定id
@Caching(// 添加多個緩存操作
put = @CachePut(key = "#user.id"),
evict = @CacheEvict(key = "'userAll'")
)
@Override
public User saveUser(User user) {
userMapper.insert(user);
return user;
}
// @CacheEvict(key = "#id")
@Caching(
evict = {@CacheEvict(key = "#id"), @CacheEvict(key = "'userAll'")}
)
@Override
public int removeUser(Integer id) {
return userMapper.deleteById(id);
}
// @CachePut(key = "#user.id")
@Caching(
put = @CachePut(key = "#user.id"),
evict = @CacheEvict(key = "'userAll'")
)
@Override
public User updateUser(User user) {
userMapper.updateById(user);
return user;
}
@Cacheable(key = "#id")
@Override
public User findById(Integer id) {
return userMapper.selectById(id);
}
@Cacheable(key = "'userAll'")
@Override
public List<User> findAll() {
return userMapper.selectList(new QueryWrapper<User>());
}我們來到測試方法,首先測試查詢?nèi)?/p>
@Test
public void selectAll(){
List<User> userList = userService.findAll();
for (User user : userList) {
System.out.println("user = " + user);
}
}第一次查詢:

我們看到控制臺出現(xiàn)了sql查詢,表示這一次是在數(shù)據(jù)庫中查詢得到的
我們查看redis中的內(nèi)容,發(fā)現(xiàn)也出現(xiàn)了userAll這條信息

接下來進行第二次查詢

我們看到這次查詢在控制臺上并沒有sql的輸出,表示我們配置redis緩存成功
接下來測試添加功能
/**
* 測試添加user
*/
@Test
public void add(){
User user = new User();
user.setName("德川");
userService.saveUser(user);
}執(zhí)行之后我們查看數(shù)據(jù)庫

執(zhí)行成功,接下來我們查看redis

我們發(fā)現(xiàn)只有一條數(shù)據(jù),就是這次添加的id為10的數(shù)據(jù),之前的userAll信息確實也被刪除掉了,表示@Caching注解直接也得到了執(zhí)行
但是我們在查看redis時發(fā)現(xiàn)一個問題,redis中存儲的數(shù)據(jù)我們根本看不懂,這是因為springboot在將數(shù)據(jù)存入redis時,由于redis并不能存儲java對象,所以springboot只能將對象序列化成字符串,再存入redis中,但是默認(rèn)使用的是jdk的序列化方式,可讀性不高,我們一般都希望其轉(zhuǎn)換成json格式,此時就需要我們進行手動配置序列化方式
首先我們導(dǎo)入jackson的啟動器依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>在config包中添加如下配置類
@Configuration
public class RedisConfig {
/**
* 設(shè)置序列化等緩存配置
*
* @return
*/
@Bean
public RedisCacheConfiguration redisCacheConfiguration() {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
// 設(shè)置序列化的方式
redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(RedisSerializationContext
.SerializationPair
.fromSerializer(RedisSerializer.json()));
return redisCacheConfiguration;
}
}接下來我們測試更新方法
/**
* 測試更新user
*/
@Test
public void update(){
User user = new User();
user.setId(10);
user.setName("原野");
userService.updateUser(user);
}我們來到redis中查看結(jié)果

發(fā)現(xiàn)存儲的信息變成了json格式,大功告成
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- SpringBoot整合Redis實現(xiàn)token緩存
- SpringBoot結(jié)合Redis實現(xiàn)緩存管理功能
- SpringBoot整合redis使用緩存注解詳解
- SpringBoot+MyBatis+Redis實現(xiàn)分布式緩存
- SpringBoot中Redis的緩存更新策略詳解
- springboot整合ehcache和redis實現(xiàn)多級緩存實戰(zhàn)案例
- SpringBoot結(jié)合Redis實現(xiàn)緩存
- SpringBoot使用Redis實現(xiàn)分布式緩存
- SpringBoot中的Redis?緩存問題及操作方法
- SpringBoot3.0集成Redis緩存的實現(xiàn)示例
相關(guān)文章
Java關(guān)于List集合去重方案詳細(xì)介紹
實際項目開發(fā)中,很多業(yè)務(wù)場景下都會遇見集合去重。在說到List集合去重之前,首先我們回顧下普通類型的list如何去重2021-09-09

