步骤
导入jar包
junit
Mybatis
MySQL
Spring
AOP
Mybatis-Spring
编写配置文件
测试
MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。
它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和 SqlSession
并注入到 bean 中,以及将 Mybatis 的异常转换为 Spring 的 DataAccessException
。
最终,可以做到应用代码不依赖于 MyBatis,Spring 或 MyBatis-Spring。
编写数据源配置
其实就相当于原来的Mybatis主配置文件加上SqlSessionFactory的功能。
可以导入Mybatis配置文件,启用Mybatis配置的内容,但是数据库链接和SqlSessionFactory必须在这里配置。
Mybatis配置的这里也都可以配置,比如别名、设置、Mapper等。
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> ? <!--DataSource:使用Spring的数据源替代Mybatis--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3308/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8"/> <property name="username" value="root"/> <property name="password" value="mysql"/> </bean> <!--sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!--绑定Mybatis配置文件--> <property name="configLocation" value="classpath:Mybatis-config.xml"/> <!--Mybatis配置文件中的内容都可以在这里配置--> <property name="mapperLocations" value="classpath:com/rzp/mapper/*.xml"/> </bean> ? <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <!--因为SqlSessionTemplate没有set方法,因此只能用构造器注入--> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean> ? </beans>
注:在spring中注册的org.mybatis.spring.SqlSessionTemplate其实就是Mybatis和Spring整合以后的SqlSession,而且是线程安全的。
Mybatis.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> ? <!-- 核心配置文件 --> <configuration> ? <typeAliases> <package name="com.rzp.pojo"/> </typeAliases> ? ? </configuration>
Mapper接口和实现类、Mapper.xml
Mapper接口
package com.rzp.mapper; ? import com.rzp.pojo.User; ? import java.util.List; ? public interface UserMapper { public List<User> selectUser(); } ?
Mapper实现类
package com.rzp.mapper; ? import com.rzp.pojo.User; import org.mybatis.spring.SqlSessionTemplate; ? import java.util.List; ? public class UserMapperImpl implements UserMapper { //我们所有的操作,原来使用SqlSession执行,现在改成使用SqlSessionTemplate private SqlSessionTemplate sqlSessionT; public void setSqlSessionT(SqlSessionTemplate sqlSession){ this.sqlSessionT = sqlSession; } @Override public List<User> selectUser() { UserMapper mapper = sqlSessionT.getMapper(UserMapper.class); return mapper.selectUser(); } } ?
将实现类注入到Spring
其实也可以放在spring-dao里面,但是现在spring-dao里只有Mybatis相关的,更规范,而且就是一个模板了。
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> ? <import resource="spring-dao.xml"/> <!----> <bean id="userMapper" class="com.rzp.mapper.UserMapperImpl"> <property name="sqlSessionT" ref="sqlSession"/> </bean> </beans>
测试
public class MyTest { @Test public void test() throws IOException { ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml"); UserMapper mapper = context.getBean(UserMapper.class); List<User> users = mapper.selectUser(); for (User user : users) { System.out.println(user); } } }
方式二是一个简化的操作,实现类可以继承SqlSessionDaoSupport,通过父类方法getSqlSession直接生成sqlSession,那么以下两个部分可以省略:
xml文件中这部分
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--因为SqlSessionTemplate没有set方法,因此只能用构造器注入-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
实现类的这部分
private SqlSessionTemplate sqlSessionT; public void setSqlSessionT(SqlSessionTemplate sqlSession){ this.sqlSessionT = sqlSession; }
实现类
package com.rzp.mapper; ? import com.rzp.pojo.User; import org.mybatis.spring.support.SqlSessionDaoSupport; ? import java.util.List; ? public class UserMapper2 extends SqlSessionDaoSupport implements UserMapper { @Override public List<User> selectUser() { return getSqlSession().getMapper(UserMapper.class).selectUser(); } } ?
spring注册
<bean id="userMapper2" class="com.rzp.mapper.UserMapper2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
在xml文件中导入tx,然后加入以下内容即可
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd"> ? ? <!--结合AOP实现事务的植入--> <!--配置事务通知--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!--给哪些方法配置事务--> <!--propagation事务的传播特性,默认Required--> <tx:attributes> <!--insert开头的开启事务 ,不过我测试method这几行不写事务也启动了。。--> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <!--所有方法都开启事务--> <tx:method name="*" propagation="REQUIRED"/> <tx:method name="query" read-only="true"/> </tx:attributes> </tx:advice> ? <aop:config> <!--通过aop代理启动事务,注明哪个包需要添加事务--> <aop:pointcut id="txPoint" expression="execution(* com.rzp.mapper.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/> </aop:config> </beans>
xml
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd"> ? <!--DataSource:使用Spring的数据源替代Mybatis--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3308/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8"/> <property name="username" value="root"/> <property name="password" value="mysql"/> </bean> <!--sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!--绑定Mybatis配置文件--> <property name="configLocation" value="classpath:Mybatis-config.xml"/> <!--Mybatis配置文件中的内容都可以在这里配置--> <property name="mapperLocations" value="classpath:com/rzp/mapper/*.xml"/> </bean> ? <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <!--因为SqlSessionTemplate没有set方法,因此只能用构造器注入--> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean> ? <!--配置声明式事务--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource" /> </bean> ? <!--结合AOP实现事务的植入--> <!--配置事务通知--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!--给哪些方法配置事务--> <!--propagation事务的传播特性,默认Required--> <tx:attributes> <!--insert开头的开启事务 ,不过我测试method这几行不写事务也启动了。。--> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <!--所有方法都开启事务--> <tx:method name="*" propagation="REQUIRED"/> <tx:method name="query" read-only="true"/> </tx:attributes> </tx:advice> ? <aop:config> <aop:pointcut id="txPoint" expression="execution(* com.rzp.mapper.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/> </aop:config> </beans>
接口实现
package com.rzp.mapper; ? import com.rzp.pojo.User; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.support.SqlSessionDaoSupport; ? import java.util.List; ? public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper { ? @Override public List<User> selectUser() { User user = new User(4, "rzp222", "123123"); UserMapper mapper = getSqlSession().getMapper(UserMapper.class); mapper.insertUser(user); //执行删除,因为删除语句是错的,就可以根据上面的insert是否执行成功来查看事务是否有开启 mapper.deleteUser(6); ? return mapper.selectUser(); } ? @Override public void insertUser(User user) { getSqlSession().getMapper(UserMapper.class).insertUser(user); } ? @Override public void deleteUser(int id) { getSqlSession().getMapper(UserMapper.class).deleteUser(id); } }
Mapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> ? <mapper namespace="com.rzp.mapper.UserMapper"> <select id="selectUser" resultType="user"> select * from user </select> ? <insert id="insertUser" parameterType="user"> insert into user (id,name,pwd) values (#{id},#{name},#{pwd}) </insert> <!--故意写错delete语句,以测试事务--> <delete id="deleteUser" parameterType="_int"> deletes from user where id = #{id} </delete> </mapper>
import com.rzp.mapper.UserMapper; import com.rzp.pojo.User; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; ? import java.util.List; ? public class Mytest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper userMapper = context.getBean("userMapper", UserMapper.class); List<User> users = userMapper.selectUser(); for (User user : users) { System.out.println(user); } } } ?
执行selectUser的时候,会先执行insert,再删除另一个记录。
因为删除的语句是错的,只要看insert的记录是否存在就可以知道事务是否开启了
原文:https://www.cnblogs.com/renzhongpei/p/12635163.html