mybatis学习整理(教程)

第一章 介绍

1.1 整合动机
正如第二版,Spring仅支持iBatis2。那么我们就想将MyBatis3的支持加入到Spring3.0(参考Spring的Jira的问题)中。不幸的是,Spring 3.0的开发在MyBatis 3.0官方发布前就结束了。因为Spring开发团队不想发布一个基于非发行版的MyBatis的整合支持,那么Spring官方的支持就不得不等到至少3.1版本了。要在Spring中支持MyBatis,MyBatis社区认为现在应该是自己团结贡献者和有兴趣的人一起来开始进行Spring和MyBatis整合的时候了。
这个小类库就来创建丢失的粘贴Spring和MyBtatis这两个流行框架的胶水。减少用户不得不来配置MyBatis和Spring 3.X上下文环境的样板和冗余代码。它还透明地增加了Spring对MyBatis事务的支持。

1.2 要求
在开始阅读本手册之前,很重要的一点是你要熟悉Spring和MyBatis这两个框架还有和它们有关的术语,本手册不会提供二者的背景内容,基本安装和配置教程。
和MyBatis一样,MyBatis-Spring也需要Java 5或更高版本。

第二章 入门

MyBatis-Spring帮助了你的MyBatis代码和Spring进行无缝整合。使用这个类库中的类,Spring将会为你加载必要的MyBatis工厂和session类。这个小类库也会提供一个简便的方式向你的service层bean中注入MyBatis的数据映射器。最终,MyBatis-Spring将会控制事务,翻译MyBatis异常到Spring的DataAccessException异常(数据访问异常,译者注)。

2.1 安装
要使用MyBatis-Spring模块,你只需要包含mybatis-spring-1.0.0-RC3.jar文件,并在类路径中加入依赖关系。
如果你使用Maven,那么在pom.xml中加入下面的代码即可:

<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.0.0-RC3</version>
</dependency>

2.2 快速创建
要和Spring一起使用MyBatis,你需要在Spring应用上下文中定义至少两样东西:一个SqlSessionFactory和至少一个数据映射器类。
在MyBatis-Spring中,SqlSessionFactoryBean是用于创建SqlSessionFactory.的。要配置这个工厂bean,放置下面的代码在Spring的XML配置文件中:

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

要注意SqlSessionFactory需要一个DataSource.(数据源,译者注)。这可以是任意的DataSource.,配置它就和配置其它Spring数据库连接一样。
假设你有一个如下编写的数据映射器类:

public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{userId}")
User getUser(@Param("userId") String userId);
}

那么可以使用,像下面这样来把接口加入到Spring中:

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

要注意指定的映射器类必须是一个接口,而不是具体的实现类。在这个示例中,注解被用来指定SQL语句,但是MyBatis的映射器XML文件也可以用。
一旦配置好,你可以以注入其它任意Spring的bean相同的方式直接注入映射器到你的business/service对象中。MapperFactoryBean控制SqlSession创建和关闭它。如果使用了Spring的事务,那么当事务完成时,session将会提交或回滚。最终,任何异常都会被翻译成Spring的DataAccessException异常。
调用MyBatis数据方法现在只需一行代码:

User user = userMapper.getUser(userId);

第三章 SqlSessionFactoryBean

在基本的MyBatis中,session工厂可以使用SqlSessionFactoryBuilder.来创建。在MyBatis-Spring中,使用了SqlSessionFactoryBean来替代。

3.1 创建
要创建工厂bean,放置下面的代码在Spring的XML配置文件中:

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

要注意SqlSessionFactoryBean实现了Spring的FactoryBean接口(请参考Spring文档的3.8章节部分)。这就说明Spring最终创建的bean不是SqlSessionFactoryBean本身完成的,但是工厂类getObject()返回的方法的结果是基于那个类的。这种情况下,Spring将会在应用启动时为你创建SqlSessionFactory对象,然后将它以SqlSessionFactory为名来存储。在Java中,相同的代码是:

SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
SqlSessionFactory sessionFactory = factoryBean.getObject();

在普通的MyBatis-Spring用法中,你不需要使用SqlSessionFactoryBean或直接和其对应的SqlSessionFactory。而session工厂将会被注入到MapperFactoryBean中或其它扩展了SqlSessionDaoSupport的DAO(Data Access Object,数据访问对象,译者注)中。

