The first is to add dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>${spring-boot.version}</version>
</dependency>
Copy the code
The SpringBoot version I’m using here is: 2.2.5.release
Jedis and lettuce
- 1, Jedis:
In the implementation is directly connected to redis Server, multi-threaded environment is not thread safe, unless the use of connection pool, for each Redis instance to increase the physical connection.
- 2, Lettuce,
RedisConnection is a scalable, thread-safe, completely non-blocking Redis client that allows multiple threads to share a Single RedisConnection. It utilizes the Netty NIO framework to efficiently manage multiple connections, thereby providing asynchronous and synchronous data access for building non-blocking, reactive applications.
In the database, the user database is created using the database database.
spring:
datasource:
url: jdbc:mysql:/ / 192.168.104.64:3306 / spring_boot_plus? serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: root
passwordHuauN2021 # Redis configurationredis:
database: 0
host: 192.168104.102.
password: huauN@2021
port: 6379
timeout: 6000Connection timeout duration (ms)lettuce:
pool:
max-active: 1024The maximum number of connections in the pool (default8, -1If a pool has been allocated more than max_active jedis instances, the pool is exhausted.10000The maximum waiting time in milliseconds is -1Max-idle: JedisConnectionException max-idle10
min-idle: 5
Copy the code
First, check the redis configuration class, if not, add a new configuration class:
package gc.cnnvd.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/** * <p> * Redis Template configuration * </p> **@author linmengmeng
* @dateThe 2021-07-21 * /
@Configuration
public class RedisTemplateConfig {
/** * redisTemplate configuration *@param factory
* @return* * * Reasons for customizing RedisTemplate: * 1, modified generic way as the < String, Object >, avoid cumbersome type conversion * 2, will change the value of serialization Jackson2JsonRedisSerializer, because the underlying RedisSerializer serialized value will not bring the double quotes, Using Jackson2JsonRedisSerializer serialized String type automatically add double quotation marks. * * /
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
// Specify the domain to serialize. ANY is public and private
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// Specify the type of serialization input. The class must be non-final or an error will be reported
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(mapper);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// Set key to String serialization
redisTemplate.setKeySerializer(stringRedisSerializer);
// Set the hash key to String serialization
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// Set value to jackson2 serialization
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// Set the hash value to jackson2 serialization
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
returnredisTemplate; }}Copy the code
If redisTemplate has been configured before, adding the redisTemplatebean will raise an exception when it is started, indicating that the redisTemplatebean failed to be created, or that it already exists.
Then RedisCacheConfig:
package gc.cnnvd.config; 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.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.time.Duration; import java.util.Arrays; /** * <p> * Redis Cache Configuration * </p> * @author geekidea * @date 2018-11-08 */ @configuration @enablecaching public class RedisCacheConfig extends CachingConfigurerSupport { @Bean @Override public KeyGenerator keyGenerator() { return (target, method, params) -> { StringBuffer redisKey = new StringBuffer(); redisKey.append(target.getClass().getName()).append("-"); redisKey.append(method.getName()); if (params.length > 0) { redisKey.append("-").append(Arrays.deepToString(params)); } return redisKey.toString(); }; } /** * Redis cache configuration * modify the serialization method to resolve cache garble * @param Factory * @return */ @bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisSerializer<String> redisSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); / / configuration serialization RedisCacheConfiguration config = RedisCacheConfiguration. DefaultCacheConfig (); RedisCacheConfiguration RedisCacheConfiguration = config //Key serialization redisSerializer .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) / / value jackson2JsonRedisSerializer serialized way SerializeValuesWith (RedisSerializationContext. SerializationPair. FromSerializer (jackson2JsonRedisSerializer)) / / / / set prefix .prefixkeyswith ("project:") // Set expiration time.entryTTL (duration.ofseconds (60*60)); RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .cacheDefaults(redisCacheConfiguration) .build(); return cacheManager; }}Copy the code
I’m going to add the @enablesCheduling annotation to the configuration file. If I don’t add the @enablesCheduling annotation to the startup class, I’m going to add the @enablescheduling annotation
Find a random service method to test:
@Override @Cacheable(value = "adminUser",key = "#adminUserDetailParam.getId()",unless = "#result==null") public AdminUserDetailVO getAdminUserDetail(AdminUserDetailParam adminUserDetailParam) { AdminUserMerger adminUserMerger = adminUserMapper.selectAdminUserDetail(adminUserDetailParam.getId(), adminUserDetailParam.getVersion()); Log. info("------------ go to the database query -------------"); If (adminUserMerger == null) {throw new BusinessException(" User information does not exist "); } AdminUserDetailVO adminUserDetailVO = new AdminUserDetailVO(); BeanCopierUtils.copyProperties(adminUserMerger, adminUserDetailVO); return adminUserDetailVO; }Copy the code
Here only on the basis of the original added a line of annotation @ Cacheable (value = “adminUser” key = “# adminUserDetailParam. GetId ()”, unless = “# result = = null”) Where value is the prefix of the key of redis,
import com.alibaba.fastjson.JSONObject;
import gc.cnnvd.system.adminuser.param.AdminUserDetailParam;
import gc.cnnvd.system.adminuser.service.AdminUserService;
import gc.cnnvd.system.adminuser.vo.AdminUserDetailVO;
import gc.cnnvd.test.BaseTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
/ * * *@Auther linmengmeng
* @Date The 2021-07-20 after * /
public class QueryTest extends BaseTest {
@Autowired
private AdminUserService adminUserService;
@Test
public void testGetAdminDetail(){
AdminUserDetailParam adminUserDetailParam = new AdminUserDetailParam();
adminUserDetailParam.setId("test001");
adminUserDetailParam.setVersion(0); AdminUserDetailVO adminUserDetail = adminUserService.getAdminUserDetail(adminUserDetailParam); System.out.println(JSONObject.toJSONString(adminUserDetail)); }}Copy the code
After writing the test case, the run found that the cache worked, the first time through the database query, the second time directly through the Redis cache.
Cache content, use visualization tools to view the following picture: