代码:

依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-data-redis</artifactId>
  5. </dependency>
  6. <!-- mybatis 持久层-->
  7. <dependency>
  8. <groupId>org.mybatis.spring.boot</groupId>
  9. <artifactId>mybatis-spring-boot-starter</artifactId>
  10. <version>2.1.2</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework.boot</groupId>
  14. <artifactId>spring-boot-starter-web</artifactId>
  15. </dependency>
  16. <dependency>
  17. <groupId>org.apache.commons</groupId>
  18. <artifactId>commons-pool2</artifactId>
  19. <version>2.8.0</version>
  20. </dependency>
  21. <dependency>
  22. <groupId>mysql</groupId>
  23. <artifactId>mysql-connector-java</artifactId>
  24. <scope>runtime</scope>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.projectlombok</groupId>
  28. <artifactId>lombok</artifactId>
  29. <optional>true</optional>
  30. </dependency>
  31. <dependency>
  32. <groupId>org.springframework.boot</groupId>
  33. <artifactId>spring-boot-starter-test</artifactId>
  34. <scope>test</scope>
  35. <exclusions>
  36. <exclusion>
  37. <groupId>org.junit.vintage</groupId>
  38. <artifactId>junit-vintage-engine</artifactId>
  39. </exclusion>
  40. </exclusions>
  41. </dependency>
  42. </dependencies>

application.properties

  1. server.port=8081
  2. # ============数据库============
  3. spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  4. spring.datasource.url=jdbc:mysql://localhost:3308/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
  5. spring.datasource.username=root
  6. spring.datasource.password=root
  7. # ============mybatis============
  8. mybatis.mapper-locations=classpath:/mapper/*.xml
  9. mybatis.type-aliases-package=com.example.entity
  10. mybatis.configuration.map-underscore-to-camel-case=true
  11. mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
  12. # ============redis============
  13. # 默认是使用0号数据库,这里我们使用1号,笔者现在0号有其他数据- -
  14. spring.redis.database=1
  15. spring.redis.host=localhost
  16. spring.redis.port=6379
  17. # 默认密码为空
  18. spring.redis.password=
  19. # 连接池最大连接数
  20. spring.redis.lettuce.pool.max-active=8
  21. # 连接池最大阻塞等待时间
  22. spring.redis.lettuce.pool.max-wait=-1ms
  23. # 连接池中的最大空闲连接
  24. spring.redis.lettuce.pool.max-idle=8
  25. # 连接池中的最小空闲连接
  26. spring.redis.lettuce.pool.min-idle=0

RedisConfig.java

  1. package com.example.redispractice.config;
  2. import com.fasterxml.jackson.annotation.JsonAutoDetect;
  3. import com.fasterxml.jackson.annotation.PropertyAccessor;
  4. import com.fasterxml.jackson.databind.ObjectMapper;
  5. import org.springframework.cache.CacheManager;
  6. import org.springframework.cache.annotation.EnableCaching;
  7. import org.springframework.context.annotation.Bean;
  8. import org.springframework.context.annotation.Configuration;
  9. import org.springframework.data.redis.cache.RedisCacheConfiguration;
  10. import org.springframework.data.redis.cache.RedisCacheManager;
  11. import org.springframework.data.redis.connection.RedisConnectionFactory;
  12. import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
  13. import org.springframework.data.redis.serializer.RedisSerializationContext;
  14. import org.springframework.data.redis.serializer.RedisSerializer;
  15. import org.springframework.data.redis.serializer.StringRedisSerializer;
  16. import java.time.Duration;
  17. /**
  18. * @author seanwang
  19. * @date 2021/7/2 0002 上午 10:09
  20. */
  21. @Configuration
  22. @SuppressWarnings("all")
  23. @EnableCaching
  24. public class RedisConfig {
  25. @Bean
  26. public CacheManager cacheManager(RedisConnectionFactory factory) {
  27. RedisSerializer<String> redisSerializer = new StringRedisSerializer();
  28. Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
  29. //解决查询缓存转换异常的问题
  30. ObjectMapper om = new ObjectMapper();
  31. om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  32. om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
  33. jackson2JsonRedisSerializer.setObjectMapper(om);
  34. // 配置序列化(解决乱码的问题)
  35. RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
  36. .entryTtl(Duration.ofDays(1))
  37. .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
  38. .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
  39. .disableCachingNullValues();
  40. RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
  41. .cacheDefaults(config)
  42. .build();
  43. return cacheManager;
  44. }
  45. }

UserDao.java

  1. package com.example.redispractice.dao;
  2. import com.example.redispractice.entity.User;
  3. import org.apache.ibatis.annotations.Mapper;
  4. import org.springframework.stereotype.Repository;
  5. import java.util.List;
  6. @Repository
  7. @Mapper
  8. public interface UserDao {
  9. int deleteByPrimaryKey(Integer id);
  10. int insert(User record);
  11. int insertSelective(User record);
  12. User selectByPrimaryKey(Integer id);
  13. int updateByPrimaryKeySelective(User record);
  14. int updateByPrimaryKey(User record);
  15. List<User> queryAllUser();
  16. }