3.2 属性
SqlSessionFactory有一个必须的属性,就是JDBC的DataSource。这可以是任意的DataSource,配置和其它的Spring数据库连接是一样的。
一个通用的属性是configLocation,它是用来指定MyBatis的XML配置文件路径的。如果基本的MyBatis配置需要改变,那么这就是一个需要它的地方。通常这会是<settings>或<typeAliases>部分。
要注意这个配置文件不需要是一个完整的MyBatis配置。确定地来讲,任意环境,数据源和MyBatis的事务管理器都会被忽略。SqlSessionFactoryBean会创建它自己的,使用这些值定制MyBatis的Environment时是需要的。
如果MyBatis映射器XML文件在和映射器类相同的路径下不存在,那么另外一个需要配置文件的原因就是它了。使用这个配置,有两种选择。第一是手动在MyBatis的XML配置文件中使用<mappers>部分来指定类路径。第二是使用工厂bean的mapperLocations属性。
mapperLocations属性一个资源位置的list。这个属性可以用来指定MyBatis的XML映射器文件的位置。它的值可以包含Ant样式来加载一个目录中所有文件,或者从基路径下递归搜索所有路径。比如:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:sample/config/mappers/**/*.xml" />
</bean>

这会从类路径下加载在sample.config.mappers包和它的子包中所有的MyBatis映射器XML文件。
在容器环境管理事务中,一个可能需要的属性是transactionFactoryClass。我们可以在第四章(事务)中来查看有关部分。

第四章 事务

一个使用MyBatis-Spring的主要原因是它允许MyBatis参与到Spring的事务中。而不是给MyBatis创建一个新的特定的事务管理器,MyBatis-Spring利用了Spring中的DataSourceTransactionManager。
一旦Spring的PlatformTransactionManager配置好了,你可以在Spring中以你通常的做法来配置事务。@Transactional注解和AOP(Aspect-Oriented Program,面向切面编程,译者注)样式的配置都是支持的。在事务期间,一个单独的SqlSession对象将会被创建和使用。当事务完成时,这个session会以合适的方式提交或回滚。
一旦事务创建之后,MyBatis-Spring将会透明的管理事务。在你的DAO类中就不需要额外的代码了。

4.1 标准配置

要开启Spring的事务处理,在你的Spring的XML配置文件中简单创建一个DataSourceTransactionManager对象:

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

指定的DataSource可以是你通常使用Spring的任意JDBC DataSource。这包含了连接池和通过JNDI查找获得的DataSource。
要注意,为事务管理器指定的DataSource必须和用来创建SqlSessionFactoryBean的是同一个数据源,否则事务管理器就无法工作了。

4.2 容器管理事务
如果你正使用一个JEE容器而且想让Spring参与到容器管理事务(Container managed transactions,CMT,译者注)中,那么Spring应该使用JtaTransactionManager或它的容器指定的子类来配置。做这件事情的最方便的方式是用Spring的事务命名空间:

<tx:jta-transaction-manager />

在这种配置中,MyBatis将会和其它由CMT配置的Spring事务资源一样。Spring会自动使用任意存在的容器事务,在上面附加一个SqlSession。如果没有开始事务,或者需要基于事务配置,Spring会开启一个新的容器管理事务。
注意,如果你想使用CMT,而不想使用Spring的事务管理,你就必须配置SqlSessionFactoryBean来使用基本的MyBatis的ManagedTransactionFactory::

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="transactionFactoryClass"
value="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />
</bean>

第五章 使用SqlSession

在MyBatis中,你可以使用SqlSessionFactory来创建SqlSession。一旦你获得一个session之后,你可以使用它来执行映射语句,提交或回滚连接,最后,当不再需要它的时候,你可以关闭session。使用MyBatis-Spring之后,你不再需要直接使用SqlSessionFactory了,因为你的bean可以通过一个线程安全的SqlSession来注入,基于Spring的事务配置来自动提交,回滚,关闭session。
5.1 SqlSessionSupport
SqlSessionDaoSupport是一个抽象的支持类,用来为你提供SqlSession。调用getSqlSession()方法你会得到一个线程安全的SqlSession,之后可以用于执行SQL方法,就像下面这样:

public class UserMapperDaoImpl extends SqlSessionDaoSupport implements UserMapper {
public User getUser(String userId) {
return (User) getSqlSession()
.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
}
}

通常MapperFactoryBean是这个类的首选,因为它不需要额外的代码。但是,如果你需要在DAO中做其它非MyBatis的工作或需要具体的类,那么这个类就很有用了。
SqlSessionDaoSupport的配置和MapperFactoryBean很相似。它需要设置sqlSessionFactory或sqlSessionTemplate属性。这些被明确地设置或由Spring来自动装配。如果两者都被设置了,那么SqlSessionFactory是被忽略的。
假设UserMapperImpl是SqlSessionDaoSupport的子类,它可以在Spring中进行如下的配置:

