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實(shí)現(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,但是如果直接寫進(jìn)去,會被當(dāng)做是變量進(jìn)行識別。
而我們則希望這個值是一個字符串類型,所以我們還需要添加一層單引號,也可以用雙引號加上轉(zhuǎn)義字符來實(shí)現(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實(shí)現(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這條信息
接下來進(jìn)行第二次查詢
我們看到這次查詢在控制臺上并沒有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信息確實(shí)也被刪除掉了,表示@Caching注解直接也得到了執(zhí)行
但是我們在查看redis時發(fā)現(xiàn)一個問題,redis中存儲的數(shù)據(jù)我們根本看不懂,這是因為springboot在將數(shù)據(jù)存入redis時,由于redis并不能存儲java對象,所以springboot只能將對象序列化成字符串,再存入redis中,但是默認(rèn)使用的是jdk的序列化方式,可讀性不高,我們一般都希望其轉(zhuǎn)換成json格式,此時就需要我們進(jìn)行手動配置序列化方式
首先我們導(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實(shí)現(xiàn)token緩存
- SpringBoot結(jié)合Redis實(shí)現(xiàn)緩存管理功能
- SpringBoot整合redis使用緩存注解詳解
- SpringBoot+MyBatis+Redis實(shí)現(xiàn)分布式緩存
- SpringBoot中Redis的緩存更新策略詳解
- springboot整合ehcache和redis實(shí)現(xiàn)多級緩存實(shí)戰(zhàn)案例
- SpringBoot結(jié)合Redis實(shí)現(xiàn)緩存
- SpringBoot使用Redis實(shí)現(xiàn)分布式緩存
- SpringBoot中的Redis?緩存問題及操作方法
- SpringBoot3.0集成Redis緩存的實(shí)現(xiàn)示例
相關(guān)文章
Java關(guān)于List集合去重方案詳細(xì)介紹
實(shí)際項目開發(fā)中,很多業(yè)務(wù)場景下都會遇見集合去重。在說到List集合去重之前,首先我們回顧下普通類型的list如何去重2021-09-09java_IO向文件中寫入和讀取內(nèi)容代碼實(shí)例
這篇文章主要介紹了java_IO向文件中寫入和讀取內(nèi)容,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03分享幾個Java工作中實(shí)用的代碼優(yōu)化技巧
這篇文章主要給大家分享幾個Java工作中實(shí)用代碼優(yōu)化技巧,文章基于Java的相關(guān)資料展開對其優(yōu)化技巧的分享,需要的小伙伴可以參考一下2022-04-04Java實(shí)現(xiàn)的計算稀疏矩陣余弦相似度示例
這篇文章主要介紹了Java實(shí)現(xiàn)的計算稀疏矩陣余弦相似度功能,涉及java基于HashMap的數(shù)值計算相關(guān)操作技巧,需要的朋友可以參考下2018-07-07