目录
首先新建一个Spring-MyBatis程序
项目结构:
![]()
1. 导入相关jar包
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
2. 创建实体类User
IDEA首先连接数据库
这里的数据库表为:
创建实体类User
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
3. 编写UserMapper接口
这里有三个方法:
- 查询所有用户
getUser
- 增加指定用户
addUser
- 删除指定id的用户
deleteUser
public interface UserMapper {
public List<User> getUser();
//添加一个用户
public int addUser(User user);
//删除一个用户
public int deleteUser(int id);
}
4. 编写UserMapper.xml配置文件
这里故意将deleteUser
的 sql语句
写错 ,delete
写成 deletes
<?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="mapper.UserMapper">
<select id="getUser" resultType="pojo.User">
select * from mybatis.user
</select>
<insert id="addUser" parameterType="pojo.User">
insert into mybatis.user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
<delete id="deleteUser" parameterType="int">
deletes from mybatis.user where id=#{id}
</delete>
</mapper>
5. 编写Spring配置文件applicationContext.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:tx="http://www.springframework.org/schema/tx"
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/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--数据源-->
<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:3306/mybatis?useSSH=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="200024"/>
</bean>
<!--sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/UserMapper.xml"/>
</bean>
<!--sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
</beans>
6. 编写UserMapper接口实现类
在getUser
方法中:
- 先后调用
addUser
和deleteUser
两个方法,增加和删除同一个用户
public class UserMapperImpl implements UserMapper {
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
public List<User> getUser() {
User user = new User(5, "小王", "1212");
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.addUser(user);
mapper.deleteUser(5);
return mapper.getUser();
}
public int addUser(User user) {
return sqlSession.getMapper(UserMapper.class).addUser(user);
}
public int deleteUser(int id) {
return sqlSession.getMapper(UserMapper.class).deleteUser(id);
}
}
然后在Spring配置文件applicationContext
中创建该实现类对象,并注入私有属性sqlSession的值
<bean id="userMapper" class="mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
7. 编写测试类
public class Test {
@org.junit.Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper userMapper = (UserMapper) context.getBean("userMapper");
List<User> users = userMapper.getUser();
for (User user : users) {
System.out.println(user);
}
}
}
8. 运行查看结果
不出所料,报错了,因为我们的sql
语句写错了
我们刷新数据表看看
发现还是增加了5号
用户,这就是因为没有添加事务
,不会要么都成功,要么都失败
9. 修改,增加声明式事务支持
以下操作均添加在Spring配置文件
applicationContext.xml
中
要引入tx
,aop
约束
1. 开启Spring的事务处理功能
- 创建一个
DataSourceTransactionManager
对象,传入上述创建好的dataSource
对象
<!--配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
2. 配置事务通知
这里使用事务tx
命名空间配置
- 常用的两个属性
-
用
name
属性规定配置事务的方法 -
用
propagation
属性配置事务的传播特性,默认为REQUIRED
REQUIRED 支持当前事务,如果当前没有事务,就新建一个事务 REQUIRED_NEW 新建事务,如果当前存在事务,把当前事务挂起 SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行 NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起 MANDATORY 支持当前事务,如果当前没有事务,就抛出异常 NEVER 以非事务方式执行,如果当前存在事务,则抛出异常 NESTED 支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务
-
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--name给哪写方法配置事务-->
<!--propagation配置事务传播特性-->
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="query" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
3. 结合AOP实现事务织入
<!--结合AOP的实现事务的织入-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
10. 再次测试
数据表中删除上述插入的5号数据,再次运行测试,同样的报错信息
但是,我们重新刷新表格,发现5号用户没有添加进来,这就是因为事务
,要么都成功,要么都失败