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

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

本文将实现:

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

版本要求

MyBatis-Spring-Boot-StarterMyBatis-SpringSpring BootJava
2.22.0(2.0.6以上解锁所有功能)2.5或以上8或以上
2.12.0(2.0.6以上解锁所有功能)2.1-2.48或以上

安装

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

Maven

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

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

Gradle

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

dependencies {
  compile("org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.1")
}

快速部署

在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);

}

你只需要创建一个正常的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"));
  }

}

这样就可以正常运行应用

进阶扫描

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);
  }

}

使用 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();
  }
}

检测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;
  }  
}

更多推荐

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