SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存

 

1 环境说明

  JDK: 1.8

  MAVEN: 3.

  SpringBoot: 2.0.4

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第1张图片

 

2 SpringBoot集成Mybatis-Plus

  2.1 创建SpringBoot

    利用IDEA创建SpringBoot项目,引入web mysql mybatis-plus lombok devtools依赖

    技巧01:SpringBoot没有mybatis的启动依赖,需要到maven仓库查询

        
            com.baomidou
            mybatis-plus-boot-starter
            3.0.1
        

复制代码



    4.0.0

    com.example
    spring_mybatisplus_redis
    0.0.1-SNAPSHOT
    jar

    spring_mybatisplus_redis
    Demo project for Spring Boot

    
        org.springframework.boot
        spring-boot-starter-parent
        2.0.5.RELEASE
         
    

    
        UTF-8
        UTF-8
        1.8
    

    
        
            
            
        

        
            com.baomidou
            mybatis-plus-boot-starter
            3.0.1
        

        
            org.springframework.boot
            spring-boot-devtools
            runtime
        
        
            mysql
            mysql-connector-java
            runtime
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


复制代码

  2.2 配置数据库连接

    在 application.yml中配置数据库的连接信息

  2.3 创建实体类

    根据数据表创建对应的实体类

复制代码

/*
Navicat MySQL Data Transfer

Source Server         : mysql5.4
Source Server Version : 50540
Source Host           : localhost:3306
Source Database       : testdemo

Target Server Type    : MYSQL
Target Server Version : 50540
File Encoding         : 65001

Date: 2018-09-16 22:55:16
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `student`
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(50) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `age` int(10) NOT NULL,
  `address` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', 'wys', '24', '重庆');
INSERT INTO `student` VALUES ('2', '王杨帅', '24', '重庆');
INSERT INTO `student` VALUES ('3', '王杨帅', '25', '渝足');
INSERT INTO `student` VALUES ('4', '王杨帅', '25', '重庆');
INSERT INTO `student` VALUES ('5', '杨玉林', '0', '大足');
INSERT INTO `student` VALUES ('6', '杨玉林', '22', '渝足');
INSERT INTO `student` VALUES ('7', '杨玉林', '20', '重庆');
INSERT INTO `student` VALUES ('8', '杨玉林', '24', '大足');
INSERT INTO `student` VALUES ('9', 'wys', '33', '渝足');
INSERT INTO `student` VALUES ('10', '杨玉林', '24', '重庆');
INSERT INTO `student` VALUES ('11', '杨玉林', '32', '渝足');
INSERT INTO `student` VALUES ('12', '杨玉林', '24', '大足');
INSERT INTO `student` VALUES ('13', '杨玉林', '6', '重庆');
INSERT INTO `student` VALUES ('14', '三少', '24', '渝足');
INSERT INTO `student` VALUES ('15', '杨玉林', '4', '大足');
INSERT INTO `student` VALUES ('16', '杨玉林', '24', '渝足');
INSERT INTO `student` VALUES ('17', 'wys', '12', '重庆');
INSERT INTO `student` VALUES ('18', '杨玉林', '0', '渝足');
INSERT INTO `student` VALUES ('19', '杨玉林', '24', null);

复制代码

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第2张图片

  2.4 创建持久层接口

    技巧01:由于使用的是mybatis-plus,所以持久层接口只要继承了BaseMapper就可以拥有简单的CRUD功能,这一点跟SpringData JPA 很相似

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第3张图片

  2.5 启动类配置

    在启动类上添加@MapperScan注解来扫描持久层接口,只有添加了这个注解才可以依赖注入持久层接口

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第4张图片

  2.6 测试

    》依赖注入持久层接口

    》调用mybatis-plus默认提供的方法进行CRUD操作

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第5张图片

 

3 SpringBoot集成Mybatis-Plus进阶

  说明:在第2节中是利用mybatis-plus提供的方法进行CRUD操作,其实mybatis-plus是对mybatis的封装,它同样可以向mybatis那样利用xml映射文件来实现数据库操作

  3.1 创建mybatis配置文件

复制代码




    
        
        
    

复制代码

  3.2 创建映射文件

    技巧01:在resources目录下创建一个xml文件用来存放映射文件

    技巧02:在映射接口中声明一个方法

复制代码

package com.example.spring_mybatisplus_redis.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.spring_mybatisplus_redis.pojo.dataobject.Student;

/**
 * @author 王杨帅
 * @create 2018-09-16 22:31
 * @desc
 **/
