Atitit 提升效率 声明式编程 约束式编程 目录 1. 。 在约束编程中,问题被视为对可能是有效解决方案的一系列限制。 1 2. 常见的约束式编程 2 2.1. 数据库约束 注解 2 2.2.

Atitit 提升效率 声明式编程  约束式编程

 

目录

1. 。 在约束编程中,问题被视为对可能是有效解决方案的一系列限制。 1

2. 常见的约束式编程 2

2.1. 数据库约束 注解 2

2.2. 约束注解(constraint annotation 2

2.2.1. schema层次验证 2

2.3. 正则表达式约束 2

2.4. Hibernate验证器 2

2.5. Bean Validation 2.0(JSR-380 2

2.6. JSR 303的1.0版本升级到JSR 349的1.1版本,再到JSR 380的2.0版本( 2

3. 应用场合 数据校验   条件选择 3

4. 相关技术 (正则表达式约束) 3

5. 3

5.1. Hibernate验证器 3

5.2. 4.1. 约束 4

5.2.1. 4.1.1. 什么是约束? 4

5.2.2. 4.1.2. 内建约束 4

5.2.3. 4.1.3. 错误信息 6

5.2.4. 4.1.4. 编写你自己的约束 6

5.2.5. 4.2.1. 数据库schema层次验证 7

5.2.6. 4.2.2. Hibernate基于事件的验证 7

5.2.7. 注意 8

5.2.8. 4.2.3. 程序级验证 8

5.3. Bean Validation 中的 constraint 9

5.4. 结束语 11

 

 

 

  1. 。 在约束编程中,问题被视为对可能是有效解决方案的一系列限制。

这种范式可以用来有效地解决一组问题,这些问题可以转化为变量和约束,或表示为一个数学方程。 在这种方式下,它与约束满足问题( CSP )有关。

它使用声明式编程风格来描述具有某些属性的通用模型。 与命令式风格相比,它不告诉如何实现目标,而是实现目标。 约束编程不是使用仅一种显而易见的方法来定义一组指令来计算值,而是声明约束内变量之间的关系。 最终模型使计算变量值成为可能,而与方向或变化无关。

 

 

  1. 常见的约束式编程

 

    1. 数据库约束 注解
    2. 约束注解(constraint annotation
      1. schema层次验证

无须额外手续,Hibernate Annotations会自动将你为实体定义的约束翻译为映射元数据。例如,如果你的实体 的一个属性注解为@NotNull,在Hibernate生成的DDL schema中这列会被定义为 not null

 

    1. 正则表达式约束
    2. Hibernate验证器

三种 Bean 验证核心概念:约束、约束违例处理和验证器。如果您在类似 JPA 的集成环境中运行应用程序,那么无需直接与验证器连接。

验证约束是添加到 JavaBeans 组件的类、字段或方法的注解或 XML 代码。 约束可以是内置约束或者用户定义的约束。这些注释用来定义常规约束定义以及

    1. Bean Validation 2.0(JSR-380

avax.validation

Bean Validation 2.0

什么是Validator

Bean Validation是Java定义的一套基于注解的数据校验规范,目前已经从

    1. JSR 303的1.0版本升级到JSR 349的1.1版本,再到JSR 380的2.0版本(

2.0完成于2017.08),已经经历了三个

 

349 -Bean Validation

  1. 应用场合 数据校验   条件选择
  2. 相关技术 (正则表达式约束)
  3.  

 

    1. Hibernate验证器

注解是一种为领域模型(domain model)指定不变约束的简洁而幽雅的方法。例如,你能 表示一个属性永远不为null,一个帐户余额一定是正值,等等。这些域模型约束通过为bean中的属性添加 注解来加以声明。随后一个验证器(validator)会读取并检查这些约束。验证机制可以执行于应用程序中的 不同层(表现层、数据访问层),而不必复述任何(前述)这些规则。Hibernate验证器正为这一目的而设计的。

Hibernate验证器工作在两个层次上。第一层,它能检查内存中一个类的实例是否违反约束。 第二层,它能将约束应用于Hibernate元模型上,并将它们融入生成的数据库schema中。

每个约束注解(constraint annotation)和一个验证器实现关联,该验证器负责检查位于实体实例上的约束。 一个验证器也能(可选地)将约束应用于Hibernate元模型上,让Hibernate生成表示这一约束的DDL。使用合适的事件监听器,你能 让Hibernate在插入和更新时执行检查操作。Hibernate验证器并不局限于同Hibernate一起使用。 你能在你应用程序的任何地方方便地使用它。

在运行时检查实例时,Hibernate验证器返回违反约束的信息, 这些信息以一个InvalidValue数组的形式返回。 除了众多其他信息外,InvalidValue包含了一个错误描述消 息,该信息可以内嵌与注解相捆绑的参数值(例如长度限制),以及能被提取至ResourceBundle的消息字串。

    1. 4.1. 约束
      1. 4.1.1. 什么是约束?

约束通过注解表示。一个约束通常有一些用来参数化约束限制的属性。约束应用于带注解的元素。

      1. 4.1.2. 内建约束

Hibernate验证器有些内建约束,这些约束覆盖了大多数的基本数据检查。随后我们会看到, 你不必受制于这些内置约束,因为一分钟内就可以写出你自己的约束。

表 4.1. 内建约束

注解

应用目标

运行时检查

Hibernate元数据影响

@Length(min=, max=)

属性(String)

检查字符串长度是否符合范围

列长度会被设到最大值

@Max(value=)

属性 (以numeric或者string类型来表示一个数字)

检查值是否小于或等于最大值

对列增加一个检查约束

@Min(value=)

属性(以numeric或者string类型来表示一个数字)

检查值是否大于或等于最小值

对列增加一个检查约束

@NotNull

属性

检查值是否非空(not null)

列不为空

@Past

属性(date或calendar)

检查日期是否是过去时

对列增加一个检查约束

@Future

属性 (date 或 calendar)

检查日期是否是将来时

@Pattern(regex="regexp", flag=)

属性 (string)

检查属性是否与给定匹配标志的正则表达式相匹配(见 java.util.regex.Pattern )

@Range(min=, max=)

属性(以numeric或者string类型来表示一个数字)

检查值是否在最小和最大值之间(包括临界值)

对列增加一个检查约束

@Size(min=, max=)

属性 (array, collection, map)

检查元素大小是否在最小和最大值之间(包括临界值)

@AssertFalse

属性

检查方法的演算结果是否为false(对以代码方式而不是注解表示的约束很有用)

@AssertTrue

属性

检查方法的演算结果是否为true(对以代码方式而不是注解表示的约束很有用)

@Valid

属性 (object)

对关联对象递归的进行验证。如果对象是集合或数组,就递归地验证其元素。如果对象是Map,则递归验证其值元素。

@Email

属性(String)

检查字符串是否符合有效的email地址规范。

      1. 4.1.3. 错误信息

Hibernate验证器提供了一组默认的错误提示信息,它们被翻译成多种语言(如果你的语言不在其中,请给 我们寄一个补丁)。你可以在org.hibernate.validator.resources.DefaultValidatorMessages.properties 之外创建ValidatorMessages.propertiesValidatorMessages_loc.properties 文件并改变相应的键值,籍此覆盖那些(默认)信息。你甚至可以在写自己的验证器 注解时添加你自己的附加消息集。

或者你可以以编程方式检查bean的验证规则并提供相应的ResourceBundle

      1. 4.1.4. 编写你自己的约束

扩展内建约束集是极其方便的。任何约束都包括两部分:约束描述符(注解) 和约束验证器(实现类)。下面是一个简单的用户定义描述符:

@ValidatorClass(CapitalizedValidator.class)

@Target(METHOD)

@Retention(RUNTIME)

@Documented

public @interface Capitalized {

    CapitalizeType type() default Capitalize.FIRST;

    String message() default "has incorrect capitalization";

}

 

 

多层数据验证,我们在一处表示约束(带注解的域模型),然后将其运用于 应用程序的不同层。

      1. 4.2.1. 数据库schema层次验证

无须额外手续,Hibernate Annotations会自动将你为实体定义的约束翻译为映射元数据。例如,如果你的实体 的一个属性注解为@NotNull,在Hibernate生成的DDL schema中这列会被定义为 not null

      1. 4.2.2. Hibernate基于事件的验证

Hibernate验证器有两个内建Hibernate事件监听器。当一个PreInsertEvent 或PreUpdateEvent发生时,监听器会验证该实体实例的所有约束,如有违反会抛出一个异常。 基本上,在Hibernate执行任何插入和更新前对象会被检查。这是激活验证过程的最便捷最简单的方法。当遇到约束 违规时,事件会引发一个运行时InvalidStateException,该异常包含一个描述每个错误的 InvalidValue数组。

<hibernate-configuration>

    ...

    <event type="pre-update">

        <listener

          class="org.hibernate.validator.event.ValidatePreUpdateEventListener"/>

    </event>

    <event type="pre-insert">

        <listener

          class="org.hibernate.validator.event.ValidatePreInsertEventListener"/>

    </event>

</hibernate-configuration>

      1. 注意

在使用Hibernate Entity Manager时,Validation框架会被自动激活。如果bean不带验证注解, 就不会有性能损失。

      1. 4.2.3. 程序级验证

Hibernate验证器能应用于你应用程序代码中的任何地方。

ClassValidator personValidator = new ClassValidator( Person.class );

ClassValidator addressValidator = new ClassValidator( Address.class, ResourceBundle.getBundle("messages", Locale.ENGLISH) );

 

InvalidValue[] validationMessages = addressValidator.getInvalidValues(address);

头两行为执行类检查而准备Hibernate验证器。第一行依赖于嵌入在Hibernate验证器内的错误 消息(见Error messages),第二行为这些消息准备资源包。这些代码只执行一次, 并将验证器进行缓存处理,这种方式是一种良好实践。

第三行真正验证了Address实例并返回一

下载 JSR 303 – Bean Validation 规范 http://jcp.org/en/jsr/detail?id=303

Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。如果想了解更多有关 Hibernate Validator 的信息,请查看 http://www.hibernate.org/subprojects/validator.html

    1. Bean Validation 中的 constraint
          1. 表 1. Bean Validation 中内置的 constraint

Constraint

详细信息

@Null

被注释的元素必须为 null

@NotNull

被注释的元素必须不为 null

@AssertTrue

被注释的元素必须为 true

@AssertFalse

被注释的元素必须为 false

@Min(value)

被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@Max(value)

被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@DecimalMin(value)

被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@DecimalMax(value)

被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@Size(max, min)

被注释的元素的大小必须在指定的范围内

@Digits (integer, fraction)

被注释的元素必须是一个数字,其值必须在可接受的范围内

@Past

被注释的元素必须是一个过去的日期

@Future

被注释的元素必须是一个将来的日期

@Pattern(value)

被注释的元素必须符合指定的正则表达式

          1. 表 2. Hibernate Validator 附加的 constraint

Constraint

详细信息

@Email

被注释的元素必须是电子邮箱地址

@Length

被注释的字符串的大小必须在指定的范围内

@NotEmpty

被注释的字符串的必须非空

@Range

被注释的元素必须在合适的范围内

一个 constraint 通常由 annotation 和相应的 constraint validator 组成,它们是一对多的关系。也就是说可以有多个 constraint validator 对应一个 annotation。在运行时,Bean Validation 框架本身会根据被注释元素的类型来选择合适的 constraint validator 对数据进行验证。

有些时候,在用户的应用中需要一些更复杂的 constraint。Bean Validation 提供扩展 constraint 的机制。可以通过两种方法去实现,一种是组合现有的 constraint 来生成一个更复杂的 constraint,另外一种是开发一个全新的 constraint。

实在整个程序的任何地方都可以调用 JSR 303 API 去对数据进行校验,然后将校验后的结果返回。

          1. 清单 8. 调用 JSR 303 API 进行校验

Order order = new Order();

...

 ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

 Validator validator = factory.getValidator();

 Set<ConstraintViolation<Order>> violations = validator.validate(order);

显示更多

    1. 结束语

JSR 303 的发布使得在数据自动绑定和验证变得简单,使开发人员在定义数据模型时不必考虑实现框架的限制。当然 Bean Validation 还只是提供了一些最基本的 constraint,在实际的开发过程中,用户可以根据自己的需要组合或开发出更加复杂的 constraint

  •  
  •  
  •  
  •  
  •  
  •  

技术 (1)

  •  

Java

  •  
  •  

目录

    •  
    •  
      •  
      •  
      •  
      •  
      •  
    •  
  •  

JSR 303 – Bean Validation 介绍及最佳实践 – IBM Developer

posted @ 2020-08-07 18:14  attilaxAti  阅读(33)  评论(0编辑  收藏  举报