注解

注解

自定义注解

//枚举
public enum OperationType {
    INSERT, UPDATE
}

// 注解
package com.sky.annotation;

import com.sky.enumeration.OperationType;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义注解 用来标识某个方法需要进行功能字段总填充
 */
@Target(ElementType.METHOD)// 标识这个注解只能用于方法
@Retention(RetentionPolicy.RUNTIME)// 标识这个注解在哪个阶段生效 RUNTIME 表示运行时
public @interface AutoFill {
    //定义了一个名为 value 的属性(默认属性)
    //类型为枚举 OperationType(需import)
    //无默认值 → 使用时必须显式指定值
    //定义注解的value 数据库操作类型
    //定义默认值 Insert
    OperationType value() default OperationType.INSERT;
}

@Target注解

  • 作用:指定注解的作用范围。

参数

参数名称参数描述
ElementType.TYPE用于类、接口或枚举
ElementType.FIELD用于字段
ElementType.METHOD用于方法
ElementType.CONSTRUCTOR用于构造方法
ElementType.PARAMETER用于参数

@Retention注解

  • 作用:指定注解的保留策略(即注解的生命周期)。
  • 保留策略:

参数

RetentionPolicy.SOURCE
  • 描述:源代码阶段保留,注解在编译时会被丢弃,不会写入 .class 文件,运行时无法通过反射读取
  • 用途:1. 提供给编译器使用的注解(如 @Override@SuppressWarnings)。2. 代码生成工具(如 Lombok)在编译前处理源码时使用。
RetentionPolicy.CLASS
  • 描述:类文件阶段保留,注解在编译时会被保留在 .class 文件中,但不会写入 .class 文件,运行时无法通过反射读取
  • 用途:
    • 字节码分析工具(如 ASM)在编译后处理字节码时使用。
    • 默认的保留策略(如果未显式指定 @Retention)。
RetentionPolicy.RUNTIME
  • 描述:运行时保留,注解在编译时和运行时都会被保留,运行时可以通过反射读取注解信息。
  • 用途:
    • 需要运行时动态处理的注解(如 Spring@Controller、自定义校验注解 @NotEmpty)。
    • 框架的依赖注入(如 @Autowired)、AOP 切面逻辑等。

自定义注解中的属性

格式:数据类型 属性名称() [default 默认值] //[]中的内容表示可选

  • 属性名称+括号 ():这是 Java 语言规范要求的语法,用于区分注解属性和普通字段。表示是注解的可配置参数
  • 后面使用@注解名称(属性名=属性值)的形式传递参数

    注意

    如果注解中定义了名为 value 的属性,且它是唯一需要赋值的属性,可以省略属性名直接赋值:

@AutoFill(OperationType.UPDATE)  // 等价于 @AutoFill(value=OperationType.

:::

全局异常处理

  1. @RestControllerAdvice

    • 作用:
    1. 是 Spring 提供的一个组合注解,结合了 @ControllerAdvice 和 @ResponseBody。
    2. 用于定义全局异常处理器,可以捕获整个应用中控制器(Controller)抛出的异常。
    3. 标记的类中定义的方法可以直接返回数据(JSON 或 XML),而不需要在每个方法上加 @ResponseBody。
    • 用法:
    1. 将该注解应用于类级别。
    2. 结合多个 @ExceptionHandler 方法,实现对不同异常类型的统一处理。
    • 示例:

@RestControllerAdvice
public class GlobalExceptionHandler {
// 异常处理方法
}

  1. @ExceptionHandler

    • 作用:
    1. 用于标记一个方法作为异常处理方法。
    2. 可以捕获并处理指定类型及其子类的异常。
    3. 在 @RestControllerAdvice 标记的类中,它能够捕获全局控制器中的异常;在普通 @Controller 类中,则只能捕获当前控制器及其子类中的异常。
    • 用法:
    1. 应用于方法级别。
    2. 指定要处理的异常类型(可选),如 @ExceptionHandler(SQLIntegrityConstraintViolationException.class)。
    3. 方法参数可以包括具体的异常对象、HttpServletRequest 等,返回值通常是错误响应对象(例如 Result.error(...))。
    • 示例:

@ExceptionHandler(BaseException.class)
public Result exceptionHandler(BaseException ex) {
    return Result.error(ex.getMessage());
}

综合示例