public interface StudentMapper extends BaseMapper {

    Student getById(Long id);

}

复制代码

复制代码






    

复制代码

  3.3 配置文件

    在 application.yml 中配置mybatis配置文件和映射文件位置

  3.4 测试效果

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第6张图片

 

4 MyBatis-Plus开启二级缓存

  技巧01:mybatis的以及缓存默认是开启的,二级缓存默认是关闭的

  技巧02:一级缓存是SqlSession级别,二级缓存是SqlSessionFactory级别

  技巧03:从二级换粗中获取到的数据都是缓存数据的副本,从一级缓存中获取到的数据是缓存数据的引用

  4.1 Mybatis默认的二级缓存

    技巧01:直接在映射文件中添加   即可开启二级缓存

    技巧02:mybatis默认的二级缓存是利用Map实现的

    4.1.1 序列化实体类

      使用二级缓存时必须对实体类进行序列化

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第7张图片

    4.1.2 映射文件修改

      在映射文件中添加   

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第8张图片

    4.1.3 利用映射器进行数据操作

      技巧01:映射器 = 映射接口 + 映射文件

      说明:本案例比较简单,直接在controller类中依赖注入映射器接口,实际开发中应该在service中进行的

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第9张图片

    4.1.4 测试效果

      启动应用后,访问多次 /test/{id} 

      技巧01:第一次访问时会从数据库中读取数据,后面的就会从二级缓存中读取数据

      技巧02:delete、update、insert操作都会清空二级缓存,前提是这三种操作对应的标签上的 flushCache属性值为true(默认值就是true)

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第10张图片

  4.2 利用EhCache实现二级缓存

    4.2.1 引入ehcache依赖

        
            org.mybatis.caches
            mybatis-ehcache
            1.1.0
        

    4.2.2 配置EhCache

复制代码



    
    
    

    
    

复制代码

    4.2.3 修改映射文件

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第11张图片

    4.2.4 测试效果

      启动应用多次访问 /student/{id}

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第12张图片

  4.3 利用Spring Cache实现缓存

    4.3.1 新建一个SpringBoot项目

      引入web springcache依赖

复制代码

        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-cache
        

复制代码

    4.3.2 开启SpringCache依赖

      在启动类上利用@EnableCaching来引入SpringCache的默认配置

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第13张图片

    4.3.3 如何使用

      在需要使用缓存的方法上添加相关注解就可以啦,例如

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第14张图片

  4.4.4 测试效果

    启动应用,多次访问 /test/test01 时,只打印了一次日志,因为从第二次开始就会到SpringCache中去寻找对应的缓存数据

    说明:SpringCache一般用于service层中的方法的,这里只是为了达到测试效果就直接在controller层中进行了测试

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第15张图片

  4.4 利用Redis实现缓存

    注意使用Redis实现缓存时需要用到SpringCache相关技术,因为SrpingCache支持多种缓存实现

    SpringBoot项目集成好SpringCache和Redis后,只需要在application.yml文件中配置  spring.cache.type=redis 就可以啦

    技巧01:具体使用时在方法上添加@Cacheable等类似注解就可以啦

复制代码

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1/javaarchitect?characterEncoding=utf-8&useSSL=false
    username: root
    password: 182838

  thymeleaf:
    cache: false

  redis:
    host: 127.0.0.1
    port: 6379

  cache:
    type: redis

  jpa:
    properties:
      hibernate:
        format_sql: true
        show_sql: true

