JAVA、Spring、Spring Boot 相关注解介绍

0 前言

在 Spring Boot 开发中注解(Annotation)占有重要的地位。注解为在代码中添加信息提供了一种形式化的方法,通过注解可以很方便地在代码中某个地方使用被注解的对象。注解常见的作用包括生成文档、跟踪代码依赖性和替代配置文件、在编译时进行格式检查(如 @Override 放在方法前)等。

本文介绍 Spring Boot 注解以及和 Spring Boot 注解密切相关的 Java 注解、Spring 注解等内容。

1. JAVA 注解

JRE 的库包 java.lang.annotation 代码中包括注解相关的接口、类等内容。接口 java.lang.annotation.Annotation 是所有自定义注解自动继承的接口,不需要定义时指定, 类似于所有 JAVA 类都自动继承的 Object 类。

1.1 JAVA 注解的介绍

注解是一系列元数据,它利用元数据来解释、说明程序代码(即被注解的对象)。但是,注解不是所标注的代码的组成部分。注解对于代码的运行效果没有直接影响。注解的作用包括:

  1. 提供信息给编译器,编译器可以利用注解来探测错误和警告信息;
  2. 软件工具可以利用注解信息来生成代码、HTML文档或者做其他相应处理;
  3. 运行时的处理,某些注解可以在程序运行时接受代码的提取。

在了解注解具体语法之前,可以将注解看成一张标签。与接口和类一样,注解也是一种类型。注解是自 JAVA 1.5 开始引入的概念,它允许开发者定义自己的注解类型和使用自定义的注解。注解通过关键词 @interface 进行定义。

public @interface TestAnnotation {
    
}

上例中的代码自定义了一个名字为 TestAnnotation 的注解,该注解自动继承了类 java.lang.annotation.Annotation。创建了自定义注解后,就可以使用自定义的注解。注解的使用方法如下所示:

@TestAnnotation
public class Test {
    
}

上例创建了一个类 Test,并在类定义的上方加上了 @TestAnnotation 注解,这意味着用 TestAnnotation 注解了类 Test。

1.2 JAVA 的元注解

要想更好地使用注解,还需要理解元注解。元注解是加到注解上的注解,它的目的是解释、说明其他普通注解。元注解有 @Retention、@Documented、@Target、@Inherited、@Repeatable 共五种。

  • @Retention 应用到一个注解时,说明该注解的存活时间。它的取值包括:

    • RetentionPolicy.SOURCE 表明注解只在源码阶段保留,在编译器进行编译时被丢失;
    • RetentionPolicy.CLASS 表明注解被保留到编译进行的时候,而不会被加载到 JVM 中;
    • RetentionPolicy.RUNTIME 表明注解可以保留到程序运行的时候,它会被加载进入 JVM 中,在程序运行时可以获取到他们。
    @Retention(RetentionPolicy.RUNTIME)
    public @interface TestAnnotation {
        
    }
    

    以上表示注解 TestAnnotation 可以在程序运行时被获取到。

  • @Documented 表示注解内容会被 Javadoc 工具提取成文档,文档内容会因为注解内容的不同而不同。

  • @Target 表示注解用于什么地方,如类型、方法和域等。元注解 @Target 的取值包括:

    • ElementType.FIELD 表示对字段、枚举常量的注解;
    • ElementType.METHOD 表示对方法的注解;
    • ElementType.PARAMETER 表示对方法参数的注解;
    • ElementType.CONSTRUCTOR 表示对构造函数的注解;
    • ElementType.LOCAL_VARIABLE 表示对局部变量的注解;
    • ElementType.ANNOTATION_TYPE 表示对注解类型的注解;
    • ElementType.PACKAGE 表示对包的注解;
    • ElementType.TYPE 表示对接口、类、枚举、注解等任意类型的注解。
  • @Inherited 表自动继承,即被 @Inherited 注解过的注解作用于父类后,子类会自动继承父类的注解。示例代码如下:

    // 定义注解
    @Inherited
    @Retention(RetentionPoilcy.RUNTIME)
    @interface Test { }
    
    // 在父类中添加注解
    @Test
    public class A { }
    
    // 子类 B 虽然没有明确给出注解信息,但是它会继承父类 A 中的注解 @Test
    public calss B extends A { }
    
  • @Repeatable 是在 JAVA 1.8 中引入的注解,其应用的示例代码如下所示。Persons 可以被看作是一张总标签,上面贴满了 Person 这种同类型但内容不一样的标签。于是,可以同时给 SuperMan 贴上画家、程序员、产品经理等标签(即加上三个注解)。

    // Persons 使用数组存放注解的容器注解,它里面必须要有一个 value 属性,即数组
    @interface PerSons {
        Person[] value();
    }
    
    // 可以重复、多次应用 Persons 注解
    @Repeatable (Persons.class)
    @interface Person {
        String role default "";
    }
    
    // 不同属性的Person注解
    @Person(role="artist")
    @Person(role="coder")
    @Person(role="PM")
    public class SuperMan {
        
    }
    

