Spring Boot 中使用 MyBatis-Spring-Boot-Starter

时间:2024-10-30 09:25:29

Spring Boot 中使用 MyBatis-Spring-Boot-Starter

本文将使用 MyBatis-Spring-Boot-Starter 在Spring Boot中建立 Mybatis 应用。

本文将实现:

  • 构建一个独立应用
  • 将JDBC模板代码减少到最小值(接近0)
  • 更少的XML配置

版本要求

MyBatis-Spring-Boot-Starter MyBatis-Spring Spring Boot Java
2.2 2.0(2.0.6以上解锁所有功能) 2.5或以上 8或以上
2.1 2.0(2.0.6以上解锁所有功能) 2.1-2.4 8或以上

安装

使用 MyBatis-Spring-Boot-Starter 模组,需要将 文件以及它的依赖(,等)添加到classpath中。

Maven

使用Maven构建时,将下述配置添加到

<dependency>
    <groupId></groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.1</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

Gradle

使用Gradle构建时,将下述配置添加到

dependencies {
  compile(":mybatis-spring-boot-starter:2.2.1")
}
  • 1
  • 2
  • 3

快速部署

在Spring上使用MyBatis,至少需要一个 SqlSessionFactory 以及至少一个 mapper 接口

MyBatis-Spring-Boot-Starter可以:

  • 自动检测一个现存的 DataSource
  • 创建并注册一个 SqlSessionFactory 并将现存的 DataSource 作为 SqlSessionFactoryBean 输入
  • 创建并注册一个从 SqlSessionFactory 得到的 SqlSessionTemplate 实例
  • 自动扫描你的映射器(Mapper),将它们链接到 SqlSessionTemplate,并将它们注册到Spring上下文中,这样它们就可以被注入到你的Bean中。

假设我们有以下的映射器:

@Mapper
public interface CityMapper {

  @Select("SELECT * FROM CITY WHERE state = #{state}")
  City findByState(@Param("state") String state);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

你只需要创建一个正常的Spring boot应用程序,并让映射器像下面那样被注入(在Spring 4.3以上可用)。

@SpringBootApplication
public class SampleMybatisApplication implements CommandLineRunner {

  private final CityMapper cityMapper;

  public SampleMybatisApplication(CityMapper cityMapper) {
    this.cityMapper = cityMapper;
  }

  public static void main(String[] args) {
    SpringApplication.run(SampleMybatisApplication.class, args);
  }

  @Override
  public void run(String... args) throws Exception {
    System.out.println(this.cityMapper.findByState("CA"));
  }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

这样就可以正常运行应用

进阶扫描

MyBatis-Spring-Boot-Starter 会检索有 @Mapper 标记的映射器。

如果你想要扫描一个特定的标注或是标识器,你需要使用 @MapperScan 标注。

如果MyBatis-Spring-Boot-Starter在Spring的上下文中发现至少一个MapperFactoryBean,它将不会启动扫描过程,所以如果你想完全停止扫描,你应该用@Bean方法明确注册你的映射器。

使用 SqlSession

由于一个SqlSessionTemplate的实例被创建并添加到Spring上下文,

因此你可以通过MyBatis API将其注入到Bean中(在Spring 4.3以上版本中可用)。

@Component
public class CityDao {

  private final SqlSession sqlSession;

  public CityDao(SqlSession sqlSession) {
    this.sqlSession = sqlSession;
  }

  public City selectCityById(long id) {
    return this.sqlSession.selectOne("selectCityById", id);
  }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

使用 SpringBootVFS

MyBatis-Spring-Boot-Starter提供SpringBootVFS作为VFS的一个实现类。VFS用于从应用程序(或应用程序服务器)中搜索类(例如,类型别名的目标类,类型处理类)。如果你使用可执行jar运行Spring Boot应用程序,你需要使用SpringBootVFS。MyBatis-Spring-Boot-Starter提供的自动配置功能会自动使用它,但它不会通过手动配置自动使用(例如,当使用多个DataSource时)。

手动配置时使用 SpringBootVFS

@Configuration
public class MyBatisConfig {
  @Bean
  public SqlSessionFactory masterSqlSessionFactory() throws Exception {
    SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
    factoryBean.setDataSource(masterDataSource());
    factoryBean.setVfs(SpringBootVFS.class); // Sets the SpringBootVFS class into SqlSessionFactoryBean
    // ...
    return factoryBean.getObject();
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

检测MyBatis组件

MyBatis-Spring-Boot-Starter将检测实现MyBatis提供的以下接口的bean。

  • 拦截器(Interceptor)
  • 类型处理器(TypeHandler)
  • 语言驱动(LanguageDriver)
  • 数据库Id提供者(DatabaseIdProvider)
@Configuration
public class MyBatisConfig {
  @Bean
  MyInterceptor myInterceptor() {
    return MyInterceptor();
  }
  @Bean
  MyTypeHandler myTypeHandler() {
    return MyTypeHandler();
  }
  @Bean
  MyLanguageDriver myLanguageDriver() {
    return MyLanguageDriver();
  }
  @Bean
  VendorDatabaseIdProvider databaseIdProvider() {
    VendorDatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
    Properties properties = new Properties();
    properties.put("SQL Server", "sqlserver");
    properties.put("DB2", "db2");
    properties.put("H2", "h2");
    databaseIdProvider.setProperties(properties);
    return databaseIdProvider;
  }  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25