在Java的MyBatis框架中,使用注解查询和XML映射文件实现SQL映射的区别

100 阅读1分钟

一、核心区别原因

1. 代码与配置的分离

  • 注解:SQL与Java代码耦合,适合简单场景。
  • XML:SQL与Java代码解耦,符合「关注点分离」原则。

2. 动态SQL支持

  • 注解:需借助脚本标签或@SelectProvider,可读性差。
  • XML:原生支持动态SQL标签(如<if><foreach>),更直观。

3. 可维护性

  • 注解:适合短小SQL,修改需重新编译代码。
  • XML:长SQL或复杂逻辑更易维护,支持热加载。

二、具体实现对比

1. 基础查询

注解方式
public interface UserMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    User getUserById(int id);
}
XML方式
<!-- UserMapper.xml -->
<mapper namespace="com.example.UserMapper">
    <select id="getUserById" resultType="User">
        SELECT * FROM users WHERE id = #{id}
    </select>
</mapper>

2. 动态SQL

注解方式(使用<script>标签)
@Select("<script>" +
        "SELECT * FROM users " +
        "<where>" +
        "  <if test='name != null'>AND name = #{name}</if>" +
        "  <if test='email != null'>AND email = #{email}</if>" +
        "</where>" +
        "</script>")
List<User> findUsers(@Param("name") String name, @Param("email") String email);
XML方式(原生动态标签)
<select id="findUsers" resultType="User">
    SELECT * FROM users
    <where>
        <if test="name != null">AND name = #{name}</if>
        <if test="email != null">AND email = #{email}</if>
    </where>
</select>

3. 关联查询

注解方式(@Results手动映射)
@Select("SELECT u.*, a.city FROM users u LEFT JOIN address a ON u.id = a.user_id")
@Results({
    @Result(property = "id", column = "id"),
    @Result(property = "address.city", column = "city")
})
List<User> getUsersWithAddress();
XML方式(ResultMap定义)
<resultMap id="UserWithAddress" type="User">
    <id property="id" column="id"/>
    <result property="address.city" column="city"/>
</resultMap>

<select id="getUsersWithAddress" resultMap="UserWithAddress">
    SELECT u.*, a.city FROM users u LEFT JOIN address a ON u.id = a.user_id
</select>

三、选择建议

场景推荐方式原因
简单、固定SQL注解代码简洁,减少文件切换
复杂动态SQLXML标签直观,易于维护
多表关联或结果集映射XMLResultMap支持更灵活的嵌套映射
需要SQL复用XML通过<sql>标签定义公共片段

四、本质总结

  • 注解:牺牲解耦性换取开发便捷性,适合快速原型或小型项目。
  • XML:通过解耦提升可维护性,适合中大型项目或复杂SQL场景。

注意优先级:注解 > XML