1.3 注解的属性

注解中可以拥有属性(也叫成员变量),示例代码如下所示。表示自定义的注解 TestAnnotation 拥有 id 和 msg 两个属性,返回类型分别为 int 和 String。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
    int id();
    String msg();
}

使用注解时,应该给属性赋值。属性的赋值方法是在注解后免得括号内以 “属性=取值” 的形式进行的,多个属性的赋值之间用逗号隔开,示例如下。需要注意的是,注解中属性的类型只能是 8 中基本数据类型和类、接口、注解及它们的数组。

@TestAnnotation(id=3, msg="hello world")
public class Test { 

}

注解中属性可以有默认值,默认值需要用关键词 default 指定,示例代码如下所示。注解 TestAnnotation 中属性 id 的默认值被指定为 -1,属性 msg 的默认值被指定为 “Hi”。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
    public int id() default -1;
    public String msg() default "Hi";
}

加入指定了属性默认值,可以不用再在注解 TestAnnotation 后面的括号内对属性进行赋值。

如果注解只有一个属性时,应用这个注解时则可以省略属性名而将属性值直接填写到注解后面的括号内。

如果注解没有任何属性,应用这个注解时注解后面的括号则可以省略。

1.4 JAVA 预置的基本注解

在 java.lang 包下,Java 预先提供了 @Deprecated、@SuppressWarnings、@Override、@SafeVarargs、@FunctionalInterface 共五个注解。

  • @Deprecated 是用来标记过时的元素。编译器在编译阶段遇到这个注解时会发出提醒警告,告诉开发者正在调用一个过时的元素(如过时的方法、类、成员变量)。
  • @SupperssWarings 表示阻止警告的意思。使用 @Deprecated 注解后,编译器有时会给开发者发出警告提醒;当开发者想忽略警告提醒时,可以通过 @SupperssWarings 注解达到目的。@SupperssWarings 的参数包括:
    • deprecation:表示忽略使用了过时元素时的警告;
    • unchecked:表示忽略执行了未检查转换时的警告;
    • fallthrough:表示忽略 switch 程序块直接通往下一种情况而没有 break 时的警告;
    • path:表示忽略类路径、源文件路径等路径中有不存在的路径时的警告;
    • serial:表示忽略可序列化的类缺少 serialVersionUID 定义时的警告;
    • finally:表示忽略任何 finally 子句不能正常完成时的警告;
    • all:表示忽略关于所有情况的警告。
  • @Override 表示子类要重写父类(或接口)的对应方法。如果想重写父类的方法如 toString() 方法,则在方法前面加上 @Override,系统可以帮助检查方法的正确性。示例代码如下:
    // @Override 可以帮忙检查方法的正确性
    @Override
    public String toString() {...} // 这是子类方法正确的写法
    
    // 下面子类方法是错误的,有 @Override,系统可以帮忙检查出 tostring 的拼写错误
    @Override
    public String tostring() {...}
    
    // 下面子类方法是错误的,由于没有 @Override,系统不会帮助检查出 tostring 的拼写错误
    public String tostring() {...}
    
  • @SafeVarargs 被用来标识参数安全类型,它被用来提醒开发者不要用参数做一些不安全的操作,它的存在会组织编译器产生 unchecked 这样的警告。他是在 Java 1.7 中引入的注解。
  • @FunctionalInterface 被用来指定某个接口必须是函数式接口,否则就会编译出错。@FunctionalInterface 是 Java 1.8 引入的新特性。如果接口中有且只有一个抽象方法(可以包含多个默认方法或多个 static 方法),该接口称为函数式接口。

2 Spring 注解及注解注入

Spring 容器通过把 JAVA 类注册成 Bean 的方式来管理 JAVA 类。把 JAVA 类变成 Bean 有两种方式:一种方式通过 XML 配置把 JAVA 类注册成 Bean; 另一种方式通过注解的方法将 JAVA 类注册成 Bean。利用不同的注解可以将 JAVA 类注册成不同的 Bean。相对于 XML 配置,注解方法更加方便、便捷。于是,越来越多的工具都支持用注解进行配置而放弃 XML 配置。

2.1 Spring 基础注解

可以将注解 @Component 放在类的前面,该类被标注成 Spring 的一个普通 Bean。

注解 @Controller 标注一个控制器组件类,它被用来实现自动检测类路径下的组件并将组件自动注册成 Bean。例如,使用 @Controller 注解标注 Java 类 UserAction 后,就表示要把类 UserAction 标注成 Bean 并交给 Spring 容器管理。如果不指定 Bean 的名字,按照约定该 Bean 会被命名为 userAction。也可以在注解后面的括号内指定 Bean 的名字,例如采用 @Controller(value=“UA”) 或者 @Controller(“UA”) 的方法来指定 Bean 的名字为 UA。

