本文介绍Spring集成Mybatis配置文件各个部分的具体含义:

1、数据源

<bean id="dataSource"
     class="org.apache.commons.dbcp2.BasicDataSource"
     destroy-method="close">
     <property name="url" value="jdbc:mysql://localhost:3306/test"/>
     <property name="username" value="root"/>
     <property name="password" value="root"/>
     <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
     </bean>

数据源是必不可少的,数据源负责提供与数据库的连接,DataSource接口有很多种实现:

  • 上面配置文件中配置的是dbcp数据连接池的数据源实现;
  • 像Spring也对DataSource也有多种实现,比如SimpleDriverDataSource,这个数据源是一个普通的不带连接池的数据源。

2、SqlSessionFactory配置

<bean id="sqlSessionFactory"
     class="org.mybatis.spring.SqlSessionFactoryBean">
      <property name="dataSource" ref="dataSource"/>
      <property name="mapperLocations" value="classpath:mybatis/mapper/*.xml"/>
     </bean>

对于SqlSessionFactory的配置稍微复杂一些,我们一步一步看源码:

public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent>{...}

上面是bean的class类SqlSessionFactoryBean的类声明:

实现FactoryBean<SqlSessionFactory>接口:

接口说明:

一般情况下,Spring通过反射机制利用<bean>的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在<bean>中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。

FactoryBean是一个工厂Bean,是一个接口,实现该接口(支持泛型),可以生成某一个类型Bean实例,它最大的一个作用是:可以让我们自定义Bean的创建过程。不同于普通Bean的是:它是实现了FactoryBean<T>接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身。

明确了此接口的意义后,我们来看对于该接口方法的实现:

@Override
  public SqlSessionFactory getObject() throws Exception {
    if (this.sqlSessionFactory == null) {
      afterPropertiesSet();
    }

    return this.sqlSessionFactory;
  }
  • 此时看到SqlSessionFactoryBean这个bean最终生成或者产生的是一个SqlSessionFactory实例,进一步追源码可以看到SqlSessionFactory的生产是在:
@Override
  public void afterPropertiesSet() throws Exception {
    notNull(dataSource, "Property 'dataSource' is required");
    notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
    state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
              "Property 'configuration' and 'configLocation' can not specified with together");

    this.sqlSessionFactory = buildSqlSessionFactory();
  }

.... 
protected SqlSessionFactory buildSqlSessionFactory() throws IOException {

    .....

    return this.sqlSessionFactoryBuilder.build(configuration);
  }

到这一步也就明确了SqlSessionFactory这个Bean在spring中是如何被创建出来的。

接下来看一下SqlSessionFactory这个bean的意义:

  • SqlSessionFactory是MyBatis的关键对象,它是个单个数据库映射关系经过编译后的内存镜像;
  • SqlSessionFactory是单例的;
  • 从命名上也可以看出SqlSessionFactory可以获取操作数据的SqlSession实例(是SqlSession的工厂);
  • 与最原始的jdbc粗略类比的话,SqlSessionFactory相当于Connection,SqlSession就相当于Statement。

接下来看一下需要配置的属性:

  • dataSource:SqlSessionFactoryBean Bean必须传入的属性,这个属性会在创建具体的SqlSessionFactory时传入构造函数中。
  • mapperLocations:用来配置sql mapper的xml文件的路径,支持扫描式加载SQL映射文件。
  • 当然配置项是非常多的,此处仅列举必备的和常用的,后续继续补充。

3、MapperScannerConfigurer配置

前述已经配置好了SqlSessionFactory和sql mapper的映射文件,接下来就需要配置dao层的接口,将dao层的接口纳入spring的管理,需要如下配置:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
      <property name="basePackage" value="com.test.database.mybatis"/>
      <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
     </bean>

MapperScannerConfigurer是一个转换器,可以将映射的dao接口直接转换为Spring容器中的Bean,这样就可以在Service中注入映射接口的Bean了,就不用去实现这些dao层接口了,直接注入使用就可以了,这也是为什么dao层的接口都不需要添加注解,因为在配置MapperScannerConfigurer这个bean时已经指明了需要处理的接口。

接下来看一下需要配置的属性:

  • basePackage:配置基础包名,MapperScannerConfigurer将扫描basePackage所指定的包下的所有接口类(包括子包),如果他们在SQL映射文件中定义过,则将他们动态定义为一个Spring Bean。
  • sqlSessionFactory:配置sqlSessionFactory的bean,这个很好理解了,既然要去对应SQL映射文件,而SQL映射文件的定义又是在上述所说的sqlSessionFactory中,所以得有这一个配置。

4、总结

上述总结了spring集成mybatis时配置文件的最小配置,并粗略对配置的各个bean进行了说明。