1.spring与mybits整合
首先导入所需的依赖
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.10</version>
</dependency>
<!--Maven 将会下载并引入 MySQL Connector/J,使你的项目能够通过 JDBC 与 MySQL 数据库进行连接和交互。-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!--datasource-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.26</version>
</dependency>
</dependencies>
配置了一个confing类,@ImportResource("classpath:tx.xml")是他的事务xml文件,也可以用注解的方式来完成(后面会提到)
package org.example.Config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
@ComponentScan("org.example")
@Configuration
@MapperScan("org.example.mapper")
@ImportResource("classpath:tx.xml")
public class Config {
@Bean("dataSource")
public DataSource datasource(){
DriverManagerDataSource source = new DriverManagerDataSource();
source.setDriverClassName("com.mysql.cj.jdbc.Driver");
source.setUsername("root");
source.setPassword("root");
source.setUrl("jdbc:mysql://localhost:3306/text?serverTimezone=Asia/Shanghai");
return source;
}
@Bean
public SqlSessionFactory getSession() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();
//sqlSessionFactoryBean.setTypeAliasesPackage("");
sqlSessionFactoryBean.setDataSource(datasource());
return sqlSessionFactoryBean.getObject();
}
}
下面是两个简单的实体类User与UserNumber
package org.example.dao;
public class User {
private int uid;
private String sex;
private String name;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package org.example.dao;
public class UserNumber {
private int pid;
private String number;
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
下面需要两个Mapper接口
package org.example.mapper;
import org.example.dao.User;
public interface UserMapper {
public void insert(User user);
}
package org.example.mapper;
import org.example.dao.UserNumber;
public interface UserNumberMapper {
public void insert(UserNumber userNumber);
}
下面是一个Service,int d=7/0;是让他产生异常,测试事务是否起效,验证两个插入同时成功或失败.
package org.example.service;
import org.example.dao.User;
import org.example.dao.UserNumber;
import org.example.mapper.UserMapper;
import org.example.mapper.UserNumberMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
@Autowired
private UserNumberMapper userNumberMapper;
@Autowired
private UserMapper userMapper;
@Transactional
public void userInsert(){
User user=new User();
user.setUid(12);
user.setName("ds");
user.setSex("男");
userMapper.insert(user);
int d=7/0;
UserNumber userNumber=new UserNumber();
userNumber.setPid(12);
userNumber.setNumber("77777777866");
userNumberMapper.insert(userNumber);
}
}
这是他们的sql语句的xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.UserMapper">
<insert id="insert" parameterType="org.example.dao.User">
insert into user values (#{uid},#{sex},#{name})
</insert>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.UserNumberMapper">
<insert id="insert" parameterType="org.example.dao.UserNumber">
insert into usernumber values (#{pid},#{number})
</insert>
</mapper>
这是他的事务管理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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
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/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--配置声明式事务管理-->
<!--配置一个事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!--配置事务策略: 对业务层的方法进行怎么样事务管理-->
<tx:attributes>
<!-- 对业务层类的具体的方法的设置事务策略
name: 业务层类的方法名, 支持通配符 *
要求你业务层类的方法必须按照你配置和名字起名
查询方法的策略
read-only: 是否只读: true只读, false不只读 默认值, 查询效率,对查询方法设置只读,
增删改方法,一定不能设置只读
propagation: 事务传播机制:
REQUIRED:默认值,表示如果存在一个事务,则支持当前事务,如果当前没有事务,则开启一个新的事务. 增删改
SUPPORTS:表示如果存在一个事务,则支持当前事务,如果当前没有事务,则按非事务方式执行, 查询
rollback-for="在那些异常下进行回滚" 默认值 RuntimeException
rollback-for="java.lang.Exception" 所有异常都回滚
no-rollback-for="那些异常不回滚"
timeout: 超时 默认 -1 永不超时
-->
<tx:method name="query*" read-only="true" propagation="SUPPORTS"/>
<tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
<tx:method name="select*" read-only="true" propagation="SUPPORTS"/>
<tx:method name="add*" rollback-for="java.lang.Exception"/>
<tx:method name="update*" rollback-for="java.lang.Exception"/>
<tx:method name="del*" rollback-for="java.lang.Exception"/>
<tx:method name="*" rollback-for="java.lang.Exception"/>
</tx:attributes>
</tx:advice>
<!--把事务通知类txAdvice与业务层的类方法进行织入: AOP的技术-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="mypointcut" expression="execution(* org.example.service..*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="mypointcut"/>
</aop:config>
</beans>
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>ref="dataSource"会是红色,可能是在运行是可以找到Confing类里的dataSource
idea版本高可能不会.他不会影响结果
我们也可以用全注解的方式完成事务管理
只要在Confing类加上一个 @EnableTransactionManagement,还有他的事务管理器
@Bean public DataSourceTransactionManager dataSourceTransaction(){ DataSourceTransactionManager dataSourceTransactionManager=new DataSourceTransactionManager(); dataSourceTransactionManager.setDataSource(datasource()); return dataSourceTransactionManager; }
我们想找到UserMapper.xml与UserNumberMapper.xml让他起作用就得让他们的项目结构一样比如上面的图.都是org.example.mapper包下面,且名字也要一致都叫UserMapper,UserNumberMapper 放xml的名字肯定多了一个.xml的后缀.
不然会报找不到的报错
而放事务管理的tx.xml可以用
@ImportResource("classpath:tx.xml")导入但是UserMapper.xml与UserNumberMapper.xml
却不行