0 说明
Mybatis使用 MyBatis-Spring 类库来集成spring框架
MyBatis-Spring官网 http://www.mybatis.org/spring/index.html
MyBatis-Spring是一个MyBatis框架的子模块,可以提供和Spring框架的无缝集成。它可以是Mybatis利用Spring来实现事务管理,使用IOC机制管理MyBatis的 映射和sql会话对象(SqlSession), 把Mybatis异常转换为Spring的DataAccessException。
不同的Mybatis和Spring需要的 mybatis-spring版本
MyBatis-Spring | MyBatis | Spring |
---|---|---|
1.0.0 and 1.0.1 | 3.0.1 to 3.0.5 | 3.0.0 or higher |
1.0.2 | 3.0.6 | 3.0.0 or higher |
1.1.0 or higher | 3.1.0 or higher | 3.0.0 or higher |
1.3.0 or higher | 3.4.0 or higher | 3.0.0 or higher |
1 添加依赖
如果用了maven,则添加
<dependency>
<groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.1</version> </dependency>
否则直接加入jar包 mybatis-spring-1.2.1.jar到build path以及 WEB-INF/lib目录
spring和mybatis原有的jar包还是必须的哦。
2 基本配置
在Spring中使用Mybatis最少要在Spring 中配置两个东西:一个SqlSessionFactory 和至少一个映射接口
在MyBatis-Spring中, 一个 SqlSessionFactoryBean 用来创建 SqlSessionFactory ,要配置这个工程bean,在spring xml配置文件中加入以下内容:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> </bean>
注意 SqlSessionFactory 需要依赖一个 DataSource . 此 DataSource 可以是任意的Spring中配置的数据源连接配置。
假定你有了一个这样定义的接口映射:
public interface UserMapper { @Select("SELECT * FROM users WHERE id = #{userId}") User getUser(@Param("userId") String userId); }
那么这个接口要在Spring中的声明需要配置为 MapperFactoryBean 的实例:
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean>
注意这个映射类必须是一个接口,而不是一个实际的实现类。在这个例子中,我们使用注解方式来指定SQL,当然也可以使用MyBatis的XML配置文件。
一旦配置好以后,就可以将映射直接注入到需要使用的业务/服务对象中,方法和其他spring bean的注入方式一样。
MapperFactoryBean 工厂类负责 SqlSession 的创建和关闭。如果当前线程处于Spring管理的事务中,会话会在事务完成时提交或回滚。最后,所有异常都会被转化Spring DataAccessExceptions.
调用MyBatis 数据访问方法现在只需要一行代码:
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); }
3 事务管理
使用 MyBatis-Spring的一个主要原因就是允许MyBatis使用Spring的事务管理,MyBatis-Spring 利用Spring现有的DataSourceTransactionManager 来管理事务
标准配置:
启用spring事务管理,只需要配置这个bean:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>
The DataSource 对应的数据源可以使 JDBC的 DataSource 也可以是支持连接池的数据源或者JNDI方式管理的数据源。
注意指定这个DataSource 也同时是用来为SqlSessionFactoryBean 连接数据库的数据源,这样事务管理才能生效。
<!-- 启动声明式事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/><!-- a PlatformTransactionManager is still required -->
Java代码:
// the service class that we want to make transactional @Transactional public class DefaultFooService implements FooService { Foo getFoo(String fooName); Foo getFoo(String fooName, String barName); void insertFoo(Foo foo); void updateFoo(Foo foo); }
AOP方式配置事务属性,需要事务管理器
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- the transactional semantics... --> <tx:attributes> <!-- all methods starting with ‘get‘ are read-only --> <tx:method name="get*" read-only="true"/> <!-- other methods use the default transaction settings (see below) --> <tx:method name="insert*"/> <tx:method name="update*"/>
</tx:attributes> </tx:advice>
<tx:advice id="txAdvice"> <tx:attributes> <tx:method name="updateStock" no-rollback-for="InstrumentNotFoundException" iolation="DEFAULT" propagation="REQUIRED" /> <tx:method name="*"/> </tx:attributes> </tx:advice>
* 编程方式使用事务:
DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status = txManager.getTransaction(def); try { userMapper.insertUser(user); } catch (MyException ex) { txManager.rollback(status); throw ex; } txManager.commit(status);
来源: http://www.mybatis.org/spring/transactions.html
注意SqlSession.commit(), SqlSession.rollback() or SqlSession.close() 这些 SqlSession.的事务方法都不能使用。否则会收到 UnsupportedOperationException 异常。这些方法在这里都不可见。
设置传播行为和隔离级别:
配置方式:
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" isolation="DEFAULT" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
注解方式:
@Transactional(readOnly = true) public class DefaultFooService implements FooService { public Foo getFoo(String fooName) { // do something } // these settings have precedence for this method @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) public void updateFoo(Foo foo) { // do something } }