要在Spring中使用MyBatis,需要在Spring的配置文件中定义一些类:
1、SqlSessionFactoryBean:为整合应用提供SqlSession对象资源
2、SqlSessionTemplate:负责管理MyBatis的SqlSession,调用SQL映射语句,实现对数据库的访问
3、MapperFactoryBean:根据指定Mapper接口生成Bean实例
4、MapperScannerConfigurer:根据指定包批量扫描Mapper接口并生成实例
整合准备工作:
1、添加mybatis-spring的jar文件
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.0</version>
</dependency>
2、创建实体类
3、创建数据访问接口
4、配置SQL映射文件
5、配置mybatis配置文件
实现对mybatis的整合:
1、配置数据源
目前流行的数据源:dbcp、c3p0、Proxool都实现了连接池功能
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<!-- <property name="url">
<value><![CDATA[jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf-8]]></value>
</property> -->
<property name="url" value="jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="hbtt" />
</bean>
2、配置SqlSessionFactoryBean
<!-- 配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 引用数据源组件 -->
<property name="dataSource" ref="dataSource" />
<!-- 引用MyBatis配置文件中的配置 -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
<!-- 配置SQL映射文件信息 -->
<property name="mapperLocations">
<list>
<value>classpath:cn/smbms/dao/**/*.xml</value><!--扫描cn.smbms.dao包以及任意层级子包-->
</list>
</property>
</bean>
第一种方式:
3、使用SqlSessionTemplate实现数据库的操作
UserMapperImpl:
package dao.impl;
import java.util.List;
import org.mybatis.spring.SqlSessionTemplate;
import dao.UserMapper;
import eneity.User;
public class UserMapperImpl implements UserMapper {
private SqlSessionTemplate sqlSession;
public List<User> getUserList(User user) {
return sqlSession.selectList("dao.UserMapper.getUserList", user);
}
public SqlSessionTemplate getSqlSession() {
return sqlSession;
}
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
}
<!-- 配置SqlSessionTemplate -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<!-- 配置DAO -->
<bean id="userMapper" class="dao.impl.UserMapperImpl">
<property name="sqlSession" ref="sqlSessionTemplate" />
</bean>
4、业务类以及测试
业务类:
public interface UserService {
public List<User> findUsersWithConditions(User user);
}
业务实现:
public class UserServiceImpl implements UserService {
private UserMapper userMapper;
public List<User> findUsersWithConditions(User user) {
try {
return userMapper.getUserList(user);
} catch (RuntimeException e) {
e.printStackTrace();
throw e;
}
}
public UserMapper getUserMapper() {
return userMapper;
}
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
}
<!-- 配置业务Bean -->
<bean id="userService" class="service.impl.UserServiceImpl">
<property name="userMapper" ref="userMapper" />
</bean>
测试类:
@Test
public void testGetUserList() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) ctx.getBean("userService");
List<User> userList = new ArrayList<User>();
User userCondition = new User();
userCondition.setUserName("赵");
userCondition.setUserRole(3);
userList = userService.findUsersWithConditions(userCondition);
for (User userResult : userList) {
logger.debug("testGetUserList userCode: " + userResult.getUserCode() + " and userName: "+ userResult.getUserName() + " and userRole: "+ userResult.getUserRole() + " and userRoleName: "+ userResult.getUserRoleName() + " and address: "+ userResult.getAddress());
}
}
注意:
1、创建SqlSessionTemplate实例时,需要通过其构造方法注入SqlSessionFactory实例。这里引用的是前文配置过的Id为SqlSessionFactory的Bean
2、与mybatis中默认的sqlSession实现不同,SqlSessionTemplate是线程安全的,可以以单例模式配置并被多个Dao对象共用,而不必为每个Dao单独配置一个SqlSessionTemplate实例
第二种方式:
针对SqlSessionTemplate的使用,mybatis-spring还提供了SqlSessionDaoSupport类来简化SqlSessionTemplate的配置和获取。
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
public List<User> getUserList(User user) {
// TODO Auto-generated method stub
return this.getSqlSession().selectList("dao.UserMapper.getUserList", user);
}
}
<!-- 配置DAO -->
<bean id="userMapper" class="dao.impl.UserMapperImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
注意:SqlSessionDaoSupport提供了sqlSessionFactory()方法来注入sqlSessionFactory实例并创建SqlSessionTemplate实例,同时提供getSqlSession()方法来返回创建好的SqlSessionTemplate实例。这样,DAO实现类只需继承SqlSessionDaoSupport类即可通过getSqlSession()方法获得创建好的SqlSessionTemplate实例,不需要SqlSession属性以及setter方法。配置文件中无需配置SqlSessionTemplate,
注入映射器实现
原因:使用SqlSessionTemplate方法,都是采用字符串来指定映射项,这种方法比较容易产生错误,如果存在拼写错误,在编译期无法识别,只能等运行时才能发现,而且命名空间发生变化,会导致很多地方需要修改,不易维护。通过配置的方式直接为业务对象注入映射器实现
1、使用MapperFactoryBean注入映射器(只作为一个了解)
<!-- 配置DAO -->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="dao.UserMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<!-- 配置业务Bean -->
<bean id="userService" class="service.impl.UserServiceImpl">
<property name="userMapper" ref="userMapper" />
</bean>
注意:sql映射文件必须遵循以下命名原则:
1、映射命名空间和映射器接口名称相同
2、映射元素的id和映射器接口的方法相同
映射器对应的SQL映射文件与映射器的类路径相同,该映射文件可以自动被MapperFactoryBean解析
2、使用MapperScannerConfigurer注入映射器(宜用映射器多,配置项也多)MapperScannerConfigurer可以扫描指定包中的接口并将他们直接注册为MapperFactoryBean
<!-- 配置DAO -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> -->
<property name="basePackage" value="dao" />
</bean>
<!-- 配置业务Bean -->
<!-- <bean id="userService" class="service.impl.UserServiceImpl">
<property name="userMapper" ref="userMapper" />
</bean> -->
<context:component-scan base-package="service" />
在业务类添加注解绑定getBean:@Service("userService")、@Autowired
MapperScannerConfigurer 与@Autowired注解或@Resource注解配合使用,自动创建映射器实现并注入给业务组件,能够最大限度地减少DAO组件与业务组件的编码和配置工作
事务分为:编程式和声明式事务
为业务层添加声明式事务
1、(配置文件)
<!-- <tx:advice>标签配置事务增强,设定事务的属性,为不同业务方法指定具体的事务规则 -->
<!-- 定义事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 使用配置文件 -->
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="find*" propagation="SUPPORTS" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<!-- 使用注解 -->
<!-- <tx:annotation-driven transaction-manager="transactionManager"/> -->
<!-- 定义切面 -->
<aop:config>
<aop:pointcut id="serviceMethod"
expression="execution(* service..*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" />
</aop:config>
配置步骤
1、导入tx和aop命名空间
2、定义事务管理器Bean,并为其注入数据源Bean
3、通过<tx:advice>配置事务增强,绑定事务管理器并针对不同方法定义事务规则
4、配置切面,将事务增强与方法切入点组合(advice-ref="txAdvice")
propagation:事务传播机制
REQUIRED(默认值)
REQUIRES_NEW 、MANDATORY、NESTED
SUPPORTS
NOT_SUPPORTED、NEVER
isolation:事务隔离等级
DEFAULT(默认值)
READ_COMMITTED
READ_UNCOMMITTED
REPEATABLE_READ
SERIALIZABLE
timeout:事务超时时间,允许事务运行的最长时间,以秒为单位。默认值为-1,表示不超时
read-only:事务是否为只读,默认值为false
rollback-for:设定能够触发回滚的异常类型
1、Spring默认只在抛出runtime exception时才标识事务回滚
2、可以通过全限定类名指定需要回滚事务的异常,多个类名用逗号隔开
no-rollback-for:设定不触发回滚的异常类型
1、Spring默认checked Exception不会触发事务回滚
2、可以通过全限定类名指定不需回滚事务的异常,多个类名用英文逗号隔开
2、(注解)
<!-- 定义事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 使用注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
@Transactional//为该类的所有业务统一添加事务处理
@Service("userService")
public class UserServiceImpl implements UserService {
……
@Transactional(propagation = Propagation.SUPPORTS)//单独进行事务设置
public List<User> findUsersWithConditions(User user) {
// 省略实现代码
}
}
1、SqlSessionFactoryBean:为整合应用提供SqlSession对象资源
2、SqlSessionTemplate:负责管理MyBatis的SqlSession,调用SQL映射语句,实现对数据库的访问
3、MapperFactoryBean:根据指定Mapper接口生成Bean实例
4、MapperScannerConfigurer:根据指定包批量扫描Mapper接口并生成实例
整合准备工作:
1、添加mybatis-spring的jar文件
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.0</version>
</dependency>
2、创建实体类
3、创建数据访问接口
4、配置SQL映射文件
5、配置mybatis配置文件
实现对mybatis的整合:
1、配置数据源
目前流行的数据源:dbcp、c3p0、Proxool都实现了连接池功能
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<!-- <property name="url">
<value><![CDATA[jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf-8]]></value>
</property> -->
<property name="url" value="jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="hbtt" />
</bean>
2、配置SqlSessionFactoryBean
<!-- 配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 引用数据源组件 -->
<property name="dataSource" ref="dataSource" />
<!-- 引用MyBatis配置文件中的配置 -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
<!-- 配置SQL映射文件信息 -->
<property name="mapperLocations">
<list>
<value>classpath:cn/smbms/dao/**/*.xml</value><!--扫描cn.smbms.dao包以及任意层级子包-->
</list>
</property>
</bean>
第一种方式:
3、使用SqlSessionTemplate实现数据库的操作
UserMapperImpl:
package dao.impl;
import java.util.List;
import org.mybatis.spring.SqlSessionTemplate;
import dao.UserMapper;
import eneity.User;
public class UserMapperImpl implements UserMapper {
private SqlSessionTemplate sqlSession;
public List<User> getUserList(User user) {
return sqlSession.selectList("dao.UserMapper.getUserList", user);
}
public SqlSessionTemplate getSqlSession() {
return sqlSession;
}
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
}
<!-- 配置SqlSessionTemplate -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<!-- 配置DAO -->
<bean id="userMapper" class="dao.impl.UserMapperImpl">
<property name="sqlSession" ref="sqlSessionTemplate" />
</bean>
4、业务类以及测试
业务类:
public interface UserService {
public List<User> findUsersWithConditions(User user);
}
业务实现:
public class UserServiceImpl implements UserService {
private UserMapper userMapper;
public List<User> findUsersWithConditions(User user) {
try {
return userMapper.getUserList(user);
} catch (RuntimeException e) {
e.printStackTrace();
throw e;
}
}
public UserMapper getUserMapper() {
return userMapper;
}
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
}
<!-- 配置业务Bean -->
<bean id="userService" class="service.impl.UserServiceImpl">
<property name="userMapper" ref="userMapper" />
</bean>
测试类:
@Test
public void testGetUserList() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) ctx.getBean("userService");
List<User> userList = new ArrayList<User>();
User userCondition = new User();
userCondition.setUserName("赵");
userCondition.setUserRole(3);
userList = userService.findUsersWithConditions(userCondition);
for (User userResult : userList) {
logger.debug("testGetUserList userCode: " + userResult.getUserCode() + " and userName: "+ userResult.getUserName() + " and userRole: "+ userResult.getUserRole() + " and userRoleName: "+ userResult.getUserRoleName() + " and address: "+ userResult.getAddress());
}
}
注意:
1、创建SqlSessionTemplate实例时,需要通过其构造方法注入SqlSessionFactory实例。这里引用的是前文配置过的Id为SqlSessionFactory的Bean
2、与mybatis中默认的sqlSession实现不同,SqlSessionTemplate是线程安全的,可以以单例模式配置并被多个Dao对象共用,而不必为每个Dao单独配置一个SqlSessionTemplate实例
第二种方式:
针对SqlSessionTemplate的使用,mybatis-spring还提供了SqlSessionDaoSupport类来简化SqlSessionTemplate的配置和获取。
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
public List<User> getUserList(User user) {
// TODO Auto-generated method stub
return this.getSqlSession().selectList("dao.UserMapper.getUserList", user);
}
}
<!-- 配置DAO -->
<bean id="userMapper" class="dao.impl.UserMapperImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
注意:SqlSessionDaoSupport提供了sqlSessionFactory()方法来注入sqlSessionFactory实例并创建SqlSessionTemplate实例,同时提供getSqlSession()方法来返回创建好的SqlSessionTemplate实例。这样,DAO实现类只需继承SqlSessionDaoSupport类即可通过getSqlSession()方法获得创建好的SqlSessionTemplate实例,不需要SqlSession属性以及setter方法。配置文件中无需配置SqlSessionTemplate,
注入映射器实现
原因:使用SqlSessionTemplate方法,都是采用字符串来指定映射项,这种方法比较容易产生错误,如果存在拼写错误,在编译期无法识别,只能等运行时才能发现,而且命名空间发生变化,会导致很多地方需要修改,不易维护。通过配置的方式直接为业务对象注入映射器实现
1、使用MapperFactoryBean注入映射器(只作为一个了解)
<!-- 配置DAO -->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="dao.UserMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<!-- 配置业务Bean -->
<bean id="userService" class="service.impl.UserServiceImpl">
<property name="userMapper" ref="userMapper" />
</bean>
注意:sql映射文件必须遵循以下命名原则:
1、映射命名空间和映射器接口名称相同
2、映射元素的id和映射器接口的方法相同
映射器对应的SQL映射文件与映射器的类路径相同,该映射文件可以自动被MapperFactoryBean解析
2、使用MapperScannerConfigurer注入映射器(宜用映射器多,配置项也多)MapperScannerConfigurer可以扫描指定包中的接口并将他们直接注册为MapperFactoryBean
<!-- 配置DAO -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> -->
<property name="basePackage" value="dao" />
</bean>
<!-- 配置业务Bean -->
<!-- <bean id="userService" class="service.impl.UserServiceImpl">
<property name="userMapper" ref="userMapper" />
</bean> -->
<context:component-scan base-package="service" />
在业务类添加注解绑定getBean:@Service("userService")、@Autowired
MapperScannerConfigurer 与@Autowired注解或@Resource注解配合使用,自动创建映射器实现并注入给业务组件,能够最大限度地减少DAO组件与业务组件的编码和配置工作
事务分为:编程式和声明式事务
为业务层添加声明式事务
1、(配置文件)
<!-- <tx:advice>标签配置事务增强,设定事务的属性,为不同业务方法指定具体的事务规则 -->
<!-- 定义事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 使用配置文件 -->
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="find*" propagation="SUPPORTS" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<!-- 使用注解 -->
<!-- <tx:annotation-driven transaction-manager="transactionManager"/> -->
<!-- 定义切面 -->
<aop:config>
<aop:pointcut id="serviceMethod"
expression="execution(* service..*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" />
</aop:config>
配置步骤
1、导入tx和aop命名空间
2、定义事务管理器Bean,并为其注入数据源Bean
3、通过<tx:advice>配置事务增强,绑定事务管理器并针对不同方法定义事务规则
4、配置切面,将事务增强与方法切入点组合(advice-ref="txAdvice")
propagation:事务传播机制
REQUIRED(默认值)
REQUIRES_NEW 、MANDATORY、NESTED
SUPPORTS
NOT_SUPPORTED、NEVER
isolation:事务隔离等级
DEFAULT(默认值)
READ_COMMITTED
READ_UNCOMMITTED
REPEATABLE_READ
SERIALIZABLE
timeout:事务超时时间,允许事务运行的最长时间,以秒为单位。默认值为-1,表示不超时
read-only:事务是否为只读,默认值为false
rollback-for:设定能够触发回滚的异常类型
1、Spring默认只在抛出runtime exception时才标识事务回滚
2、可以通过全限定类名指定需要回滚事务的异常,多个类名用逗号隔开
no-rollback-for:设定不触发回滚的异常类型
1、Spring默认checked Exception不会触发事务回滚
2、可以通过全限定类名指定不需回滚事务的异常,多个类名用英文逗号隔开
2、(注解)
<!-- 定义事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 使用注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
@Transactional//为该类的所有业务统一添加事务处理
@Service("userService")
public class UserServiceImpl implements UserService {
……
@Transactional(propagation = Propagation.SUPPORTS)//单独进行事务设置
public List<User> findUsersWithConditions(User user) {
// 省略实现代码
}
}