spring和mybatis的整合
- 创业
- 2025-09-10 04:33:01

一、环境搭建与依赖管理 1. 依赖配置扩展
除了基础的Spring、MyBatis和数据库驱动,推荐添加以下依赖以增强功能:
<!-- Spring JDBC(事务管理依赖) --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.20</version> </dependency> <!-- 日志框架(推荐SLF4J + Logback) --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.36</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.11</version> </dependency> <!-- 测试支持 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.3.20</version> <scope>test</scope> </dependency> 2. 多环境配置(开发、测试、生产)通过Spring的Profile机制实现环境隔离:
<!-- applicationContext.xml --> <beans profile="dev"> <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"> <!-- 开发环境数据库配置 --> </bean> </beans> <beans profile="prod"> <bean id="dataSource" class="com.zaxxer.HikariDataSource"> <!-- 生产环境数据库配置 --> </bean> </beans>激活方式:
JVM参数:-Dspring.profiles.active=dev
代码中:System.setProperty("spring.profiles.active", "dev")
二、进阶配置技巧 1. JavaConfig配置方式(替代XML)使用注解驱动配置更简洁:
@Configuration @MapperScan("com.example.mapper") // 自动扫描Mapper接口 @EnableTransactionManagement // 启用注解事务 public class MyBatisConfig { @Bean public DataSource dataSource() { HikariDataSource ds = new HikariDataSource(); ds.setDriverClassName("com.mysql.cj.jdbc.Driver"); ds.setJdbcUrl("jdbc:mysql://localhost:3306/test_db"); ds.setUsername("root"); ds.setPassword("123456"); return ds; } @Bean public SqlSessionFactory sqlSessionFactory() throws Exception { SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(dataSource()); factory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources("classpath:mapper/**/*.xml")); return factory.getObject(); } @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } } 2. 多数据源配置在复杂项目中可能需要连接多个数据库:
@Configuration public class MultiDataSourceConfig { @Bean(name = "primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().type(HikariDataSource.class).build(); } @Bean(name = "secondaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().type(HikariDataSource.class).build(); } @Bean @Primary public SqlSessionFactory primarySqlSessionFactory( @Qualifier("primaryDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(dataSource); return factory.getObject(); } @Bean public SqlSessionFactory secondarySqlSessionFactory( @Qualifier("secondaryDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(dataSource); return factory.getObject(); } } 三、MyBatis高阶特性实战 1. 动态SQL与复杂查询在Mapper XML中编写动态SQL:
<select id="selectUsers" resultType="User"> SELECT * FROM user <where> <if test="name != null"> AND name LIKE CONCAT('%', #{name}, '%') </if> <if test="email != null"> AND email = #{email} </if> </where> ORDER BY id DESC </select> 2. 一级与二级缓存配置一级缓存:默认开启,作用域为SqlSession。
<mapper namespace="com.example.mapper.UserMapper"> <cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/> </mapper> 在Spring中需确保SqlSessionFactory的配置: factory.setConfiguration(mybatisConfiguration()); // 设置全局配置 // 自定义Configuration public Configuration mybatisConfiguration() { Configuration config = new Configuration(); config.setCacheEnabled(true); // 启用二级缓存 return config; } 3. 自定义TypeHandler处理复杂类型转换(如JSON字段与Java对象的映射):
@MappedTypes(UserDetail.class) @MappedJdbcTypes(JdbcType.VARCHAR) public class UserDetailTypeHandler extends BaseTypeHandler<UserDetail> { private final ObjectMapper objectMapper = new ObjectMapper(); @Override public void setNonNullParameter(PreparedStatement ps, int i, UserDetail parameter, JdbcType jdbcType) { ps.setString(i, objectMapper.writeValueAsString(parameter)); } @Override public UserDetail getNullableResult(ResultSet rs, String columnName) { return parseJson(rs.getString(columnName)); } // 其他方法省略... }在MyBatis配置中注册:
<typeHandlers> <typeHandler handler="com.example.handler.UserDetailTypeHandler"/> </typeHandlers> 四、性能优化与最佳实践 1. 连接池调优(HikariCP为例) HikariConfig config = new HikariConfig(); config.setMaximumPoolSize(20); // 最大连接数 config.setMinimumIdle(5); // 最小空闲连接 config.setConnectionTimeout(30000); // 连接超时时间(毫秒) config.setIdleTimeout(600000); // 空闲连接存活时间 config.setMaxLifetime(1800000); // 连接最大生命周期 2. 批量操作提升性能使用SqlSession的批量模式:
@Autowired private SqlSessionFactory sqlSessionFactory; public void batchInsertUsers(List<User> users) { try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) { UserMapper mapper = session.getMapper(UserMapper.class); for (User user : users) { mapper.insertUser(user); } session mit(); // 手动提交 } } 3. SQL优化建议避免在循环中执行单条SQL
使用<foreach>标签实现批量插入:
<insert id="batchInsert"> INSERT INTO user (name, email) VALUES <foreach item="user" collection="list" separator=","> (#{user.name}, #{user.email}) </foreach> </insert> 五、测试与调试 1. 单元测试(Spring Test + JUnit) @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MyBatisConfig.class) public class UserMapperTest { @Autowired private UserMapper userMapper; @Test @Transactional // 测试后自动回滚 public void testInsertUser() { User user = new User("Alice", "alice@example "); userMapper.insertUser(user); assertNotNull(user.getId()); } } 2. SQL日志输出配置Logback(logback.xml):
<logger name="com.example.mapper" level="DEBUG"/> <!-- Mapper接口日志 --> <logger name="java.sql.Connection" level="DEBUG"/> <!-- SQL执行日志 --> <logger name="org.mybatis" level="TRACE"/> <!-- MyBatis内部日志 --> 六、常见问题深度解析 1. 事务失效场景原因1:非public方法使用@Transactional
原因2:自调用(同类方法内部调用) 解决方案:通过AOP代理调用或使用AopContext.currentProxy()。
2. 懒加载异常(LazyInitializationException)背景:在事务外访问延迟加载的关联对象
解决方案:
使用OpenSessionInViewFilter(Web项目)
在事务范围内提前加载所需数据(如JOIN FETCH)
3. MyBatis映射字段丢失原因:数据库字段名与Java属性名不一致(如驼峰vs下划线)
解决: 全局配置开启驼峰映射:
<settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>spring和mybatis的整合由讯客互联创业栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“spring和mybatis的整合”