MyBatis 学习-与 Spring 集成篇
根据官方的说法,在 ibatis3,也就是 Mybatis3 问世之前,Spring3 的开发工作就已经完成了,所以 Spring3 中还是没有对 Mybatis3 的支持。因此由 Mybatis 社区自己开发了一个 Mybatis-Spring 用来满足 Mybatis 用户整合 Spring 的需求。下面就将通过 Mybatis-Spring 来整合 Mybatis 跟 Spring 的用法做一个简单的介绍。
一、SqlSessionFactoryBean
Mybatis 的所有操作都是基于一个 SqlSession 的,而 SqlSession 是由 SqlSessionFactory 来产生的,SqlSessionFactory 又是由 SqlSessionFactoryBuilder 来生成的。而在 Mybatis-Spring 中则使用 SqlSessionFactoryBean 来替代。在这个 Bean 中通过 SqlSessionFactoryBuilder 来建立对应的 SqlSessionFactory,进而获取到 SqlSession。
<!-- 定义MyBatis的SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 指定MyBatis配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
<!-- 给Bean指定别名 -->
<property name="typeAliasesPackage" value="com.enh.bean"/>
</bean>
在定义 SqlSessionFactoryBean 的时候。dataSource 属性必须配置,它表示用于连接数据库的数据源,多数据源时会有多个 dataSource,同时也需要配置多个 SqlSessionFactory 来对应。当然,我们也可以指定一些其他的属性,下面简单列举几个:
- mapperLocations:它表示我们的 Mapper 文件存放的位置,当我们的 Mapper 文件跟对应的 Mapper 接口处于同一位置的时候可以不用指定该属性的值。
- configLocation:用于指定 Mybatis 的配置文件位置。如果指定了该属性,那么会以该配置文件的内容作为配置信息构建对应的 SqlSessionFactoryBuilder,但是后续属性指定的内容会覆盖该配置文件里面指定的对应内容。
- typeAliasesPackage:它一般对应我们的实体类所在的包,这个时候会自动取对应包中不包括包名的简单类名作为包括包名的别名。多个 package 之间可以用逗号或者分号等来进行分隔。
- typeAliases:数组类型,用来指定别名的。指定了这个属性后,Mybatis会把这个类型的短名称作为这个类型的别名,前提是该类上没有标注@Alias注解,否则将使用该注解对应的值作为此种类型的别名。
<property name="typeAliases">
<array>
<value>com.tiantian.mybatis.model.Blog</value>
<value>com.tiantian.mybatis.model.Comment</value>
</array>
</property>
- plugins:数组类型,用来指定 Mybatis 的 Interceptor。
- typeHandlersPackage:用来指定 TypeHandler 所在的包,如果指定了该属性,SqlSessionFactoryBean 会自动把该包下面的类注册为对应的 TypeHandler。多个 package 之间可以用逗号或者分号等来进行分隔。
- typeHandlers:数组类型,表示 TypeHandler。
二、MapperFactoryBean
接下来就是在 Spring 的 applicationContext 文件中定义我们想要的 Mapper 对象对应的 MapperFactoryBean 了。MapperFactoryBean 实现了 Spring 的 FactoryBean 接口,所以 MapperFactoryBean 是通过 FactoryBean 接口中定义的 getObject 方法来获取对应的 Mapper 对象的。
在定义一个 MapperFactoryBean 的时候有两个属性需要我们注入:
- sqlSessionFactory:Mybatis-Spring 用来生成实现了 SqlSession 接口的 SqlSessionTemplate 对象。
- mapperInterface:我们所要返回的 Mapper 接口全类名。
定义好相应 Mapper 接口对应的 MapperFactoryBean 之后,我们就可以把我们对应的 Mapper 接口注入到由 Spring 管理的 bean 对象中了,比如 Service层。
这时候我们的配置文件是这样的:
<!-- 引用外部配置文件 供数据源使用 -->
<context:property-placeholder location="classpath:application.properties"/> <!-- 数据源配置,使用应用内的DBCP数据库连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${dbcp.maxIdle}" />
<!-- 连接池最大数量 -->
<property name="maxActive" value="${dbcp.maxActive}" />
<property name="defaultAutoCommit" value="false" />
</bean> <!-- 定义MyBatis的SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 指定MyBatis配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
<!-- 给Bean指定别名 -->
<property name="typeAliasesPackage" value="com.enh.bean"/>
</bean> <!-- 创建MemberMapper对象 -->
<bean id="memberMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.enh.mapper.MemberMapper.java" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
三、MapperScannerConfigurer
利用上面的方法进行整合的时候,我们有一个 Mapper 就需要定义一个对应的 MapperFactoryBean,当我们的 Mapper 比较少的时候,这样做也还可以,但是当我们的 Mapper 相当多时我们再这样定义一个个 Mapper 对应的 MapperFactoryBean 就显得速度比较慢了。为此 Mybatis-Spring 为我们提供了一个叫做 MapperScannerConfigurer 的类,通过这个类 Mybatis-Spring 会自动为我们注册 Mapper 对应的 MapperFactoryBean 对象。
如果我们需要使用 MapperScannerConfigurer 来帮我们自动扫描和注册 Mapper 接口的话我们需要在 Spring 的 applicationContext 配置文件中定义一个 MapperScannerConfigurer 对应的 bean。对于 MapperScannerConfigurer 而言有一个属性是我们必须指定的,那就是 basePackage。basePackage 是用来指定 Mapper 接口文件所在的基包的,在这个基包或其所有子包下面的 Mapper 接口都将被搜索到。多个基包之间可以使用逗号或者分号进行分隔。最简单的 MapperScannerConfigurer 定义就是只指定一个 basePackage 属性,如:
<!-- 创建所有mapperFactoryBean -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.enh.mapper" />
</bean>
这样 MapperScannerConfigurer 就会扫描指定基包下面的所有接口,并把它们注册为一个个 MapperFactoryBean 对象。
有时候我们指定的基包下面的并不全是我们定义的 Mapper 接口,为此 MapperScannerConfigurer 还为我们提供了另外两个可以缩小搜索和注册范围的属性。一个是 annotationClass,另一个是 markerInterface。
- annotationClass:当指定了 annotationClass 的时候,MapperScannerConfigurer 将只注册使用了 annotationClass 注解标记的接口。
- markerInterface:markerInterface 是用于指定一个接口的,当指定了 markerInterface 之后,MapperScannerConfigurer 将只注册继承自 markerInterface 的接口。
如果上述两个属性都指定了的话,那么 MapperScannerConfigurer 将取它们的并集,而不是交集。即使用了 annotationClass 进行标记或者继承自 markerInterface 的接口都将被注册为一个 MapperFactoryBean。
现在假设我们的 Mapper 接口都继承了一个 SuperMapper 接口,那么我们就可以这样来定义我们的 MapperScannerConfigurer。
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.enh.mapper" />
<property name="markerInterface" value="com.enh.mapper.SuperMapper"/>
</bean>
除了用于缩小注册 Mapper 接口范围的属性之外,我们还可以指定一些其他属性,如:
- sqlSessionFactory:这个属性已经废弃。当我们使用了多个数据源的时候我们就需要通过 sqlSessionFactory 来指定在注册 MapperFactoryBean 的时候需要使用的 SqlSessionFactory,因为在没有指定 sqlSessionFactory 的时候,会以 Autowired 的方式自动注入一个。换言之当我们只使用一个数据源的时候,即只定义了一个 SqlSessionFactory 的时候我们就可以不给 MapperScannerConfigurer 指定 SqlSessionFactory。
- sqlSessionFactoryBeanName:它的功能跟 sqlSessionFactory 是一样的,只是它指定的是定义好的 SqlSessionFactory 对应的 bean 名称。
- sqlSessionTemplate:这个属性已经废弃。它的功能也是相当于 sqlSessionFactory 的,因为就像前面说的那样,MapperFactoryBean 最终还是使用的 SqlSession 的 getMapper 方法取的对应的 Mapper 对象。当定义有多个 SqlSessionTemplate 的时候才需要指定它。对于一个 MapperFactoryBean 来说 SqlSessionFactory 和 SqlSessionTemplate 只需要其中一个就可以了,当两者都指定了的时候,SqlSessionFactory 会被忽略。
- sqlSessionTemplateBeanName:指定需要使用的 sqlSessionTemplate 对应的 bean 名称。
注意:由于使用 sqlSessionFactory 和 sqlSessionTemplate 属性时会使一些内容在 PropertyPlaceholderConfigurer 之前加载,导致在配置文件中使用到的外部属性信息无法被及时替换而出错,因此官方现在新的 Mybatis-Spring 中已经把 sqlSessionFactory 和 sqlSessionTemplate 属性废弃了,推荐大家使用 sqlSessionFactoryBeanName 属性和 sqlSessionTemplateBeanName 属性。
四、SqlSessionTemplate
除了上述整合之后直接使用 Mapper 接口之外,Mybatis-Spring 还为我们提供了一种直接使用 SqlSession 的方式。Mybatis-Spring 为我们提供了一个实现了 SqlSession 接口的 SqlSessionTemplate 类,它是线程安全的,可以被多个 Dao 同时使用。同时它还跟 Spring 的事务进行了关联,确保当前被使用的 SqlSession 是一个已经和 Spring 的事务进行绑定了的。而且它还可以自己管理 Session 的提交和关闭。当使用了 Spring 的事务管理机制后,SqlSession 还可以跟着 Spring 的事务一起提交和回滚。
使用 SqlSessionTemplate 时我们可以在 Spring 的 applicationContext 配置文件中如下定义:
<!-- 定义MyBatis的SqlSessionBean -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
这样我们就可以通过 Spring 的依赖注入在 Dao 中直接使用 SqlSessionTemplate 来编程了,这个时候我们的 Dao 可能是这个样子:
package com.erim.dao;
@Repository("userDetailDao")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class UserDetailDao extends BaseDao {
public List<UserDetailBean> selectPageTown(BaseBean baseBean, ModelMap model) {
return getSqlSession().selectList("userdetail.selectPageTown", baseBean,
new RowBounds(baseBean.getPageLinkBean().getStart(), baseBean.getPageLinkBean().getLimit()));
}
}
五、最终的配置文件
<!-- 引用外部配置文件 供数据源使用 -->
<context:property-placeholder location="classpath:application.properties"/> <!-- 数据源配置,使用应用内的DBCP数据库连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${dbcp.maxIdle}" />
<!-- 连接池最大数量 -->
<property name="maxActive" value="${dbcp.maxActive}" />
<property name="defaultAutoCommit" value="false" />
</bean> <!-- 定义MyBatis的SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 指定MyBatis配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
<!-- 给Bean指定别名 -->
<property name="typeAliasesPackage" value="com.enh.bean"/>
</bean> <!-- 创建所有mapperFactoryBean -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.enh.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean> <!-- 定义MyBatis的SqlSessionBean -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
MyBatis 学习-与 Spring 集成篇的更多相关文章
- 因此mybatis最好与spring集成起来使用
单独使用mybatis是有很多限制的(比如无法实现跨越多个session的事务),而且很多业务系统本来就是使用spring来管理的事务,因此mybatis最好与spring集成起来使用. spring ...
- 深入浅出mybatis之与spring集成
目录 写在前面 详细配置 1.dataSource(数据源) 2.sqlSessionFactory(Session工厂) 3.Mapper(映射器) 4.TransactionManager(事务管 ...
- 【spring源码学习】spring集成orm数据框架
[一]简易的数据源配置 (1)配置文件 <!--springJdbcTemplemate数据操作配置信息 --> <bean id="driver" class= ...
- 【ActiveMQ入门-9】ActiveMQ学习-与Spring集成2
概述: 下面将介绍如何在Spring下集成ActiveMQ. 消费者:同步接收: 目的地:Queue 环境: 共5个文件 Receiver.java ReceiverTest.java Sender. ...
- 【ActiveMQ入门-8】ActiveMQ学习-与Spring集成
概述: 下面将介绍如何在Spring下集成ActiveMQ. 消费者:同步接收: 目的地:topic 环境: 主要包括4个文件: HelloSender.java: JMSTest.java: Pro ...
- mybatis学习笔记 spring与mybatis整合
转载自http://blog.csdn.net/naruto_Mr/article/details/48239357 1.创建web工程,导入spring依赖包与mybatis依赖包,还需要mybat ...
- MyBatis学习-映射文件标签篇(select、resultMap)
MyBatis 真正的核心在映射文件中.比直接使用 JDBC 节省95%的代码.而且将 SQL 语句独立在 Java 代码之外,可以进行更为细致的 SQL 优化. 一. 映射文件的顶级元素 selec ...
- MyBatis操作指南-与Spring集成(基于注解)
- Spring学习笔记--spring+mybatis集成
前言: 技术的发展, 真的是日新月异. 作为javaer, 都不约而同地抛弃裸写jdbc代码, 而用各种持久化框架. 从hibernate, Spring的JDBCTemplate, 到ibatis, ...
随机推荐
- JavaScript插件——弹出框
(JavaScript插件——弹出框) 前言 阅读之前您也可以到Bootstrap3.0入门学习系列导航中进行查看http://www.cnblogs.com/aehyok/p/3404867.htm ...
- require.js实践
ASP.NET MVC应用require.js实践 这里有更好的阅读体验和及时的更新:http://pchou.info/javascript/asp.net/2013/11/10/527f6ec41 ...
- 从异步更新进度想起的事儿——IProgress
今天,在群里向大家请教了这样一个问题:“两个对象(类.窗体或什么)之间,要完成比较频繁的报告进度更新都有哪些好的方式”,Somebody 跳出来给出了个“IProgress”,没了解过,后面围绕着它讨 ...
- 对中级 Linux 用户有用的 20 个命令
也许你已经发现第一篇文章非常的有用,这篇文章是继对初级Linux用户非常有用的20个命令的一个延伸. 第一篇文章的目的是为新手准备的而这篇文章则是为了Linux的中高级用户.在这里你将学会如何进行自定 ...
- ios学习笔记之UIControl解读
UIControl,相信大家对其并不陌生吧,比如平常最常用的UIButton就是继承自UIControl的.按照惯例,还是先来看看为什么有UIControl这个类?什么时候用到它? 查下文档就可以看到 ...
- 鸟哥的LINUX私房菜基础篇第三版 阅读笔记 一
1. Linux的档案权限与目录配置 一.基础知识: a.分为三类,拥有者(owner).群组(group).其他人(other) b.三个核 ...
- Koala Framework
Koala Framework是什么?我为什么要写这个框架? 当时的监管组,技术力量累积的很少,还在直连DB,使用着DataTable.DataSet作为数据的承载,监管是公司最近几年主推的项目, ...
- 浅谈XSS
最近在做项目中的漏洞修复工作,在短时间内接触到很多关于web开发需要防范的漏洞,例如SQL injection , XSS, CSRF等等,这些漏洞对web开发的项目来说的破坏还是比较大的,其实在网上 ...
- aix上使用裸设备安装oracle10g数据库
一.检查系统信息 [root@aix222 /]# oslevel -r 5300-08 [root@aix222 /]# prtconf | grep -i mem Memory Size: 190 ...
- 最近学习了下BI(商业智能)做报表
最近公司购买了Style intelligence 出的BI报表工具,接触新的东西不是很容易上手,这个东西是别的项目组用的,我们项目组由于进度比较快就让我先到他们项目组帮他们,为了使用这个东西,他们已 ...