SpringBoot is quick to start -- four: SpringBoot integrates Redis +SpringCache

Keywords: Java Redis Spring SpringBoot MySQL

Spring boot integrates redis + spring cache for caching

github source code: https://github.com/xivinChen/SpringBoot

1, Cache user

1. First, create the springboot redis cache module and copy the contents of the springboot restful API.

2. Modify the three-tier architecture, that is, add the service tier

Add the service.UserService interface, and then create the implementation class service.impl.UserServiceimpl. Remember to add @ Service annotation to the implementation class. And realize the function of adding, deleting, modifying and checking user. At the same time, change the call of Controller to UserService.

3. Add redis cache pool and other dependencies

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>

    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
    </dependency>

4. Configure redis

server:
  port: 8090

# Scan mapper.xml file
mybatis:
  mapper-locations:
    - classpath:mapping/*.xml
spring:
  application:
    name: springboot-ssm
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/springboot?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123zxc
  redis:
    host: 127.0.0.1
    port: 6379
    password: 123zxc
    database: 0
    lettuce:
      pool:
        max-active: 32
        max-wait: 300ms
        max-idle: 16
        min-idle: 8

5. Add @ EnableCaching annotation to startup class

6.Service caching

@Service
public class UserServiceImpl implements UserService {

    private Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Resource
    private UserMapper userMapper;

    @Override
    @Cacheable(value = "user:id",key = "#id")
    public User getOneUser(int id) {
        logger.info("get one go mysql ...");
        return userMapper.selectByPrimaryKey(id);
    }

    @Cacheable(value = "user:list")
    @Override
    public List<User> findAll() {
        logger.info("find all go mysql ...");
        return userMapper.list();
    }

    @CacheEvict(value = "user:list",allEntries = true)
    @Override
    public int add(User user) {
        return userMapper.insert(user);
    }

    @Caching(
            evict = {
                    @CacheEvict(value = "user:id", key = "#user.id"),
                    @CacheEvict(value = "user:list", allEntries = true)
            }
    )
    @Override
    public int update(User user) {
        return userMapper.updateByPrimaryKey(user);
    }

    @Caching(
            evict = {
                    @CacheEvict(value = "user:id", key = "#id"),
                    @CacheEvict(value = "user:list", allEntries = true)
            }
    )
    @Override
    public int delete(int id) {
        return delete(id);
    }
}

The above spring boot defaults to the configuration of redis. If we want to modify the configuration of redis, such as serialization method, default expiration time, etc. Then we need to create RedisConfig.java configuration class.

2, Manually configure RedisConfig.java

The specific configuration is as follows: one is to operate RedisTemplate of redis, and the other is the cache manager used by cache. The serialization method has been modified, so the original cache should be cleared.

@Component
@Configuration
@ConfigurationProperties("spring.cache.redis")
public class RedisConfig extends CachingConfigurerSupport {
    private Duration timeToLive = Duration.ofMinutes(30);

    public void setTimeToLive(Duration timeToLive) {
        this.timeToLive = timeToLive;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        //Solve the problem of query cache conversion exception
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        // Configure serialization (to solve the problem of garbled code)
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(timeToLive)
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();

        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }

    //RedisTemplate configuration
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        //Configuration transaction
        template.setEnableTransactionSupport(true);
        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);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key is serialized by String
        template.setKeySerializer(stringRedisSerializer);
        // The hash key also uses String serialization
        template.setHashKeySerializer(stringRedisSerializer);
        // value serialization is jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // value serialization of hash adopts jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

}

2, How to operate Redis in SpringBoot

The dependency introduced by the spring boot operation redis can be avoided

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

1. description

Spring boot redis provides a powerful template operation redis, which is RedisTemplate. It can be used to easily operate the five data types of redis. Next, we write a test class to use RedisTemplate API.

First, introduce spring boot starter test dependency and remove junit dependency. Otherwise, an error will be reported!

2. Add RedisTemplateTest

Create the RedisTemplateTest test test class under test/java/xyz.java1024, and add @ RunWith(SpringRunner.class)
@The SpringBootTest(classes = RedisApp.class) annotation specifies that the startup class is used to read configuration information. The specific code is as follows:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = RedisApp.class)
public class RedisTemplateTest {

    @Resource
    private RedisTemplate redisTemplate;

    /**
     *
     * How to use redisTemplate to operate String List Set ZSet Hash
     * This test only uses some commonly used APIs, such as more APIs for complex data types such as collections to achieve more powerful functions, just consult the relevant documents!
     *
     */

    /**
     * String Type set
     */
    @Test
    public void testSet() {
        redisTemplate.opsForValue().set("test","this is test");
    }

    /**
     * String Type get
     */
    @Test
    public void testGet() {
        Object test = redisTemplate.opsForValue().get("test");
        System.out.println("test = " + test);
    }

    /**
     * Additive elements
     */
    @Test
    public void testLSet() {
        redisTemplate.opsForList().leftPush("testList","testList1");
    }

    /**
     * Get all elements of List
     */
    @Test
    public void testLGet() {
        List testList = redisTemplate.opsForList().range("testList", 0, -1);
        System.out.println("testList = " + testList);
    }

    /**
     * Set Type set
     */
    @Test
    public void testSSet() {
        redisTemplate.opsForSet().add("testSet","testSet1");
    }

    /**
     * Set Type get
     */
    @Test
    public void testSGet() {
        Set testSet = redisTemplate.opsForSet().members("testSet");
        System.out.println("testSet = " + testSet);
    }

    /**
     * hash set
     */
    @Test
    public void testHSet() {

        redisTemplate.opsForHash().put("testHash","value1","key1");
        redisTemplate.opsForHash().put("testHash","value2","key2");
    }

    /**
     * hash get
     */
    @Test
    public void testHget() {
        Object o = redisTemplate.opsForHash().get("testHash", "value1");
        System.out.println("o = " + o);
    }

    /**
     * Zset set
     */
    @Test
    public void testZSet() {
        redisTemplate.opsForZSet().add("java1024","SpringBoot",10);
        redisTemplate.opsForZSet().add("java1024","SpringCloud",3);
    }

    /**
     * Zset get
     */
    @Test
    public void testZGet() {

        // positive sequence
        Set all = redisTemplate.opsForZSet().range("java1024", 0, -1);
        System.out.println("all = " + all);

        //Reverse order
        Set reverseRange = redisTemplate.opsForZSet().reverseRange("java1024", 0, -1);
        System.out.println("reverseRange = " + reverseRange);
    }
}

summary

Operation Redis does not rely on spring cache, and implementation of spring cache is not only Redis, but also ehCache! But now the mainstream still uses Redis for caching.

Posted by wha??? on Thu, 09 Jan 2020 06:38:02 -0800