文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Springboot整合mybatis开启二级缓存的实现示例

2024-04-02 19:55

关注

前言

下面大部分内容来源于网上的相关帖子和官网,自己简单写了个demo体验了下,个人感觉mybatis的缓存并不是很合适

查询做缓存时,遇到更新操作就会刷新缓存,尤其是多表查询时,就会很难控制。对于那些需要缓存的热数据应该抽出来放到redis上做。

mybatis 一级缓存和二级缓存的概念

之所以称之为“二级缓存”,是相对于“一级缓存”而言的。既然有了一级缓存,那么为什么要提供二级缓存呢?我们知道,在一级缓存中,不同session进行相同SQL查询的时候,是查询两次数据库的。显然这是一种浪费,既然SQL查询相同,就没有必要再次查库了,直接利用缓存数据即可,这种思想就是MyBatis二级缓存的初衷。

另外,Spring和MyBatis整合时,每次查询之后都要进行关闭sqlsession,关闭之后数据被清空。所以MyBatis和Spring整合之后,一级缓存是没有意义的。如果开启二级缓存,关闭sqlsession后,会把该sqlsession一级缓存中的数据添加到mapper namespace的二级缓存中。这样,缓存在sqlsession关闭之后依然存在。

pom引入依赖

<dependencies>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.2</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependencies>    

application.properties 文件配置

spring.datasource.type=com.zaxxer.hikari.HikariDataSource
#Spring jdbc 数据源配置 需要mysql-connector-java驱动依赖
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/gefrm?useUnicode=true&characterEncoding=utf-8&useSSL=false&useInformationSchema=true&serverTimezone=Asia/Shanghai&autoReconnect=true&failOverReadOnly=false
spring.datasource.username=root
spring.datasource.password=123456
#mybatis配置
mybatis.mapper-locations=classpath:mapper

SET NAMES utf8mb4;
SET
FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for bsc_dict_info_test
-- ----------------------------
DROP TABLE IF EXISTS `bsc_dict_info_test`;
CREATE TABLE `bsc_dict_info_test`
(
    `dict_id`        varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci   NOT NULL DEFAULT ' ' COMMENT '字典标识',
    `dict_name`      varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci  NOT NULL DEFAULT ' ' COMMENT '字典名称',
    `dict_sitm_id`   varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci   NOT NULL DEFAULT ' ' COMMENT '字典子项标识',
    `dict_sitm_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci  NOT NULL DEFAULT ' ' COMMENT '字典子项名称',
    `suse_flag`      char(1) CHARACTER SET utf8 COLLATE utf8_general_ci       NOT NULL DEFAULT '0' COMMENT '启用标志',
    `disp_orde`      int(11) NOT NULL DEFAULT 0 COMMENT '展示顺序',
    `memo`           varchar(4000) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT ' ' COMMENT '备注'
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of bsc_dict_info_test
-- ----------------------------
INSERT INTO `bsc_dict_info_test`
VALUES ('bbbbbtest', '担保人/被担保人与上市公司关联关系', '999', '无关联关系', '0', 190, '1');
INSERT INTO `bsc_dict_info_test`
VALUES ('aaaaatest', '担保人/被担保人与上市公司关联关系', '999', '无关联关系', '0', 190, '1');
INSERT INTO `bsc_dict_info_test`
VALUES ('bbbbbtest', '担保人/被担保人与上市公司关联关系', '999', '无关联关系', '0', 190, '1');
INSERT INTO `bsc_dict_info_test`
VALUES ('aaaaatest', '担保人/被担保人与上市公司关联关系', '999', '无关联关系', '0', 190, '1');
INSERT INTO `bsc_dict_info_test`
VALUES ('bbbbbtest', '担保人/被担保人与上市公司关联关系', '999', '无关联关系', '0', 190, '\'0\'');

SET
FOREIGN_KEY_CHECKS = 1;

bean 类

package com.example.mybatis_cache.bean;

import lombok.Builder;
import lombok.Data;

import java.io.Serializable;


@Data
@Builder
public class BscDictInfoTestDO implements Serializable {
    private String dictId;
    private String dictName;
    private String dictSitmId;
    private String dictSitmName;
    private String suseFlag;
    private String dispOrde;
    private String memo;

}

mapper

package com.example.mybatis_cache.mapper;

import com.example.mybatis_cache.bean.BscDictInfoTestDO;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;


@Mapper
public interface BscDictInfoTestMapper {
    
    List<BscDictInfoTestDO> selectAll();
}

service

package com.example.mybatis_cache.service;


public interface BscDictService {
    void info(String name, int age);
}

impl

package com.example.mybatis_cache.service.impl;


import com.example.mybatis_cache.bean.BscDictInfoTestDO;
import com.example.mybatis_cache.mapper.BscDictInfoTestMapper;
import com.example.mybatis_cache.service.BscDictService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;


@Slf4j
@Component
public class BscDictServiceImpl implements BscDictService {

    @Resource
    BscDictInfoTestMapper mapper;

    @Override
    public void info(String name, int age) {
        log.warn("name:{}, age:{}", name, age);
        List<BscDictInfoTestDO> list = mapper.selectAll();
        list.forEach(item -> {
            log.error("{}", item);
        });
    }
}

测试类
 

package com.example.mybatis_cache.service.impl;

import com.example.mybatis_cache.service.BscDictService;
import com.mysql.cj.xdevapi.SessionFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.*;


@Slf4j
@SpringBootTest
class BscDictServiceImplTest {

    @Autowired
    private BscDictService dictService;

    @Test
    void levelOneCacheTest() {
        dictService.info("a", 1);
        log.warn("======================== 分割线  ======================");
        dictService.info("a", 2);

    }

    @Test
    void testRawLevelOne() {
    }
}

测试结果

执行2次查询,只执行了一次,第二次命中的是缓存

踩坑

启动抛异常:

Error creating bean with name 'cacheAutoConfigurationValidator' defined in class path resource [org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: No cache manager could be auto-configured, check your configuration (caching type is 'EHCACHE')

解决 添加依赖 spring-boot-starter-cache

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

启动抛异常:

Error creating bean with name 'cacheManager' defined in class path resource [org/springframework/boot/autoconfigure/cache/EhCacheCacheConfiguration.class]: Unsatisfied dependency expressed through method 'cacheManager' parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ehCacheCacheManager' defined in class path resource [org/springframework/boot/autoconfigure/cache/EhCacheCacheConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [net.sf.ehcache.CacheManager]: Factory method 'ehCacheCacheManager' threw exception; nested exception is java.lang.IllegalArgumentException: Cache configuration does not exist 'ServletContext resource [/ehcache.xml]'

解决:注意classpath:不能少

spring.cache.ehcache.config=classpath:ehcache.xml

参考资料

MyBatis二级缓存介绍
mybatis官网中文
MyBatis 二级缓存全详解
Spring Cache和EhCache实现缓存管理
第四篇:SpringBoot中Cache缓存的使用

到此这篇关于Springboot整合mybatis开启二级缓存的实现示例的文章就介绍到这了,更多相关Springboot mybatis二级缓存内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