1740 字
约 5 分钟
10
第12章 注解开发
无标签

第12章 注解开发

学习使用注解方式进行 SQL 映射和配置
学习进度:48% 代码演示按钮 💻 查看完整代码 - 在线IDE体验

🎯 学习目标

📚

理解核心概念

掌握本章的核心概念和基本原理
🔧

掌握实践技能

学会相关的配置方法和实践技巧
💡

了解应用场景

明确在实际项目中的应用场景和最佳实践

1. 注解开发概述

1.1 注解开发的优势

  • 简化配置:减少XML配置文件,提高开发效率
  • 类型安全:编译时检查,减少运行时错误
  • 代码集中:SQL语句与Java代码在同一位置,便于维护
  • IDE支持:更好的代码提示和重构支持

1.2 注解开发的适用场景

  • 简单的CRUD操作
  • SQL语句相对简单的场景
  • 需要快速开发的项目
  • 团队更偏向于Java代码而非XML配置

注意:对于复杂的SQL语句和动态SQL,XML配置方式可能更加清晰和易于维护。

2. 基本CRUD注解

2.1 核心注解介绍

注解 作用 示例
@Select 定义查询语句 @Select("SELECT * FROM users WHERE id = #{id}")
@Insert 定义插入语句 @Insert("INSERT INTO users(name, email) VALUES(#{name}, #{email})")
@Update 定义更新语句 @Update("UPDATE users SET name=#{name} WHERE id=#{id}")
@Delete 定义删除语句 @Delete("DELETE FROM users WHERE id=#{id}")
@Options 配置选项 @Options(useGeneratedKeys = true, keyProperty = "id")

2.2 基本CRUD示例

public interface UserMapper {
    
    // 查询单个用户
    @Select("SELECT * FROM users WHERE id = #{id}")
    User selectUserById(Long id);
    
    // 查询所有用户
    @Select("SELECT * FROM users")
    List<User> selectAllUsers();
    
    // 插入用户(自动生成主键)
    @Insert("INSERT INTO users(username, email, create_time) VALUES(#{username}, #{email}, #{createTime})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insertUser(User user);
    
    // 更新用户
    @Update("UPDATE users SET username=#{username}, email=#{email} WHERE id=#{id}")
    int updateUser(User user);
    
    // 删除用户
    @Delete("DELETE FROM users WHERE id=#{id}")
    int deleteUser(Long id);
}

3. 动态SQL注解

3.1 Provider注解

对于复杂的动态SQL,MyBatis提供了Provider注解:

  • @SelectProvider- 动态查询
  • @InsertProvider- 动态插入
  • @UpdateProvider- 动态更新
  • @DeleteProvider- 动态删除

3.2 SQL提供者类

public class UserSqlProvider {
    
    public String selectByCondition(String username, String email) {
        return new SQL() {{
            SELECT("*");
            FROM("users");
            if (username != null && !username.trim().isEmpty()) {
                WHERE("username LIKE CONCAT('%', #{username}, '%')");
            }
            if (email != null && !email.trim().isEmpty()) {
                WHERE("email LIKE CONCAT('%', #{email}, '%')");
            }
        }}.toString();
    }
    
    public String updateSelective(Long id, String username, String email) {
        return new SQL() {{
            UPDATE("users");
            if (username != null && !username.trim().isEmpty()) {
                SET("username = #{username}");
            }
            if (email != null && !email.trim().isEmpty()) {
                SET("email = #{email}");
            }
            WHERE("id = #{id}");
        }}.toString();
    }
}

3.3 使用Provider注解

public interface UserMapper {
    
    // 使用动态SQL查询
    @SelectProvider(type = UserSqlProvider.class, method = "selectByCondition")
    List<User> selectUsersByCondition(@Param("username") String username, 
                                     @Param("email") String email);
    
