springboot集成mybatis原理剖析

article/2025/9/1 12:48:39

前言:本文主要基于springboot项目,从springboot的拓展角度来分析mybatis是如何与springboot集成的。

1、首先搭建springboot集成mybatis环境

1.1、maven pom文件依赖

<?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>imalvisc-parent</artifactId><groupId>com.imalvisc</groupId><version>1.0.0</version></parent><modelVersion>4.0.0</modelVersion><artifactId>spring-mybatis</artifactId><dependencies><!-- lombok插件 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- MySQL数据库 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- Druid数据源 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency><!-- Mybatis SpringBoot组件 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency></dependencies></project>

1.2、application.yml配置文件

###服务器配置
server:port: 9001spring:application:name: user###druid数据源配置datasource:name: dataSourcetype: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/imalvisc?useSSL=falseusername: rootpassword: imalviscdruid:initial-size: 5min-idle: 5max-active: 20max-wait: 60000time-between-eviction-runs-millis: 60000min-evictable-idle-time-millis: 300000validation-query: select 1 from dualtest-while-idle: truetest-on-borrow: falsetest-on-return: falsepool-prepared-statements: truemax-open-prepared-statements: 50max-pool-prepared-statement-per-connection-size: 20filters: stat,wallconnectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000###mybatis数据源配置
mybatis:type-aliases-package: com.imalvisc.spring.mybatis.modelconfiguration:map-underscore-to-camel-case: true

1.3、application启动类

package com.imalvisc.spring.mybatis;import com.imalvisc.spring.mybatis.mapper.UserInfoMapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;@SpringBootApplication
@MapperScan(basePackages = {"com.imalvisc.spring.mybatis.mapper"})
public class Application {public static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);UserInfoMapper userInfoMapper = applicationContext.getBean(UserInfoMapper.class);System.out.println(userInfoMapper.selectAll());}}

1.4、启动测试

以上就已经将springboot集成mybatis环境搭建完成。下面进行集成原理的解读。

2、springboot集成mybatis原理解读

2.1、在项目中引入了mybatis-spring-boot-starter依赖,mybatis-spring-boot-starter又引进了mybatis-spring-boot-autoconfigure依赖,在mybatis-spring-boot-autoconfigure的类路径下,可以看到META-INF目录下有一个spring.factories文件,文件里面的内容是org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration,这里的意思是springboot项目加载时,会扫描项目本身以及jar包类路径下的META-INF目录的spring.factories文件,然后会加载执行文件里面所配置到的类,同时这就是springboot自动配置的真谛所在。

2.2、查看MybatisAutoConfiguration类发现,这是一个Configuration类,@AutoConfigureAfter(DataSourceAutoConfiguration.class)代表在DataSourceAutoConfiguration类加载完后再加载,这里是因为mybatis环境需要依赖数据源配置,所以必须在数据源配置完成后才进行mybatis配置。在MybatisAutoConfiguration类中,配置了SqlSessionFactory类,所在到这里mybatis的环境就已经生效了。

  @Bean@ConditionalOnMissingBeanpublic SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {SqlSessionFactoryBean factory = new SqlSessionFactoryBean();factory.setDataSource(dataSource);factory.setVfs(SpringBootVFS.class);if (StringUtils.hasText(this.properties.getConfigLocation())) {factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));}applyConfiguration(factory);if (this.properties.getConfigurationProperties() != null) {factory.setConfigurationProperties(this.properties.getConfigurationProperties());}if (!ObjectUtils.isEmpty(this.interceptors)) {factory.setPlugins(this.interceptors);}if (this.databaseIdProvider != null) {factory.setDatabaseIdProvider(this.databaseIdProvider);}if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());}if (this.properties.getTypeAliasesSuperType() != null) {factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType());}if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());}if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {factory.setMapperLocations(this.properties.resolveMapperLocations());}

2.3、SqlSessionFactory配置完成后,剩下的就是扫描mapper接口并生成代理类存放到IOC容器中,这样就可以依赖注入Mapper了。