注解 @Service 标注一个业务逻辑组件类。例如,类 Action 需要使用 UserServiceImpl 实例时,可以用 @Service(“uaerService”) 注解告诉 Spring 创建好一个 UserServiceImpl 实例 (名字为 userService)。Spring 创建好 userService 之后可以将其注入给 Action,Action就可以使用该 UserServiceImpl 实例了。

注解 @Repository 标注一个 DAO 组件类。可以用 @Repository(value=“userDao”) 注解告诉 Spring 创建一个 UserDao 实例(名字为 userDao)。当 Service 需要使用 userDao 时,可以用 @Repository(name=“userDao”) 注解告诉 Spring 把创建好的 userDao 注入给 Service。

2.2 Spring 常见注解

注解 @Autowired 被用来实现自动装配,@Autowired 可以被用来标注成员变量、方法、构造函数等对象。虽然 @Autowired 的标注对象不同,但是都会在 Spring 初始化 Bean 时进行自动装配。使用 @Autowired 可以使 Spring 容器自动搜索符合要求的 Bean,并将其作为参数注入。

@Autowired 是根据类型进行自动装配的,示例代码如下所示。如果 Spring 上下文中存在多个同类型的 Bean 时(如有两个类都实现了 EmployeeService 接口),Spring 不知道应该绑定哪个实现类,就会抛出 BeanCreationException 异常。如果 Spring 上下文中不存在某个类型的 Bean 时,也会抛出 BeanCreationException 异常。

注解 @Autowired 的应用代码示例:

// 接口 Employeeservice 声明
public interface EmployeeService {
    public EmployeeDto getEmployeeById(Long ld);
}

// 两个实现类 EmployeeServiceImpl 和 EmployeeServiceImpl1
@Service("service")
public class EmployeeserviceImpl implements EmployeeService {
    public EmployeeDto getEmployeeById(Long id) {
        return new EmployeeDto();
    }
}

Service("service1")
public class EmployeeServiceImpll implements EmployeeService {
    public EmployeeDto getEmployeeById(Long id) {
        return new EmpioyeeDto();
    }
}

// 调用接口实现类
@Controller
@RequestMapping("/emplayee.do")
public class EmployeeInfoControl {
	@Autowired//此注解处会出错,因为有两个实现类,而不知道绑定哪一个
	EmployeeService employee5ervice;
	
    @RequestMapping(params = "method=showEmplayeeInfo")
    public void showEmplayeeInfo(HttpServletRequest request, HttpservletRespcnmresponse, EmployeeDto dto) {
        ... // 代码省略
    }
}

可以使用 @Qualifier 配合 @Autowired 来解决异常 BeanCreationlException,示例代码如下:

// 接口 Employeeservice 声明与上例一致
// 接口的两个实现类 EmployeeserviceImpl 和 EmployeeserviceImpl1 与上例一致

// 接口实现类的调用
@Controller
@RequestMapping("/emplayee.do")
public class EmployeeInfoControl {
    @Autowired
    @Qualifier( "service") // 新增加语句,指定调用第一个接口实现类
    EmployeeService employeeService;
    @RequestMapping(params = "method=showEmplayeeInfo")
    public void showEmplayeeInfo(HttpServletRequest request, HttpservletRespcnmresponse, EmployeeDto dto) {
        ... // 代码省略
    }
}

注解 @Resource 可用于标注一个对象的 SET 方法。注解 @Resource 的作用相当于 @Autowired,只不过 @Autowired 按类型自动注入,而 @Resource 默认按名字自动注入。JSR-250 标准推荐使用通用注解 @Resource 来代替 Spring 专有的 @Autowired 注解。

JSR(Java Specification Requests, Java规范提案) 是指向 JCP(Java Community Process) 提出新增一个标准化技术规范的正式请求。任何人都可以提交 JSR,以向 Java 平台增添新的 API 和服务。JSR 已成为 Java 界的一个重要标准。从 Spring 2.5 开始,Spring 框架的核心支持 JSR-250 标准中的注解 @Resource、注解 @PostConstruct 和注解 @PreDestroy。

@Resource 有两个属性比较重要,分别是名字 name 和属性 type。Spring 将 @Resource 注解 name 属性解析为 Bean 的名字,而将 type 属性解析为 Bean 的类型。如果使用 name 属性,则使用按名字自动注入的注入策略,而使用 type 属性时则使用按类型自动注入的注入策略。如果既不指定 name 属性也不指定 type 属性,则通过反射机制使用按名字自动注入的注入策略。@Resource 使用按名字自动注入的注入策略时,与使用 @Qualifier 明确指定 Bean 的名称进行注入作用相同。在众多相同的 Bean 中,优先使用 @Primary 注解的 Bean。这和 @Qualificr 有点区别,@Qualificr 指的是使用哪个 Bean 进行注入。

