一.Spring整合的映射器:
注入映射器
与其在数据访问对象(DAO)中手工编写使用 SqlSessionDaoSupport
或 SqlSessionTemplate
的代码,还不如让 Mybatis-Spring 为你创建一个线程安全的映射器,这样你就可以直接注入到其它的 bean 中了:
<bean id="fooService" class="org.mybatis.spring.sample.service.FooServiceImpl"> <constructor-arg ref="userMapper" /> </bean>
注入完毕后,映射器就可以在你的应用逻辑代码中使用了:
public class FooServiceImpl implements FooService { private final UserMapper userMapper; public FooServiceImpl(UserMapper userMapper) { this.userMapper = userMapper; } public User doSomeBusinessStuff(String userId) { return this.userMapper.getUser(userId); } }
注意代码中并没有任何的对 SqlSession
或 MyBatis 的引用。你也不需要担心创建、打开、关闭 session,MyBatis-Spring 将为你打理好一切。
注册映射器
注册映射器的方法根据你的配置方法,即经典的 XML 配置或新的 3.0 以上版本的 Java 配置(也就是常说的 @Configuration
),而有所不同。
XML 配置
在你的 XML 中加入 MapperFactoryBean
以便将映射器注册到 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" /> </bean>
如果映射器接口 UserMapper 在相同的类路径下有对应的 MyBatis XML 映射器配置文件,将会被 MapperFactoryBean
自动解析。不需要在 MyBatis 配置文件中显式配置映射器,除非映射器配置文件与接口类不在同一个类路径下。 参考 SqlSessionFactoryBean
的 configLocation 属性以获取更多信息。
注意 MapperFactoryBean
需要配置一个 SqlSessionFactory
或 SqlSessionTemplate
。它们可以分别通过 sqlSessionFactory
和 sqlSessionTemplate
属性来进行设置。 如果两者都被设置,SqlSessionFactory
将被忽略。由于 SqlSessionTemplate
已经设置了一个 session 工厂,MapperFactoryBean
将使用那个工厂。
Java 配置
@Configuration public class MyBatisConfig { @Bean public MapperFactoryBean<UserMapper> userMapper() throws Exception { MapperFactoryBean<UserMapper> factoryBean = new MapperFactoryBean<>(UserMapper.class); factoryBean.setSqlSessionFactory(sqlSessionFactory()); return factoryBean; } }
发现映射器
不需要一个个地注册你的所有映射器。你可以让 MyBatis-Spring 对类路径进行扫描来发现它们。
有几种办法来发现映射器:
- 使用
<mybatis:scan/>
元素 - 使用
@MapperScan
注解 - 在经典 Spring XML 配置文件中注册一个
MapperScannerConfigurer
<mybatis:scan/>
和 @MapperScan
都在 MyBatis-Spring 1.2.0 中被引入。@MapperScan
需要你使用 Spring 3.1+。
@MapperScan
当你正在使用 Spring 的基于 Java 的配置时(也就是 @Configuration
),相比于使用 <mybatis:scan/>
,你会更喜欢用 @MapperScan
。
@MapperScan
注解的使用方法如下:
@Configuration @MapperScan("org.mybatis.spring.sample.mapper") public class AppConfig { // ... }
MapperScannerConfigurer
MapperScannerConfigurer
是一个 BeanDefinitionRegistryPostProcessor
,这样就可以作为一个 bean,包含在经典的 XML 应用上下文中。为了配置 MapperScannerConfigurer
,使用下面的 Spring 配置:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="org.mybatis.spring.sample.mapper" /> </bean>
二.声明式事务:
声明式事务的2种实现方式
-
配置文件的方式,即在spring xml文件中进行统一配置,开发者基本上就不用关注事务的事情了,代码中无需关心任何和事务相关的代码,一切交给spring处理。
-
注解的方式,只需在需要spring来帮忙管理事务的方法上加上@Transaction注解就可以了,注解的方式相对来说更简洁一些,都需要开发者自己去进行配置,可能有些同学对spring不是太熟悉,所以配置这个有一定的风险,做好代码review就可以了。
-
声明式事务注解方式5个步骤
1、启用Spring的注释驱动事务管理功能
在spring配置类上加上
@EnableTransactionManagement
注解 -
@EnableTransactionManagement
public class MainConfig4 {
} -
JpaTransactionManager:如果你用jpa来操作db,那么需要用这个管理器来帮你控制事务。
DataSourceTransactionManager:如果你用是指定数据源的方式,比如操作数据库用的是:JdbcTemplate、mybatis、ibatis,那么需要用这个管理器来帮你控制事务。
HibernateTransactionManager:如果你用hibernate来操作db,那么需要用这个管理器来帮你控制事务。
JtaTransactionManager:如果你用的是java中的jta来操作db,这种通常是分布式事务,此时需要用这种管理器来控制事务。
-
比如:我们用的是mybatis或者jdbctemplate,那么通过下面方式定义一个事务管理器。
-
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
} -
二.spring支持编程式事务管理和声明式事务管理两种方式。
编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。
显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等。