LOADING

加载过慢请开启缓存 浏览器默认开启

redis做mybatis的二级缓存

redis做mybatis的二级缓存

项目版本: springboot:3.1.4 、数据库:MySQL 8.0.27、redis: 7.0.14、jkd17

1.导入相关jar包

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>
        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>2.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.21</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.13.0</version>
        </dependency>
        <!-- 使用 Redis 作为缓存实现,需要添加此 starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>32.1.2-jre</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
            <version>4.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

2.设置配置文件

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
  datasource:
    # 数据库连接地址
    url: jdbc:127.0.0.1:3306/cache?useUnicode=true
    # 数据库用户名
    username: root
    # 数据库密码
    password: 123456
    # 数据库驱动类
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 数据源类型
    type: com.zaxxer.hikari.HikariDataSource
  data:
    # redis连接地址
    redis:
      host: 127.0.0.1
      port: 11524
      lettuce:
        pool:
          max-active: 8
          max-idle: 8
          max-wait: -1
  cache:
    #缓存类型
    type: redis
    # redis缓存配置
    redis:
      # 缓存key前缀
      key-prefix: cache-
      #      # 是否缓存空值
      #      cache-null-values: true
      #过期时间15分钟
      time-to-live: 900s
mybatis-plus:
  type-aliases-package: com.example.cache.domain
  mapper-locations: classpath:mapper/*.xml
  configuration:
    cache-enabled: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# springdoc-openapi项目配置
springdoc:
  swagger-ui:
    path: /swagger-ui.html
    tags-sorter: alpha
    operations-sorter: alpha
  api-docs:
    path: /v3/api-docs
  group-configs:
    - group: 'default'
      paths-to-match: '/**'
      packages-to-scan: com.example.cache.controller
# knife4j的增强配置,不需要增强可以不配
knife4j:
  enable: true
  setting:
    language: zh_cn

3.Mapper查询

@Mapper
public interface UserMapper extends BaseMapper<User> {

    List<User> list();
}

4.Redis使用json序列化RedisTemplate

   /**
     * redis序列化
     */
    @Bean(name = "RedisTemplate")
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //设置key的序列化方式
        redisTemplate.setKeySerializer(RedisSerializer.string());
        //设置value的序列化方式
        redisTemplate.setValueSerializer(RedisSerializer.json());
        //设置hash的key的序列化方式
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        //设置hash的value的序列化方式
        redisTemplate.setHashValueSerializer(RedisSerializer.json());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

5.实现自定义cache

/**
 * @author 25212
 */
@Slf4j
public class MybatisRedisCache implements Cache {

    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);


    private final RedisTemplate<String, Object> redisTemplate = SpringUtil.getBean("RedisTemplate");


    private final String id;

    public MybatisRedisCache(final String id) {
        if (StringUtils.isBlank(id)) {
            throw new IllegalArgumentException("Cache instances require an ID");
        }
        this.id = id;
    }


    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public void putObject(Object key, Object value) {
        if (value != null) {
            log.debug("保存缓存");
            //保存数据并设置其过期时间为1天
            redisTemplate.opsForValue().set(key.toString(), value, Duration.ofDays(1));
        }
    }

    @Override
    public Object getObject(Object key) {
        try {
            if (key != null) {
                return redisTemplate.opsForValue().get(key.toString());
            }
        } catch (Exception e) {
            log.error("缓存出错 ");
        }
        return null;
    }

    @Override
    public Object removeObject(Object key) {
        if (key != null) {
            log.debug("清除缓存");
            redisTemplate.delete(key.toString());
        }
        return null;
    }

    @Override
    public void clear() {
        log.debug("清空缓存");
        Set<String> keys = redisTemplate.keys("*:" + this.id + "*");
        if (!CollectionUtils.isEmpty(keys)) {
            redisTemplate.delete(keys);
        }
    }

    @Override
    public int getSize() {
        Long size = redisTemplate.execute(RedisServerCommands::dbSize);
        return size != null ? size.intValue() : 0;
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        return this.readWriteLock;
    }
}

6.在mapper中开启二级缓存

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.cache.mapper.UserMapper">
<!--    指定自定义序列号方式-->
    <cache type="com.example.cache.cache.MybatisRedisCache"/>

    <select id="list" resultType="com.example.cache.domain.User">
        select  * from user
    </select>
</mapper>