注解 @PostConstruct 和注解 @PreDestroy 都是 JSR-250 标准的注解。标注了 @PreDestroy 的方法将在类销毁之前调用,@PostConstruct 注解过的方法将在类实例化后调用。

从 Spring 3.0 开始,Spring 开始支持 JSR-330 标准的注解。JSR-330 中,@Inject 和 Spring 中的 @Autowired 的职责相同,@Named 和 Spring 中的 @Component 的职责类似。

可以用注解 @Scope 来定义 Bean 的作用范围 (称为作用域),也可以通过在 XML 文件中设置 Bean 的 scope 属性值来实现这一目的。@Scope 注解的值可以是 singleton、prototype、request、session、global scssion 等作用域,默认是单例模式,即 scope=“singleton”。其中:

  • 单例模式 singleton 表示全局有且仅有一个实例;
  • 原型模式 prototype 表示每次获取 Bean 时都会有一个新的实例;
  • request 表示针对每一次 HTTP 请求都会产生一个新的 Bean,而且该 Bean 仅在当前 HTTP 请求内有效;
  • session 表示针对每一次 HTTP 请求都会产生一个新的 Bean,而且该 Bean 仅在当前 HTTP session 内有效;
  • global session 类似于标准的 HTTP session,不过它仅仅在基于 Portlet 的 Web 应用中才有意义。

Portlet 的请求处理分为 action 阶段和 render 阶段。在一个请求中,action 阶段只执行一次,但是 render 阶段可能由于用户的浏览器操作而被执行多次。Portlet 规范定义了global session 的概念,它被所有构成某个Portlet Web 应用的各种不同 Portlet 所共享。在 global session 中定义的 Bean 被限定Portlet 全局会话 (global scssion) 的生命周期范围内。如果在 Web 中使用 global session 来标识 Bean,那么 Web 会自动当成 session 类型来使用。

JSR-330 默认的作用域类似 Spring 的 prototype, ISR-330 标准中的 Bean 在 Spring 中默认也是单例的。如果要使用非单例的作用域,开发者应该使用 Spring 的 @Scope 注解。JSR-330 也提供了一个 @Scope 注解,然而,这个注解仅仅在用来创建自定义的作用域时才能使用。

注解 @RequestMapping 为类或方法指定一个映射路径,可以通过指定的路径来访问对应的类或方法,应用示例如下例所示。其中,userid 值通过 @PathVariable 注解方法进行绑定。注解 @PathVariable 主要用来获取单一的 URI 参数,如果想通过 URI 传输一些复杂的参数,则要考虑使用注解 @MatrixVariable。@MatrixVariable 的矩阵变量可以出现在 URI 中任何地方,变量之间用分号(;)分隔。@MatrixVariable 默认是不启用的,启用它时需要将 enable-matrix-variablcs 设置为 true。

注解 @RequestMapping 的应用代码示例。

@RequestMapping(value="/getName/{userid}", method = RequestMethod.Get)
public void login(@Pathvariable String userid, Model mcdel){
    
}

注解 @RequestParam 将请求中带的值赋给被注解的方法参数。如下例所示,把请求中的值 username 赋给方法中 username 这个参数。属性 required 代表参数是否必须赋值,默认为 true;当不能确定请求中是否有值可以赋给参数时,就必须把属性 required 设置为 false。

public void login(@RequestParam(value="username" required="true") String username){
}

不管是 HTTP 请求还是 HTTP 响应都是通过报文传输的,而报文都有头和正文。头包含服务端或者客户端的一些信息,用来表明身份、提供验证或限制等。正文是要传递的内容。注解 @RequestBody 把请求报文中的正文自动转换成绑定给方法参数的变量字符串。响应请求时,@ResponseBody 将内容或 Java 对象转换成响应报文的正文返回。当返回的数据不是 HTML 标记页面 (视图) 而是其他某种格式数据 (如JSON、XML等) 时,才使用 @RequestBody 注解。

注解 @Param 表示对参数的解释,一般写在注释里面。

注解 @JoinTable 表示 Java 类和数据库表的映射关系,也可以标识列的映射、主键的映射等。

注解 @Transational 是 Spring 事务管理的注解。被 @Transational 注解的方法或类自动被注册成事务,接受 Spring 容器的管理。

注解 @Syschronized 表示实现 Java 同步机制,用它作注解相当于加同步锁。

注解 @ModelAttribute 声明在属性上,表示该属性的值来源于 model 里 queryBean,并被保存到 model 里。注解 @ModelAttribute 声明在方法上,表示该方法的返回值被保存到model里。

