标签:
声明:本文系转载,有改动,原文请参考http://haohaoxuexi.iteye.com/blog/1843309
感谢作者的贡献!!!
根据官方的说法,在ibatis3,也就是Mybatis3问世之前,Spring3的开发工作就已经完成了,所以Spring3中还是没有对Mybatis3的支持。因此由Mybatis社区自己开发了一个Mybatis-Spring用来满足Mybatis用户整合Spring的需求。下面就将通过Mybatis-Spring来整合Mybatis跟Spring的用法做一个简单的介绍。
注: 本文是基于Mybatis3.2.1、Mybatis-Spring1.1.0和Spring3.1写的。
首先,我们需要从Mybatis官网上下载Mybatis-Spring的jar包添加到我们项目的类路径下,当然也需要添加Mybatis的相关jar包和Spring的相关jar包。我们知道在Mybatis的所有操作都是基于一个SqlSession的,而SqlSession是由SqlSessionFactory来产生的,SqlSessionFactory又是由SqlSessionFactoryBuilder来生成的。但是Mybatis-Spring是基于SqlSessionFactoryBean的。在使用Mybatis-Spring的时候,我们也需要SqlSession,而且这个SqlSession是内嵌在程序中的,一般不需要我们直接访问。SqlSession也是由SqlSessionFactory来产生的,但是Mybatis-Spring给我们封装了一个SqlSessionFactoryBean,在这个bean里面还是通过SqlSessionFactoryBuilder来建立对应的SqlSessionFactory,进而获取到对应的SqlSession。通过SqlSessionFactoryBean我们可以通过对其指定一些属性来提供Mybatis的一些配置信息。所以接下来我们需要在Spring的applicationContext配置文件中定义一个SqlSessionFactoryBean。
(SqlSessionFactoryBuilder------>SqlSessionFactory------>SqlSession)
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath:com/tiantian/ckeditor/mybatis/mappers/*Mapper.xml" /> <property name="typeAliasesPackage" value="com.tiantian.ckeditor.model" /> </bean>
在定义SqlSessionFactoryBean的时候,dataSource属性是必须指定的,它表示用于连接数据库的数据源。当然,我们也可以指定一些其他的属性,下面简单列举几个:
<property name="typeAliases"> <array> <value>com.tiantian.mybatis.model.Blog</value> <value>com.tiantian.mybatis.model.Comment</value> </array> </property>
接下来就是在Spring的applicationContext文件中定义我们想要的Mapper对象对应的MapperFactoryBean了。通过MapperFactoryBean可以获取到我们想要的Mapper对象。MapperFactoryBean实现了Spring的FactoryBean接口,所以MapperFactoryBean是通过FactoryBean接口中定义的getObject方法来获取对应的Mapper对象的。在定义一个MapperFactoryBean的时候有两个属性需要我们注入,一个是Mybatis-Spring用来生成实现了SqlSession接口的SqlSessionTemplate对象的sqlSessionFactory(这个属性好像会自动注入);另一个就是我们所要返回的对应的Mapper接口了。
定义好相应Mapper接口对应的MapperFactoryBean之后,我们就可以把我们对应的Mapper接口注入到由Spring管理的bean对象中了,比如Service bean对象。这样当我们需要使用到相应的Mapper接口时,MapperFactoryBean会从它的getObject方法中获取对应的Mapper接口,而getObject内部还是通过我们注入的属性调用SqlSession接口的getMapper(Mapper接口)方法来返回对应的Mapper接口的。这样就通过把SqlSessionFactory和相应的Mapper接口交给Spring管理实现了Mybatis跟Spring的整合。
Spring的applicationContext.xml配置文件:
BlogMapper.xml文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.tiantian.mybatis.mapper.BlogMapper"> <!-- 新增记录 --> <insert id="insertBlog" parameterType="Blog" useGeneratedKeys="true" keyProperty="id"> insert into t_blog(title,content,owner) values(#{title},#{content},#{owner}) </insert> <!-- 查询单条记录 --> <select id="selectBlog" parameterType="int" resultMap="BlogResult"> select * from t_blog where id = #{id} </select> <!-- 修改记录 --> <update id="updateBlog" parameterType="Blog"> update t_blog set title = #{title},content = #{content},owner = #{owner} where id = #{id} </update> <!-- 查询所有记录 --> <select id="selectAll" resultType="Blog"> select * from t_blog </select> <!-- 删除记录 --> <delete id="deleteBlog" parameterType="int"> delete from t_blog where id = #{id} </delete> </mapper>
BlogMapper.java:
BlogServiceImpl.java:
利用上面的方法进行整合的时候,我们有一个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属性,如:
这样MapperScannerConfigurer就会扫描指定基包下面的所有接口,并把它们注册为一个个MapperFactoryBean对象。当使用MapperScannerConfigurer加basePackage属性的时候,我们上面例子的applicationContext配置文件将变为这样:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <context:component-scan base-package="com.tiantian.mybatis" /> <context:property-placeholder location="classpath:config/jdbc.properties" /> <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}" /> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath:com/tiantian/mybatis/mapper/*.xml" /> <property name="typeAliasesPackage" value="com.tiantian.mybatis.model" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.tiantian.mybatis.mapper" /> </bean> </beans>
有时候我们指定的基包下面的并不全是我们定义的Mapper接口,为此MapperScannerConfigurer还为我们提供了另外两个可以缩小搜索和注册范围的属性。一个是annotationClass,另一个是markerInterface。
如果上述两个属性都指定了的话,那么MapperScannerConfigurer将取它们的并集,而不是交集。即使用了annotationClass进行标记或者继承自markerInterface的接口都将被注册为一个MapperFactoryBean。
现在假设我们的Mapper接口都继承了一个SuperMapper接口,那么我们就可以这样来定义我们的MapperScannerConfigurer。
如果是都使用了注解MybatisMapper标记的话,那么我们就可以这样来定义我们的MapperScannerConfigurer。
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.tiantian.mybatis.mapper" /> <property name="annotationClass" value="com.tiantian.mybatis.annotation.MybatisMapper"/> </bean>
除了用于缩小注册Mapper接口范围的属性之外,我们还可以指定一些其他属性,如:
注意:由于使用sqlSessionFactory和sqlSessionTemplate属性时会使一些内容在PropertyPlaceholderConfigurer之前加载,导致在配置文件中使用到的外部属性信息无法被及时替换而出错,因此官方现在新的Mybatis-Spring中已经把sqlSessionFactory和sqlSessionTemplate属性废弃了,推荐大家使用sqlSessionFactoryBeanName属性和sqlSessionTemplateBeanName属性。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:mybatis="http://www.mybatis.org/schema/mybatis" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.mybatis.org/schema/mybatis http://www.mybatis.org/schema/mybatis/mybatis-spring.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <context:component-scan base-package="com.tiantian.mybatis" /> <context:property-placeholder location="classpath:config/jdbc.properties" /> <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}" /> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath:com/tiantian/mybatis/mapper/*.xml" /> <property name="typeAliasesPackage" value="com.tiantian.mybatis.model" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.tiantian.mybatis.mapper" /> <property name="markerInterface" value="com.tiantian.mybatis.mapper.SuperMapper"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean> </beans>
除了上述整合之后直接使用Mapper接口之外,Mybatis-Spring还为我们提供了一种直接使用SqlSession的方式。Mybatis-Spring为我们提供了一个实现了SqlSession接口的SqlSessionTemplate类,它是线程安全的,可以被多个Dao同时使用。同时它还跟Spring的事务进行了关联,确保当前被使用的SqlSession是一个已经和Spring的事务进行绑定了的。而且它还可以自己管理Session的提交和关闭。当使用了Spring的事务管理机制后,SqlSession还可以跟着Spring的事务一起提交和回滚。
使用SqlSessionTemplate时我们可以在Spring的applicationContext配置文件中如下定义:
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>
这样我们就可以通过Spring的依赖注入在Dao中直接使用SqlSessionTemplate来编程了,这个时候我们的Dao可能是这个样子:
package com.tiantian.mybatis.dao; import java.util.List; import javax.annotation.Resource; import org.mybatis.spring.SqlSessionTemplate; import org.springframework.stereotype.Repository; import com.tiantian.mybatis.model.Blog; @Repository publicclass BlogDaoImpl implements BlogDao { private SqlSessionTemplate sqlSessionTemplate; publicvoid deleteBlog(int id) { sqlSessionTemplate.delete("com.tiantian.mybatis.mapper.BlogMapper.deleteBlog", id); } public Blog find(int id) { returnsqlSessionTemplate.selectOne("com.tiantian.mybatis.mapper.BlogMapper.selectBlog", id); } public List<Blog> find() { returnthis.sqlSessionTemplate.selectList("com.tiantian.mybatis.mapper.BlogMapper.selectAll"); } publicvoid insertBlog(Blog blog) { this.sqlSessionTemplate.insert("com.tiantian.mybatis.mapper.BlogMapper.insertBlog", blog); } publicvoid updateBlog(Blog blog) { this.sqlSessionTemplate.update("com.tiantian.mybatis.mapper.BlogMapper.updateBlog", blog); } public SqlSessionTemplate getSqlSessionTemplate() { returnsqlSessionTemplate; } @Resource publicvoid setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) { this.sqlSessionTemplate = sqlSessionTemplate; } }
标签:
原文地址:http://www.cnblogs.com/starskys/p/5146240.html