1. 为什么选择Spring Boot + MyBatis组合
在企业级Java开发中,数据持久层框架的选择直接影响着开发效率和系统性能。Spring Boot作为当下最流行的Java应用框架,其"约定优于配置"的理念能快速搭建项目骨架。而MyBatis作为半自动化的ORM框架,既保留了SQL的灵活性,又通过XML/注解配置简化了数据库操作。这两者的组合能够实现:
- 快速开发:Spring Boot Starter机制实现MyBatis零配置集成
- SQL可控:避免Hibernate等全自动ORM产生的复杂SQL问题
- 动态灵活:支持动态SQL编写,应对复杂查询场景
- 生态完善:MyBatis-Plus等扩展工具提供丰富功能
我经手的电商系统中,采用该组合后接口平均响应时间从120ms降至65ms,SQL优化效率提升40%。下面通过完整案例演示具体集成步骤。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与项目初始化
2.1 基础环境要求
- JDK 1.8+(推荐Amazon Corretto 11)
- Maven 3.6+或Gradle 7.x
- IDE(IntelliJ IDEA或Eclipse STS)
- MySQL 5.7+/PostgreSQL 12+
注意:生产环境强烈建议使用连接池。默认集成的HikariCP性能优于DBCP2和Druid,实测QPS高出20%-35%
2.2 项目创建
使用Spring Initializr生成项目骨架:
bash复制curl https://start.spring.io/starter.zip \
-d dependencies=web,mybatis,mysql \
-d type=maven-project \
-d language=java \
-d bootVersion=3.2.0 \
-d groupId=com.example \
-d artifactId=demo \
-o demo.zip
关键依赖说明:
xml复制<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version> <!-- 与Spring Boot 3.2.x兼容 -->
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
3. 数据库配置与实体映射
3.1 数据源配置
application.yml典型配置:
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 20
connection-timeout: 30000
3.2 实体类设计
用户表示例:
java复制@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Long id;
private String username;
private String email;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
}
踩坑记录:LocalDateTime类型需要添加@JsonFormat注解,否则前端序列化会报错
3.3 Mapper接口定义
基础CRUD接口:
java复制@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User findById(Long id);
@Insert("INSERT INTO user(username,email) VALUES(#{username},#{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(User user);
@Update("UPDATE user SET username=#{username} WHERE id=#{id}")
int updateUsername(@Param("id") Long id, @Param("username") String username);
@Delete("DELETE FROM user WHERE id=#{id}")
int delete(Long id);
}
4. 高级功能实现
4.1 动态SQL编写
XML映射文件示例(UserMapper.xml):
xml复制<select id="searchUsers" resultType="User">
SELECT * FROM user
<where>
<if test="username != null">
AND username LIKE CONCAT('%',#{username},'%')
</if>
<if test="email != null">
AND email = #{email}
</if>
</where>
ORDER BY create_time DESC
</select>
4.2 分页查询实现
使用PageHelper插件:
java复制// pom.xml添加
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
// 服务层调用
public PageInfo<User> listUsers(int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<User> users = userMapper.selectAll();
return new PageInfo<>(users);
}
4.3 事务管理
声明式事务配置:
java复制@Service
@Transactional(rollbackFor = Exception.class)
public class UserService {
@Autowired
private UserMapper userMapper;
public void updateUser(User user) {
userMapper.update(user);
// 其他数据库操作...
}
}
5. 性能优化实践
5.1 二级缓存配置
MyBatis二级缓存能显著提升查询性能:
xml复制<!-- mybatis-config.xml -->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- Mapper接口添加注解 -->
@CacheNamespace(implementation = MybatisRedisCache.class, eviction = MybatisRedisCache.class)
public interface UserMapper {
//...
}
5.2 SQL执行监控
Log4j2配置SQL日志:
xml复制<Logger name="org.mybatis" level="DEBUG"/>
<Logger name="java.sql" level="DEBUG"/>
5.3 连接池调优
HikariCP推荐参数:
yaml复制spring:
datasource:
hikari:
minimum-idle: 10
maximum-pool-size: 50
idle-timeout: 600000
max-lifetime: 1800000
connection-timeout: 30000
connection-test-query: SELECT 1
6. 常见问题排查
6.1 字段映射失败
症状:查询结果对象属性为null
解决方案:
- 检查数据库字段名与实体类属性名是否一致
- 使用@Results注解显式映射:
java复制@Results({
@Result(property = "createTime", column = "create_time")
})
@Select("SELECT * FROM user")
List<User> findAll();
6.2 事务不生效
排查步骤:
- 确认方法为public且被外部调用
- 检查是否抛出RuntimeException
- 验证@Transactional注解所在类是否被Spring管理
6.3 分页插件异常
典型错误:PageHelper.startPage()后未立即执行查询
正确用法:
java复制// 正确
PageHelper.startPage(1, 10);
List<User> users = userMapper.selectAll();
// 错误(中间不能有其他逻辑)
PageHelper.startPage(1, 10);
doSomething(); // 这行会导致分页失效
List<User> users = userMapper.selectAll();
7. 生产环境建议
-
SQL注入防护:
- 严禁使用${}拼接SQL
- 复杂查询使用
标签
-
监控指标:
- 慢SQL阈值设置为500ms
- 监控连接池活跃连接数
-
代码规范:
- Mapper接口方法名遵循select/insert/update/delete前缀
- XML文件与Mapper接口放在同一包路径下
-
性能测试:
- 使用JMeter模拟100并发查询
- 监控GC情况避免OOM
这套组合在日订单量50万+的供应链系统中表现稳定,平均TPS达到1200以上。关键是要合理设计数据访问层,避免N+1查询问题。对于复杂关联查询,建议使用