注解 @Cacheable 表明一个方法的返回值应该被缓存,注解 @CacheFlush 声明一个方法是清空缓存的触发器,这两个注解要配合缓存处理器使用。

Spring 允许指定 ModelMap 中哪些属性需要转存到会话中,以便下一个请求还能访问到这些属性。注解 @SessionAttributes 只能标注类,而不能标注方法。

如果希望某个属性编辑器仅作用于特定的控制器 Controller,可以在 Controller 中定义一个被注解 @InitBinder 标注的方法,可以在该方法中向 Controller 注册若干个属性编辑器。

注解 @Required 负责检查一个 Bean 在初始化时其 SET 方法是否被执行,如果 SET 方法没有被调用,则 Spring 在解析时会抛出异常来提醒开发者设置对应的属性。@Required 注解只能标注在 SET 方法上,如果将其标注在非 SET 方法上就会被忽略。

Spring 4.0 中引入了条件化配置特性,提供了更加通用的基于条件的 Bean 创建方法:即使用 @Conditional 注解。@Conditional 根据满足某一特定条件创建一个特定的 Bean。条件化配置允许配置存在于应用程序中,但在满足某些特定条件之前都忽略这些配置。在 Spring 里可以很方便地编写自定义的条件,只需要实现 Condition 接口并覆盖它的 matches()方法;如下例所示。在下例中,只有当 JdbcTemplateCondition 类的条件成立时才会创建 MyService 这个 Bean。否则,这个 Bean 的声明就会被忽略掉。

//具体条件类,需实现 Condition 接口,并重写 matches(...,...) 方法
public class JdbcTemplateCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata){
        try{       
            context.getc1assLoader().1oadclass(
        "org.springframework.jdbc.core.JdbcTemplate");
            return true;
        } catch (Exception e) {
            return false;
        }
    }
                                    
    //声明bean时,使用自定义条件类,作为eConditional的参数value
	@Conditional(JdbcTemplateCondition.class)
	public MyService myService(){...}
}

2.3 Spring 的注解注入

注解注入是通过注解来实现注入。Spring 中和注入相关的常见注解有 @Autowired、@Resource、@Qualifier、@Service、@Controller、@Repository、@Component 等。其中:

注解 @Autowired 实现自动注入;

注解 @Resource 通过指定名称的方式进行注入;

注解 @Qualifier 和注解 @Autowired 配合使用,通过指定名称的方式进行注入;

注解 @Autowired,@Resource 可以被用来标注字段、构造函数、方法,并进行注入。

注解 @Service、@Controller、@Repository 被用来标注类,Spring 扫描注解标注的类时要生成的 Bean。注解 @Service、@Controller、@Repository 标注的类分别位于服务层、控制层、数据存储层。注解 @Component 是一种泛指,标记被注解的对象是组件。

注解 @EnableAspectJAutoProxy 表示开启 AOP 代理自动配置机制,可以通过设置@EnableAspectJAutoProxy(exposeProxy=true) 表示使用 AOP 框架来暴露该代理对象,这样 aopContext 就能够访问。从注解 @EnableAspectJAutoProxy 的定义可以看出,它引入了一个 AspectJAutoProxyRegister.class 对象,该对象是一个用 @EnableAspectJAutoProxy 注解标注的 AnnotationAwareAspectJAutoProxyCreator。

AnnotationAwareAspectJAutoProxyCreator 能通过调用类 AopConfigUtils 的方法 registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry) 来注册一个 AOP 代理对象生成器。

注解 @Profiles 提供了一种隔离应用配置的方法,让这些配置只能在特定环境下生效。任何组件或配置类都能被 @Profiles 标记,从而限制它们的加载时机。

3 Spring Boot 的注解

3.1 Spring Boot 基础注解

注解 @SpringBootApplication 和注解 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解等价。其中,注解 @Configuration 标注在类上,等同于 Spring 的 XML 配置文件中 Bean。注解 @EnablcAutoConfiguration 实现自动配置。注解 @ComponentScar 扫描组件,可自动发现和装配 Bean,并把 Bean 加入到程序上下文。

注解 @RestController 是注解 @Controller 和注解 @ResponscBody 的合集,表示被标注的对象是 REST 风格的 Bean,并且是将方法的返回值直接填入 HTTP 响应正文中返回给用户。

注解 @JsonBackReference 可以用来解决无限递归调用问题。注解 @RepositoryRestResource 配合 spring-boot-starter-data-rest 使用,用于创建 RESTful 入口点。注解 @Import 用来导入其他配置类。注解 @ImportResource 用来加载 XML 配置文件。

注解 @Bean 标注方法等价于 XML 配置中的 Bean。注解 @Value 注入Spring Boot 配置文件 application.properties 中配置的属性值。注解 @Inject 等价于默认的 @Autowired,只是没有 required 属性。