2.4、在Application启动类中,加上了@MapperScan(basePackages = {"com.imalvisc.spring.mybatis.mapper"})注解,打开MapperScan注解可以发现,MapperScan加上另一个注解@Import(MapperScannerRegistrar.class),@Import注解这里简单说明下其作用是spring环境监测到@Import注解时,会加载其指定的配置类,具体详细作用可以另查阅资料。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MapperScannerRegistrar.class)
@Repeatable(MapperScans.class)
public @interface MapperScan {

2.5、查看MapperScannerRegistrar发现,其实现了ImportBeanDefinitionRegistrar接口,该接口的作用是spring会调用实现该接口的registerBeanDefinitions方法,传入AnnotationMetadata和BeanDefinitionRegistry两个参数,AnnotationMetadata的作用是封装了加上@Import注解的注解的属性,这里解析的可能有点绕口,举例说明就是@MapperScan注解加上了@Import注解,@MapperScan有一个basePackages属性,所以AnnotationMetadata封装了@MapperScan注解的basePackages属性的值。

2.6、MapperScannerRegistrar的registerBeanDefinitions方法中,获取了@MapperScan注解的属性后,调用了自身的重载registerBeanDefinitions方法,重载registerBeanDefinitions方法通过调用ClassPathMapperScanner的doScan方法就完成了Mapper的扫描并加入到spring容器中,到了这里整个mybatis的环境就完全生效了。doScan方法里面的深入逻辑这里就不展开了,需要继续深入剖析的同学可以另查阅资料。

  @Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {AnnotationAttributes mapperScanAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));if (mapperScanAttrs != null) {registerBeanDefinitions(mapperScanAttrs, registry);}}void registerBeanDefinitions(AnnotationAttributes annoAttrs, BeanDefinitionRegistry registry) {ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);// this check is needed in Spring 3.1Optional.ofNullable(resourceLoader).ifPresent(scanner::setResourceLoader);Class<? extends Annotation> annotationClass = annoAttrs.getClass("annotationClass");if (!Annotation.class.equals(annotationClass)) {scanner.setAnnotationClass(annotationClass);}Class<?> markerInterface = annoAttrs.getClass("markerInterface");if (!Class.class.equals(markerInterface)) {scanner.setMarkerInterface(markerInterface);}Class<? extends BeanNameGenerator> generatorClass = annoAttrs.getClass("nameGenerator");if (!BeanNameGenerator.class.equals(generatorClass)) {scanner.setBeanNameGenerator(BeanUtils.instantiateClass(generatorClass));}Class<? extends MapperFactoryBean> mapperFactoryBeanClass = annoAttrs.getClass("factoryBean");if (!MapperFactoryBean.class.equals(mapperFactoryBeanClass)) {scanner.setMapperFactoryBeanClass(mapperFactoryBeanClass);}scanner.setSqlSessionTemplateBeanName(annoAttrs.getString("sqlSessionTemplateRef"));scanner.setSqlSessionFactoryBeanName(annoAttrs.getString("sqlSessionFactoryRef"));List<String> basePackages = new ArrayList<>();basePackages.addAll(Arrays.stream(annoAttrs.getStringArray("value")).filter(StringUtils::hasText).collect(Collectors.toList()));basePackages.addAll(Arrays.stream(annoAttrs.getStringArray("basePackages")).filter(StringUtils::hasText).collect(Collectors.toList()));basePackages.addAll(Arrays.stream(annoAttrs.getClassArray("basePackageClasses")).map(ClassUtils::getPackageName).collect(Collectors.toList()));scanner.registerFilters();scanner.doScan(StringUtils.toStringArray(basePackages));}

结语:mybatis集成到springboot中,主要是基于两大核心特性,一是springboot的自动配置特性,在路径下的META-INF目录的spring.factories文件配置需要加载的类,二是利用spring的@Import的ImportBeanDefinitionRegistrar特性,根据注解上指定的属性来加载配置。其实其它的技术(如Redis、RabbitMQ、JPA、Swagger等等)通过自动配置的方法集成到springboot环境中,基本都是通过这两种特性来实现,所以希望本文章不仅仅是帮助到同学们理解springboot集成mybatis的原理,更多的希望同学们可以理解springboot环境的拓展思路,以后写出更加优雅springboot拓展代码。