    // 使用动态SQL更新
    @UpdateProvider(type = UserSqlProvider.class, method = "updateSelective")
    int updateUserSelective(@Param("id") Long id, 
                           @Param("username") String username, 
                           @Param("email") String email);
}

4. 结果映射注解

4.1 @Results和@Result注解

用于定义结果集映射关系:

@Results(id = "userResultMap", value = {
    @Result(property = "id", column = "id", id = true),
    @Result(property = "username", column = "username"),
    @Result(property = "email", column = "email"),
    @Result(property = "createTime", column = "create_time")
})
@Select("SELECT id, username, email, create_time FROM users")
List<User> selectUsersWithMapping();

4.2 关联映射注解

一对多关联映射

@Select("SELECT * FROM users")
@Results({
    @Result(property = "id", column = "id", id = true),
    @Result(property = "username", column = "username"),
    @Result(property = "email", column = "email"),
    @Result(property = "createTime", column = "create_time"),
    @Result(property = "orders", column = "id", javaType = List.class,
            many = @Many(select = "com.mybatis.annotation.mapper.OrderMapper.selectOrdersByUserId",
                        fetchType = FetchType.LAZY))
})
List<User> selectUsersWithOrders();

一对一关联映射

@Select("SELECT * FROM orders")
@Results({
    @Result(property = "id", column = "id", id = true),
    @Result(property = "orderNo", column = "order_no"),
    @Result(property = "user", column = "user_id", javaType = User.class,
            one = @One(select = "com.mybatis.annotation.mapper.UserMapper.selectUserById",
                      fetchType = FetchType.LAZY))
})
List<Order> selectOrdersWithUser();

5. 高级注解特性

5.1 批量操作

// 批量插入
@Insert({
    "<script>",
    "INSERT INTO users(username, email, create_time) VALUES",
    "<foreach collection='users' item='user' separator=','>",
    "(#{user.username}, #{user.email}, #{user.createTime})",
    "</foreach>",
    "</script>"
})
int insertUsers(@Param("users") List<User> users);

5.2 复杂查询条件

// 多条件查询
@Select("SELECT * FROM orders WHERE amount > #{minAmount} AND status = #{status}")
List<Order> selectOrdersByAmountAndStatus(@Param("minAmount") BigDecimal minAmount, 
                                        @Param("status") String status);

6. 注解与XML的对比

注解开发

  • 优点:
  • 配置简单,开发快速
  • 类型安全,编译时检查
  • 代码集中,便于查看
  • 缺点:
  • 复杂SQL难以维护
  • 动态SQL支持有限
  • SQL与Java代码耦合

XML配置

  • 优点:
  • 支持复杂的动态SQL
  • SQL与Java代码分离
  • 更好的可读性和维护性
  • 缺点:
  • 配置文件较多
  • 开发效率相对较低
  • 运行时才能发现错误

7. 最佳实践

7.1 选择原则

  • 简单CRUD:优先使用注解
  • 复杂查询:使用XML配置
  • 动态SQL:根据复杂度选择Provider或XML
  • 团队偏好:保持项目内一致性

7.2 注解开发建议

  • 合理使用@Param注解明确参数名称
  • 复杂SQL考虑使用Provider类
  • 注意SQL注入安全问题
  • 适当使用@Results复用结果映射
  • 关联查询时注意懒加载配置

7.3 性能优化

  • 合理使用延迟加载避免N+1问题
  • 批量操作提高数据处理效率
  • 适当使用缓存减少数据库访问
  • 优化SQL语句和索引

8. 常见问题与解决方案

8.1 参数传递问题

问题:多参数传递时参数名不明确解决:使用@Param注解明确指定参数名称

8.2 结果映射问题

问题:数据库字段名与Java属性名不匹配解决:使用@Result注解或开启驼峰命名转换

8.3 动态SQL复杂度

问题:注解中的动态SQL过于复杂解决:使用Provider类或考虑XML配置

9. 实践练习

练习任务

  1. 创建用户和订单的注解Mapper接口
  2. 实现基本的CRUD操作
  3. 使用Provider实现动态查询
  4. 配置一对多关联映射
  5. 实现批量插入功能
  6. 编写测试用例验证功能

10. 运行示例程序

运行步骤

  1. 确保MySQL数据库服务正在运行
  2. 执行src/main/resources/init.sql脚本创建数据库和表
  3. 修改db.properties中的数据库连接信息
  4. 运行AnnotationDemo主程序查看注解开发演示
  5. 运行AnnotationTest测试类验证各项功能
  6. 观察控制台输出,理解注解开发的执行过程

学习重点:掌握基本CRUD注解的使用方法理解动态SQL的注解实现方式学会配置结果映射和关联查询了解注解与XML配置的适用场景掌握注解开发的最佳实践

返回目录 本章小结

📖 本章小结

本章我们学习了 注解开发 的相关内容,包括:

  • 核心概念和基本原理
  • 配置方法和实践技巧
  • 应用场景和最佳实践
  • 常见问题和解决方案
第12章 注解开发
https://clxhxhhr.top/posts/3065/
作者
clxstart
发布于
2026-09-24
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。