Spring Boot 定义了很多条件,将其运用到了配置类上,这些配置类构成了 Spring Boot 的自动配置。Spring Boot 提供的条件化注解包括 @ConditionalOnBean (配置了某个特定Bean)、@ConditionalOnMissingBean (没有配置特定的 Bean)、@ConditionalOnClass (classPath 目录里有指定的类)、@ConditionalOnMissingClass (classpath 目录里缺少指定的类)、@ConditionalOnExpression (给定的 SpEL表达式计算结果为 true)、@ConditionalOnJava (Java 的版本匹配特定值或者一个范围值)、@ConditionalOnJndi (参数中给定的 JNDI 位置必须存在一个)、@ConditionalOnProperty (指定的配置属性要有一个明确的值)、@ConditionalOnResource (classpath 目录有指定的资源)、@ConditionalOnWebApplication (是一个 Web 应用程序)、@ConditionalOnNotWcbApplication (不是一个 Web 应用程序)。

3.2 JPA 注解

注解 @Entity 表明被标注的对象是一个实体类,注解 @Table(name=" ") 指出实体对应的表名;这两个注解一般一起使用。但是如果表名和实体类名相同,则 @Table 可以省略。

进行开发项目时,经常会用到将实体类映射到数据库表的操作。有时需要映射的几个实体类有共同的属性,例如编号 ID、创建者、创建时间、备注等。这时,可以把这些属性抽象成一个父类,然后各个实体类继承这个父类。可以使用 @MappedSuperclass 注解标注父类,它不会映射到数据库表,但子类在映射时会自动扫描父类的映射属性,并将这些属性添加到子类对应的数据库表中。使用 @MappedSuperclass 注解后不能再有 @Entity 或 @Table 注解。

SpringData 中提供了很多 DAO 接口,但是依然有可能满足不了日常应用的需要,需要自定义 Repository 实现。注解 @NoRepositoryBean 一般用作父类的 Repository,有这个注解 Spring 不会去实例化该 Repository。

注解 @Column 标识实体类中属性与数据表中字段的对应关系。如果注解 @Column 的字段名与列名相同,则可以省略。@Column 注解一共有 10 个属性,这 10 个属性均为可选属性。常用属性有 name、unique、nullable、table、length、precision、scale 等。其中,name 属性定义了被标注字段在数据库表中所对应字段的名称。unique 属性表示该字段是否为唯一标识,默认值为 false。如果表中有一个字段需要唯一标识,则既可以使用该标记,也可以使用 @Table 标记中的 @UniqueConstraint。nullable 属性表示该字段是否可以为 null 值,默认值为 true。table 属性定义了包含当前字段的表名。length 属性表示字段的长度,当字段的类型为 varchar 时,该属性才有效;默认值为 255 个字符。precision 属性和 scale 属性表示精度,当字段类型为 double 时,precision 表示数值的总长度,scale 表示小数点所占的位数。

注解 @Id 用于声明一个实体类的属性映射为数据库的主键列。该属性通常置于属性声明语句之前,可与声明语句同行,也可写在单独行上。@Id 标注也可置于属性的 getter 方法之前。

注解 @GeneratedValue 用于标注主键的生成策略,通过属性 strategy 指定策略。例如,注解 @GeneratedValue(strategy=GenerationType.SEQUENCE) 表示主键生成策略是 scquence,@GeneratedValue(generator =“repair_scq”) 指定 sequence 的名字是 repair_seq。

在 javax.persistcnce.GenerationTypc 中定义了 IDENTITY、AUTO、SEQUENCE 等几种可供选择的策略。其中,IDENTITY 策略表示采用数据库ID自增长的方式来自增主键字段,Oracle 不支持这种方式;SEQUENCE 表示通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySOL 不支持这种方式。默认情况下,JPA 自动选择一个最适合的底层数据库的主键生成策略,例如 SQL Server 对应的默认策略为 identity,MySQL 对应的默认策略为 auto increment。 注解 @SequenceGeneretor(name =“repair_seq”, sequenceName =“seq_repair”,allocationSize=1) 中 name 为 sequence 的名称,以便使用 sequenceName 为数据库的 sequence 名称,两个名称可以一致。

注解 @Transient 表示被标注的属性不是一个到数据库表的字段的映射,对象关系映射 (Objcct Relational Mapping,ORM) 框架将忽略该属性。如果一个属性并非数据库表的字段映射,就务必将其标示为 @Transicnt;否则,ORM 框架默认其注解为 @Basic。注解 @Basic(fetch=FctcbType.LAZY) 可以指定实体属性的加载方式。

