redis緩存神器之@Cacheable注解詳解
redis之@Cacheable注解
在之前的文章中,我們寫了redis結(jié)合springboot做緩存分頁的方法:
在Spring Boot中結(jié)合Redis進行緩存分頁數(shù)據(jù)
可以通過以下步驟實現(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)建一個 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 對象進行緩存操作。
例如,對于分頁查詢操作,可以將查詢結(jié)果緩存到 Redis 中,下次查詢時先從 Redis 中獲取數(shù)據(jù),如果緩存中不存在,則進行數(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 插件進行分頁查詢,并將查詢結(jié)果緩存到 Redis 中,緩存時間為 1 分鐘。下次查詢時,如果緩存中存在數(shù)據(jù),則直接從緩存中獲取,避免了頻繁查詢數(shù)據(jù)庫的操作。
以上就是 Spring Boot 結(jié)合 Redis 進行緩存分頁數(shù)據(jù)的實現(xiàn)方法。需要注意的是,緩存的數(shù)據(jù)需要根據(jù)實際情況進行設(shè)置過期時間,避免緩存數(shù)據(jù)過期后仍然被使用。
但是,以上代碼還是存在問題的,如果page數(shù)據(jù)發(fā)生了變化怎么辦,redis獲取的還是老數(shù)據(jù)??!
所以,我們需要在數(shù)據(jù)更新的時候,也要更新緩存里面的數(shù)據(jù)。
來嘮嘮怎么更新緩存和簡化這些操作
Spring Boot提供了一個注解@EnableCaching來啟用緩存功能。在啟用緩存功能后,可以使用注解來對某個方法進行緩存。
首先,在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);
}
}在需要進行緩存的方法上添加@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注解有兩個重要的參數(shù):value和key。value表示緩存的名稱,如果沒有指定則使用默認緩存;key表示緩存的key值,可以使用SpEL表達式來表示。
這樣,當(dāng)?shù)谝淮握{(diào)用getUserById方法時,會將返回結(jié)果緩存起來,下次再調(diào)用該方法時,直接從緩存中獲取結(jié)果,而不是執(zhí)行方法體。如果需要更新緩存,可以調(diào)用@CachePut注解或@CacheEvict注解來實現(xiàn)。
需要注意的是,在使用@Cacheable注解時,被緩存的方法不能拋出異常,否則會導(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ù)時,先調(diào)用更新方法updateUser,然后再調(diào)用查詢方法getUserById,此時會更新緩存中的數(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注解來實現(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ù)時,先調(diào)用刪除方法deleteUserById,然后再調(diào)用查詢方法getUserById,此時會重新從數(shù)據(jù)庫中獲取數(shù)據(jù)。
// 刪除用戶信息 userService.deleteUserById(1L); // 查詢用戶信息,會重新從數(shù)據(jù)庫中獲取 User userFromDB = userDao.getUserById(1L);
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

