Spring Boot USES redis to implement data caching
- 2020-06-23 00:28:41
- OfStack
Based on spring Boot 1.5.2.ES3en version, 1 aspect validates the integration approach with Redis, plus understands the usage.
Integration method
1. Configuration dependencies
Modify ES11en. xml to add the following.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2. Configure Redis
Modify the
application.yml
, add the following.
spring:
redis:
host: localhost
port: 6379
pool:
max-idle: 8
min-idle: 0
max-active: 8
max-wait: -1
3. Configure Redis cache
package net.jackieathome.cache;
import java.lang.reflect.Method;
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 com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration
@EnableCaching // Enable caching
public class RedisConfig extends CachingConfigurerSupport {
// When caching data Key Can be customized based on business and technical scenarios
// @Bean
// public KeyGenerator customizedKeyGenerator() {
// 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();
// }
// };
//
// }
// Custom cache manager properties, provided by default CacheManager The object may not meet the requirements
// Therefore, it is recommended to rely on business and technical requirements and do it yourself 1 Some extensions and customizations
@Bean
public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
redisCacheManager.setDefaultExpiration(300);
return redisCacheManager;
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
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;
}
}
Verify the effect of the integration
Considering that future projects will implement database access based on MyBatis, and the use of caching can effectively improve the interaction experience of Web pages, the following two validation schemes are designed.
Plan 1
Adds a cache annotation to the data object accessing the database, defining the cache policy. From the test results, the cache works.
1. Page controller
package net.jackieathome.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import net.jackieathome.bean.User;
import net.jackieathome.dao.UserDao;
import net.jackieathome.db.mapper.UserMapper;
@RestController
public class UserController {
@Autowired
private UserDao userDao;
@RequestMapping(method = RequestMethod.GET, value = "/user/id/{id}")
public User findUserById(@PathVariable("id") String id) {
return userDao.findUserById(id);
}
@RequestMapping(method = RequestMethod.GET, value = "/user/create")
public User createUser() {
long time = System.currentTimeMillis() / 1000;
String id = "id" + time;
User user = new User();
user.setId(id);
userDao.createUser(user);
return userDao.findUserById(id);
}
}
2. Mapper definition
package net.jackieathome.db.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import net.jackieathome.bean.User;
@Mapper
public interface UserMapper {
void createUser(User user);
User findUserById(@Param("id") String id);
}
3. Data access objects
package net.jackieathome.dao;
import java.util.ArrayList;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import net.jackieathome.bean.User;
import net.jackieathome.db.mapper.UserMapper;
@Component
@CacheConfig(cacheNames = "users")
@Transactional
public class UserDao {
private static final Logger LOG = LoggerFactory.getLogger(UserDao.class);
@Autowired
private UserMapper userMapper;
@CachePut(key = "#p0.id")
public void createUser(User user) {
userMapper.createUser(user);
LOG.debug("create user=" + user);
}
@Cacheable(key = "#p0")
public User findUserById(@Param("id") String id) {
LOG.debug("find user=" + id);
return userMapper.findUserById(id);
}
}
Scheme 2
Add cache annotations directly to the Mapper definition to control the cache policy. From the test results, the cache is effective and the test code is a little more concise than that in scenario 1.
1. Page controller
package net.jackieathome.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import net.jackieathome.bean.User;
import net.jackieathome.dao.UserDao;
import net.jackieathome.db.mapper.UserMapper;
@RestController
public class UserController {
@Autowired
private UserMapper userMapper;
@RequestMapping(method = RequestMethod.GET, value = "/user/id/{id}")
public User findUserById(@PathVariable("id") String id) {
return userMapper.findUserById(id);
}
@RequestMapping(method = RequestMethod.GET, value = "/user/create")
public User createUser() {
long time = System.currentTimeMillis() / 1000;
String id = "id" + time;
User user = new User();
user.setId(id);
userMapper.createUser(user);
return userMapper.findUserById(id);
}
}
2. Mapper definition
package net.jackieathome.db.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import net.jackieathome.bean.User;
@CacheConfig(cacheNames = "users")
@Mapper
public interface UserMapper {
@CachePut(key = "#p0.id")
void createUser(User user);
@Cacheable(key = "#p0")
User findUserById(@Param("id") String id);
}
conclusion
The above two test schemes are not superior or inferior, but only to verify the use method of cache and reflect different control granularity. In the actual project development process, different decisions should be made according to the actual situation.