1, Build environment
- Configure Maven.
- Spring boot integrates Redis.
- SpringBoot integrates Mybatis.
The parent pom.xml file is as follows:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>spring-boot-starter-parent</artifactId> <groupId>org.springframework.boot</groupId> <version>2.5.6</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.zhao</groupId> <artifactId>Redis</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <properties> <jedis.version>4.0.0-beta4</jedis.version> <junit.version>4.13.1</junit.version> <spring.boot.starter.data.redis>2.5.4</spring.boot.starter.data.redis> <lombok.version>1.18.20</lombok.version> <mybatis.spring.boot.starter>2.2.0</mybatis.spring.boot.starter> <druid.spring.boot.starter>1.2.5</druid.spring.boot.starter> <mysql.connect.java>8.0.26</mysql.connect.java> </properties> <modules> <module>01-Jedis</module> <module>02-SpringBoot-Redis</module> <module>03-Mybatis-Redis</module> </modules> <dependencyManagement> <dependencies> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>${jedis.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>${spring.boot.starter.data.redis}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis.spring.boot.starter}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid.spring.boot.starter}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.connect.java}</version> </dependency> </dependencies> </dependencyManagement> </project>
The configuration file application.yaml is as follows:
server: port: 8809 spring: redis: database: 0 port: 6379 host: localhost datasource: type: com.alibaba.druid.pool.DruidDataSource druid: url: jdbc:mysql://localhost:3306/demo?characterEncoding=UTF-8 username: root password: 123 driver-class-name: com.mysql.cj.jdbc.Driver mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.zhao.entity configuration: cache-enabled: true logging: level: com: zhao: dao: debug
2, Get Redis client's tool class
RedisTemplate is used here as the Redis client.
package com.zhao.util; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Configuration; //Get the factory created by SpringBoot @Configuration @Slf4j public class ApplicationContextUtils implements ApplicationContextAware { //Retained factories private static ApplicationContext applicationContext; //Pass the created factory to this class as a parameter @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } //Provides methods to get objects in the factory //RedisTemplate redisTemplate public static Object getBean(String beanName) { if (beanName == null && beanName.equals(" ")) { return null; } return applicationContext.getBean(beanName); } }
3, Customize Redis Cache class and implement Cache interface.
Note: 1. There must be a string member variable. 2. There must be a constructor to pass values for this member variable. 3.pojo/entity object must implement serialization interface.
package com.zhao.cache; import com.zhao.util.ApplicationContextUtils; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.cache.Cache; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.util.concurrent.locks.ReadWriteLock; @Slf4j public class RedisCache implements Cache { private final String id; public RedisCache(String id) { if (id == null) { throw new IllegalArgumentException("Cache instances require an ID"); } this.id = id; } @Override public String getId() { return id; } @Override public void putObject(Object key, Object value) { //Use the hash type in redis as the storage type of the cache getRedisTemplate().opsForHash().put(id.toString(), key.toString(), value); log.info("Query results stored in cache: id:{} key:{} value:{}", id.toString(), key.toString(), value.toString()); } @Override public Object getObject(Object key) { //Get stored data Object value = getRedisTemplate().opsForHash().get(id.toString(), key.toString()); log.info("Get cached content:{}", value); return value; } @Override public Object removeObject(Object key) { log.info("implement removeObject Method to remove the cache."); getRedisTemplate().opsForHash().delete(id, key.toString()); return null; } @Override public void clear() { log.info("implement clear Method to empty the cache."); getRedisTemplate().delete(id.toString());//wipe cache } @Override public int getSize() { //Gets the number of key values in the hash int num = getRedisTemplate().opsForHash().size(id).intValue(); log.info("Gets the number of key value pairs in the cache:", num); return num; } @Override public ReadWriteLock getReadWriteLock() { return null; } //Encapsulate redisTemplate private RedisTemplate getRedisTemplate() { //Get redisTemplate RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate"); redisTemplate.setValueSerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); return redisTemplate; } }
- getId(): get the Id value. This Id value is the same as namespace.
- putObject(Object key, Object value): store the queried value into the cache. Since both keys and values are objects, we choose redisTemplate as the client for Redis operation and use hash type data to store cached values. Key corresponds to the member variable id, hkey corresponds to the method parameter Object key, and hvalue corresponds to the method parameter Object value.
- getObject(Object key): get value according to the key.
- Removeobject (object key): a reserved method in mybatis. It can only be called when fallback. It can not be implemented.
- clear(): update/delete/insert this method is called at the bottom when updating the cache. What I implement here is to delete the cache under the current namespace according to the member variable id.
- getReadWriteLock(): read-write lock is used to keep synchronization, which can not be implemented.
- getRedisTemplate(): This is a method we added ourselves, not a method in the Cache interface. Use this method to obtain the RedisTemplate object in the ApplicationContext. In addition, key and hkey do not need to store objects, but only strings. So I set key and hkey to use StringRedisSerializer instead of the default JDK serializer.
4, Enable L2 cache and set cache
xml is used here
<!--open mybatis L2 cache for--> <cache type="com.zhao.cache.RedisCache"/>
5, Special attention
If transaction control is added to the server layer, if @ Transactional(propagation = Propagation.SUPPORTS) or @ Transactional(propagation = Propagation.NOT_SUPPORTED) annotations are added to update / delete / add methods, update / delete / add will not call the clear() method in the buffer class, and the cache in Redis cannot be cleared.