http://chatgpt.dhexx.cn/article/9w4Juj0s.shtml

相关文章

MyBatis原理分析(通俗易懂)

MyBatis原理分析 MyBatis工作流程简述原生MyBatis原理分析初始化工作解析配置文件配置类方式 执行SQLSqlSession API方式接口方式 真正掌握一个框架源码分析是少不了的~ 在讲解整合Spring的原理之前理解原生的MyBatis执行原理是非常有必要的 MyBatis工作流程简述 传统工作模…

【MyBatis学习笔记九】——MyBatis原理

一、Mybatis工作原理图 mybatis 原理图如下所示&#xff1a; 二、工作原理解析 mybatis应用程序通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件&#xff08;也可以用Java文件配置的方式&#xff0c;需要添加Configuration&#xff09;来构建SqlSessionFactory&…

【mybatis原理工作原理】

文章目录 mybatis原理&#xff1a;mybatis缓存机制 mybatis原理&#xff1a; mybatis的工作原理就是&#xff1a;先封装sql&#xff0c;接着调用jdbc操作数据库&#xff0c;最后把数据库返回的表结果封装成java类。 通过代码实现jdbc查询操作&#xff1a; mybatis-config.xm…

mybatis原理(含图)

上面中流程就是MyBatis内部核心流程&#xff0c;每一步流程的详细说明如下文所述&#xff1a; &#xff08;1&#xff09;读取MyBatis的配置文件。mybatis-config.xml为MyBatis的全局配置文件&#xff0c;用于配置数据库连接信息。 &#xff08;2&#xff09;加载映射文件。映…

MyBatis原理分析

是什么? MyBatis 是一款优秀的持久层框架&#xff0c;它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO&#xff08;Plain Old Java …

Spring 整合 Mybatis 原理

目录 Mybatis的基本工作原理分析需要解决的问题Spring中Bean的产生过程解决问题解决方案FactoryBean Import总结优化 Mybatis的基本工作原理 在 Mybatis 中&#xff0c;我们可以使用一个接口去定义要执行 sql&#xff0c;简化代码如下&#xff1a;定义一个接口&#xff0c;Sel…

Springboot整合mybatis原理

文章目录 加载过程1、读取META-INF/spring.factories配置文件里需要自动装载的类2、解析MybatisAutoConfiguration类里的注解信息&#xff0c;将需要管理的Bean注册到Spring容器2.1 注册SqlSessionFactory&#xff0c;并根据mapper配置文件解析出dao与具体jdbc操作、resultMap与…

【mybatis原理】

mybatis mybatis原理mybatis框架分层架构核心接口和对象mapper接口与xml的映射mybatis执行过程mybatis执行时序图一级缓存和二级缓存一级缓存二级缓存 mybatis核心流程1、初始化阶段2、代理阶段3、数据读写阶段 mybatis如何获取数据源mybatis如何获取执行SQLMyBatis 如何执行 s…

Mybatis原理

文章目录 - 什么是Mybatis&#xff1f;- Mybaits的优点&#xff1a;- MyBatis框架的缺点&#xff1a;- MyBatis与Hibernate有哪些不同&#xff1f;- 架构MyBatis缓存一级缓存一级缓存和sqlsession之间的关系一级缓存的生命周期有多长&#xff1f;SqlSession 一级缓存的工作流程…

深入详解Mybatis的架构原理与6大核心流程

MyBatis 是 Java 生态中非常著名的一款 ORM 框架&#xff0c;目前在一线互联网大厂中应用广泛&#xff0c;Mybatis已经成为了一个必会框架。 如果你想要进入一线大厂&#xff0c;能够熟练使用 MyBatis 开发已经是一项非常基本的技能&#xff0c;同时大厂也更希望自己的开发人员…

