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, ...
随机推荐
- knockoutJS 快速上手
翻译:Knockout 快速上手 - 3: knockoutJS 快速上手 许多时候,学会一种技术的有效方式就是使用它解决实际中的问题.在这一节,我们将学习使用 Knockout 来创建一个常见的应用 ...
- mvc的验证
mvc的验证锦上添点花(2) 上一篇文章我们演示了通过对jquery.validate.unobtrusive.js做点小修改,如何给MVC的验证添点花 主要还是修改了onError与onSucces ...
- Windows 安装Mongoliadb
1. 下载 下载地址: http://www.mongodb.org/downloads 我这里用的是:mongodb-win32-x86_64-2008plus-2.4.5.zip 2. 设置目录 ...
- Workflow:自定义工作流 之 模型选择
Workflow:自定义工作流 之 模型选择 背景 毕业5年,做了4个版本的工作流框架,工作流几乎是每个企业应用开发人员必须跨过的门槛(我还没有跨过去),下面简要说一下之前的4个版本,然后重点介绍第5 ...
- 关于Symfony2+nginx搭建过程总结
关于Symfony2+nginx搭建过程总结 最近在试着用nginx+symfony搭建公司的网站,由于nginx不支持pathinfo模式,所以必须修改nginx(我使用的是nginx1.5.1)的 ...
- 公共建筑能耗监测平台的GPRS通讯服务器的开发方法分享
公共建筑能耗监测平台的GPRS通讯服务器的开发方法分享 在这个文章里面我将用一个实际的案例来分享如何来构建一个能够接受3000+个连接的GPRS通讯服务器软件,这个软件被我认为是一个艺术品,实现周期为 ...
- KnockOut文档--模板绑定
目的 模板绑定使用数据render模板,然后把渲染的结果填充到Dom树中.模板通过重复或嵌套块(通常为您的视图模型数据的函数)用一种简单,方便的方式来建立复杂的UI结构 . 有两种方式使用模板: Na ...
- GetWindowRect和GetClientRect的区别详解
一:关于坐标 MFC中绘图时经常涉及到坐标计算,GetWindowRect和GetClientRect这两个函数,是获取逻辑坐标系中窗口或控件(其实也是窗口)大小和坐标的常用函数了,有什么不一样的? ...
- Linux-gate.so技术细节
1. linux-gate.so是什么参考这里:http://www.trilithium.com/johan/2005/08/linux-gate/简而言之,linux-gate.so是为了实现用户 ...
- 结构-行为-样式-Js排序算法之 直接插入排序
最新因工作原因需要接触到算法,之前学习C++的时候有接触过算法,Javascript中实现算法其实也是大同小异.下面我讲下第一个实现的排序算法--直接插入排序.基本实现思路:假定一个数组中前n(n&g ...