springboot使用redis注解做緩存的基本操作方式
springboot使用redis注解做緩存
在springboot中,我們可以很方便地使用注解來讓redis為我們的數(shù)據(jù)庫作緩存
以下為基本步驟
數(shù)據(jù)庫中的用戶表(主鍵id自增)
在,創(chuàng)建springboot項目時,我們選中非關系型數(shù)據(jù)庫中的redis
項目結構:
首先添加連接池的依賴
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.9.0</version> </dependency>
在配置文件中添加有關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層
我們準備五個方法用于測試,增刪改查,以及全部查詢,方法的返回值不能隨便寫,由于我們要添加緩存,添加到緩存中的數(shù)據(jù)是根據(jù)方法的返回值來操作的,所以除了刪除的操作,方法的返回值都要給定成相應的對象
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,但是如果直接寫進去,會被當做是變量進行識別。
而我們則希望這個值是一個字符串類型,所以我們還需要添加一層單引號,也可以用雙引號加上轉(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中,但是默認使用的是jdk的序列化方式,可讀性不高,我們一般都希望其轉(zhuǎn)換成json格式,此時就需要我們進行手動配置序列化方式
首先我們導入jackson的啟動器依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> </dependency>
在config包中添加如下配置類
@Configuration public class RedisConfig { /** * 設置序列化等緩存配置 * * @return */ @Bean public RedisCacheConfiguration redisCacheConfiguration() { RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig(); // 設置序列化的方式 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中查看結果
發(fā)現(xiàn)存儲的信息變成了json格式,大功告成
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- SpringBoot整合Redis實現(xiàn)token緩存
- SpringBoot結合Redis實現(xiàn)緩存管理功能
- SpringBoot整合redis使用緩存注解詳解
- SpringBoot+MyBatis+Redis實現(xiàn)分布式緩存
- SpringBoot中Redis的緩存更新策略詳解
- springboot整合ehcache和redis實現(xiàn)多級緩存實戰(zhàn)案例
- SpringBoot結合Redis實現(xiàn)緩存
- SpringBoot使用Redis實現(xiàn)分布式緩存
- SpringBoot中的Redis?緩存問題及操作方法
- SpringBoot3.0集成Redis緩存的實現(xiàn)示例