@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler
    public Result exceptionHandler(BaseException ex) {
        log.error("异常信息:{}", ex.getMessage());
        return Result.error(ex.getMessage());
    }

    @ExceptionHandler
    public Result exceptionHandler(SQLIntegrityConstraintViolationException ex) {
        log.error("异常信息:{}", ex.getMessage());
        String message = ex.getMessage();
        if (message.contains("Duplicate entry")) {
            String[] split = message.split(" ");
            return Result.error(split[2] + "已存在");
        }
        return Result.error("Sql异常");
    }
}
  • @RestControllerAdvice 使得这个类成为一个全局异常处理器。
  • 第一个 @ExceptionHandler 方法捕获所有 BaseException 类型的异常。
  • 第二个 @ExceptionHandler 方法专门捕获 SQLIntegrityConstraintViolationException,并根据异常信息进行定制化处理(如检测唯一性冲突)。
  • 所有异常处理的结果都会直接返回给客户端,格式为 Result 对象(通常包含状态码和错误信息)。
注解作用范围返回值是否自动序列化使用场景
@RestControllerAdvice全局(整个应用的控制器)是(自动添加 @ResponseBody)全局异常处理
@ControllerAdvice全局否(需手动添加 @ResponseBody)全局异常处理(返回视图名称时使用
@ExceptionHandler局部(所在类或其子类控制器)控制器内部异常处理

注意

若想实现统一的错误响应结构,推荐使用 @RestControllerAdvice 配合多个 @ExceptionHandler。

myBites注解

CRUD相关注解

注解等效 XML 标签作用示例
@Select<select>查询@Select("SELECT * FROM user WHERE id = #{id}")
@Insert<insert>插入@Insert("INSERT INTO user (name, age) VALUES (#{name}, #{age})")
@Update<update>更新@Update("UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}")
@Delete<delete>删除@Delete("DELETE FROM user WHERE id = #{id}")
@Options<selectKey>置主键生成、超时等选项@Options(useGeneratedKeys = true, keyProperty = "id")

参数处理注解

注解作用
@Param用于给 SQL 中的参数起别名,区分参数名
@MapKey指定返回 Map 的键字段(用于结果集转为 Map 时)
@ConstructorArgs绑定结果集到构造方法参数(替代 <constructor>

其他实用注解

注解作用
@Flush强制立即执行 SQL(用于批量操作后立即刷新)
@Lang指定自定义语言驱动(如实现动态 SQL 方言)

@Param

它是 MyBatis 框架中的一个注解,主要用于 给 Mapper 接口方法的参数命名,以便在 XML 映射文件或注解 SQL 中引用。

核心作用

  • 参数绑定:将 Java 方法的参数与 SQL 中的变量名绑定。
  • 解决多参数问题:当方法有多个参数时,避免 MyBatis 默认使用 param1, param2...arg0, arg1... 这种不直观的命名(在-parameters编译选项开启的情况下 Spring Boot 默认开启)。

使用场景

Lambda 表达式支持:在 MyBatis-PlusLambdaQueryWrapper 中,@Param(Constants.WRAPPER) 用于绑定条件构造器。
@Update("UPDATE emp SET username = CONCAT(username, #{admin}) ${ew.customSqlSegment}")
void setAddAdmin(
    @Param(Constants.WRAPPER) LambdaQueryWrapper<EmpPo> wrapper, // 绑定为 ${ew}
    @Param("admin") String suffix
);
Mapper 接口方法(在参数名和 使用名不一致时必须使用@Param)
// Mapper 接口方法
@Select("SELECT * FROM user WHERE name = #{name} AND age = #{age}")
void User findUser(
    @Param("name") String username,  // 参数绑定为 #{name}
    @Param("age") int userAge        // 参数绑定为 #{age}
);
在动态 SQL 中引用参数
<!-- XML 映射文件 -->
<select id="findUser" resultType="User">
    SELECT * FROM user 
    WHERE 1=1
    <if test="name != null">   <!-- 直接使用 @Param 定义的名称 -->
        AND name = #{name}
    </if>
    <if test="age != null">
        AND age = #{age}
    </if>
</select>

注意事项

注意

  • 单参数可省略:如果方法只有一个参数且没有动态 SQL,可以省略 @Param
// 以下两种方式等效
User findById(@Param("id") int id);
User findById(int id);  // XML 中直接写 #{id}

  • Spring@RequestParam 区别:

@ParamMyBatis 注解,用于 SQL 参数绑定。
@RequestParamSpring MVC 注解,用于 HTTP 请求参数绑定

上次更新 2025/6/26 17:17:52