springboot2与mybaties整合

本文详细介绍了如何在SpringBoot2项目中整合Mybatis,从项目搭建到源码分析,涵盖依赖配置、数据源设置、XML与注解方式的Mapper使用,并探讨了SpringBoot2默认的Hikari连接池。通过实例解析,帮助读者深入理解整合过程。
摘要由CSDN通过智能技术生成

在实际项目中,应该很少有不使用数据库的项目吧,目前来看,大部分的公司使用的都是mysql+mybaties做持久化存储。因此,在这里为大家讲解一下springboot与mybaties应该如何整合。以下内容纯属个人见解,若有不对的地方,望大家指正。

项目搭建

通过第一篇文章,我们已经能够很熟练的搭建springboot项目了,这里,我们就减少项目搭建的步骤,若大家不会搭建,可以返回第一篇文章了解。要想与mybaties进行整合,我们需要添加如下依赖:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>1.3.2</version>
</dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <scope>runtime</scope>
</dependency>
<!--用于减少get set等,加速开发-->
<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <optional>true</optional>
</dependency>

springboot在启动的时候,会自动化配置mybaties相关信息,但是前提下,我们需要配置数据源信息,否则会抛出异常。如下所示:

#数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

至于这里的driver,我们要使用com.mysql.cj.jdbc.Driver,是因为我们使用的是最新的mysql驱动,com.mysql.jdbc.Driver也能够使用,只是在项目启动的时候,会抛出警告。

好了,现在我们已经写好数据源配置,接下来,我们就来写一个示例,来验证是否能够使用。

User:

@Data
public class User {
    private Long id;
    private String name;
    private int age;
}

UserMapper:

@Repository
public interface UserMapper {

    /**
     * 查询所有用户
     * @return list
     */
    List<User> selectAll();
}

关于mybaties的使用方式,一般分为两种:注解和XML配置。下面分别介绍一下,方便大家回顾:

XML配置

在使用XML配置的时候,需要注意,我们要在配置文件中加上如下配置:

#mybatis配置
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
mybatis.type-aliases-package=com.fanqie.springboot2.entity
  • mapper-locations:指定Mapper.xml文件的位置,以供springboot扫描。
  • type-aliases-package:使用别名。方便开发,不是必须的。若不提供该配置,我们就需要指定全限定名或者配置ResultMap。

UserMapper.xml配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fanqie.springboot2.mapper.UserMapper">
    <select id="selectAll" resultType="user">
        select * from user
    </select>
</mapper>

注解

使用注解的形式就相对比较简单了,我们不需要提供XML文件,也不需要指定别名。应该如何使用呢?请看下面:

@Repository
public interface UserMapper {

    /**
     * 查询所有用户
     * @return list
     */
    @Select("select * from user")
    List<User> selectAll();
}

我们可以使用注解的形式进行配置,不需要额外的XML文件的配置,方便,快速。支持select、update、insert、delete。

下面我们就写一个接口来调用,看是否配置成功。这里我们省略service层,如下所示:

@RestController
@RequestMapping("/user")
public class UserController {
    /**
     * 注入userMapper
     */
    private final UserMapper userMapper;

    @Autowired
    public UserController(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @GetMapping("/all")
    public List<User> selectAll(){
        return this.userMapper.selectAll();
    }
}

大家注意了,在使用Mybaties的时候,千万不要漏掉一步,那就是在启动类上加上Mapper扫描注解,以免mapper类找不到。如下所示:

@SpringBootApplication
@MapperScan("com.fanqie.springboot2.mapper")
public class MybatiesApplication {

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

}

启动项目,访问结果如下:

初步整合,就算完成了,如果大家想要看到查询过程中sql语句,参数,以及查询结果,可以在配置文件中加上如下配置:

logging.level.com.fanqie.springboot2.mapper:debug

level后面跟的是包路径,mapper目录下使用debug模式,就可以看到sql相关信息,具体效果,大家自行观察。

源码分析

在分析源码之前,先来了解几个注解,对分析源码特别重要:

