跳转到内容

Spring整合MyBatis

来自代码酷

Spring整合MyBatis[编辑 | 编辑源代码]

简介[编辑 | 编辑源代码]

Spring整合MyBatis是指通过Spring框架提供的依赖注入和事务管理能力,与MyBatis持久层框架进行无缝集成。这种整合方式允许开发者利用MyBatis的SQL映射灵活性,同时享受Spring的声明式事务管理和松耦合优势。主要整合组件包括:

  • SqlSessionFactoryBean:创建MyBatis的SqlSessionFactory
  • MapperScannerConfigurer:自动扫描并注册Mapper接口
  • @MapperScan注解:替代XML配置的扫描方式

整合原理[编辑 | 编辑源代码]

graph LR A[Spring容器] --> B[SqlSessionFactoryBean] B --> C[DataSource] A --> D[MapperScannerConfigurer] D --> E[Mapper接口代理对象] A --> F[Spring事务管理器] F --> C

整合的核心是通过Spring的IoC容器管理MyBatis的核心组件,实现: 1. 数据源(DataSource)由Spring管理 2. SqlSessionFactory通过Spring配置 3. Mapper接口自动注入

配置方式[编辑 | 编辑源代码]

XML配置方式[编辑 | 编辑源代码]

传统配置方式,适用于Spring 3.x及早期版本:

<!-- 数据源配置 -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/test"/>
    <property name="username" value="root"/>
    <property name="password" value="password"/>
</bean>

<!-- MyBatis-Spring整合 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mapperLocations" value="classpath*:mapper/*.xml"/>
</bean>

<!-- Mapper扫描 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.example.dao"/>
</bean>

Java配置方式[编辑 | 编辑源代码]

Spring 4+推荐的方式:

@Configuration
@MapperScan("com.example.dao")
public class MyBatisConfig {
    
    @Bean
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        return dataSource;
    }
    
    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource());
        factoryBean.setMapperLocations(
            new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        return factoryBean.getObject();
    }
}

事务管理[编辑 | 编辑源代码]

Spring提供声明式事务管理,与MyBatis整合后可通过注解控制事务:

@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Transactional
    @Override
    public void createUser(User user) {
        userMapper.insert(user);
        // 其他数据库操作
    }
}

关键点:

  • 需要在配置类添加@EnableTransactionManagement
  • 事务管理器需使用DataSourceTransactionManager

实际案例[编辑 | 编辑源代码]

电商系统中的订单处理场景:

@Repository
public interface OrderMapper {
    @Insert("INSERT INTO orders(order_id, user_id, amount) VALUES(#{orderId}, #{userId}, #{amount})")
    int insert(Order order);
    
    @Update("UPDATE inventory SET stock = stock - #{quantity} WHERE product_id = #{productId}")
    int reduceStock(@Param("productId") Long productId, @Param("quantity") int quantity);
}

@Service
public class OrderService {
    
    @Autowired
    private OrderMapper orderMapper;
    
    @Transactional
    public void placeOrder(Order order, List<OrderItem> items) {
        orderMapper.insert(order);
        items.forEach(item -> {
            orderMapper.reduceStock(item.getProductId(), item.getQuantity());
        });
    }
}

常见问题[编辑 | 编辑源代码]

类型别名处理[编辑 | 编辑源代码]

可通过以下方式配置:

@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
    SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
    //...
    factoryBean.setTypeAliasesPackage("com.example.model");
    return factoryBean.getObject();
}

多数据源配置[编辑 | 编辑源代码]

需要为每个数据源创建独立的配置:

@Configuration
@MapperScan(basePackages = "com.example.primary", sqlSessionFactoryRef = "primarySqlSessionFactory")
public class PrimaryDataSourceConfig {
    // 主数据源配置...
}

@Configuration
@MapperScan(basePackages = "com.example.secondary", sqlSessionFactoryRef = "secondarySqlSessionFactory")
public class SecondaryDataSourceConfig {
    // 从数据源配置...
}

性能优化[编辑 | 编辑源代码]

1. 批量操作:使用SqlSessionTemplate的批量模式 2. 二级缓存:在Mapper XML中配置<cache/>标签 3. 延迟加载:在MyBatis配置中设置lazyLoadingEnabled=true

最佳实践[编辑 | 编辑源代码]

  • 始终使用接口绑定方式(Mapper接口)
  • 生产环境使用连接池(如HikariCP)
  • 复杂的SQL写在XML中,简单CRUD可使用注解
  • 事务边界应定义在Service层

数学表示[编辑 | 编辑源代码]

事务的ACID特性可以用以下公式表示:

{原子性(A):oO,要么全部执行Φ(o),要么全部回滚一致性(C):Φ(Spre)=Spost隔离性(I):Φ1Φ2Φ1(S)Φ2(S)=持久性(D):一旦提交,t>tcommit,St保持提交状态

其中Φ表示事务操作,S表示系统状态。