2141 字
约 7 分钟
10
第13章 Spring集成
无标签

第13章 Spring集成

学习 MyBatis 与 Spring 框架的集成配置
学习进度:52% 代码演示按钮 💻 查看完整代码 - 在线IDE体验

🎯 学习目标

📚

理解核心概念

掌握本章的核心概念和基本原理
🔧

掌握实践技能

学会相关的配置方法和实践技巧
💡

了解应用场景

明确在实际项目中的应用场景和最佳实践

1. Spring集成概述

1.1 集成的优势

MyBatis与Spring集成带来以下优势:

  • 依赖注入:自动管理Mapper接口和服务层依赖
  • 事务管理:声明式事务支持,简化事务处理
  • 配置管理:统一的配置管理和环境切换
  • 测试支持:完善的测试框架和模拟支持
  • AOP支持:面向切面编程,增强功能

1.2 集成方式

Spring与MyBatis有多种集成方式:

  • XML配置:传统的XML配置方式
  • Java配置:基于@Configuration的配置
  • 混合配置:XML和Java配置结合
  • Spring Boot:自动配置和起步依赖

2. 依赖配置

2.1 Maven依赖

<dependencies>
    <!-- Spring Core -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.21</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.3.21</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.3.21</version>
    </dependency>
    
    <!-- MyBatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.13</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.1.0</version>
    </dependency>
    
    <!-- Database -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.18</version>
    </dependency>
</dependencies>

3. XML配置方式

3.1 Spring配置文件

<?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/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">

    <!-- 启用注解扫描 -->
    <context:component-scan base-package="com.mybatis.spring"/>
    
    <!-- 加载属性文件 -->
    <context:property-placeholder location="classpath:db.properties"/>
    
    <!-- 配置数据源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    
    <!-- 配置SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>
    
    <!-- 配置Mapper扫描 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.mybatis.spring.mapper"/>
    </bean>
    
    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <!-- 启用事务注解 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
</beans>

3.2 MyBatis配置文件

<?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>
    
    <settings>
        <setting name="logImpl" value="LOG4J"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="cacheEnabled" value="true"/>
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
    
    <typeAliases>
        <package name="com.mybatis.spring.entity"/>
    </typeAliases>
    
</configuration>

4. Java配置方式

4.1 配置类

@Configuration
@PropertySource("classpath:db.properties")
@EnableTransactionManagement
public class DatabaseConfig {
    
    @Value("${jdbc.driver}")
    private String driverClassName;
    
    @Value("${jdbc.url}")
    private String url;
    
    @Value("${jdbc.username}")
    private String username;
    
    @Value("${jdbc.password}")
    private String password;
    
    /**
     * 配置数据源
     */
    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        
        // 连接池配置
        dataSource.setInitialSize(5);
        dataSource.setMinIdle(5);
        dataSource.setMaxActive(20);
        dataSource.setMaxWait(60000);
        
        return dataSource;
    }
    
    /**
     * 配置SqlSessionFactory
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        
        // 设置MyBatis配置文件位置
        factoryBean.setConfigLocation(
            new PathMatchingResourcePatternResolver().getResource("classpath:mybatis-config.xml"));
        
        // 设置Mapper XML文件位置
        factoryBean.setMapperLocations(
            new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        
        return factoryBean.getObject();
    }
    
    /**
     * 配置Mapper扫描
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer configurer = new MapperScannerConfigurer();
        configurer.setBasePackage("com.mybatis.spring.mapper");
        return configurer;
    }
    
    /**
     * 配置事务管理器
     */
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

5. 依赖注入

5.1 Mapper接口注入

@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Override
    public Long createUser(User user) {
        userMapper.insertUser(user);
        return user.getId();
    }
    
    @Override
    public User getUserById(Long id) {
        return userMapper.selectUserById(id);
    }
    
    @Override
    public List<User> getAllUsers() {
        return userMapper.selectAllUsers();
    }
}

5.2 服务层注入

public class SpringIntegrationDemo {
    public static void main(String[] args) {
        // 加载Spring配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        
        // 获取UserService Bean
        UserService userService = context.getBean(UserService.class);
        
        // 使用服务
        User user = new User("spring_user", "[email protected]");
        Long userId = userService.createUser(user);
        System.out.println("创建用户成功,ID: " + userId);
    }
}

6. 事务管理

6.1 声明式事务

@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    /**
     * 带事务的创建用户方法
     */
    @Transactional(rollbackFor = Exception.class)
    public Long createUserWithTransaction(String username, String email, boolean shouldFail) throws Exception {
        User user = new User(username, email);
        userMapper.insertUser(user);
        
        if (shouldFail) {
            throw new Exception("模拟业务异常,触发事务回滚");
        }
        
        return user.getId();
    }
    
    /**
     * 批量操作事务
     */
    @Transactional
    public int batchCreateUsers() {
        List<User> users = new ArrayList<>();
        users.add(new User("batch_user1", "[email protected]"));
        users.add(new User("batch_user2", "[email protected]"));
        users.add(new User("batch_user3", "[email protected]"));
        
        return userMapper.batchInsertUsers(users);
    }
}

6.2 事务传播行为

传播行为 说明
REQUIRED 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务
REQUIRES_NEW 创建一个新的事务,如果当前存在事务,则把当前事务挂起
SUPPORTS 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行
NOT_SUPPORTED 以非事务方式运行,如果当前存在事务,则把当前事务挂起
NEVER 以非事务方式运行,如果当前存在事务,则抛出异常
MANDATORY 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常
NESTED 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行