mybatis-plus:
  type-aliases-package: com.example.homework.pojo
  config-location: classpath:/mybatis-config.xml
  mapper-locations: classpath:xml/*Mapper.xml

复制代码

 

5 SpringBoot 集成 Spring Cache

  请参见第4.3小节

 

6 SpringBoot集成Redis

  6.1 安装redis服务器

    参考博文

  6.2 创建SpringBoot项目

    引入web redis lombok devtools依赖

        
            org.springframework.boot
            spring-boot-starter-data-redis
        

  6.3 配置redis服务信息

spring.redis.host=127.0.0.1
spring.redis.port=6379

  6.4 重写配置RedisTemplate对应Bean的配置

    主要是为了设置序列化方式

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第16张图片

复制代码

package com.example.spring_redis02.configs;

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 java.net.UnknownHostException;

@Configuration
public class RedisConfiguration {

    /**
     * 重写RedisTemplate的Bean
     * @param redisConnectionFactory
     * @return
     * @throws UnknownHostException
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        RedisTemplate template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        jackson2JsonRedisSerializer.setObjectMapper(new ObjectMapper());

        template.setKeySerializer(jackson2JsonRedisSerializer);
        template.setValueSerializer(jackson2JsonRedisSerializer);

        return template;
    }

}

复制代码

  6.5 编写RedisTemplate工具类

    技巧01:这个工具类只是为了简化操作而言的,没有也没关系

复制代码

package com.example.spring_redis02.utils;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

@Component
public class RedisUtil {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     * @return
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据key 获取过期时间
     *
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除缓存
     *
     * @param key 可以传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    //============================String=============================  

    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 递增
     *
     * @param key 键
     * @param by  要增加几(大于0)
     * @return
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 递减
     *
     * @param key 键
     * @param by  要减少几(小于0)
     * @return
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    //================================Map=================================  

    /**
     * HashGet
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return 值
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 获取hashKey对应的所有键值
     *
     * @param key 键
     * @return 对应的多个键值
     */
    public Map hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     *
     * @param key 键
     * @param map 对应多个键值
     * @return true 成功 false 失败
     */
    public boolean hmset(String key, Map map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * HashSet 并设置时间
     *
     * @param key  键
     * @param map  对应多个键值
     * @param time 时间(秒)
     * @return true成功 false失败
     */
    public boolean hmset(String key, Map map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  时间(秒)  注意:如果已存在的hash表有时间,这里将会替换原有的时间
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除hash表中的值
     *
     * @param key  键 不能为null
     * @param item 项 可以使多个 不能为null
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }

    /**
     * 判断hash表中是否有该项的值
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return true 存在 false不存在
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     *
     * @param key  键
     * @param item 项
     * @param by   要增加几(大于0)
     * @return
     */
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }

    /**
     * hash递减
     *
     * @param key  键
     * @param item 项
     * @param by   要减少记(小于0)
     * @return
     */
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }

    //============================set=============================  

    /**
     * 根据key获取Set中的所有值
     *
     * @param key 键
     * @return
     */
    public Set sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据value从一个set中查询,是否存在
     *
     * @param key   键
     * @param value 值
     * @return true 存在 false不存在
     */
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将数据放入set缓存
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 将set数据放入缓存
     *
     * @param key    键
     * @param time   时间(秒)
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSetAndTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) expire(key, time);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 获取set缓存的长度
     *
     * @param key 键
     * @return
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 移除值为value的
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 移除的个数
     */
    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    //===============================list=================================  

    /**
     * 获取list缓存的内容
     *
     * @param key   键
     * @param start 开始
     * @param end   结束  0 到 -1代表所有值
     * @return
     */
    public List lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取list缓存的长度
     *
     * @param key 键
     * @return
     */
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 通过索引 获取list中的值
     *
     * @param key   键
     * @param index 索引  index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
     * @return
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, List value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, List value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据索引修改list中的某条数据
     *
     * @param key   键
     * @param index 索引
     * @param value 值
     * @return
     */
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 移除N个值为value
     *
     * @param key   键
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */
    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
} 
  

复制代码

  6.6 测试效果

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存_第17张图片

你可能感兴趣的:(50,工作中基础学习)