第九章 : mybatis-spring-boot-starter 机制原理
第九章 : mybatis-spring-boot-starter 机制原理
前言
本章节知识重点:通过分析 mybatis-spring-boot-starter组件构成以及 @Mapper 或 @MapperScan 注解的作用,深入理解mybatis的集成原理,理解Springboot是如何加载mybatis的接口、mapper.xml以及mybatis.conf配置文件参数.
mybatis-spring-boot-starter 机制原理
设计原理主要基于 MyBatis 和 Spring Boot 的自动配置特性。其核心组件包括 SqlSessionFactory、SqlSessionTemplate 和 MapperScanner。
- SqlSessionFactory:这是 MyBatis 的核心接口,用于创建 SqlSession。在 mybatis-spring-boot-starter 中,SqlSessionFactory 通常会通过 XML 配置文件或 Java 配置类自动配置。
- SqlSessionTemplate:这是 Spring 提供的一个模板类,封装了对 SqlSession 的操作,使得开发者可以更方便地执行 SQL 语句。在 mybatis-spring-boot-starter 中,SqlSessionTemplate 会通过自动配置的方式引入到 Spring 容器中。
- MapperScanner:这是 MyBatis 提供的一个组件,用于扫描指定包下的所有 Mapper 接口,并将其注册到 Spring 容器中。在 mybatis-spring-boot-starter 中,MapperScanner 会通过自动配置的方式引入到 Spring 容器中。
- 在 Spring Boot 项目中使用 MyBatis 时,如果没有显式地配置 SqlSessionFactory 和 MapperScanner,Spring Boot 会自动扫描相关的类和配置文件,并自动创建和配置这两个组件。
- 利用 MyBatis 和 Spring Boot 的自动配置特性,简化我们在 Spring Boot 项目中使用 MyBatis 的配置和操作。
如果没有显式地配置 SqlSessionFactory 和 MapperScanner,Spring Boot 会默认自动扫描相关的类和配置文件,并自动创建和配置这两个组件。
具体来说,Spring Boot 会执行以下步骤:
-
扫描启动类所在的包及其子包下的所有类,寻找标注了 @Mapper 或 @MapperScan 注解的类。
-
对于找到的 @Mapper 注解的类,将其注册到 Spring 容器中,并自动创建 SqlSessionFactory 和 MapperScanner。
-
对于找到的 @MapperScan 注解的类,将其作为配置类,并自动创建 SqlSessionFactory 和 MapperScanner。
-
对于没有 @Mapper 或 @MapperScan 注解的类,如果它们实现了接口,且接口中标注了 @Mapper 或 @MapperScan 注解,那么也会将它们注册到 Spring 容器中,并自动创建 SqlSessionFactory 和 MapperScanner。
-
在创建 SqlSessionFactory 和 MapperScanner 时,Spring Boot 会根据默认的配置规则,自动配置相关的参数和属性。例如,它会使用默认的数据库连接信息、事务管理器、类型别名等。
mybatis-spring-boot-starter pom.xml
<dependency>
<!--定义springboot启动-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<!--定义springboot jdbc-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<!--定义mybatis自动配置-->
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<!--定义mybatis包-->
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<!--定义mybatis与spring集成-->
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
以上pom.xml定义了 spring-boot-starter 、spring-boot-starter-jdbc、mybatis、mybatis-spring、mybatis-spring-boot-autoconfigure
通过以上分析,第三方jar与Spring Boot集成都会包含三个必须的 jar:spring-boot-starter 、自身定义的包、以及与Spring集成的定义
@Mapper
package org.apache.ibatis.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker interface for MyBatis mappers.
*
* <p>
* <b>How to use:</b>
*
* <pre>
* @Mapper
* public interface UserMapper {
* // ...
* }
* </pre>
*
* @author Frank David Martínez
*/
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
public @interface Mapper {
// Interface Mapper
}
定义所属包,表示@Mapper注解类是mybatis框架定义的
package org.apache.ibatis.annotations
代码示例:
@Mapper 注解是由 Mybatis 框架中定义的一个描述数据层接口的注解,用于告诉 Spring 框架此接口的实现类由 Mybatis 负责创建,并将其实现类对象存储到 Spring 容器中。通常情况下,我们会在接口方法上添加 @Mapper 注解,以实现 Mybatis 对该接口方法的映射。
示例代码如下:
@Mapper
public interface UserMapper {
List<User> findAll();
}
在上面的代码中,我们使用 @Mapper 注解声明了一个 UserMapper 接口,该接口用于操作数据库中的用户数据。通过在接口方法上添加 @Mapper 注解,我们告诉 Mybatis 在编译后生成相应的接口实现类,并将其实例存储到 Spring 容器中。这样,我们就可以通过 Spring 容器中的 UserMapper 接口来访问数据库中的用户数据。
@MapperScan
package org.mybatis.spring.annotation;
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.mybatis.spring.mapper.MapperFactoryBean;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.Import;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({MapperScannerRegistrar.class})
@Repeatable(MapperScans.class)
public @interface MapperScan {
String[] value() default {};
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
Class<? extends Annotation> annotationClass() default Annotation.class;
Class<?> markerInterface() default Class.class;
String sqlSessionTemplateRef() default "";
String sqlSessionFactoryRef() default "";
Class<? extends MapperFactoryBean> factoryBean() default MapperFactoryBean.class;
String lazyInitialization() default "";
}
定义所属包,表示 @MapperScan注解类是mybatis.spring框架定义的
package org.mybatis.spring.annotation;
代码示例:
@MapperScan 注解是 MyBatis-Spring 项目中的一个注解,用于指示 Spring 扫描并注册 MyBatis 的 Mapper 接口,使得这些接口可以被自动实例化并注入到 Spring 容器中。在使用 MyBatis 时,通常会定义 Mapper 接口来描述 SQL 操作,而实际的 SQL 语句和参数映射是通过 XML 文件完成的。@MapperScan 注解的作用是告诉 Spring 扫描指定的包路径,查找这些包下的 Mapper 接口,并将它们注册到 Spring 容器中。
以下是一个简单的示例,展示了如何在 Spring Boot 项目中使用 @MapperScan 注解:
在 Spring Boot 项目的入口类上使用 @MapperScan 注解,指定需要扫描的 Mapper 接口所在的包路径:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@MapperScan("com.example.mapper") // 指定 Mapper 接口所在的包路径
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
在上述代码中,@MapperScan(“com.example.mapper”) 注解告诉 Spring Boot 扫描 com.example.mapper 包路径下的所有类,查找其中的 Mapper 接口,并将它们注册到 Spring 容器中。这样,在应用启动时,Spring Boot 就会自动扫描该包下的所有 Mapper 接口,并将其实例化后交给 Spring 容器管理。使用 @MapperScan 注解可以避免手动在配置文件中配置 Mapper 的 Bean,从而简化配置过程,提高开发效率。同时,使用注解也可以提高代码的可读性和维护性,使得代码更加易于理解和修改。
SpringBoot中使用MyBatis时参数
mybatis-spring-boot-starter:这是MyBatis与Spring Boot集成的自动配置类,可以通过在Maven或Gradle的构建配置文件中添加依赖来引入。它提供了对MyBatis的自动配置和简化配置的支持。@MapperScan:注解类,用于指示Spring扫描指定的包路径,查找其中的Mapper接口,并将它们注册到Spring容器中。可以指定多个包路径,用逗号分隔。@Mapper:注解类,用于标注Mapper接口,指示Spring将其注册到Spring容器中。可以在接口方法上添加@Mapper注解,以实现特定的SQL操作。sqlSessionFactoryBean():这是一个方法,用于创建SqlSessionFactory的Bean对象。可以在配置类中重写该方法,以提供自定义的SqlSessionFactory配置。sqlSessionTemplateBean():这是一个方法,用于创建SqlSessionTemplate的Bean对象。可以在配置类中重写该方法,以提供自定义的SqlSessionTemplate配置。mapperLocations():这是一个方法,用于指定Mapper接口所在的XML文件或Java配置类的位置。可以在配置类中重写该方法,以提供自定义的Mapper接口配置。typeAliasesPackage():这是一个方法,用于指定类型别名的包路径。可以在配置类中重写该方法,以提供自定义的类型别名配置。configLocation():这是一个方法,用于指定MyBatis的配置文件路径。可以在配置类中重写该方法,以提供自定义的MyBatis配置文件路径。environment():这是一个方法,用于指定MyBatis的环境配置。可以在配置类中重写该方法,以提供自定义的环境配置。properties():这是一个方法,用于指定MyBatis的属性配置。可以在配置类中重写该方法,以提供自定义的属性配置。
package org.mybatis.spring.boot.autoconfigure;
import java.io.IOException;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Stream;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
/**
* Configuration properties for MyBatis.
*
* @author Eddú Meléndez
* @author Kazuki Shimizu
*/
@ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX)
public class MybatisProperties {
public static final String MYBATIS_PREFIX = "mybatis";
private static final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
/**
* Location of MyBatis xml config file.
*/
private String configLocation;
/**
* Locations of MyBatis mapper files.
*/
private String[] mapperLocations;
/**
* Packages to search type aliases. (Package delimiters are ",; \t\n")
*/
private String typeAliasesPackage;
/**
* The super class for filtering type alias. If this not specifies, the MyBatis deal as type alias all classes that
* searched from typeAliasesPackage.
*/
private Class<?> typeAliasesSuperType;
/**
* Packages to search for type handlers. (Package delimiters are ",; \t\n")
*/
private String typeHandlersPackage;
/**
* Indicates whether perform presence check of the MyBatis xml config file.
*/
private boolean checkConfigLocation = false;
/**
* Execution mode for {@link org.mybatis.spring.SqlSessionTemplate}.
*/
private ExecutorType executorType;
/**
* The default scripting language driver class. (Available when use together with mybatis-spring 2.0.2+)
*/
private Class<? extends LanguageDriver> defaultScriptingLanguageDriver;
/**
* Externalized properties for MyBatis configuration.
*/
private Properties configurationProperties;
/**
* A Configuration object for customize default settings. If {@link #configLocation} is specified, this property is
* not used.
*/
@NestedConfigurationProperty
private Configuration configuration;
application.properties
mybatis.mapper-locations=classpath:/mapper/*
作为一个开发人员,我们心中是否会一直疑惑,为什么在application.properties 要定义mybatis开头的参数?通过下面源码可以看出,环境变量进行了隔离,必须以mybatis开头,否则不能注入到mybatis Bean.
@ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX)
public class MybatisProperties {
public static final String MYBATIS_PREFIX = "mybatis";
总结
- Springboot集成第三方框架的时候,会进行参数隔离,通过PREFIX
- @Mapper 与@MapperScan注解的功能是一样的,@MapperScan按照Springboot规范与风格进行了封装,底层原理不变

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)