spring整合mybatis

现在很多项目都是基于Spring框架进行开发的,这种情况下如果仍然按照上面的方式来配置使用mybatis则会有很多的不方便。好在针对Spring框架mybatis也提供了配置方案,主要是通过一系列的mybatis-spring-xxx.jar来实现组合的,下面就来介绍如何在Spring项目中配置使用mybatis框架。
spring-mybatis的整合配置方式有很多种,可以通过XML和注解进行配置,下面主要介绍基于注解的配置。配置mybatis-spring分为以下几个部分:配置数据源、配置SqlSessionFactory、配置SqlSessionTemplate、配置mapper(为dao层接口配置动态代理对象)和配置事务处理。

1.配置SqlSessionFactory

SqlSessionFactory的作用是生成SqlSession,在之前SqlSessionFactory是通过SqlSessionFactoryBuilder类的build()方法来进行生成的,在结合Spring之后可以直接将其配置成一个Bean。具体来说mybatis-spring项目中提供了org.mybatis.spring.SqlSessionFactoryBean类给我们进行配置,一般来说这个配置类需要的提供的参数是数据源和Mybatis配置文件的位置。一个示例如下:

id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/bank"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    

id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="mybatis-config.xml"/>

首先配置了一个数据源,这里用的是spring提供的DriverManagerDataSource类,但其实可以配置任何实现了javax.sql.DataSource的数据源都是可以配置的,所以这里可以灵活使用一些第三方的数据源,比如说使用连接池管理的C3PO数据源。然后是配置一个SqlSessionFactoryBean对象,配置的主要属性就是数据源和指定mybatis的配置文件,有了这些属性之后Spring在初始化IOC容器的时候会初始化SpringFactoryBean得到mybatis运行所需的上下文。
看到这里的配置,可能让人觉得奇怪为什么需要的是SqlSessionFactory对象却在这里配置了一个SqlSessionFactoryBean对象。实际上SqlSessionFactoryBean是一个实现了FactoryBean接口的工厂Bean,对于这种类型的Bean,spring容器注入实际上是这个Bean getObject()方法的返回值。下面是其getObject()方法:

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

可以看到确实是注入了一个SqlSessionFactory对象。
上面配置的mybatis-config.xml文件和原先配置的config文件的主要区别是少了数据源部分的配置,这是因为我们在这里显示的指定了数据源所以没有必要再重复配置,即使在文件里又配置了数据源也是不会生效的。除此之外mybatis-config.xml中任然可以配置其它的元素并且配置也都是有效的,比如settings、typeAliases、mappers等属性。实际上是完全可以通过只配置SqlSessionFactoryBean来完成mybatis的配置的,下面是SqlSessionFactoryBean所有可配置项:

 private Resource configLocation;
  private Configuration configuration;
  private Resource[] mapperLocations;
  private DataSource dataSource;
  private TransactionFactory transactionFactory;
  private Properties configurationProperties;
  private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
  private SqlSessionFactory sqlSessionFactory;
  //EnvironmentAware requires spring 3.1
  private String environment = SqlSessionFactoryBean.class.getSimpleName();
  private boolean failFast;
  private Interceptor[] plugins;
  private TypeHandler[] typeHandlers;
  private String typeHandlersPackage;
  private Class[] typeAliases;
  private String typeAliasesPackage;
  private Class typeAliasesSuperType;
  //issue #19. No default provider.
  private DatabaseIdProvider databaseIdProvider;
  private Class vfs;
  private Cache cache;
  private ObjectFactory objectFactory;
  private ObjectWrapperFactory objectWrapperFactory;

可以看到原先需要在mybatis-config.xml中配置的属性,这里面都有;但实际上对于比较复杂的配置,还是会通过xml文件的形式进行配置,这样更易于管理并且可读性也会高一点。

2.配置SqlSessionTemplate

前面说过SqlSession表示一个数据库会话,负责执行sql并获取返回结果。之前是通过SqlSessionFactory的openSession()方法来获取SqlSession对象的,实际上得到的是DefaultSqlSession类对象,而在mybatis-spring中提供了SqlSession接口的另一个实现SqlSessionTemplate。配置SqlSessionTemplate时支持两种方式,
一种是只指定SqlSessionFactory;另外一种是还指定Executor的类型,这里指定的类型会覆盖掉配置文件中设置的结果。下面是一个配置示例:

 <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory"/>
        <constructor-arg index="1" value="BATCH"/>
    bean>

过上面的配置,Spring就可以把SqlSessionFactory注入到SqlSessionTemplate中去,另外这里还可以指定sqlsession中的Executor类型,上面的就配置了BATCH类型的Executor。SqlSessionTemplate也提供了一些可以直接调用的方法,但是一般都不会直接去调用这些方法,而是通过调用Dao层接口的动态代理对象去执行相关的sql。

3.配置Mapper(为dao层接口配置动态代理对象)

大部分情况下其实我们都是不关心SqlSessionTemplate的,而是直接通过Mapper接口和数据库打交道。在之前是通过SqlSession的getMapper()方法获取Mapper接口的动态代理对象,然后通过这个动态代理对象来负责sql的执行和结果的返回,但在spring是没有办法为一个接口生成一个实例的,所以mybatis-spring为Mapper接口提供了一个中间类MapperFactoryBean,我们可以给它传入需要包装的接口和需要的SqlSessionTemplate或SqlSessionFactory就可以为接口生成动态代理对象,并允许我们在代码中直接注入使用。

 <bean id="branchDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
        
        <property name="mapperInterface" value="com.sankuai.lkl.BranchDao"/>
        <property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>
        
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    bean>

这里的MapperFactoryBean也是一个继承了FactoryBean的工程Bean,同样看下它的getObject()方法:

@Override
  public T getObject() throws Exception {
    return getSqlSession().getMapper(this.mapperInterface);
  }

这里看到其实还是调用sqlSession的getMapper()方法来获取的配置的接口的动态代理对象,所以注入的就是这个动态代理对象。

上面的配置是针对单个Dao的,但是在实际的工程中一般都会有很多的Dao层接口,我们当然可以像上面一样为每个Dao层接口配置一个MapperFactoryBean但这样太过于繁琐,mybatis-spring中提供了MapperScannerConfigurer来实现对指定包的扫描:


    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        
        <property name="basePackage" value="com.sankuai.lkl.dao"/>
        <property name="sqlSessionTemplateBeanName" value="sqlSessionTemplate"/>
        
        
    bean>

这样会给配置路径下的每个接口都生成一个动态代理对象,并注入到spring容器中。

4.配置事务

mybatis和spring是使用AOP来管理事务的,分为编程式事务和声明式事务,目前用的最多的是声明式事务,下面是声明式事务的配置:


    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    bean>

    
    <tx:annotation-driven transaction-manager="txManager"/>

这样配置之后就可以通过在类或方法加上 @Transactional注解来开启事务了。在这个注解里还可以指定事务的超时时间、事务隔离级别、事务传播规则等。

你可能感兴趣的:(深入学习mybatis)