redis緩存神器之@Cacheable注解詳解
redis之@Cacheable注解
在之前的文章中,我們寫了redis結(jié)合springboot做緩存分頁的方法:
在Spring Boot中結(jié)合Redis進(jìn)行緩存分頁數(shù)據(jù)
可以通過以下步驟實(shí)現(xiàn):
在 pom.xml 文件中添加 Redis 相關(guān)依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>在 application.properties 文件中配置 Redis 連接信息:
spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password=
創(chuàng)建一個(gè) RedisTemplate 對象,用于操作 Redis 緩存:
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;
}
}在 Service 層中,使用 RedisTemplate 對象進(jìn)行緩存操作。
例如,對于分頁查詢操作,可以將查詢結(jié)果緩存到 Redis 中,下次查詢時(shí)先從 Redis 中獲取數(shù)據(jù),如果緩存中不存在,則進(jìn)行數(shù)據(jù)庫查詢,并將查詢結(jié)果緩存到 Redis 中:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private UserDao userDao;
@Override
public List<User> getUsersByPage(int pageNum, int pageSize) {
String key = "user:page:" + pageNum + ":" + pageSize;
List<User> users = (List<User>) redisTemplate.opsForValue().get(key);
if (users == null) {
PageHelper.startPage(pageNum, pageSize);
users = userDao.getUsers();
PageInfo<User> pageInfo = new PageInfo<>(users);
redisTemplate.opsForValue().set(key, pageInfo, 1, TimeUnit.MINUTES);
}
return users;
}
}在上述代碼中,使用了 PageHelper 插件進(jìn)行分頁查詢,并將查詢結(jié)果緩存到 Redis 中,緩存時(shí)間為 1 分鐘。下次查詢時(shí),如果緩存中存在數(shù)據(jù),則直接從緩存中獲取,避免了頻繁查詢數(shù)據(jù)庫的操作。
以上就是 Spring Boot 結(jié)合 Redis 進(jìn)行緩存分頁數(shù)據(jù)的實(shí)現(xiàn)方法。需要注意的是,緩存的數(shù)據(jù)需要根據(jù)實(shí)際情況進(jìn)行設(shè)置過期時(shí)間,避免緩存數(shù)據(jù)過期后仍然被使用。
但是,以上代碼還是存在問題的,如果page數(shù)據(jù)發(fā)生了變化怎么辦,redis獲取的還是老數(shù)據(jù)??!
所以,我們需要在數(shù)據(jù)更新的時(shí)候,也要更新緩存里面的數(shù)據(jù)。
來嘮嘮怎么更新緩存和簡化這些操作
Spring Boot提供了一個(gè)注解@EnableCaching來啟用緩存功能。在啟用緩存功能后,可以使用注解來對某個(gè)方法進(jìn)行緩存。
首先,在pom.xml文件中添加redis依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>在application.properties文件中配置redis連接信息:
spring.redis.host=127.0.0.1 spring.redis.port=6379
在啟動類上添加@EnableCaching注解,開啟緩存功能:
@SpringBootApplication
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}在需要進(jìn)行緩存的方法上添加@Cacheable注解:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
@Cacheable(value = "userCache", key = "#id") // 添加緩存注解
public User getUserById(Long id) {
return userDao.getUserById(id);
}
}其中,@Cacheable注解有兩個(gè)重要的參數(shù):value和key。value表示緩存的名稱,如果沒有指定則使用默認(rèn)緩存;key表示緩存的key值,可以使用SpEL表達(dá)式來表示。
這樣,當(dāng)?shù)谝淮握{(diào)用getUserById方法時(shí),會將返回結(jié)果緩存起來,下次再調(diào)用該方法時(shí),直接從緩存中獲取結(jié)果,而不是執(zhí)行方法體。如果需要更新緩存,可以調(diào)用@CachePut注解或@CacheEvict注解來實(shí)現(xiàn)。
需要注意的是,在使用@Cacheable注解時(shí),被緩存的方法不能拋出異常,否則會導(dǎo)致緩存失效。
當(dāng)使用@Cacheable注解后,如果需要更新緩存,可以通過調(diào)用@CachePut注解來更新緩存。
@CachePut注解的使用方法和@Cacheable注解類似。在需要更新緩存的方法上添加@CachePut注解,并指定value和key值。
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
@Cacheable(value = "userCache", key = "#id")
public User getUserById(Long id) {
return userDao.getUserById(id);
}
@Override
@CachePut(value = "userCache", key = "#user.id")
public User updateUser(User user) {
userDao.updateUser(user);
return user;
}
}在更新數(shù)據(jù)時(shí),先調(diào)用更新方法updateUser,然后再調(diào)用查詢方法getUserById,此時(shí)會更新緩存中的數(shù)據(jù)。
// 更新用戶信息
User user = new User();
user.setId(1L);
user.setName("new name");
userService.updateUser(user);
// 查詢用戶信息,會從緩存中獲取
User userFromCache = userService.getUserById(1L);如果需要刪除緩存中的數(shù)據(jù),可以通過調(diào)用@CacheEvict注解來實(shí)現(xiàn)。
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
@Cacheable(value = "userCache", key = "#id")
public User getUserById(Long id) {
return userDao.getUserById(id);
}
@Override
@CachePut(value = "userCache", key = "#user.id")
public User updateUser(User user) {
userDao.updateUser(user);
return user;
}
@Override
@CacheEvict(value = "userCache", key = "#id")
public void deleteUserById(Long id) {
userDao.deleteUserById(id);
}
}在刪除數(shù)據(jù)時(shí),先調(diào)用刪除方法deleteUserById,然后再調(diào)用查詢方法getUserById,此時(shí)會重新從數(shù)據(jù)庫中獲取數(shù)據(jù)。
// 刪除用戶信息 userService.deleteUserById(1L); // 查詢用戶信息,會重新從數(shù)據(jù)庫中獲取 User userFromDB = userDao.getUserById(1L);
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
小白也能看懂的Redis遍歷鍵和數(shù)據(jù)庫管理詳解
這篇文章主要為大家介紹了小白也能看懂的Redis遍歷鍵和數(shù)據(jù)庫管理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
redis.clients.jedis.exceptions.JedisDataException異常的錯(cuò)誤解決
本文主要介紹了redis.clients.jedis.exceptions.JedisDataException異常的錯(cuò)誤解決,這個(gè)異常通常發(fā)生在嘗試連接到一個(gè)?Redis?服務(wù)器時(shí),客戶端發(fā)送了一個(gè)?AUTH?命令來驗(yàn)證密碼,但是沒有配置密碼驗(yàn)證,下來就來解決一下2024-05-05
redis設(shè)置密碼并修改查看的幾種實(shí)現(xiàn)過程
這篇文章主要介紹了redis設(shè)置密碼并修改查看的幾種實(shí)現(xiàn)過程,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2026-06-06
Linux服務(wù)器快速安裝Redis6.0步驟示例詳解
這篇文章主要為大家介紹了Linux服務(wù)器快速安裝Redis6.0步驟示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
虛擬機(jī)linux安裝redis實(shí)現(xiàn)過程解析
這篇文章主要介紹了虛擬機(jī)linux安裝redis實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08