7. 连接池配置

7.1 Druid连接池配置

# 数据库连接配置
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_spring?useSSL=false&serverTimezone=UTC&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456

# 连接池配置
jdbc.initialSize=5
jdbc.minIdle=5
jdbc.maxActive=20
jdbc.maxWait=60000
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.minEvictableIdleTimeMillis=300000
jdbc.validationQuery=SELECT 1 FROM DUAL
jdbc.testWhileIdle=true
jdbc.testOnBorrow=false
jdbc.testOnReturn=false

7.2 连接池监控

@Bean
public DataSource dataSource() {
    DruidDataSource dataSource = new DruidDataSource();
    
    // 基本配置
    dataSource.setDriverClassName(driverClassName);
    dataSource.setUrl(url);
    dataSource.setUsername(username);
    dataSource.setPassword(password);
    
    // 连接池配置
    dataSource.setInitialSize(5);
    dataSource.setMinIdle(5);
    dataSource.setMaxActive(20);
    dataSource.setMaxWait(60000);
    
    // 监控配置
    dataSource.setTimeBetweenEvictionRunsMillis(60000);
    dataSource.setMinEvictableIdleTimeMillis(300000);
    dataSource.setValidationQuery("SELECT 1 FROM DUAL");
    dataSource.setTestWhileIdle(true);
    dataSource.setTestOnBorrow(false);
    dataSource.setTestOnReturn(false);
    
    // 开启监控统计
    try {
        dataSource.setFilters("stat,wall");
    } catch (SQLException e) {
        e.printStackTrace();
    }
    
    return dataSource;
}

8. 测试支持

8.1 Spring测试配置

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
@Transactional
public class SpringIntegrationTest {
    
    @Autowired
    private UserService userService;
    
    @Test
    public void testCreateAndQueryUser() {
        // 创建用户
        User user = new User("test_user", "[email protected]");
        Long userId = userService.createUser(user);
        System.out.println("创建用户ID: " + userId);
        
        // 查询用户
        User foundUser = userService.getUserById(userId);
        System.out.println("查询到的用户: " + foundUser);
        
        // 验证
        assert foundUser != null;
        assert "test_user".equals(foundUser.getUsername());
        assert "[email protected]".equals(foundUser.getEmail());
    }
    
    @Test
    public void testTransactionRollback() {
        try {
            userService.createUserWithTransaction("rollback_user", "[email protected]", true);
        } catch (Exception e) {
            System.out.println("事务回滚测试: " + e.getMessage());
        }
        
        // 验证用户没有被创建
        User user = userService.getUserByUsername("rollback_user");
        assert user == null;
        System.out.println("事务回滚验证成功");
    }
}

9. 性能优化

9.1 连接池优化

  • 合理设置连接池大小:根据并发量调整initialSize、minIdle、maxActive
  • 连接验证:配置validationQuery和testWhileIdle
  • 连接回收:设置合理的timeBetweenEvictionRunsMillis
  • 监控统计:开启Druid监控,分析SQL性能

9.2 事务优化

  • 事务范围:尽量缩小事务范围,避免长事务
  • 只读事务:对于查询操作使用readOnly=true
  • 传播行为:合理选择事务传播行为
  • 异常处理:明确指定rollbackFor异常类型

10. 常见问题与解决方案

10.1 Mapper注入失败

问题:@Autowired注入Mapper接口时报错解决:检查MapperScannerConfigurer的basePackage配置确保Mapper接口在正确的包路径下验证SqlSessionFactory配置是否正确

10.2 事务不生效

问题:@Transactional注解不生效解决:确保启用了@EnableTransactionManagement或tx:annotation-driven 检查方法是否为public避免在同一个类中调用@Transactional方法确保异常类型在rollbackFor范围内

10.3 连接池配置问题

问题:数据库连接超时或连接泄漏解决:合理配置maxWait和连接池大小开启连接泄漏检测配置连接验证和回收机制监控连接池状态

11. 最佳实践

11.1 配置管理

  • 环境分离:使用Profile管理不同环境配置
  • 外部化配置:将数据库连接等配置外部化
  • 配置加密:对敏感信息进行加密处理
  • 配置验证:启动时验证关键配置项

11.2 代码组织

  • 分层架构:明确Controller、Service、Mapper职责
  • 接口设计:面向接口编程,便于测试和扩展
  • 异常处理:统一异常处理机制
  • 日志记录:合理配置日志级别和输出

12. 实践练习

练习任务:配置MyBatis与Spring的XML集成实现用户管理的CRUD操作配置声明式事务管理编写单元测试验证功能配置Druid连接池监控实现Java配置方式的集成测试事务回滚机制优化连接池和事务配置

13. 运行示例程序

运行步骤:

  1. 创建数据库:执行init.sql脚本
  2. 配置数据库:修改db.properties文件
  3. 编译项目:mvn clean compile
  4. 运行主程序:java SpringIntegrationDemo
  5. 运行测试:mvn test
  6. 查看监控:访问Druid监控页面

注意事项:确保MySQL服务已启动检查数据库连接配置注意Spring和MyBatis版本兼容性观察事务和连接池的行为

本章小结

📖 本章小结

本章我们学习了 Spring集成 的相关内容,包括:

  • 核心概念和基本原理
  • 配置方法和实践技巧
  • 应用场景和最佳实践
  • 常见问题和解决方案
第13章 Spring集成
https://clxhxhhr.top/posts/3066/
作者
clxstart
发布于
2026-09-24
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。