天天看点

mybatis之三:与spring集成

一:需求

1,MyBatis-Spring 1.1.0(mybatis-spring-x.x.x.jar )

2,MyBatis 3.1.0 or higher

3,Spring 3.0.0 or higher

二:集成(web应用为例)

1,将所需要的jar文件添加到类路径下.准备好Mybatis的主配置文件

例如:batis-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE configuration

    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

    "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

 <mappers>

 </mappers>

</configuration>

2,在spring配置文件中配置数据源

例如:applicationContext.xml

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"

        destroy-method="close">

        <property name="driverClass" value="${jdbc.driver}"></property>

        <property name="jdbcUrl" value="${jdbc.url}"></property>

        <property name="user" value="${jdbc.username}"></property>

        <property name="password" value="${jdbc.password}"></property>

        <property name="maxPoolSize" value="50" /> 

</bean>

3,在spring配置文件中配置SqlSessionFactory

    在基本的mybatis中,我们使用SqlSessionFactoryBuilder来创建SqlSessionFactory的,但在MyBatis-Spring中,我们将用SqlSessionFactoryBean里创建。SqlSessionFactoryBean实现了 Spring 的 FactoryBean 接口,我们在spring的配置文件中,进行以下的配置:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

        <property name="dataSource" ref="dataSource" />

        <property name="configLocation" value="/WEB-INF/conf/mybatis/batis-config.xml" /></bean>

SqlSessionFactory的属性:

dataSource:是SqlSessionFactory必须的。

configLocation:用来指定 MyBatis 的 XML 主配置文件路径。当与spring集成时,mybatis主配置文件里面除了<settings> ,<typeAliases>和<mappers>,其他部分都会被忽略。也就是说在主配置文件中配置的数据源 和 MyBatis 的事务管理器都会被忽略。

mapperLocations:如果映射器 XML 文件在和映射器类不在相同的路径下,而且又没有在主配置文件中配置<mappers>,那么我们可以使用该属性来引入映射器文件。例如:

  <property name="dataSource" ref="dataSource" />

  <property name="mapperLocations"

                           value="classpath*:sample/config/mappers/**/*.xml" />

这会加载在 sample.config.mappers 包和它的子包中所有的 MyBatis 映射器 XML 文件。

transactionFactory:如果你想让 Spring 参与到容器管理事务中, 你 就 必 须 配 置 SqlSessionFactoryBean 来使用基本的 MyBatis 的 ManagedTransactionFactory 而不是其 它任意的 Spring 事务管理器,例如:

  <property name="transactionFactory">

    <bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />

  </property> 

4,配置事务管理器

    使用Sping来管理事务只需下面的标准配置即可。

<bean id="transactionManager"

          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

     <property name="dataSource" ref="dataSource" />

要注意, 为事务管理器指定的 DataSource 必须和用来创建 SqlSessionFactoryBean 的 是同一个数据源,否则事务管理器就无法工作了。

对于事务管理,我们还可以选择:容器管理事务的方式和编程管理事务的方式。

到此,其实mybatis已经和spring集成在了一起,接下来需要启动spring.

5,启动spring

在web.xml文件中添加如下内容:

<listener>

  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

三:应用

1,使用SqlSessionTemplate

    SqlSessionTemplate 是 MyBatis-Spring 的核心。 这个类负责管理 MyBatis 的 SqlSession, 调用 MyBatis 的 SQL 方法, 翻译异常。 SqlSessionTemplate 是线程安全的, 可以被多个 DAO 所共享使用。

SqlSessionTemplate 实现了 SqlSession 接口,也就是说我们可以为dao类声明一个SqlSession成员属性来被所有线程使用。

  SqlSessionTemplate 对象可以使用 SqlSessionFactory 作为构造方法的参数来创建。

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">

      <constructor-arg index="0" ref="sqlSessionFactory" />

 DAO:

public class UserDaoImpl implements UserDao {

    public SqlSession sqlSession;

}

  注入 SqlSessionTemplate:

