在之前的文章中,我們寫(xiě)了redis結(jié)合springboot做緩存分頁(yè)的方法:
在 Spring Boot 中結(jié)合 Redis 進(jìn)行緩存分頁(yè)數(shù)據(jù),可以通過(guò)以下步驟實(shí)現(xiàn):
-
在 pom.xml 文件中添加 Redis 相關(guān)依賴(lài):
<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è)查詢(xún)操作,可以將查詢(xún)結(jié)果緩存到 Redis 中,下次查詢(xún)時(shí)先從 Redis 中獲取數(shù)據(jù),如果緩存中不存在,則進(jìn)行數(shù)據(jù)庫(kù)查詢(xún),并將查詢(xún)結(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è)查詢(xún),并將查詢(xún)結(jié)果緩存到 Redis 中,緩存時(shí)間為 1 分鐘。下次查詢(xún)時(shí),如果緩存中存在數(shù)據(jù),則直接從緩存中獲取,避免了頻繁查詢(xún)數(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ù)。
這一節(jié)我們來(lái)嘮嘮怎么更新緩存和簡(jiǎn)化這些操作。
Spring Boot提供了一個(gè)注解@EnableCaching來(lái)啟用緩存功能。在啟用緩存功能后,可以使用注解來(lái)對(duì)某個(gè)方法進(jìn)行緩存。
-
首先,在pom.xml文件中添加redis依賴(lài):
<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)類(lèi)上添加@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表示緩存的名稱(chēng),如果沒(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注解類(lèi)似。在需要更新緩存的方法上添加@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)用查詢(xún)方法getUserById,此時(shí)會(huì)更新緩存中的數(shù)據(jù)。
//?更新用戶(hù)信息
User?user?=?new?User();
user.setId(1L);
user.setName("new?name");
userService.updateUser(user);
//?查詢(xún)用戶(hù)信息,會(huì)從緩存中獲取
User?userFromCache?=?userService.getUserById(1L);
-
如果需要?jiǎng)h除緩存中的數(shù)據(jù),可以通過(guò)調(diào)用@CacheEvict注解來(lái)實(shí)現(xiàn)。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-462697.html
@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)用查詢(xún)方法getUserById,此時(shí)會(huì)重新從數(shù)據(jù)庫(kù)中獲取數(shù)據(jù)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-462697.html
//?刪除用戶(hù)信息
userService.deleteUserById(1L);
//?查詢(xún)用戶(hù)信息,會(huì)重新從數(shù)據(jù)庫(kù)中獲取
User?userFromDB?=?userDao.getUserById(1L);
到了這里,關(guān)于redis緩存神器:@Cacheable注解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!