[学习笔记] Spring之MyBatis与Spring的整合
# 学习 # · 2021-02-11
Spring整合MyBatis的准备工作
1、导入相关的jar包。
<!--导入相关的依赖包-->
<dependencies>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!--Spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!--Spring JDBC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!--Asceptj-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<!--MyBatis-Spring-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
</dependencies>
2、创建User实体类。
public class User {
private long id;
private String name;
private String pwd;
//省略getter/setter方法
}
3、编写数据访问层Dao接口。
public interface UserMapper {
public List<User> selectUser();
}
4、编写SQK映射文件UserMapper.xml。
<mapper namespace="com.demo.dao.UserMapper">
<!--select查询-->
<select id="selectUser" resultType="User">
select * from user;
</select>
</mapper>
5、编写MyBatis配置文件。
<configuration>
<!--设置POJO包下的类的别名-->
<typeAliases>
<package name="com.demo.pojo"/>
</typeAliases>
<!--此处数据库连接配置由Spring处理-->
<!--此处绑定Mapper文件由Spring处理-->
</configuration>
实现Spring与MyBatis整合
1、步骤一:编写Spring配置文件,配置数据源。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisdb"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
</beans>
(1)dataSource使用Spring的数据源替换MyBatis的配置,这里使用Spring的JDBC。
(2)目前流行的数据源有:dbcp、c3p0、Proxool等,它们都实现了连接池的功能。
(3)若url属性包含特殊符号,则需要使用<![CDATA[]]>
进行标记,或将其替换为实体引用&
。
2、步骤二:配置SqlSessionFactoryBean。
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--引用数据源组件-->
<property name="dataSource" ref="dataSource"></property>
<!--绑定MyBatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!--配置SQL映射文件-->
<property name="mapperLocations" value="classpath:com/demo/dao/*.xml"></property>
</bean>
(1)配置SQL映射文件信息的另一种写法。
<property name="mapperLocations">
<list>
<value>classpath:com/demo/dao/*.xml</value>
</list>
</property>
3、步骤三:使用SqlSessionTemplate实现数据库的操作。
//创建UserMapper实现类,并实现UserMapper接口
public class UserMapperImpl implements UserMapper{
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; }
public List<User> selectUser() {
return sqlSession.getMapper(UserMapper.class).selectUser();
}
}
<!--配置SqlSessionTemplate-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg>
</bean>
<!--配置Dao组件并注入SqlSessionTemplate实例-->
<bean id="UserMapper" class="com.demo.dao.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"></property>
</bean>
(1)SqlSessionTemplate类实现了MyBatis的SqlSession接口,可以替换MyBatis中原有的SqlSession实现类提供数据库访问操作。
(2)使用SqlSessionTemplate可以更好地简化工作,可以保证和当前Spring事务相关联,自动管理会话的生命周期,包括必要的关闭、提交和回滚操作。
4、步骤四:创建测试类。
@Test
public void run() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
List<User> userList = context.getBean(UserMapper.class).selectUser();
for(User u : userList) {
System.out.println(u);
}
}
5、使用SqlSessionDaoSupport 简化SqlSessionTemplate的配置和获取:
(1)修改实现类。
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
public List<User> selectUser() {
SqlSession sqlSession = getSqlSession();
return sqlSession.getMapper(UserMapper.class).selectUser();
}
}
(2)修改Spring配置文件。
<!--省略数据源配置-->
<!--配置SqlSessionFactoryBean-->
<!--配置Dao,注册Bean-->
<bean id="UserMapper" class="com.demo.dao.UserMapperImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
注入映射器实现
1、手动编写映射器实现存在的问题:
(1)SqlSession.selectList() 等方式需要采用字符串来指定映射项。
(2)SqlSession.getMapper() 等方式需要每次调用时都实现一次映射器接口,才能调用相应的方法,即每次的执行到getMapper(UserMapper.class)时,都会实现一次此接口,占用资源和时间。
sqlSession.getMapper(UserMapper.class).selectUser();
2、注入映射器实现的方法一:使用MapperFactoryBean注入映射器。修改Spring配置文件:
<!--省略数据源配置-->
<!--配置SqlSessionFactoryBean-->
<!-- 注入映射器,MapperFactoryBean -->
<bean id="UserMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!--mapperInterface属性指定映射器(只能是接口类型,不能是某个实现类)-->
<property name="mapperInterface" value="com.demo.dao.UserMapper"></property>
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
3、方法二:使用MapperScannerConfigurer注入映射器。修改Spring配置文件:
<!--省略数据源配置-->
<!--配置SqlSessionFactoryBean-->
<!--配置Dao,注册Bean-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.demo.dao"></property>
</bean>
(1)basePackage属性指定扫描的基准包,多个基准包以逗号隔开。
(2)MapperScannerConfigurer将递归扫描基准包,如果它们在SQL映射文件中定义过,则将他们动态注册为MapperFactoryBean。
4、更普遍的做法:在使用MapperScannerConfigurer自动完成映射器注册后,使用注解实现对业务组件的依赖注入。
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
public List<User> selectUser() {
return userMapper.selectUser();
}
}
声明式事务
1、声明式事务:基于AOP实现,无需编写任何事务管理代码,所有的工作全在配置文件中完成。
2、配置并实现声明式事务:
(1)编写SQL映射文件。
<insert id="insertUser" parameterType="User">
insert into user(id, name, pwd) values(#{id}, #{name}, #{pwd})
</insert>
<!--编写一条错误的SQL语句-->
<delete id="deleteUser" parameterType="int">
deletes from user where id=#{id}
</delete>
(2)修改UserMapper接口及其实现类:在SQL语句异常情况下,需要使用事务管理。
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
public List<User> selectUser() {
SqlSession sqlSession = getSqlSession();
//实例化一个新的User实体
User user = new User();
user.setId(17);
user.setName("小王");
user.setPwd("123456");
//添加新用户
sqlSession.getMapper(UserMapper.class).insertUser(user);
//删除旧用户
sqlSession.getMapper(UserMapper.class).deleteUser(16);
return sqlSession.getMapper(UserMapper.class).selectUser();
}
}
(3)定义事务管理器Bean,并为其注入数据源dataSource。
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
(4)配置事务增强。
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 定义属性,声明事务规则 -->
<tx:attributes>
<tx:method name="insert*"></tx:method>
<tx:method name="delete*"></tx:method>
<tx:method name="update*"></tx:method>
<tx:method name="*"></tx:method>
</tx:attributes>
</tx:advice>
(5)定义切入点,配置事务切入。
<aop:config>
<aop:pointcut id="txPointcut" expression="execution(* com.demo.dao.UserMapperImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"></aop:advisor>
</aop:config>
3、<tx:method>
属性说明:
(1)propagation:事务传播机制。
①REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
②SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
③MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
④REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
⑤NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
⑥NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
⑦NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。
(2)isolation:事务隔离等级,即当前事务和其他事务的隔离成都,在并发事务处理的情况下需要考虑其设置。
①DEFAULT:使用后端数据库默认的隔离级别。
②READ_UNCOMMITTED:允许读取尚未提交的更改。可能导致脏读、幻影读或不可重复读。
③READ_COMMITTED:允许从已经提交的并发事务读取。可防止脏读,但幻影读和不可重复读仍可能会发生。
④REPEATABLE_READ:对相同字段的多次读取的结果是一致的,除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻影读仍可能发生。
⑤SERIALIZABLE:完全服从ACID的隔离级别,确保不发生脏读、不可重复读和幻影读。这在所有隔离级别中也是最慢的,因为它通常是通过完全锁定当前事务所涉及的数据表来完成的。
(3)timeout:事务超时时间,即允许事务运行的最长时间。
(4)read-only:事务是否为只读,默认为false。
(5)rollback-for:设定能够出发回滚的异常类型。Spring默认只在抛出Runtime Exceotion时才标识事务回滚。
(6)no-rollback-for:设定不触发回滚的异常类型。Spring默认checked Exception不会触发事务回滚。
使用注解实现声明式事务处理
1、Spring支持使用注解配置声明式事务,所使用的注解是@Transactional
。
2、实现步骤:
(1)在Spring配置文件中配置事务管理类,并添加对注解配置的事务支持。
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
(2)使用注解来配置事务。
@Transactional
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
public List<User> selectUser() {
//省略实现代码
}
}
3、@Transactional
注解的属性:
如若转载,请注明出处:一木林多 - https://www.l5v.cn/archives/218/
评论