UserService.java

  1. package com.example.redispractice.service;
  2. import com.example.redispractice.entity.User;
  3. import java.util.List;
  4. /**
  5. * @author seanwang
  6. * @date 2021/7/2 0002 上午 9:11
  7. */
  8. public interface UserService {
  9. int deleteByPrimaryKey(Integer id);
  10. int insert(User record);
  11. int insertSelective(User record);
  12. User selectByPrimaryKey(Integer id);
  13. int updateByPrimaryKeySelective(User record);
  14. int updateByPrimaryKey(User record);
  15. List<User> queryAllUser();
  16. int get1();
  17. int get2();
  18. int put1();
  19. int evict();
  20. }

UserServiceImpl.java

  1. package com.example.redispractice.service.impl;
  2. import com.example.redispractice.dao.UserDao;
  3. import com.example.redispractice.entity.User;
  4. import com.example.redispractice.service.UserService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.cache.annotation.CacheConfig;
  7. import org.springframework.cache.annotation.CacheEvict;
  8. import org.springframework.cache.annotation.CachePut;
  9. import org.springframework.cache.annotation.Cacheable;
  10. import org.springframework.stereotype.Service;
  11. import javax.annotation.Resource;
  12. import java.util.List;
  13. /**
  14. * @author seanwang
  15. * @date 2021/7/2 0002 上午 9:12
  16. */
  17. @Service
  18. @CacheConfig(cacheNames = "userCache")
  19. public class UserServiceImpl implements UserService {
  20. @Resource
  21. UserDao userDao;
  22. static int i = 0;
  23. @Override
  24. public int deleteByPrimaryKey(Integer id) {
  25. return userDao.deleteByPrimaryKey(id);
  26. }
  27. @Override
  28. public int insert(User record) {
  29. return userDao.insert(record);
  30. }
  31. @Override
  32. public int insertSelective(User record) {
  33. return userDao.insertSelective(record);
  34. }
  35. @Override
  36. @Cacheable
  37. public User selectByPrimaryKey(Integer id) {
  38. return userDao.selectByPrimaryKey(id);
  39. }
  40. @Override
  41. public int updateByPrimaryKeySelective(User record) {
  42. return userDao.updateByPrimaryKeySelective(record);
  43. }
  44. @Override
  45. public int updateByPrimaryKey(User record) {
  46. return userDao.updateByPrimaryKey(record);
  47. }
  48. @Override
  49. @Cacheable(value = "allUser")
  50. public List<User> queryAllUser() {
  51. return userDao.queryAllUser();
  52. }
  53. @Override
  54. @Cacheable(value="cache1")
  55. public int get1() {
  56. return ++i;
  57. }
  58. /**
  59. * Cacheable注解会根据设置的value先读缓存,读取到value值下的缓存就不走方法,没有对应的才会执行方法,(没有缓存才执行)
  60. * @return 更新后的i值
  61. */
  62. @Override
  63. @Cacheable(value="cache2")
  64. public int get2() {
  65. return ++i;
  66. }
  67. /**
  68. * CachePut注解会执行方法,判断设置的value是否有对应缓存来进行新增/更新缓存
  69. * @return 返回操作后的i值
  70. */
  71. @Override
  72. @CachePut(value={"cache1"})
  73. public int put1() {
  74. return ++i;
  75. }
  76. /**
  77. * 清空CacheEvict指定value的缓存,并执行方法。
  78. * @return 返回操作后的i值
  79. */
  80. @Override
  81. @CacheEvict(value={"cache1","cache2"})
  82. public int evict() {
  83. System.out.println("some thing");
  84. return --i;
  85. }
  86. }

UserController.java

  1. package com.example.redispractice.controller;
  2. import com.example.redispractice.entity.User;
  3. import com.example.redispractice.service.UserService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.web.bind.annotation.GetMapping;
  6. import org.springframework.web.bind.annotation.PathVariable;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.RestController;
  9. import javax.annotation.Resource;
  10. import javax.servlet.http.HttpServletRequest;
  11. import java.util.List;
  12. /**
  13. * @author seanwang
  14. * @date 2021/7/2 0002 下午 1:57
  15. */
  16. @RestController
  17. public class UserController {
  18. @Resource
  19. private UserService userService;
  20. @GetMapping("/list")
  21. public List<User> getAllUsers() {
  22. return userService.queryAllUser();
  23. }
  24. @GetMapping("/{id}")
  25. public User getUserById(@PathVariable("id") int id) {
  26. return userService.selectByPrimaryKey(id);
  27. }
  28. @RequestMapping("/login")
  29. public String login(HttpServletRequest request){
  30. System.out.println(userService.get1());
  31. System.out.println(userService.get2());
  32. return "fail";
  33. }
  34. @RequestMapping("/put")
  35. public String put(HttpServletRequest request){
  36. userService.put1();
  37. return "fail";
  38. }
  39. @RequestMapping("/evict")
  40. public int evict(HttpServletRequest request){
  41. return userService.evict();
  42. }
  43. }

测试:

访问localhost:8081/list:
image.png
此时Service中的查询方法上的注解@Cacheable(value = “allUser”)生效,会保存到缓存:
image.png

再次访问localhost:8081/list:
直接走缓存里的数据,并没有走方法执行sql:
image.png


注解介绍:

@CacheConfig

image.pngimage.png

@Cacheable

优先读取缓存,缓存读到了就不走方法了。缓存如果没有则执行方法,并缓存到redis。

@CachePut

CachePut注解会执行方法,判断设置的value是否有对应缓存来进行新增/更新缓存
image.png

@CacheEvict

清空CacheEvict指定value的缓存,并执行方法。
image.png