Mybatis整合Spring

Mybatis提供了和Spring无缝对接的功能,它主要通过mybatis-spring-x.x.x.jar来实现。我们可以在 http://www.mybatis.org/spring/ 这个网址中找到对应的版本关系,然后下载对应版本即可。在Spring中,配置的方法较多,可以通过XML进行配置,也可以通过注解进行配置,但是通过XML配置的方式较为主流。

配置mybatis-spring分为以下几个部分:

  • 配置数据源
  • 配置SqlSessionFactory
  • 配置SqlSessionTemplate(如需要)
  • 配置Mapper
  • 事务处理

配置数据源

我们这里就通过引入properties外置配置文件的方式来配置数据源,一个简单的properties文件:

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///ssm_crud
jdbc.user=root
jdbc.password=root

我们在spring的配置文件中引入这个文件,并配置四大参数即可,我这里用的是c3p0作为数据库连接池:

<!-- 引入jdbc.properties文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
       
<!-- 配置dataSource -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  <property name="driverClass" value="${jdbc.driverClass}"></property>
  <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
  <property name="user" value="${jdbc.user}"></property>
  <property name="password" value="${jdbc.password}"></property>
</bean>

当然我们也可以直接将四大参数写死,或者使用JNDI配置数据源都是可以的。

配置SqlSessionFactory

配置SqlSessionFactoryBean对象,我们还需要向其注入一个数据源和配置文件,使用classpath指定配置文件存在于类路径下:

<!--配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
   <property name="configLocation" value="classpath:mybatis/sqlMapConfig.xml"></property>
   <property name="dataSource" ref="dataSource"></property>
   <!-- 指定mybatis,mapper文件的位置 -->
   <property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>

这样配置之后,我们就无需在mybatis配置文件中再配置environment节点信息了。严格来说,SqlSessionfactoryBean 已经可以通过Spring IOC配置了,我们完全可以在其内部配置很多原来的配置,如typeHandler,objectFactory,plugin,databaseIdProvider等等。但是建议还是将mybatis配置写到XML文件中,因为它方便管理,且可读性高。

configLocation属性指定Mybatis设置文件所在位置,dataSource属性指定数据源,mapperLocation属性指定Mapper映射XML文件所在的位置(所以在Mybatis设置文件中无需mapper元素)

Mybatis中使用的是SqlSessionFactoryBean,Hibernate中使用的是LocalSessionFactoryBean,JPA中使用的是LocalContainerEntityManagerFactoryBean

配置SqlSessionTemplate

SqlSessionTemplate(org.mybatis.spring.SqlSessionTemplate)是一个模版类,通过调用SqlSession来完成工作,所以在Mybatis-Spring项目中也是一个核心类。它有两个构建方式,一种是只有一个SqlSessionFactory作为参数;另一种是有两个参数的,一个是SqlSessionFactory,另一个是执行器类型,它是一个枚举类。

构建方法一,使用SqlSessionFactory参数构建

<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
   <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
</bean>

构建方式二,使用两个参数构建

<!-- 配置一个可以执行批量(批处理)的sqlSessionTemplate -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
   <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
   <constructor-arg name="executorType" value="BATCH"></constructor-arg>
</bean>

这里executeType使用时BATCH,这是一个支持批处理的执行器,它的取值范围是:SIMPLE(默认,一个简易的执行器),RESULT(可重用预处理语句的执行器),BATCH(支持批处理和重用语句的执行器)

通过个SqlSessionTemplate配置就意味着Spring会把我们之前配置的SqlSessionFactory设置到SqlSessionTemplate中。如果我们同时配置了SqlSessionFactory和SqlSessionTemplate,那么系统就只会用使用SqlSessionTemplate去配置掉SqlSessionFactory。

在ibatis时代SqlSessionTemplate可以执行很多的功能,同样的在Mybatis中也是可以的。但是在目前的mybatis的编程中用的不多,因为我们完全可以使用映射器擦除它,这样更易于理解。除非是需要使用它完成定制的编程,不然不建议使用这种编程方式,原因有两个:

  • SqlSessionTemplate是Mybatis的类,我们还需要使用id标记出调用的这条SQL,这对于编程来说是困难的,有侵入框架之嫌,可读性较差
  • 我们在编写的时候无法保证调用SQL的id正确性,因为IDE无法验证id正确性

配置Mapper

在代码中,大部分场景都不建议使用SqlSessionTemplate或者SqlSession的方式,我们强烈建议使用Mapper接口的方式。

MapperFactoryBean

在Mybatis中,mapper只是一个接口,而不是一个实现类,它是有Mybatis通过动态代理的形式生成代理对象去运行的,所以Spring也没有办法为其生成实现类。为了解决这个问题,Mybatis-Spring团队提供了一个 MapperFactoryBean 类作为中介,配置MapperFactoryBean有3个参数,mapperInterface,SqlSessionfactory和SqlSessionTemplate。

  • mapperInterface,用于定制接口,当我们的接口继承了配置的接口,那么Mybatis就认为它是一个Mapper
  • SqlSessionfactory,当SqlSessionTemplate属性不被配置的时候,Mybatis-Spring才会去设置它
  • SqlSessionTemplate,当它被配置的时候,SqlSessionFactory将被作废
<bean id="userDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
   <!--userDao接口将被扫描为Mapper-->
   <property name="mapperInterface" value="cn.lynu.dao.UserDao"/>
   <property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>
   <!--如果同时注入SqlSessionTemplate和SqlSessionFactory,则只会启用sqlSessionTemplate-->
   <!--
    property name="sqlSessionFactory" ref="sqlSessionFactory"/> 
   -->
</bean>    

这样我们就可以使用这个接口进行编程了,它的作用等同于sqlSession.getMapper(UserDao.class),不过与Spring整合之后更加优雅。

MapperScannerConfigurer

一个复杂的系统存在许许多多的Dao,如果一个个配置,那么工作量会很大,不过Mybatis-Spring团队已经处理的这种场景,它采用自动扫描的形式来配置我们的映射器,这样我们就可以在很少的到代码情况下完成映射器的配置,提高效率。

我们采用的是MapperScannerConfigurer,它的部分常用属性如下:

  • basePackage,指定Spring自动扫描什么包,它会逐层深入扫描
  • annotationClass,表示如果这个类被这个注解标识的时候,才进行扫描
  • sqlSessionFactoryBeanName,指定在Spring中定义的sqlSessionFactory的bean名称,如果它被定义,sqlSessionFactory 将不起作用
<!-- 配置mapper扫描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  <property name="basePackage" value="cn.lynu.mapper"></property>
  <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>

这样Spring上下文就会自动扫描cn.lynu.mapper这个包下的所有接口,并自动生成Mapper,而无需多余配置

配置事务

Mybatsi与Spring整合之后是使用Spring AOP去管理事务的,使用Spring AOP是相当简单的,它分为声明式事务和注解式事务,这里记录使用注解的方式配置事务

<!-- spring事务管理 -->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
   <property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 开启基于注解的事务 -->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>

在Mybatsi中使用的是DataSourceTransactionManager来作为事务管理器的,而Hibernate中我们使用HibernateTransactionManager 作为事务管理器,JPA中使用JpaTransactionManager作为事务管理器

这样我们在Service层使用@Transaction开启事务即可,这个注解可以作为类的注解,也可以细化请求的标在方法上

 

posted @ 2018-02-09 23:25  OverZeal  阅读(414)  评论(0编辑  收藏  举报