redis緩存神器之@Cacheable注解詳解
redis之@Cacheable注解
在之前的文章中,我們寫了redis結(jié)合springboot做緩存分頁(yè)的方法:
在Spring Boot中結(jié)合Redis進(jìn)行緩存分頁(yè)數(shù)據(jù)
可以通過(guò)以下步驟實(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 對(duì)象,用于操作 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 對(duì)象進(jìn)行緩存操作。
例如,對(duì)于分頁(yè)查詢操作,可以將查詢結(jié)果緩存到 Redis 中,下次查詢時(shí)先從 Redis 中獲取數(shù)據(jù),如果緩存中不存在,則進(jìn)行數(shù)據(jù)庫(kù)查詢,并將查詢結(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)行分頁(yè)查詢,并將查詢結(jié)果緩存到 Redis 中,緩存時(shí)間為 1 分鐘。下次查詢時(shí),如果緩存中存在數(shù)據(jù),則直接從緩存中獲取,避免了頻繁查詢數(shù)據(jù)庫(kù)的操作。
以上就是 Spring Boot 結(jié)合 Redis 進(jìn)行緩存分頁(yè)數(shù)據(jù)的實(shí)現(xiàn)方法。需要注意的是,緩存的數(shù)據(jù)需要根據(jù)實(shí)際情況進(jìn)行設(shè)置過(guò)期時(shí)間,避免緩存數(shù)據(jù)過(guò)期后仍然被使用。
但是,以上代碼還是存在問(wèn)題的,如果page數(shù)據(jù)發(fā)生了變化怎么辦,redis獲取的還是老數(shù)據(jù)??!
所以,我們需要在數(shù)據(jù)更新的時(shí)候,也要更新緩存里面的數(shù)據(jù)。
來(lái)嘮嘮怎么更新緩存和簡(jiǎn)化這些操作
Spring Boot提供了一個(gè)注解@EnableCaching來(lái)啟用緩存功能。在啟用緩存功能后,可以使用注解來(lái)對(duì)某個(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
在啟動(dòng)類上添加@EnableCaching注解,開(kāi)啟緩存功能:
@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表示緩存的名稱,如果沒(méi)有指定則使用默認(rèn)緩存;key表示緩存的key值,可以使用SpEL表達(dá)式來(lái)表示。
這樣,當(dāng)?shù)谝淮握{(diào)用getUserById方法時(shí),會(huì)將返回結(jié)果緩存起來(lái),下次再調(diào)用該方法時(shí),直接從緩存中獲取結(jié)果,而不是執(zhí)行方法體。如果需要更新緩存,可以調(diào)用@CachePut注解或@CacheEvict注解來(lái)實(shí)現(xiàn)。
需要注意的是,在使用@Cacheable注解時(shí),被緩存的方法不能拋出異常,否則會(huì)導(dǎo)致緩存失效。
當(dāng)使用@Cacheable注解后,如果需要更新緩存,可以通過(guò)調(diào)用@CachePut注解來(lái)更新緩存。
@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í)會(huì)更新緩存中的數(shù)據(jù)。
// 更新用戶信息
User user = new User();
user.setId(1L);
user.setName("new name");
userService.updateUser(user);
// 查詢用戶信息,會(huì)從緩存中獲取
User userFromCache = userService.getUserById(1L);如果需要?jiǎng)h除緩存中的數(shù)據(jù),可以通過(guò)調(diào)用@CacheEvict注解來(lái)實(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í)會(huì)重新從數(shù)據(jù)庫(kù)中獲取數(shù)據(jù)。
// 刪除用戶信息 userService.deleteUserById(1L); // 查詢用戶信息,會(huì)重新從數(shù)據(jù)庫(kù)中獲取 User userFromDB = userDao.getUserById(1L);
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Redis熱點(diǎn)Key問(wèn)題的完整解決方案:
熱點(diǎn)Key就像雙十一爆款商品,1%的Key承擔(dān)了90%的流量!本文將用電商案例,教你如何智能分流、化解壓力,并通過(guò)代碼示例講解的非常詳細(xì),需要的朋友可以參考下2025-08-08
完美解決linux上啟動(dòng)redis后配置文件未生效的問(wèn)題
今天小編就為大家分享一篇完美解決linux上啟動(dòng)redis后配置文件未生效的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
Redis實(shí)現(xiàn)分布式事務(wù)的示例
Redis雖不支持傳統(tǒng)SQL數(shù)據(jù)庫(kù)ACID特性的事務(wù),但提供了事務(wù)特性,允許多命令捆綁執(zhí)行,通過(guò)命令MULTI、EXEC、DISCARD、WATCH實(shí)現(xiàn),感興趣的可以了解一下2024-10-10
使用redis獲取自增序列號(hào)實(shí)現(xiàn)方式
這篇文章主要介紹了使用redis獲取自增序列號(hào)實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
redis 存儲(chǔ)對(duì)象的方法對(duì)比分析
這篇文章主要介紹了redis 存儲(chǔ)對(duì)象的方法對(duì)比分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07