注解 @Jsonlgnore 的作用是 JSON 序列化时将 Java Bean 中的一些属性忽略掉,序列化和反序列化都受影响。例如,如果希望返回的 JSON 数据中不包含属性 goodsInfo 和 extendsInfo 快照值;在实体类快照属性上加注解 @JsonIgnore 即可,最后返回的 JSON 数据将不会包含 goodsInfo 和 extendsInfo 两个属性值。

注解 @JoinColumn(name=“loginld”) 表示一张表有指向另一个表的外键。假设 Person 表和 Address 表是一对一的关系,Person 有一个指向 Address 表主键的字段 addressID;可以用注解 @JoinColumn 注解 addressID。@OncToOne、@OneToMany、@ManyToOne、@ManyToMany 对应 Hibernate 配置文件中的一对一、对多、多对一、多对多关系。@ManyToOne 不产生中间表,可以用@Joincolumn(name=" “) 来指定外键的名字。@OneToMany 会产生中间表,可以用 @onetoMany @Joincolumn(name=” ") 避免产生中间表,并且能指定外键的名字。

3.3 异常处理注解

注解 @ControllerAdvice 包含注解 @Component,可以被扫描到,统一处理异常。

注解 @ExccptionHandler(Exception.class) 用在方法上面表示遇到这个异常就执行所注解的方法。

3.4 注解配置解析和使用环境

注解 @PreUpdate 用于为相应的生命周期事件指定回调方法。该注解可以应用于实体类、映射超类或回调监听器类的方法。如果要每次更新实体时都要更新属性,可以使用注解 @PreUpdate 注释。注解 @PreUpdate 不允许更改实体。

注解 @PrePersist 帮助在持久化之前自动填充实体属性。@PrePersist 事件在调用 persist() 方法后立刻发生,此时的数据还没有真正插入数据库。可以用来在使用 JPA 时记录一些与业务无关的字段,如最后更新时间等。生命周期方法注解 (删除没有生命周期事件 @PrePersist 在保存之前被调用,注解 @PostPersist 在保存之后被调用。@PostPersist 事件在数据已经插入数据库后发生。

注解 @PostLoad 在 Entity 被映射之后被调用,注解 @EntityListeners 指定外部生命同期事件实现类。注解 @PostLoad 事件在执行 EntityManager.find() 或 getreference() 方法载入一个实体后、执行 JPA SQL 查询后或 EntityManager.refresh() 方法被调用后执行。

注解 @PreRemove 和注解 @PostRemove 事件的触发由删除实体引起。注解 @PreRemove 事件在实体从数据库删除之前触发。注解 @PostRemove 事件在实体从数据库删除后触发。

注解 @NoArgsConstructor 提供一个无参的构造方法。注解 @AllArgsConstructor 提供一个全参的构造方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/7216.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL-四大类日志

目录 🍁MySQL日志分为4大类 🍁错误日志 🍃修改系统配置 🍁二进制日志 🍃查看二进制日志 🍃删除二进制日志 🍃暂时停止二进制日志的功能 🍁事务日志(或称redo日志) 🍁慢查…

chatgpt3中文辅助写作-gpt2中文文本生成

GPT-3是一种深度学习模型,具有潜在的巨大计算成本和训练麻烦。根据OpenAI公司的官方消息,训练GPT-3是一项昂贵的和耗时的过程,在OpenAI公司,训练GPT-3的成本已经超过了10亿美元。考虑到GPT-3的架构、规模和训练时间,这…

高分子PEG磷酸盐mPEG-phosphoric acid,Phosphate PEG,甲氧基聚乙二醇磷酸,可用于修饰金属氧化物表面

规格单位:g |货期:按照具体的库存进行提供 | 端基取代率:95% 中英文名:mPEG-phosphoric acid|Phosphate PEG|甲氧基聚乙二醇磷酸​ 一、Phosphate PEG化学结构式: 二、产品详情: 外观:灰白…

[oeasy]python0123_中文字符_文字编码_gb2312_激光照排技术_王选

中文编码GB2312 回忆上次内容 上次回顾了 日韩各有 编码格式 日本 有假名 五十音一字节 可以勉强放下 有日本汉字 字符数量超过20000 韩国 有谚文 数量超过500一个字节 放不下 有朝鲜汉字 字符数量超过20000 作为 汉字源头的中国 究竟应该 如何对汉字 进行编码 呢&#x…

操作系统-AOSOA

一、个人感受 1.1 权衡 在我写这份报告的时候,已经是 6 月 30 号了,经历了一个学期的“折磨”,我面对终点,已经没啥感觉了,就想着赶快呼噜完了就完事了。其实做这个项目最大的体会就是“人力有穷,一切皆权…

视频剪辑:教你如何调整视频画面的大小。

大家应该都会调整图片的大小吧,那你们会调整视频画面的大小吗?我想,应该会有人不还不知道要调整的吧,今天就让小编来教大家一个方法怎样去调整视频画面的大小尺寸。 首先,我们要有以下材料: 一台电脑 【…

列的类型定义——整形类型

文章目录 前言一、整数类型的附带属性 类型名称后面的小括号unsignedauto_increment总结前言 1)采用26字母和0-9的自然数加上下互相 ‘_’ 组成,命名简洁明确,多个单词用下划线 ‘_’ 隔开 2)全部小写命名,尽量避免…

