<!-- MyBatis-Spring 整合包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version> <!-- 對應 MyBatis 3.5+ -->
</dependency>
<!-- 連接池:Druid 推薦 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.18</version>
</dependency>
<!-- Spring 事務 & AOP -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
mybatis-config.xml 僅保留類型別名,數據源、事務管理器、Mapper 掃描全部交給 Spring 管理。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.example.demo.entity"/>
</typeAliases>
<!-- 移除 environments、mappers 等,全由 Spring 接管 -->
</configuration>
@Configuration
@MapperScan("com.example.demo.mapper") // 掃描 Mapper 接口
@EnableTransactionManagement // 開啟註解事務
public class MyBatisConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.druid")
public DataSource dataSource() {
return new DruidDataSource();
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
factory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mapper/**/*Mapper.xml"));
return factory.getObject();
}
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
// StudentMapper.java
@Repository
public interface StudentMapper {
List selectAll();
int insert(Student student);
// 批量插入返回自增 ID
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertBatch(List students);
}
// StudentMapper.xml
<mapper namespace="com.example.demo.mapper.StudentMapper">
<resultMap id="studentMap" type="Student">
<id column="id" property="id"/>
<result column="name" property="name"/>
</resultMap>
<select id="selectAll" resultMap="studentMap">
SELECT id, name FROM student
</select>
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO student(name) VALUES(#{name})
</insert>
</mapper>
@Service
@Transactional(rollbackFor = Exception.class) // 類級別默認事務
public class StudentService {
@Autowired
private StudentMapper studentMapper;
// 單表操作:繼承類級別事務
public void addStudent(Student student) {
studentMapper.insert(student);
}
// 多表事務:同一事務內操作多個 Mapper
@Transactional // 可覆蓋傳播行為、隔離級別、超時等
public void transferAccount(TransferDTO dto) {
studentMapper.deductBalance(dto.getFromId(), dto.getAmount());
studentMapper.addBalance(dto.getToId(), dto.getAmount());
// 拋出 RuntimeException 觸發回滾
}
// 僅讀事務優化
@Transactional(readOnly = true)
public List getAllStudents() {
return studentMapper.selectAll();
}
}
| 傳播類型 | 行為 | 典型場景 |
|---|---|---|
| REQUIRED (默認) | 有事務加入,無則新建 | 90% 業務方法 |
| REQUIRES_NEW | 掛起當前,開啟新事務 | 日誌記錄、審計、獨立計數 |
| NESTED | 嵌套事務(Savepoint) | 批量導入部分回滾 |
| SUPPORTS | 有事務用,無則非事務 | 純查詢方法 |
| NOT_SUPPORTED | 掛起事務,以非事務運行 | 長耗時非關鍵操作 |
rollbackFor = Exception.class@Qualifier 区分MyBatis-Spring 整合核心三步:DataSource → SqlSessionFactory → TransactionManager。配合 @MapperScan、@EnableTransactionManagement、@Transactional,即可實現零侵入式聲明事務管理。生產環境務必配置連接池監控、慢 SQL 日誌、事務超時保護。