总结Mybatis的原理

一、什么是Mybatis Mybatis是一个半ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;底层封装了JDBC&#xff0c;是程序员在开发时只需要关注SQL语句本身&#xff0c;不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。MyBatis 可以使用简单的 XM…

MyBatis基本工作原理介绍

1、MyBatis基本工作原理介绍 计算机的基本工作就是存储和计算&#xff0c;而MyBatis是存储领域的利器。MyBatis的基本工作原理就是&#xff1a;先封装SQL&#xff0c;接着调用JDBC操作数据库&#xff0c;最后把数据库返回的表结果封装成Java类。 2、MyBatis的核心流程介绍 m…

Mybatis 工作原理详解

目录 Mybatis持久层框架 结果集进行ORM映射 步骤解析 1、获取结果集及结果映射入口 2、开始ORM映射接口 3、数据库结果集解析&#xff0c;完成ORM映射 4、保存并获取ORM映射后的结果集 参数传递方式 顺序传参法 Param注解传参法 Map传参法 Java Bean传参法 mybat…

《深入理解mybatis原理》 MyBatis的架构设计以及实例分析

MyBatis是目前非常流行的ORM框架&#xff0c;它的功能很强大&#xff0c;然而其实现却比较简单、优雅。本文主要讲述MyBatis的架构设计思路&#xff0c;并且讨论MyBatis的几个核心部件&#xff0c;然后结合一个select查询实例&#xff0c;深入代码&#xff0c;来探究MyBatis的实…

【图片压缩】三个方法压缩图片体积

图片体积过大&#xff0c;会占用电脑过多的容量&#xff0c;也有可能无法发送给其他人。我们可以压缩图片体积来解决问题。分享三个方法压缩图片体积&#xff1a; 方法一&#xff1a;改变图片格式 首先是改变图片的格式&#xff0c;如果你不介意压缩之后的图片画质损失&#…

Windows不同压缩软件、压缩算法、压缩率详细对比测试与选择

上次写了图片压缩&#xff0c;这倒让我想起几年前看过的一个很有意思的东西 那就是这张鸭子图&#xff1a; 不过微信会压缩图片&#xff0c;你可以打开这个链接&#xff1a;http://2.im.guokr.com/F70Kn-4wz7aF5Yejf9W3g6kO4exDBqVEb0TumQmxy5MiAQAAEAEAAEpQ.jpg 来获取原图 …

为什么压缩图片和压缩

为什么要压缩图片&#xff1f; 表示图像需要大量的数据&#xff0c;但图像数据是高度相关的&#xff0c;或者说存在冗余(Redundancy)信息&#xff0c;去掉这些冗余信息后可以有效压缩图像&#xff0c;同时又不会损害图像的有效信息。 视网膜上有两种感光细胞&#xff0c;能够…

2款免费的图片压缩工具

今天写这篇文章的目的&#xff0c;主要是为大家介绍2款免费的图片压缩工具&#xff0c;在工作和学习中这也是一项必备的技能。比如当你遇到比较大的图片需要发送的时候&#xff0c;或者对图片的大小有强制要求的时候&#xff0c;这些小工具就派上了用场。 网上也有一些付费的压…

如何批量压缩图片体积大小kb?

工作中&#xff0c;我们在使用图片素材时&#xff0c;图片kb体积过大怎么办&#xff1f; 通常我们会直接在电脑上将图片调整成我们想要的尺寸大小&#xff0c;可以利用的工具有photoshop或者截图的方法&#xff0c;这对于有些小伙伴来说不是很难的事情&#xff0c;今天我就不做…

图片批量压缩方法及步骤

图片批量压缩方法及步骤&#xff01;平常我们会将手机拍摄的照片传输到电脑里保存&#xff0c;时间久了后电脑中会有大量的图片&#xff0c;这些图片大都是1M-2M的体积大小&#xff0c;这些图片会占用大量的电脑磁盘空间&#xff0c;可能会导致电脑变得很卡等现象。但是又不忍心…