<bean id="userMapper" class="org.mybatis.spring.sample.mapper.UserMapperImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

5.2 SqlSessionTemplate
SqlSessionTemplate是MyBatis-Spring的核心。这个类负责管理MyBatis的SqlSession,调用MyBatis的SQL方法,翻译异常。SqlSessionTemplate是线程安全的,可以被多个DAO所共享使用。
当调用SQL方法时,包含从映射器getMapper()方法返回的方法,SqlSessionTemplate将会保证的SqlSession使用是和当前Spring的事务相关的。此外,它管理session的生命周期,包含必要的关闭,提交或回滚操作。

SqlSessionTemplate实现了SqlSession,这就是说要对MyBatis进行简易替换,通常SqlSession. SqlSessionTemplate是被用来替代SqlSession的,因为MyBatis基本的SqlSession不能参与到Spring的事务中而且是线程不安全的。相同应用程序中两个类之间的转换可能会引起数据一致性的问题。
并不需要直接创建或使用SqlSessionTemplate。很多情况下,MapperFactoryBean内部使用一个模板,那就是所有需要的。当需要访问一个SqlSessionTemplate时,它可以使用SqlSessionFactory作为构造方法的参数来创建。

SqlSessionTemplate sessionTemplate = new SqlSessionTemplate(sqlSessionFactory);

相似地,模板可以在Spring的XML文件中配置。
SqlSessionTemplate有一个使用ExecutorType作为参数的构造方法。这允许你用来创建对象,比如,一个批量SqlSession,但是使用了下列Spring配置的XML文件:

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
<constructor-arg index="1" value="BATCH" />
</bean>

现在你所有的语句可以批量操作了,下面的语句就可以在DAO中使用了。

public void insertUsers(User[] users) {
SqlSession sqlSession = getSqlSession();
for (User user : users) {
sqlSession.insert("org.mybatis.spring.sample.mapper.UserMapper.insertUser", user);
}
}

注意如果所需的执行方法和默认的SqlSessionFactory设置不同,这种配置风格仅能使用。对这种形式需要说明的是当这个方法被调用时,不能有一个存在使用不同ExecutorType运行的事务。也要保证在不同的事务中,使用不同执行器来调用SqlSessionTemplate时,不如PROPAGATION_REQUIRES_NEW或完全在一个事务外面。


第六章 MapperFactoryBean

为了代替手工使用SqlSessionDaoSupport或SqlSessionTemplate编写数据访问对象(DAO)的代码,MyBatis-Spring提供了一个动态代理的实现:MapperFactoryBean。这个类可以让你直接注入数据映射器接口到你的service层bean中。当使用映射器时,你仅仅如调用你的DAO一样调用它们就可以了,但是你不需要编写任何DAO实现的代码,因为MyBatis-Spring将会为你创建代理。
使用注入的映射器代码,在MyBatis,Spring或MyBatis-Spring上面不会有直接的依赖。MapperFactoryBean创建的代理控制开放和关闭session,翻译任意的DataAccessException异常到Spring的异常中。此外,如果需要或参与到一个已经存在活动事务中,代理将会开启一个新的Spring事务。

6.1 创建
数据映射器接口可以按照如下做法加入到Spring中:

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

MapperFactoryBean创建的代理类实现了UserMapper接口,并且注入到应用程序中。因为代理创建在运行时环境中(Runtime,译者注),那么指定的映射器必须是一个接口,而不是一个实现类。
如果UserMapper有一个对应的MyBatis的XML映射器文件,如果XML文件在类路径的位置和映射器类相同时,它会被MapperFactoryBean自动解析。没有必要在MyBatis配置文件中去指定映射器,除非映射器的XML文件在不同的类路径下。可以参考SqlSessionFactoryBean的configLocation属性(第三章)来获取更多信息。
注意,当MapperFactoryBean需要SqlSessionFactory或SqlSessionTemplate时。这些可以通过各自的SqlSessionFactory或SqlSessionTemplate属性来设置,或者可以由Spring来自动装配。如果两个属性都设置了,那么SqlSessionFactory就会被忽略,因为SqlSessionTemplate是需要有一个session工厂的设置;那个工厂会由MapperFactoryBean.来使用。

6.2 注入映射器
你可以在business/service对象中直接注入映射器,和注入Spring的bean是一样的:

<bean id="fooService" class="org.mybatis.spring.sample.mapper.FooServiceImpl">
<property name="userMapper" ref="userMapper" />
</bean>

这个bean可以直接用在应用程序的逻辑中:

public class FooService {
private UserMapper userMapper;
...
public User doSomeBusinessStuff(String userId) {
return this.userMapper.getUser(userId);
}
}

