Spring整合MyBatis詳解
- 一、整合優勢與核心思路
- 1.1 整合優勢
- 1.2 核心整合思路
- 二、環境搭建與依賴配置
- 2.1 開發環境
- 2.2 Maven依賴配置
- 三、整合配置(核心步驟)
- 3.1 數據庫配置文件(db.properties)
- 3.2 Spring配置文件(spring-mybatis.xml)
- 四、實戰案例:用戶管理模塊
- 4.1 數據庫表設計
- 4.2 POJO實體類(User.java)
- 4.3 Mapper接口與XML
- 4.3.1 UserMapper接口
- 4.3.2 UserMapper.xml(映射文件)
- 4.4 Service層(業務邏輯)
- 4.5 測試類
- 五、常見問題與避坑指南
- 5.1 Mapper注入失敗(NoSuchBeanDefinitionException)
- 5.2 事務不生效(@Transactional無效)
- 5.3 Mapper XML與接口不匹配
企業級開發中,Spring(負責依賴管理和事務控制)與MyBatis(負責持久層操作)的整合是主流方案,本文我將詳細講解Spring整合MyBatis的完整流程,這種整合能充分發揮兩者優勢:Spring的IoC容器管理MyBatis的核心組件,AOP實現事務控制;MyBatis簡化數據庫操作。
一、整合優勢與核心思路
1.1 整合優勢
- 依賴管理自動化:Spring的IoC容器自動管理MyBatis的
SqlSessionFactory
、Mapper
等組件,無需手動創建; - 事務控制簡化:通過Spring的
@Transactional
注解輕松實現事務管理,替代MyBatis手動提交事務的繁瑣操作; - 配置集中化:數據庫連接信息、MyBatis配置等統一在Spring配置中管理,便于維護;
- 開發效率提升:開發者專注業務邏輯,無需關注組件創建和資源釋放。
1.2 核心整合思路
Spring整合MyBatis的核心是將MyBatis的核心組件交給Spring管理,關鍵步驟:
- Spring管理數據源(
DataSource
); - Spring創建
SqlSessionFactory
(依賴數據源和MyBatis配置); - Spring自動掃描Mapper接口,生成代理對象并注入到Service中;
- Spring管理事務(通過
DataSourceTransactionManager
)。
二、環境搭建與依賴配置
2.1 開發環境
- JDK:1.8+
- 依賴管理:Maven
- 框架版本:Spring 5.3.x + MyBatis 3.5.x
- 數據庫:MySQL 8.0
2.2 Maven依賴配置
在pom.xml
中添加核心依賴(Spring核心、Spring-JDBC、MyBatis、MyBatis-Spring整合包、MySQL驅動):
<dependencies><!-- Spring核心 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.20</version></dependency><!-- Spring JDBC(數據源和事務) --><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.20</version></dependency><!-- MyBatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.9</version></dependency><!-- MyBatis與Spring整合包 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.7</version></dependency><!-- MySQL驅動 --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.33</version></dependency><!-- 數據庫連接池(HikariCP,Spring默認) --><dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId><version>4.0.3</version></dependency><!-- lombok(簡化POJO代碼) --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version><optional>true</optional></dependency>
</dependencies>
三、整合配置(核心步驟)
整合配置采用注解+XML混合方式(XML配置數據源和MyBatis,注解管理Bean),清晰分離配置與業務代碼。
3.1 數據庫配置文件(db.properties)
創建src/main/resources/db.properties
,存儲數據庫連接信息:
# db.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=123456
jdbc.maxPoolSize=10
jdbc.minIdle=5
3.2 Spring配置文件(spring-mybatis.xml)
創建src/main/resources/spring-mybatis.xml
,配置數據源、SqlSessionFactory、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:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttps://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 1. 掃描注解(Service、Repository等) --><context:component-scan base-package="com.example"/><!-- 2. 加載數據庫配置文件 --><context:property-placeholder location="classpath:db.properties"/><!-- 3. 配置數據源(HikariCP連接池) --><bean id="dataSource" class="com.zaxxer.hikari.HikariConfig"><property name="driverClassName" value="${jdbc.driver}"/><property name="jdbcUrl" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/><property name="maximumPoolSize" value="${jdbc.maxPoolSize}"/><property name="minimumIdle" value="${jdbc.minIdle}"/></bean><bean id="hikariDataSource" class="com.zaxxer.hikari.HikariDataSource"><constructor-arg ref="dataSource"/></bean><!-- 4. 配置SqlSessionFactory(MyBatis核心) --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="hikariDataSource"/> <!-- 關聯數據源 --><property name="mapperLocations" value="classpath:mapper/*.xml"/> <!-- Mapper XML路徑 --><property name="typeAliasesPackage" value="com.example.pojo"/> <!-- 別名包 --><!-- 配置MyBatis全局設置(可選) --><property name="configuration"><bean class="org.apache.ibatis.session.Configuration"><property name="mapUnderscoreToCamelCase" value="true"/> <!-- 下劃線轉駝峰 --><property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/> <!-- 日志 --></bean></property></bean><!-- 5. 掃描Mapper接口(生成代理對象,注入Spring容器) --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.example.mapper"/> <!-- Mapper接口包路徑 --><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/></bean><!-- 6. 配置事務管理器 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="hikariDataSource"/></bean><!-- 7. 開啟事務注解支持 --><tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
四、實戰案例:用戶管理模塊
通過一個完整的用戶管理模塊(CRUD操作)演示整合后的使用流程。
4.1 數據庫表設計
創建user
表:
CREATE TABLE `user` (`id` int NOT NULL AUTO_INCREMENT,`username` varchar(50) NOT NULL,`age` int DEFAULT NULL,`create_time` datetime DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
4.2 POJO實體類(User.java)
package com.example.pojo;import lombok.Data;
import java.util.Date;@Data // lombok注解,自動生成getter/setter
public class User {private Integer id;private String username;private Integer age;private Date createTime;
}
4.3 Mapper接口與XML
4.3.1 UserMapper接口
package com.example.mapper;import com.example.pojo.User;
import java.util.List;public interface UserMapper {// 新增int insert(User user);// 更新int update(User user);// 刪除int deleteById(Integer id);// 根據ID查詢User selectById(Integer id);// 查詢所有List<User> selectAll();
}
4.3.2 UserMapper.xml(映射文件)
創建src/main/resources/mapper/UserMapper.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.example.mapper.UserMapper"><!-- 新增 --><insert id="insert" useGeneratedKeys="true" keyProperty="id">INSERT INTO user (username, age, create_time)VALUES (#{username}, #{age}, #{createTime})</insert><!-- 更新 --><update id="update">UPDATE userSET username = #{username}, age = #{age}WHERE id = #{id}</update><!-- 刪除 --><delete id="deleteById">DELETE FROM user WHERE id = #{id}</delete><!-- 根據ID查詢 --><select id="selectById" resultType="User">SELECT id, username, age, create_time AS createTimeFROM userWHERE id = #{id}</select><!-- 查詢所有 --><select id="selectAll" resultType="User">SELECT id, username, age, create_time AS createTimeFROM user</select>
</mapper>
4.4 Service層(業務邏輯)
package com.example.service;import com.example.mapper.UserMapper;
import com.example.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;@Service
public class UserService {// 注入Mapper接口(Spring自動生成代理對象)@Autowiredprivate UserMapper userMapper;// 新增用戶(添加事務)@Transactionalpublic int addUser(User user) {user.setCreateTime(new Date()); // 設置創建時間return userMapper.insert(user);}// 更新用戶@Transactionalpublic int updateUser(User user) {return userMapper.update(user);}// 刪除用戶@Transactionalpublic int deleteUser(Integer id) {return userMapper.deleteById(id);}// 根據ID查詢public User getUserById(Integer id) {return userMapper.selectById(id);}// 查詢所有public List<User> getAllUsers() {return userMapper.selectAll();}
}
4.5 測試類
package com.example.test;import com.example.pojo.User;
import com.example.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;public class UserTest {public static void main(String[] args) {// 加載Spring配置,啟動容器ApplicationContext context = new ClassPathXmlApplicationContext("spring-mybatis.xml");UserService userService = context.getBean(UserService.class);// 1. 新增用戶User user = new User();user.setUsername("Spring-MyBatis");user.setAge(25);userService.addUser(user);System.out.println("新增用戶ID:" + user.getId());// 2. 查詢用戶User queryUser = userService.getUserById(user.getId());System.out.println("查詢用戶:" + queryUser);// 3. 更新用戶queryUser.setAge(26);userService.updateUser(queryUser);System.out.println("更新后年齡:" + userService.getUserById(user.getId()).getAge());// 4. 查詢所有List<User> users = userService.getAllUsers();System.out.println("所有用戶:" + users);// 5. 刪除用戶userService.deleteUser(user.getId());System.out.println("刪除后查詢:" + userService.getUserById(user.getId()));}
}
五、常見問題與避坑指南
5.1 Mapper注入失敗(NoSuchBeanDefinitionException)
錯誤信息:No qualifying bean of type 'com.example.mapper.UserMapper' available
原因:
MapperScannerConfigurer
的basePackage
配置錯誤(未掃描到Mapper接口);- Mapper接口未定義(或包路徑與配置不符);
SqlSessionFactory
未正確創建(依賴的數據源錯誤)。
解決方案:
- 檢查
basePackage
是否正確(value="com.example.mapper"
); - 確保Mapper接口在指定包下(
com.example.mapper
); - 查看日志,確認
SqlSessionFactory
和數據源初始化成功。
5.2 事務不生效(@Transactional無效)
問題:Service方法中拋出異常,但數據庫操作未回滾。
原因:
- 異常被
try-catch
捕獲(未拋出到外層,Spring無法感知); - 拋出的異常不是
RuntimeException
(默認只回滾運行時異常); @Transactional
注解被添加到非public方法上(Spring事務不支持非public方法)。
解決方案:
- 不捕獲異常,或捕獲后重新拋出:
@Transactional
public void addUser(User user) {try {// 業務邏輯} catch (Exception e) {throw new RuntimeException(e); // 拋出運行時異常}
}
- 若需支持checked異常,指定
rollbackFor
:
@Transactional(rollbackFor = Exception.class) // 所有異常都回滾
5.3 Mapper XML與接口不匹配
錯誤信息:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.mapper.UserMapper.selectById
原因:
- Mapper XML的
namespace
與接口全類名不一致; - XML中
id
與接口方法名不一致; - XML文件未被正確加載(
mapperLocations
配置錯誤)。
解決方案:
- 確保
namespace
正確(namespace="com.example.mapper.UserMapper"
); - 保持
id
與方法名一致(selectById
對應selectById
); - 檢查
mapperLocations
配置(value="classpath:mapper/*.xml"
需與XML存放路徑一致)。
總結:Spring整合MyBatis的核心要點
- 簡化配置與管理:Spring的IoC容器統一管理數據源、SqlSessionFactory、Mapper等組件,無需手動創建和釋放資源;
- 強大的事務支持:通過
@Transactional
注解輕松實現事務控制,替代MyBatis手動提交/回滾的繁瑣操作;- 開發效率提升:開發者只需關注業務邏輯(Service)和SQL編寫(Mapper),組件依賴和生命周期由Spring自動處理;
- 擴展性強:支持連接池、日志、緩存等高級特性,且易于集成其他Spring生態組件(如Spring MVC、Spring Boot)。
若這篇內容幫到你,動動手指支持下!關注不迷路,干貨持續輸出!
ヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノ