Spring整合MyBatis
外观
Spring整合MyBatis[编辑 | 编辑源代码]
简介[编辑 | 编辑源代码]
Spring整合MyBatis是指通过Spring框架提供的依赖注入和事务管理能力,与MyBatis持久层框架进行无缝集成。这种整合方式允许开发者利用MyBatis的SQL映射灵活性,同时享受Spring的声明式事务管理和松耦合优势。主要整合组件包括:
- SqlSessionFactoryBean:创建MyBatis的SqlSessionFactory
- MapperScannerConfigurer:自动扫描并注册Mapper接口
- @MapperScan注解:替代XML配置的扫描方式
整合原理[编辑 | 编辑源代码]
整合的核心是通过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特性可以用以下公式表示:
其中表示事务操作,表示系统状态。