✅ 一、注解写 SQL(无需 Mapper.xml)
MyBatis 支持直接在 Mapper 接口上用注解写 SQL:
java
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User selectById(Long id);
@Insert("INSERT INTO user(name, email) VALUES(#{name}, #{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(User user);
@Update("UPDATE user SET name = #{name} WHERE id = #{id}")
int update(User user);
@Delete("DELETE FROM user WHERE id = #{id}")
int delete(Long id);
}
✅ 优点:简单、轻量、无 XML 文件
❌ 缺点:复杂 SQL 难维护(比如多表关联、动态条件)
✅ 二、XML 写 SQL(传统方式)
SQL 写在 UserMapper.xml 中:
xml
<select id="selectByCondition" resultType="User">
SELECT * FROM user
<where>
<if test="name != null">AND name LIKE CONCAT('%', #{name}, '%')</if>
<if test="age != null">AND age = #{age}</if>
</where>
</select>
✅ 优点:支持动态 SQL(
<if><foreach>等)、可读性强、易调试❌ 缺点:需要额外 XML 文件
🎯 三、使用场景对比(大厂真实实践)
| 场景 | 推荐方式 | 原因 |
|---|---|---|
| 简单 CRUD(单表、无条件) | ✅ 注解 | 快速开发,减少文件数量 |
| 带动态条件的查询(如搜索) | ✅ XML | 注解不支持 <if>,拼字符串易错且难维护 |
| 多表关联 / 复杂 JOIN | ✅ XML | SQL 长,XML 更清晰 |
需要 <resultMap> 处理字段映射 |
✅ XML | 注解中写 @Results 极其繁琐 |
| 团队协作 / 代码审查 | ✅ XML | SQL 集中管理,便于 DBA 审核 |
| SQL 需要频繁调整 | ✅ XML | 不用改 Java 代码,热更新更方便 |
⚠️ 四、大厂规范建议
- 禁止在注解里拼接动态 SQL (如
"SELECT * FROM user WHERE 1=1 " + (name != null ? "AND name=..." : ""))→ 容易出错、无法预编译、有注入风险。 - 统一风格 :一个 Mapper 要么全用注解,要么全用 XML,不要混用(除非极特殊场景)。
- Spring Boot 项目 :即使使用注解,也建议开启
mapUnderscoreToCamelCase,避免字段名不匹配。
✅ 五、一句话总结
简单 SQL 用注解,复杂 SQL 用 XML。
大厂项目 90% 以上用 XML ------ 可维护性 > 少写一个文件。
如果你只是学习或写 demo,注解很方便;但一旦进入真实业务(尤其是带搜索、分页、关联查询),XML 是唯一合理的选择。