【SpringBoot】自定义Starter

🚩本文已收录至专栏:Spring家族学习之旅 👍希望您能有所收获 一.概述 在使用SpringBoot进行开发的时候,我们发现使用很多技术都是直接导入对应的starter,然后就实现了springboot整合对应技术,再加上一些简…

【论文导读】Inferring deterministic causal relations

前段时间看Scholkopf教授的《Towards Causal Representation Learning》,看到这篇挺有意思来读读。 这一篇只在Arxiv上挂着,重点主要是研究发掘两变量之间的因果关系(无法应用独立性检验等方法),引入了信息论中的正则…

Elasticsearch:配置选项

Elasticsearch 带有大量的设置和配置,甚至可能让专家工程师感到困惑。 尽管它使用约定优于配置范例并且大部分时间使用默认值,但在将应用程序投入生产之前自定义配置是必不可少的。 在这里,我们将介绍属于不同类别的一些属性,并讨…

2023年泰迪杯数据挖掘挑战赛B题--产品订单数据分析与需求预测(2.数据探索性分析)

前言 继续上一片数据预处理进行续写,利用预处理之后的数据进行数据分析并且解决问题一相关的问题。问题一主要目的是让研究各种因素对于需求量的影响,然后找到确定影响需求量的主要因素并且进行数据分析和主要特征抽取。 对于问题提出的八个小问&#…

解决云服务器ssh经常断开的问题

问题描述:无论是腾讯云服务器还是阿里云服务器等,在使用MobaXterm或者Xshell连接云服务器时,如果十分钟左右无任何操作,ssh就会自动断开,非常烦人,下面提供几种方法来解决该问题。 MobaXterm的报错如下&am…

Cookie和Session的工作流程及区别(附代码案例)

目录 一、 HTTP协议 1.1 为什么HTTP协议是无状态的? 1.2 在HTTP协议中流式传输和分块传输编码的区别 二、Cookie和Session 2.1 Cookie 2.2 Session 2.3 Cookie和Session的区别 三、servlet中与Cookie和Session相关的API 3.1 HttpServletRequest 类中的相关方…

mysql与redis区别

一、.redis和mysql的区别总结 (1)类型上 从类型上来说,mysql是关系型数据库,redis是缓存数据库 (2)作用上 mysql用于持久化的存储数据到硬盘,功能强大,但是速度较慢 redis用于存储使…

【新2023Q2押题JAVA】华为OD机试 - 挑选字符串

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:挑选字符串 题目 给定a-z,…

二.microchip samE54-- ATSAME54P20A 开发板使用总结

板子图片 2.1 板子硬件资源 2.1.1 外部插件1 2.2.2 外部插件2 2.2.3 外部插件3 2.2.IDE KIT连接(USB DEBUG) 板子自带,不是JLINK 出现这个说明板载 调试软件识别成功 2.3 编译与下载 D:\HarmonyProjects\usart\usart_echo_blocking\f…

DataHub调研数据血缘

DataHub调研&数据血缘 1. DataHub? 阿里的数据工具datahub? 回答: 不是 DataHub是由Linkedin开源的,官方喊出的口号为:The Metadata Platform for the Modern Data Stack - 为现代数据栈而生的元数据平台。官方网站A Metadata Platfo…

Qt C++与Python混合编程:补充错误

在提示中,需要引用Python.h,出现错误。 1、找不到Python.h 如果是pro工程,需要在里面配置; INCLUDEPATH /Users/xinnianwang/opt/anaconda3/include LIBS /Users/xinnianwang/opt/anaconda3/lib 如果是CMakeLists.txt需要配…

【清明节】开发平台公司流辰信息缅怀先祖,传承精神,撸起袖子创佳绩!

四月暖春,草长莺飞,杨柳依依,大自然呈现出一片生机勃勃的朝气景象。中国传统民俗节日——清明节踏春而来,在回乡祭祖,缅怀先人的季节里,哀思、怀念、伤感已经成为整个清明节的主基调。在这万物复苏、春和景…

Spring循环依赖冤冤相报何时了

Spring循环依赖 🚎什么是循环依赖?那么循环依赖是个问题吗?单例setter, spring是如何解决的为什么需要三级缓存单单只有两级缓存行不行还得是你三级缓存三级缓存解决依赖循环全解梦想不会逃跑,会逃跑的永远都是自己 什么是循环依赖…
最新文章