MyBatis总结

mybatis xml和annotation有什么区别
 
MyBatis 是一个流行的 Java 持久层框架,它支持两种主要的 SQL 映射方式:XML 配置和注解(Annotation)。这两种方式各有优缺点,适用于不同的场景。以下是它们的核心区别:

1. 语法与定义位置

  • XML 配置:
    • SQL 语句和映射关系定义在 XML 文件中(如 UserMapper.xml)。
    • 需要在 mybatis-config.xml 中注册映射文件,或通过注解 @Mapper 自动扫描。
  • 注解配置:
    • SQL 语句直接写在接口方法上,使用 @Select@Insert@Update@Delete 等注解。
    • 映射关系通过 @Results@Result 等注解定义在接口方法上。

2. 适用场景

  • XML 配置:
    • 复杂 SQL:如动态 SQL(<if><where><foreach>)、多表关联查询。
    • SQL 经常变动:XML 文件修改无需重新编译 Java 代码。
    • 团队协作:SQL 与 Java 代码分离,便于 DBA 或后端工程师维护。
  • 注解配置:
    • 简单 SQL:如单表 CRUD 操作。
    • 快速开发:减少 XML 文件数量,代码更简洁。
    • 小型项目:SQL 逻辑简单,无需复杂映射。

3. 示例对比

场景:查询用户列表

XML 方式:

xml
 
 
<!-- UserMapper.xml -->
<select id="getUserList" resultType="User">
  SELECT * FROM users
  <where>
    <if test="name != null">AND name = #{name}</if>
    <if test="age != null">AND age = #{age}</if>
  </where>
</select>
 

注解方式:

java
 
 
// UserMapper.java
@Select("SELECT * FROM users WHERE name = #{name} AND age = #{age}")
List<User> getUserList(@Param("name") String name, @Param("age") Integer age);
 

4. 动态 SQL 支持

  • XML:支持完整的动态 SQL,通过 <if><choose><set> 等标签实现复杂逻辑。
    xml
     
     
    <select id="getUserList" resultType="User">
      SELECT * FROM users
      <where>
        <if test="name != null">AND name = #{name}</if>
        <if test="age != null">AND age = #{age}</if>
      </where>
    </select>
    
     
  • 注解:动态 SQL 支持有限,需使用 @SelectProvider@InsertProvider 等注解结合 Java 代码实现。
    java
     
     
    @SelectProvider(type = UserSqlProvider.class, method = "getUserListSql")
    List<User> getUserList(String name, Integer age);
    
    class UserSqlProvider {
      public String getUserListSql(String name, Integer age) {
        StringBuilder sql = new StringBuilder("SELECT * FROM users WHERE 1=1");
        if (name != null) sql.append(" AND name = #{name}");
        if (age != null) sql.append(" AND age = #{age}");
        return sql.toString();
      }
    }
    
     

5. 结果映射

  • XML:通过 <resultMap> 标签定义复杂映射关系。
    xml
     
     
    <resultMap id="userMap" type="User">
      <id property="id" column="user_id"/>
      <result property="name" column="user_name"/>
      <collection property="orders" ofType="Order">
        <id property="id" column="order_id"/>
        <result property="product" column="product_name"/>
      </collection>
    </resultMap>
    
     
  • 注解:通过 @Results@Result@One@Many 等注解定义映射。
    java
     
     
    @Results({
      @Result(property = "id", column = "user_id"),
      @Result(property = "name", column = "user_name"),
      @Result(property = "orders", column = "user_id",
              many = @Many(select = "com.mapper.OrderMapper.getOrdersByUserId"))
    })
    @Select("SELECT * FROM users WHERE id = #{id}")
    User getUserById(Integer id);
    
     

6. 维护性与扩展性

  • XML:
    • 优点:SQL 与代码分离,适合复杂查询的维护;支持热更新(修改 XML 无需重启应用)。
    • 缺点:XML 文件过多时管理成本高;IDE 对 XML 中的 SQL 智能提示较弱。
  • 注解:
    • 优点:代码集中,无需额外文件;IDE 对注解内 SQL 的语法检查和提示更友好。
    • 缺点:SQL 逻辑复杂时,注解代码冗长,可读性下降。

7. 性能

两者在性能上无显著差异,MyBatis 最终都会将配置解析为 MappedStatement 对象。但 XML 方式可能因多一次文件读取导致极轻微延迟(可忽略不计)。

8. 最佳实践

  • 混合使用:
    • 简单 SQL 使用注解,复杂 SQL 使用 XML。
    • 通过 @Select 引用 XML 中的 <sql> 片段:
      java
       
       
      @Select("SELECT * FROM users WHERE ${sql}")
      List<User> getUserByCustomSql(@Param("sql") String sql);
      
       
  • 选择建议:
    • 新项目:从注解开始,必要时迁移到 XML。
    • 历史项目:已有大量 XML 配置时,保持现状或逐步重构。

总结

特性XML 配置注解配置
定义位置 XML 文件 接口方法上
适用场景 复杂 SQL、动态 SQL 简单 SQL、快速开发
动态 SQL 支持 完整支持(标签) 有限支持(需 Java 代码辅助)
结果映射 复杂映射更清晰 简单映射更简洁
维护性 SQL 与代码分离 代码集中
IDE 支持 SQL 提示较弱 SQL 提示较强

根据项目规模、SQL 复杂度和团队习惯选择合适的方式,或混合使用以发挥两者优势。
 
 
 
 
 
posted @ 2025-07-05 20:44  我爱麻辣香锅  阅读(15)  评论(0)    收藏  举报