<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">

  <property name="sqlSession" ref="sqlSession" />

  SqlSessionTemplate 有一个使用 ExecutorType 作为参数的构造方法。这允许你用来 创建对象,比如,一个批量 SqlSession,但是使用了下列 Spring 配置的 XML 文件:      

      <constructor-arg index="1" value="BATCH" />

 然后可以到DAO中进行批处理操作:

public void insertUsers(User[] users) {

   for (User user : users) {

         sqlSession.insert("org.mybatis.spring.sample.mapper.UserMapper.insertUser", user);

   }

}

注意,如果所需的执行方法和默认的 SqlSessionFactory 设置不同,这种配置风格才 能使用。

对这种形式需要说明的是当这个方法被调用时,不能有一个存在使用不同 ExecutorType 运行的事务。也要保证在不同的事务中,使用不同执行器来调用 SqlSessionTemplate 时, (比如 PROPAGATION_REQUIRES_NEW)或完全在一个事务外面。

2,使用SqlSessionDaoSupport

    SqlSessionDaoSupport 是 一 个 抽象 的支 持 类, 用来 为你 提供 SqlSession 。 调 用 getSqlSession()方法你会得到一个 SqlSessionTemplate,之后可以用于执行 SQL 方法, 就像下面这样:

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {

  public User getUser(String userId) {

    return (User) getSqlSession()

                 .selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);

  }

SqlSessionDaoSupport 需要一个 sqlSessionFactory 或 sqlSessionTemplate 属性来 设 置 。 这 些要被 被 明 确 地 设 置 或 者由 Spring 来 自 动 装 配 。 如 果 两 者 都 被 设 置 了 , 那 么 SqlSessionFactory 是被忽略的。

3,使用Mapper

    以往的操作我们都需要定义一个Dao来操作数据库,在Dao层我们需要使用SqlSession来完成对数据库的操作,为了简便我们的操作,Mybatis-Spring为我们提供了一个动态代理的实现,这就是为我们提供的:MapperFactoryBean。这个类 可以让你直接注入数据映射器接口到你的 service 层中,然后你仅仅如调 用你的 DAO 一样调用它们就可以了,但是你不需要编写任何 DAO 实现的代码,因为 MyBatis-Spring 将会为你创建代理。 这就等于说,我们不用再去创建我们自己的DAO类。

    数据映射器接口可以按照如下做法加入到 Spring 中:

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">

      <property name="mapperInterface"

                 value="org.mybatis.spring.sample.mapper.UserMapper" />

      <property name="sqlSessionFactory" ref="sqlSessionFactory" />

    MapperFactoryBean 创建的代理类实现了 UserMapper 接口,并且注入到应用程序中。 因为代理创建在运行时环境中 ,那么指定的映射器必须是一个接口,而 不是一个具体的实现类。

   如果UserMapper有个对应的映射器文件,并在同一路径下,那么MapperFactoryBean会自动解析而不用再将该映射文件配置到mybatis的主配置文件中。

   注意:映射文件的namespace要设置为Mapper接口的全路径。

   现在可以这样使用:

<bean id="fooService" class="org.mybatis.spring.sample.mapper.FooServiceImpl">

       <property name="userMapper" ref="userMapper" />

public class FooServiceImpl implements FooService {

  private UserMapper userMapper;

  public void setUserMapper(UserMapper userMapper) {

    this.userMapper = userMapper;

  public User doSomeBusinessStuff(String userId) {

    return this.userMapper.getUser(userId);

 一般情况下我们会在mybatis的主配置文件中引入各个Mapper的映射器xml文件,或者在SqlSessionFactory下指定,但其实我们可以使用MapperScannerConfigurer来注册所有的映射器。它 将 会 查 找 类 路 径 下 的 映 射 器 并 自 动 将 它 们 创 建 成 MapperFactoryBean。

要创建 MapperScannerConfigurer,可以在 Spring 的配置中添加如下代码:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

      <property name="basePackage" value="org.mybatis.spring.sample.mapper" />

basePackage 属性是让你为映射器接口文件设置基本的包路径。 你可以使用分号或逗号 作为分隔符设置多于一个的包路径。每个映射器将会在指定的包路径中递归地被搜索到。

<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />