Java SpringBoot Redis

前言

Redis安装参考

语雀内容

1、JavaBean对象缓存

I,SpringBoot提供的Redis缓存使用注解

A.@CachePut

将方法结果返回存放到缓存中。

B.@Cacheable

先从缓存中通过定义的键查询,如果可以查到数据,则返回,否则执行该方法,返回数据,并且将返回的结果保存到缓存中。

C.@CacheEvict

通过定义的键移除缓存,它有一个boolean类型的配置项beforeInvocation,表示在方法之前或者之后移除缓存。默认是false,所以默认为方法之后将缓存移除。

II,SpringBoot整合RedisTemplate案例

A.配置缓存管理RedisConfig.java

  1. package org.hand.train.springboot.springboot.config;
  2. import org.hand.train.springboot.springboot.bean.UserInfo;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.context.annotation.Primary;
  6. import org.springframework.data.redis.cache.RedisCacheConfiguration;
  7. import org.springframework.data.redis.cache.RedisCacheManager;
  8. import org.springframework.data.redis.cache.RedisCacheWriter;
  9. import org.springframework.data.redis.connection.RedisConnectionFactory;
  10. import org.springframework.data.redis.core.RedisTemplate;
  11. import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
  12. import org.springframework.data.redis.serializer.RedisSerializationContext;
  13. /**
  14. * RedisConfig
  15. * <p>
  16. * encoding:UTF-8
  17. *
  18. * @author Fcant 19:20 2019/12/5
  19. */
  20. @Configuration
  21. public class RedisConfig {
  22. @Bean
  23. public RedisTemplate<Object, UserInfo> redisUserTemplate(RedisConnectionFactory redisConnectionFactory) {
  24. RedisTemplate<Object, UserInfo> template = new RedisTemplate<>();
  25. template.setConnectionFactory(redisConnectionFactory);
  26. Jackson2JsonRedisSerializer<UserInfo> serializer = new Jackson2JsonRedisSerializer<UserInfo>(UserInfo.class);
  27. template.setDefaultSerializer(serializer);
  28. return template;
  29. }
  30. /**
  31. * 配置主缓存管理@Primary,使用时默认用主缓存,其他的相应配置也可以在类@CacheConfig 方法@Cacheable引入
  32. * @author Fcant 19:44 2019/12/5
  33. */
  34. @Primary
  35. @Bean
  36. public RedisCacheManager userCacheManager(RedisTemplate<Object, UserInfo> redisEmpTemplate) {
  37. RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisEmpTemplate.getConnectionFactory());
  38. RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
  39. .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisEmpTemplate.getValueSerializer()));
  40. return new RedisCacheManager(redisCacheWriter,redisCacheConfiguration);
  41. }
  42. }

B.缓存配置CacheConfig.java

  1. package org.hand.train.springboot.springboot.config;
  2. import org.springframework.cache.interceptor.KeyGenerator;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import java.lang.reflect.Method;
  6. import java.util.Arrays;
  7. /**
  8. * CacheConfig
  9. * <p>
  10. * encoding:UTF-8
  11. *
  12. * @author Fcant 22:09 2019/12/5
  13. */
  14. @Configuration
  15. public class CacheConfig {
  16. @Bean("keyGenerator")
  17. public KeyGenerator keyGenerator() {
  18. return new KeyGenerator() {
  19. @Override
  20. public Object generate(Object o, Method method, Object... objects) {
  21. return method.getName() + "[" + Arrays.asList(objects).toString() + "]";
  22. }
  23. };
  24. }
  25. }

C.在ServiceImpl实现类上配置主机使用缓存

  1. package org.hand.train.springboot.springboot.service.impl;
  2. import org.hand.train.springboot.springboot.bean.UserInfo;
  3. import org.hand.train.springboot.springboot.mapper.IUserMapper;
  4. import org.hand.train.springboot.springboot.service.IUserService;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.cache.annotation.CacheConfig;
  9. import org.springframework.cache.annotation.CacheEvict;
  10. import org.springframework.cache.annotation.CachePut;
  11. import org.springframework.cache.annotation.Cacheable;
  12. import org.springframework.stereotype.Service;
  13. import org.springframework.transaction.annotation.Transactional;
  14. import java.util.List;
  15. /**
  16. * UserServiceImpl
  17. * <p>
  18. * encoding:UTF-8
  19. *
  20. * @author Fcant
  21. * @date 17:27 2019/12/3
  22. */
  23. @Service
  24. @CacheConfig(cacheNames = "user", cacheManager = "userCacheManager")
  25. public class UserServiceImpl implements IUserService {
  26. /**
  27. * 数据库操作失败的数字返回值
  28. */
  29. private final int FAILURE_CODE = 0;
  30. private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);
  31. @Autowired
  32. IUserMapper userMapper;
  33. @Cacheable(cacheNames = "user", key = "#id")
  34. @Override
  35. public UserInfo selectUserById(int id) {
  36. LOGGER.info("从数据库查询ID为 {} 的用户" , id);
  37. return userMapper.selectUserById(id);
  38. }
  39. /**
  40. * 添加用户
  41. * 此处缓存主键使用Mybatis回填的自增主键
  42. *
  43. * @param userInfo
  44. * @return UserInfo
  45. * @author Fcant 9:22 2019/12/6
  46. */
  47. @CachePut(cacheNames = "user", key = "#result.userId")
  48. @Transactional(rollbackFor = Exception.class)
  49. @Override
  50. public UserInfo addUser(UserInfo userInfo) {
  51. int i = userMapper.addUser(userInfo);
  52. if (i == FAILURE_CODE) {
  53. return null;
  54. }
  55. return userInfo;
  56. }
  57. @CachePut(cacheNames = "user", key = "#userInfo.userId")
  58. @Transactional(rollbackFor = Exception.class)
  59. @Override
  60. public UserInfo updateUser(UserInfo userInfo) {
  61. int i = userMapper.updateUser(userInfo);
  62. if (i == FAILURE_CODE) {
  63. return null;
  64. }
  65. return userInfo;
  66. }
  67. @CacheEvict(beforeInvocation = true, cacheNames = "user", key = "#userInfo.userId")
  68. @Transactional(rollbackFor = Exception.class)
  69. @Override
  70. public UserInfo delUser(UserInfo userInfo) {
  71. int i = userMapper.delUser(userInfo);
  72. if (i == FAILURE_CODE) {
  73. return null;
  74. }
  75. userInfo = userMapper.selectUserById(userInfo.getUserId());
  76. return userInfo;
  77. }
  78. }