  • @ConditionalOnClass:表明注解后的参数类必须存在,否则不会实例化该注解修饰的类或Bean。
  • @ConditionalOnBean:表明注解后的参数类必须在上下文存在Bean对象,否则不会实例化该注解修饰的类或Bean。
  • @ConditionalOnMissingBean:当上下文不存在该注解修饰的Bean对象,才会实例化该Bean。
  • @ConfigurationProperties:用于加载配置。当application.properties或者application.yml中有属性配置,可以通过该注解去加载,例如:user.name=张三,可以在user类上添加@ConfigurationProperties(prefix = "user")来使用。@ConfigurationProperties通常用于对象级别的资源加载,若单个字段的属性加载,使用@Value即可。
  • @EnableConfigurationProperties:该注解一般与@ConfigurationProperties配合使用,表明开启对@ConfigurationProperties注解的支持。
  • @AutoConfigureAfter:表明在自动配置该注解所使用的参数类之后再来加载当前类。

使用过spring-mybatie的伙伴,应该知道在使用的过程中,我们都需要配置DataSource、SqlSessionFactoryBean配置sqlSessionFactory、MapperScannerConfigurer配置自动扫描接口包路径等。现在,我们来看看springboot是如何自动配置这些Bean,如何找到自动配置的类在哪里呢?如下图:

MybatisAutoConfiguration就是自动配置类,部分内容如下:

/**
 *该类用于springboot自动配置mybaties
 *通过类注解,我们可以发现,自动配置有限定条件:上下文必须存在SqlSessionFactory.class、SqlSessionFactoryBean.class、
 *DataSource.clas的Bean对象,mybaties的配置从MybatisProperties(加载前缀为mybatis的属性)配置类中获取
 *该类仅会在DataSourceAutoConfiguration.class自动配置之后实例化
 */
 @org.springframework.context.annotation.Configuration
 @ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
 @ConditionalOnBean(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisAutoConfiguration {

  /**
   *在实例化之前执行,校验是否存在mybaties配置文件
   */
  @PostConstruct
  public void checkConfigFileExists() {
    if (this.properties.isCheckConfigLocation() && StringUtils.hasText(this.properties.getConfigLocation())) {
      Resource resource = this.resourceLoader.getResource(this.properties.getConfigLocation());
      Assert.state(resource.exists(), "Cannot find config location: " + resource
          + " (please add config file or check your Mybatis configuration)");
    }
  }
  
  /**
   *若上下文不存在SqlSessionFactory,则进行实例化
   *需要上下文存在DataSource
   */
  @Bean
  @ConditionalOnMissingBean
  public 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()));
    }
    Configuration configuration = this.properties.getConfiguration();
    if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) {
      configuration = new Configuration();
    }
    if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) {
      for (ConfigurationCustomizer customizer : this.configurationCustomizers) {
        customizer.customize(configuration);
      }
    }
    factory.setConfiguration(configuration);
    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())) {
      //向SqlSessionFactoryBean注入需要使用别名的Entity包路径
      factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
    }
    if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
      factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
    }
    if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
        //向SqlSessionFactoryBean注入mapper.xml文件包路径
      factory.setMapperLocations(this.properties.resolveMapperLocations());
    }

    return factory.getObject();
  }

 /**
   *若上下文不存在SqlSessionTemplate,则进行实例化
   *需要上下文存在SqlSessionFactory
   */
  @Bean
  @ConditionalOnMissingBean
  public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
    ExecutorType executorType = this.properties.getExecutorType();
    if (executorType != null) {
      return new SqlSessionTemplate(sqlSessionFactory, executorType);
    } else {
      return new SqlSessionTemplate(sqlSessionFactory);
    }
  }
}

 /**
   * 该类用于自动扫描被@Mapper所修饰的Mapper接口
   * 在springboot启动类上,通过@MapperScan("com.fanqie.springboot2.mapper")即可使用
   */
public static class AutoConfiguredMapperScannerRegistrar
    implements BeanFactoryAware, ImportBeanDefinitionRegistrar, ResourceLoaderAware

分析发现,我们没有看到DataSource是如何自动配置的,大家请注意该类上有这样的一个注解@AutoConfigureAfter(DataSourceAutoConfiguration.class),表明在实例化MybatisAutoConfiguration时,DataSource已经自动配置了,我们来看看里面的具体内容:

//DataSourceProperties加载的就是application.properties中配置的以spring.datasource为前缀的参数
@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class,
      DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {

    /**
     * 配置嵌入式数据源
    */
   @Configuration
   @Conditional(EmbeddedDatabaseCondition.class)
   @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
   @Import(EmbeddedDataSourceConfiguration.class)
   protected static class EmbeddedDatabaseConfiguration {

   }
  /**
   * 配置连接池数据源,支持Hikari、Tomcat、Dbcp2、Generic、Jmx
   * 默认使用HikariDataSource
   */
   @Configuration
   @Conditional(PooledDataSourceCondition.class)
   @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
   @Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
         DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class,
         DataSourceJmxConfiguration.class })
   protected static class PooledDataSourceConfiguration {

   }
}

在SpringBoot2中默认使用Hikari连接池,相应的使用HikariDataSource数据源,若大家不想使用Hikari连接池,可以按照自己项目的需要进行配置,示例如下:

spring.datasource.type=com.zaxxer.hikari.HikariDataSource

大家或许会问,我是如何知道默认采用的是HikariDataSource,其实所有的信息都会在日志中输出,只是默认使用的是INFO级别的日志,看不到Debug信息,所以大家在调试的时候,不妨在application.properties添加如下配置:

logging.level.root:debug

这时大家就可以在日志中搜索自己想要的内容,例如这里的DataSource:

2019-03-31 19:36:51.180 DEBUG 16692 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'dataSource'
2019-03-31 19:36:51.180 DEBUG 16692 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari'
2019-03-31 19:36:51.181 DEBUG 16692 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties'

mybaties的基础部分就描述到这里了,相关信息不难,大家可以亲自调试代码,才能有更深的了解。

总结

SpringBoot2与Mybaties整合,需要配置的内容变得非常的少,大家只需要配置数据库连接信息,基本上就可以很好的工作。支持注解和XML两种Mapper方式,可以任选其一。SpringBoot2中默认使用Hikari连接池,至于具体的好处还不是很清楚,只是说性能更好,至于具体使用哪种连接池,大家可以根据项目需要自行配置。

源码可见https://gitee.com/hpaw/SpringBoot2Demo/tree/master

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值