代码:
依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- mybatis 持久层--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.2</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.8.0</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies>
application.properties
server.port=8081# ============数据库============spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3308/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8spring.datasource.username=rootspring.datasource.password=root# ============mybatis============mybatis.mapper-locations=classpath:/mapper/*.xmlmybatis.type-aliases-package=com.example.entitymybatis.configuration.map-underscore-to-camel-case=truemybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl# ============redis============# 默认是使用0号数据库,这里我们使用1号,笔者现在0号有其他数据- -spring.redis.database=1spring.redis.host=localhostspring.redis.port=6379# 默认密码为空spring.redis.password=# 连接池最大连接数spring.redis.lettuce.pool.max-active=8# 连接池最大阻塞等待时间spring.redis.lettuce.pool.max-wait=-1ms# 连接池中的最大空闲连接spring.redis.lettuce.pool.max-idle=8# 连接池中的最小空闲连接spring.redis.lettuce.pool.min-idle=0
RedisConfig.java
package com.example.redispractice.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;import com.fasterxml.jackson.annotation.PropertyAccessor;import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.cache.CacheManager;import org.springframework.cache.annotation.EnableCaching;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.cache.RedisCacheConfiguration;import org.springframework.data.redis.cache.RedisCacheManager;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;import org.springframework.data.redis.serializer.RedisSerializationContext;import org.springframework.data.redis.serializer.RedisSerializer;import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;/*** @author seanwang* @date 2021/7/2 0002 上午 10:09*/@Configuration@SuppressWarnings("all")@EnableCachingpublic class RedisConfig {@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisSerializer<String> redisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);//解决查询缓存转换异常的问题ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);// 配置序列化(解决乱码的问题)RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofDays(1)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues();RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();return cacheManager;}}
UserDao.java
package com.example.redispractice.dao;import com.example.redispractice.entity.User;import org.apache.ibatis.annotations.Mapper;import org.springframework.stereotype.Repository;import java.util.List;@Repository@Mapperpublic interface UserDao {int deleteByPrimaryKey(Integer id);int insert(User record);int insertSelective(User record);User selectByPrimaryKey(Integer id);int updateByPrimaryKeySelective(User record);int updateByPrimaryKey(User record);List<User> queryAllUser();}
UserService.java
package com.example.redispractice.service;import com.example.redispractice.entity.User;import java.util.List;/*** @author seanwang* @date 2021/7/2 0002 上午 9:11*/public interface UserService {int deleteByPrimaryKey(Integer id);int insert(User record);int insertSelective(User record);User selectByPrimaryKey(Integer id);int updateByPrimaryKeySelective(User record);int updateByPrimaryKey(User record);List<User> queryAllUser();int get1();int get2();int put1();int evict();}
UserServiceImpl.java
package com.example.redispractice.service.impl;import com.example.redispractice.dao.UserDao;import com.example.redispractice.entity.User;import com.example.redispractice.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cache.annotation.CacheConfig;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;import javax.annotation.Resource;import java.util.List;/*** @author seanwang* @date 2021/7/2 0002 上午 9:12*/@Service@CacheConfig(cacheNames = "userCache")public class UserServiceImpl implements UserService {@ResourceUserDao userDao;static int i = 0;@Overridepublic int deleteByPrimaryKey(Integer id) {return userDao.deleteByPrimaryKey(id);}@Overridepublic int insert(User record) {return userDao.insert(record);}@Overridepublic int insertSelective(User record) {return userDao.insertSelective(record);}@Override@Cacheablepublic User selectByPrimaryKey(Integer id) {return userDao.selectByPrimaryKey(id);}@Overridepublic int updateByPrimaryKeySelective(User record) {return userDao.updateByPrimaryKeySelective(record);}@Overridepublic int updateByPrimaryKey(User record) {return userDao.updateByPrimaryKey(record);}@Override@Cacheable(value = "allUser")public List<User> queryAllUser() {return userDao.queryAllUser();}@Override@Cacheable(value="cache1")public int get1() {return ++i;}/*** Cacheable注解会根据设置的value先读缓存,读取到value值下的缓存就不走方法,没有对应的才会执行方法,(没有缓存才执行)* @return 更新后的i值*/@Override@Cacheable(value="cache2")public int get2() {return ++i;}/*** CachePut注解会执行方法,判断设置的value是否有对应缓存来进行新增/更新缓存* @return 返回操作后的i值*/@Override@CachePut(value={"cache1"})public int put1() {return ++i;}/*** 清空CacheEvict指定value的缓存,并执行方法。* @return 返回操作后的i值*/@Override@CacheEvict(value={"cache1","cache2"})public int evict() {System.out.println("some thing");return --i;}}
UserController.java
package com.example.redispractice.controller;import com.example.redispractice.entity.User;import com.example.redispractice.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import java.util.List;/*** @author seanwang* @date 2021/7/2 0002 下午 1:57*/@RestControllerpublic class UserController {@Resourceprivate UserService userService;@GetMapping("/list")public List<User> getAllUsers() {return userService.queryAllUser();}@GetMapping("/{id}")public User getUserById(@PathVariable("id") int id) {return userService.selectByPrimaryKey(id);}@RequestMapping("/login")public String login(HttpServletRequest request){System.out.println(userService.get1());System.out.println(userService.get2());return "fail";}@RequestMapping("/put")public String put(HttpServletRequest request){userService.put1();return "fail";}@RequestMapping("/evict")public int evict(HttpServletRequest request){return userService.evict();}}
测试:
访问localhost:8081/list:
此时Service中的查询方法上的注解@Cacheable(value = “allUser”)生效,会保存到缓存:
再次访问localhost:8081/list:
直接走缓存里的数据,并没有走方法执行sql:
注解介绍:
@CacheConfig
@Cacheable
优先读取缓存,缓存读到了就不走方法了。缓存如果没有则执行方法,并缓存到redis。
@CachePut
CachePut注解会执行方法,判断设置的value是否有对应缓存来进行新增/更新缓存
@CacheEvict
清空CacheEvict指定value的缓存,并执行方法。

