Spring基础(六)整合Mybatis
需要加载mybatis-spring的jar包。
因为在mybatis中也有许多new出来的对象,例如SqlSession等,都可以放到spring中进行托管。
<!-- spring操作数据库还需要一个spring-jdbc的包 -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<!-- 与webmvc版本相同 -->
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
</dependencies>
注意!在配置时需要mybatis的jar包,否则报:Bean must be of 'org.apache.ibatis.session.SqlSessionFactory’
Mybatis-Spring
mybatis-spring会帮助你将mybatis代码整合到Spring中!
使用步骤:
- 导入mybatis-spring的jar包
- 需要内置一个SqlSessionFactory到spring容器中(这个工厂需要数据源创建)
- 需要内置一个DataSource到spring容器中(因为原来这个在conf配置文件中,这下使用spring的数据源替代配置文件中的数据源)org.springframework.jdbc.datasource.DriverManagerDataSource
- 通过SqlSessionTemplate生成sqlSession(模板需要注入sqlSessionFactory)
- 给mapper接口加实现类(因为接口不能new对象,进而不能将mapper对象加到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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 创建一个spring的数据源对象 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="111111"/>
</bean>
<!-- 根据数据源创建一个sqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 以下属性不是必须的,绑定mybatis的配置文件,这样这个sqlSessionFactory就可以根据mybatis的配置文件的一些信息生成 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- 使用模板生成sqlSession,模板是根据SQLSessionFactory生成sqlSession -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
</beans>
在原来sqlSessionFactory是根据mybatis的conf配置文件生成的,现在是bean里面配置后进行生成的,==所以这个SQLSessionFactory的bean里面可以配置一切mybatis-conf文件中有的东西(包括连接mybaits-conf配置文件)==但是数据源是必须有的!
所以mybatis配置文件可以完全被替代。
一般在mybatis-conf文件中留有两项内容:别名管理;设置管理。然后使用configLocation进行连接。
public class User {
private String name;
public User() {
}
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public interface UserMapper {
List<User> getUsers();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org/DTD Mapper 3.0"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qiu.mapper.UserMapper">
<select id="getUsers" resultType="User">
select * from `user`
</select>
</mapper>
原来,mapper对象是在service层中使用的。使用spring后需要将mapper对象放到spring容器中,但是没有对应的类去生成,所以只能将UserMapper再实现以下作为一个实现类去生成mapper对象放到spring容器中去管理!
按照原来的mybaits,是通过反射生成mapper的。但是接口不能创建对象,所以不能放到spring容器中。没办法只能再加一层Impl,去实现一下接口,进而可以使之创建对象。
public class UserMapperImpl implements UserMapper {
SqlSessionTemplate sqlSession;
@Override
public List<User> getUsers() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.getUsers();
return users;
}
public SqlSessionTemplate getSqlSession() {
return sqlSession;
}
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
}
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<import resource="spring-dao.xml"/>
<bean id="userMapper" class="com.qiu.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
</beans>
SqlSessionDaoSupport
这是mybatis-spring提供的一个抽象类,有了这个类都不用去写sqlSession了(也就是说不需要去配置sqlSession到spring容器中,但还需要Factory、DataSource)
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
public getUsers(){
SqlSession session = getSqlSession();
retuen session.selectLise("com.qiu.mapper.UserMapper.getUsers");
}
}
<bean id="userMapper" class="com.qiu.mapper.UserMapperImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
这其实也没简化多少,就只是将sqlSession不用注册到spring中而已。而之前的操作需要将SqlSessionTemplate注册到spring容器中,并注入UserMapperImpl中供创建sqlSession使用而已。
就是少一个注入操作。并且userMapper的bean的注入是注入工厂(父类SqlSessionDaoSupport需要)
声明式事务
使用mybatis-spring的主要原因是它允许mybatis参与到spring的事务管理中。而不是给mybatis创建一个新的专用的事务管理器,mybatis-spring借助了spring的DataSourceTransactionManager类实现事务的管理、
要开启spring的事务处理功能,在spring的配置文件beans中创建一个DataSourceTransactionManager对象:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSoueceTransactionManager">
<constructor-arg ref="dataSource"/>
</bean>
spring中拥有两种事务管理方式:
- 声明式事务:AOP实现
- 编程式事务:需要改变原有代码
实现步骤:
-
创建一个事务管理对象,交由spring容器管理(表明这个源被事务管理。因为一个源拥有使用的哪种数据库、哪个数据库)创建一个切面类。这个切面类是mybatis-spring已经给你提供好的!你只需要创建对象、配置切面类即可!
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSoueceTransactionManager"> <constructor-arg ref="dataSource"/> </bean>
-
配置事务的通知(通知就是要插入的方法。这个表明要给所有add、delete插入方法)配置这个切面类
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/aop/spring-tx.xsd"> <!-- 注意这里的头信息需要配置 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSoueceTransactionManager"> <constructor-arg ref="dataSource"/> </bean> <!-- 配置事务的通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 给哪些方法配置事务 --> <tx:attributes> <!-- 给所有的add、delete方法添加事务 --> <tx:method name="add"/> <tx:method name="delete"/> <!-- 给所有的方法添加事务(增删改查) --> <tx:method name="*"/> </tx:attributes> </tx:advice> </beans>
可以把transactionManager看成一个切面类,advice是配置切面类的通知!
-
配置事务的切入。将切面类切入切入点
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSoueceTransactionManager"> <constructor-arg ref="dataSource"/> </bean> <!-- 配置事务的通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 给哪些方法配置事务 --> <tx:attributes> <!-- 给所有的add、delete方法添加事务 --> <tx:method name="add"/> <tx:method name="delete"/> <!-- 给所有的方法添加事务(增删改查) --> <tx:method name="*"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="txPointCut" expression="execution(* com.qiu.mapper.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config>
注意这里的切入点是mapper包中的所有mapper类的所有方法。因为mapper类中的方法是最原子的方法,这些原子jdbc操作方法支持事务后,service中使用的mapper方法自然就支持事务了