[cache] use Redis cache in SpringBoot

Posted by richardbotw on Fri, 03 Apr 2020 19:17:08 +0200

I. Preface

Select is the most frequently used in the database, and it is basically the same every time. update, delete and insert are not used as frequently as select, and they are basically different every time. In order to reduce the pressure of the database, it is necessary to use cache for select. In the past, Ehcache was used for caching, but it has a very obvious disadvantage, that is, there is no ip or port, but the path is used, so it is not easy to share the cache. So using Redis for caching is the best choice.

Two, code

1,entity

package com.cun.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * User entity
 * @author linhongcun
 *
 */
@Entity
@Table(name = "user")
public class User{

    @Id
    @GeneratedValue
    private Integer id;

    @Column(length = 20)
    private String userName;

    @Column(length = 20)
    private String password;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

2. dao interface

package com.cun.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

import com.cun.entity.User;

/**
 * User dao interface
 * @author linhongcun
 *
 */
public interface UserDao extends JpaRepository<User, Integer>,JpaSpecificationExecutor<User>{

}

3. Service interface

package com.cun.service;

import java.util.List;

import com.cun.entity.User;

public interface UserService {

    /**
     * Get all users
     * @return
     */
    List<User> getAllUsers();

}

4. Service implementation class

package com.cun.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.cun.dao.UserDao;
import com.cun.entity.User;
import com.cun.service.UserService;

@Service
@CacheConfig(cacheNames = "userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    /**
     * 2,Method @ cache in the implementation class of Service layer
     * ① Specifies the cached key, which is the bean of the wisekeygenerator
     * 
     */
    @Override
    @Cacheable(value = "getAllUsers",keyGenerator="wiselyKeyGenerator") 
    public List<User> getAllUsers() {
        return userDao.findAll();
    }

}

5,Controller

package com.cun.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.cun.entity.User;
import com.cun.service.UserService;

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/all")
    public List<User> getAllUsers() {
        System.out.println("Print only the first time sql Sentence");
        return userService.getAllUsers();
    }

}

6. Redis configuration

package com.cun.conf;

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.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import java.lang.reflect.Method;

/**
 * Redis Cache configuration class (general)
 * @author linhongcun
 *
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    /**
     * In the collection of cache objects, the cache is saved in the form of key value. When the cached key is not specified, SpringBoot uses the SimpleKeyGenerator to generate the key.
     * @return
     */
    @Bean
    public KeyGenerator wiselyKeyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };

    }

    @Bean
    public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
        return new RedisCacheManager(redisTemplate);
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        @SuppressWarnings({ "rawtypes", "unchecked" })
        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);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

7,application.yml

server:
  port: 80
  context-path: /
spring:
  redis:
    host: 120.79.197.130
    port: 6378
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis
    username: root
    password: 123
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

8. pom.xml of redis springboot

Three, test

1. The original Redis database is empty

2. First query execution

Browser

Consoles

③ Redis database

2. Second query

Control console

Topics: Redis Database Java SQL