2、List集合缓存

I,自定义处理List集合的缓存接口-IUserCache.java

  1. package org.hand.train.springboot.springboot.cache;
  2. import org.hand.train.springboot.springboot.bean.UserInfo;
  3. import java.util.List;
  4. /**
  5. * UserCache
  6. * <p>
  7. * encoding:UTF-8
  8. *
  9. * @author Fcant 10:18 2019/12/6
  10. */
  11. public interface IUserCache {
  12. /**
  13. * 将查询到的Users的List集合缓存到Redis
  14. *
  15. * @param key
  16. * @param userInfoList
  17. * @author Fcant 10:21 2019/12/6
  18. */
  19. void listUsersSave(String key, List<UserInfo> userInfoList);
  20. /**
  21. * 从缓存中获取用户集合
  22. *
  23. * @param key
  24. * @return List<UserInfo>
  25. * @author Fcant 10:25 2019/12/6
  26. */
  27. List<UserInfo> getUsersList(String key);
  28. }

II,实现缓存处理的接口-UserCacheImpl.java

  1. package org.hand.train.springboot.springboot.cache.impl;
  2. import com.google.gson.Gson;
  3. import org.hand.train.springboot.springboot.bean.UserInfo;
  4. import org.hand.train.springboot.springboot.cache.IUserCache;
  5. import org.springframework.data.redis.core.StringRedisTemplate;
  6. import org.springframework.data.redis.core.ValueOperations;
  7. import org.springframework.stereotype.Service;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. /**
  11. * IUserCacheImpl
  12. * <p>
  13. * encoding:UTF-8
  14. *
  15. * @author Fcant 10:26 2019/12/6
  16. */
  17. @Service
  18. public class UserCacheImpl implements IUserCache {
  19. private final StringRedisTemplate redisTemplate;
  20. public UserCacheImpl(StringRedisTemplate redisTemplate) {
  21. this.redisTemplate = redisTemplate;
  22. }
  23. /**
  24. * 将查询到的Users的List集合缓存到Redis
  25. *
  26. * @param key 缓存的Key
  27. * @param userInfoList 缓存的集合
  28. * @author Fcant 10:21 2019/12/6
  29. */
  30. @Override
  31. public void listUsersSave(String key, List<UserInfo> userInfoList) {
  32. Gson gson = new Gson();
  33. ValueOperations<String, String> stringStringValueOperations = redisTemplate.opsForValue();
  34. stringStringValueOperations.set(key, gson.toJson(userInfoList));
  35. }
  36. /**
  37. * 从缓存中获取用户集合
  38. *
  39. * @param key 获取缓存的key
  40. * @return List<UserInfo>
  41. * @author Fcant 10:25 2019/12/6
  42. */
  43. @Override
  44. public List<UserInfo> getUsersList(String key) {
  45. ValueOperations<String,String> vo = redisTemplate.opsForValue();
  46. String userList = vo.get(key);
  47. Gson gson = new Gson();
  48. List<UserInfo> userInfoList = gson.fromJson(userList, List.class);
  49. return userInfoList == null ? new ArrayList<>() : userInfoList;
  50. }
  51. }

III,在Service层使用

  1. package org.hand.train.springboot.springboot.service.impl;
  2. import org.hand.train.springboot.springboot.bean.UserInfo;
  3. import org.hand.train.springboot.springboot.cache.IUserCache;
  4. import org.hand.train.springboot.springboot.mapper.IUserMapper;
  5. import org.hand.train.springboot.springboot.service.IUserService;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.stereotype.Service;
  10. import java.util.List;
  11. /**
  12. * UserServiceImpl
  13. * <p>
  14. * encoding:UTF-8
  15. *
  16. * @author Fcant
  17. * @date 17:27 2019/12/3
  18. */
  19. @Service
  20. public class UserServiceImpl implements IUserService {
  21. /**
  22. * 数据库操作失败的数字返回值
  23. */
  24. private final int FAILURE_CODE = 0;
  25. private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);
  26. @Autowired
  27. private IUserCache userCache;
  28. @Autowired
  29. IUserMapper userMapper;
  30. @Override
  31. public List<UserInfo> selectAllUser() {
  32. List<UserInfo> usersList;
  33. usersList = userCache.getUsersList("userList");
  34. if (usersList.isEmpty()) {
  35. LOGGER.info("从数据库查询所有用户信息");
  36. usersList = userMapper.selectAllUser();
  37. userCache.listUsersSave("userList", usersList);
  38. }
  39. return usersList;
  40. }
  41. }

3、本次整合的目录结构

image.png