注意,在这段代码中没有SqlSession或MyBatis的引用。也不需要去创建,打开或关闭session。如果使用了Spring的事务,那么当事务完成或由于错误回滚时,session也会被提交。

6.3 自动配置
没有必要在Spring的XML配置文件中注册所有的映射器。相反,你可以使用一个MapperScannerConfigurer,它将会查找类路径下的映射器并自动将它们创建成MapperFactoryBeans。
要创建MapperScannerConfigurer,可以在Spring的配置中添加如下代码:

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

basePackage属性是让你为映射器接口文件设置基本的包路径。你可以使用分号或逗号作为分隔符设置多于一个的包路径。每个映射器将会在指定的包路径中递归地被搜索到。
注意,没有必要去指定SqlSessionFactory或SqlSessionTemplate,因为MapperScannerConfigurer将会创建MapperFactoryBean,之后自动装配。但是,如果你使用了一个以上的DataSource(因此,也是多个的SqlSessionFactory),那么自动装配可能会失效。这种情况下,你可以使用sqlSessionFactoryBeanName或sqlSessionTemplateBeanName属性来设置正确的工厂/模板。
MapperScannerConfigurer支持过滤由指定的创建接口或注解创建映射器。annotationClass属性指定了要寻找的注解名称。markerInterface属性指定了要寻找的父接口。如果两者都被指定了,加入到接口中的映射器会匹配两种标准。默认情况下,这两个属性都是null,所以在基包中给定的所有接口可以作为映射器加载。
被发现的映射器将会使用Spring对自动侦测组件(参考Spring手册的3.14.4)默认的命名策略来命名。也就是说,如果没有发现注解,它就会使用映射器的非大写的非完全限定类名。但是如果发现了@Component或JSR-330 @Named注解,它会获取名称。注意你可以配置annotationClass到org.springframework.stereotype.Component,javax.inject.Named(如果你使用JSE 6)或你自己的注解(肯定是自我注解)中,这样注解将会用作生成器和名称提供器。

第七章 使用MyBatis API

使用MyBatis-Spring,你可以继续直接使用MyBatis的API。仅仅在Spring中使用SqlSessionFactoryBean来创建一个SqlSessionFactory,之后在你的代码中使用这个工厂。这种情况下你就不需要在代码中编写任何MyBatis-Spring的依赖了;仅在DAO中使用注入的SqlSessionFactory就行了。

public class UserMapperSqlSessionImpl implements UserMapper {
// SqlSessionFactory会通常由SqlSessionDaoSupport来设置
private SqlSessionFactory sqlSessionFactory;
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
public User getUser(String userId) {
// 注意标准的MyBatis API用法 – 手动打开和关闭session
SqlSession session = sqlSessionFactory.openSession();
try {
return (User) session.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
} finally {
session.close();
}
}
}

注意这种用法不会参与到任何Spring的事务中。更进一步来说,如果SqlSession使用了DataSource,它也被Spring的事务管理器使用了,还有当前过程中的事务,那么这段代码就会抛出异常。出于这个原因,如果你必须使用这种样式的代码,你就不应该使用Spring的事务数据库连接。

第八章 示例代码

这个示例代码展示了一个典型的事务服务层从数据访问层获取领域对象的设计。
这个service由FooService.java和FooServiceImpl.java实现类组成。这个Service是事务性的,所以当任何方法被调用和提交并没有以抛出非检查的异常而结束时,事务都会启动。

@Transactional
public interface FooService {
User doSomeBusinessStuff(String userId);
}

要注意,事务特性是由@Transactional属性配置的。这不是必须的;任何其它由Spring提供的方法都可以用来标定你的事务。
这个service使用MyBatis调用了一个数据访问层。这层由MyBatis的映射器接口UserMapper.java和可选的实现UserMapperImpl.java组成。
在所有的示例代码中,映射器都被注入到service bean中,所以service代码可以如下编写:

public class FooServiceImpl implements FooService {
private UserMapper userMapper;
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
public User doSomeBusinessStuff(String userId) {
return this.userMapper.getUser(userId);
}
}

在这个手册中,数据库访问层已经实现了使用不同技术来实现。SampleBasicTest会展示给你推荐的和最基于MapperFactoryBean最简单的配置。SampleAutoTest展示了一个基于组件扫描和自动装配的最小XML配置。SampleSqlSessionTest将会给你展示如何使用Spring管理的SqlSession.来手工编写一个DAO。最后SampleBatchTest将会给你展示如何使用批量操作的SqlSession。可以在实践中来看看这些不同的applicationContext.xml文件来使用MyBatis-Spring。
















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值