深入浅出mybatis之spring集成

描绘于前

以Java世界,AOP编程是老流行的模式,大大降低了职能业务与主导业务之间的代码耦合度。而说交AOP,Spring更是业界主流实现框架。
MyBatis作为ORM框架,既可独自使用,当然也不可免俗地好和Spring集成以联名下。
特别是在已经用Spring框架的应用程序中,如果欲利用MyBatis作为ORM组件时,就势必需要拿双方集成以一块儿。
实质上,MyBatis与Spring集成,本质上便是将MyBatis中之应和组件交给Spring容器进行保管,使得我们得以随Spring方式来行使MyBatis。

翔布置

既然MyBatis与Spring集成时是用那组件交给Spring进行管制,是哪些兑现之也?
其实,集成MyBatis与Spring需要利用通过mybatis-spring是组件来实现。

<!-- mybatis集成spring -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>${version.mybatis.spring}</version>
</dependency>

现实是怎组件要交给Spring托管呢?

1.数据源独立布置。可以动用相应之数据库连接池,既可以c3p0,也足以使druid。

druid数据源配置示范(详见:https://github.com/alibaba/druid):

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    <property name="url" value="${url}" />
    <property name="username" value="${username}" />
    <property name="password" value="${password}" />

    <property name="filters" value="stat" />

    <property name="maxActive" value="20" />
    <property name="initialSize" value="1" />
    <property name="maxWait" value="60000" />
    <property name="minIdle" value="1" />

    <property name="timeBetweenEvictionRunsMillis" value="60000" />
    <property name="minEvictableIdleTimeMillis" value="300000" />

    <property name="testWhileIdle" value="true" />
    <property name="testOnBorrow" value="false" />
    <property name="testOnReturn" value="false" />

    <property name="poolPreparedStatements" value="true" />
    <property name="maxOpenPreparedStatements" value="20" />

    <property name="asyncInit" value="true" />
</bean>

2.sqlSessionFactory

在MyBatis中,sqlSessionFactory是通过SqlSessionFactoryBuilder构建的。

// 从xml配置中构建sessionFactory
String resource = "mybatis-config.xml";
InputStream is = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

设若跟Spring集成时,sqlSessionFactory直接提交Spring管理。
实质上就是当Spring中采用SqlSessionFactoryBean对MyBatis的sqlSessionFactory进行了包装。

<!-- 配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
</bean>

3.映射器

mybatis在同spring集成时映射器配置来2种植艺术:

夫,在sqlSessionFactory中指定属性:mapperLocations,指定映射器的xml配置文件路径。

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <!-- mybatis映射器配置方式一: 直接指定映射器的xml配置文件来路径 -->
    <property name="mapperLocations" value="classpath*:org/chench/test/mybatis/mapper/**/*.xml" />
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg index="0" ref="sqlSessionFactory" />
</bean>

当这种措施下,需要而于Spring中扬言一个sqlSession对象,用于实践xml映射器中布局的CRUD操作。
注意:此以Spring中注册sqlSession对象并无是MyBatis的sqlSession对象,而是SqlSessionTemplate。
SqlSessionTemplate是MyBatis-Spring的中心。 这个类似负责管理
MyBatis的SqlSession, 调用MyBatis的SQL方法, 翻译异常。
SqlSessionTemplate是线程安全的, 可以让多个DAO所共享利用。
当调用SQL方法时, 包含从映射器getMapper()方法返回的办法,
SqlSessionTemplate将见面保证使用的SqlSession是暨当下Spring的事务相关的。
此外,它管理session的生命周期,包含必要的关,提交或回滚操作。
应用举例:

// 使用spring提供的sqlSession
SqlSession sqlSession = (SqlSession) context.getBean("sqlSession");
Test test = sqlSession.selectOne("org.chench.test.mybatis.mapper.selectOneTest", 1);
logger.info("test: {}", test);

test.setName(new Date().getTime() + "_haha");
sqlSession.update("org.chench.test.mybatis.mapper.updateOneTest", test);
//注意: 使用spring管理的sqlSession时,不允许手动提交事务
//sqlSession.commit();

彼,通过org.mybatis.spring.mapper.MapperFactoryBean配置映射器接口。

<bean id="testMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <!-- 独立注册每一个映射器接口 -->
    <property name="mapperInterface" value="org.chench.test.mybatis.mapper.impl.TestMapper" />
    <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

事实上,在报映射器接口时无需手动注册每一个映射器,而下MapperScannerConfigurer可以兑现挂号指定包路径下的有所映射器接口。

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="org.chench.test.mybatis.mapper.impl" />
</bean>

动举例:

// 当使用映射器接口时,直接获取映射器接口组件进行CRUD操作
TestMapper testMapper = context.getBean(TestMapper.class);
Test test = testMapper.selectOneTest(1);
logger.info("test: {}", test);

test.setName("heihei");
testMapper.updateOneTest(test);

推荐应用第二种方法注册MyBatis映射器,这样可一直用SQL语句写在Java注解上,非常节省了大气底xml配置。
本,对于Java注解SQL无法处理的复杂性气象,还是需用借助xml映射器来实现。

4.事务管理器

一个利用MyBatis-Spring的重要性由是它们同意MyBatis参与到Spring的事务管理中。
而非是叫MyBatis创建一个初的特定的事务管理器,MyBatis-Spring以了是为Spring中的
DataSourceTransactionManager。
若果Spring的PlatformTransactionManager配置好了,你可当
Spring中为你平常的做法来部署事务,@Transactional注解和AOP样式的布都是支持之。
在事务处理期间,一个独的SqlSession对象将会受创造及以。当工作完成时,这个session会以适合的措施提交或回滚。
若事情创建之后,MyBatis-Spring将会见透明底管住业务。在你的DAO类中虽未需要额外的代码了。

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>
<!-- 开启注解方式控制事务 -->
<tx:annotation-driven transaction-manager="transactionManager" /> 

注意:于事务管理器的使用,与MyBatis注册映射器方式不同而不同!
(1)如果MyBatis映射器为xml配置,则不得不编程式地决定作业。

// 编程控制事务
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

PlatformTransactionManager txManager = (PlatformTransactionManager) context.getBean("transactionManager");
TransactionStatus status = txManager.getTransaction(def);
try {
    sqlSession.update("org.chench.test.mybatis.mapper.updateOneTest", test);
    txManager.commit(status);
} catch (Exception e) {
    txManager.rollback(status);
    e.printStackTrace();
}

(2)如果MyBatis的映射器为接口,则可用注解方式管理工作(需要在Spring中布局开启注解方式决定工作)。

/**
 * 这是一个事务型操作
 * 使用注解方式控制事务
 * @param test
 * @return
 */
@Transactional
@Update("update test set name=#{name},descr=#{descr},url=#{url},update_time=now() where id=#{id}")
public Integer updateOneTest(Test test);

至于MyBatis与Spring集成的事无巨细例子:https://gitee.com/cchanghui/test-mybatis.git

【参考】
http://www.mybatis.org/spring/
http://www.mybatis.org/spring/zh/sqlsession.html

网站地图xml地图