浓厚浅出mybatis之spring集成

图片 1

写在前头

在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地图