Hibernate项目中不仅有ORM一个框架,这里介绍的是它的另一个框架Validator,用来验证实体类是否满足需求。Validator实现了Java的一项标准Bean Validation。 如果使用Maven,就需要在pom.xml中添加如下一段,Hibernate需要Java EL表达式,因此需要添加EL的依赖项。 <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.3.4.Final</version> </dependency> <dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> <version>2.2.4</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>javax.el</artifactId> <version>2.2.4</version> </dependency> 如果使用Gradle,需要将上面的依赖项转换一下。 compile group: ‘org.hibernate‘, name: ‘hibernate-validator‘, version: ‘5.3.4.Final‘ compile group: ‘javax.el‘, name: ‘javax.el-api‘, version: ‘3.0.1-b04‘ compile group: ‘org.glassfish.web‘, name: ‘javax.el‘, version: ‘2.2.6‘ 添加依赖之后,就可以在实体类中添加条件注解了。常用的几个注解如下: Bean Validation 中内置的 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(regex=,flag=) 被注释的元素必须符合指定的正则表达式 Hibernate Validator 附加的 constraint @NotBlank(message =) 验证字符串非null,且长度必须大于0 @Email 被注释的元素必须是电子邮箱地址 @Length(min=,max=) 被注释的字符串的大小必须在指定的范围内 @NotEmpty 被注释的字符串的必须非空 @Range(min=,max=,message=) 被注释的元素必须在合适的范围内 注解 作用 AssertTrue 布尔值为真 AssertFalse 布尔值为假 Null 引用为空 NotNull 引用不为空 NotEmpty 字符串引用和值都不是空 Min 数字的最小值 Max 数字的最大值 Past 日期必须是过去 Future 日期必须是未来 Pattern 字符串必须匹配正则表达式 Valid 递归验证引用 Size 验证字符串是否在Size范围内 Email 验证字符串是否是一个有效的电子邮箱 URL 字符串是否是一个有效的URL
需要注意最后两个注解是Hibernate Validator自定义的,假如使用其他的Bean Validation实现,可能没有这两个注解。 下面向两个实体类添加了验证注解,其他方法已经省略了。和JPA注解一样,如果验证注解添加到字段上,Hibernate就会直接读取字段的值。如果注解到Getter方法上,Hibernate就会调用方法取得值。在一个类中不要同时应用这两种方式,会导致重复验证的问题。如果在一个集合上应用Valid注解, Hibernate就会递归验证集合中的每一个元素。 public class Author { @NotNull @Size(min = 6, max = 15) @Pattern(regexp = "([a-zA-Z]+\d*)+") private String username; @NotNull @Size(min = 6, max = 20) private String password; @NotNull private String nickname; @Email private String email; @Min(0) private int age; @Size(max = 500) private String address; @Past @NotNull private Date birthday; @Valid @NotNull private List<Article> articles = new ArrayList<>(); } public class Article { @NotNull private String title; @NotNull private String content; @NotNull private Author author; @Past private Date createTime; @Past private Date modifyTime; } 向实体类添加了验证注解之后,我们就可以开始验证了。首先需要构造一个ValidatorFactory,然后使用构造出的ValidatorFactory生成一个Validator,然后调用这个Validator的validate方法,就可以验证实体类了。validate方法会返回一个Set,每一个ConstraintViolation都是一个验证结果,如果实体类没有错误,那么这个集合的大小就是0,表示验证通过。如果存在错误,我们就可以通过这个集合来查看存在什么错误。 public class ValidatorTest { private static ValidatorFactory factory; private static Validator validator; private static Logger logger; @BeforeClass public static void init() { factory = Validation.buildDefaultValidatorFactory(); validator = factory.getValidator(); logger = LoggerFactory.getLogger(ValidatorTest.class); } @AfterClass public static void clean() { factory.close(); } @Test public void testKindsOfErrors() { Author author = new Author(); author.setUsername("123"); author.setPassword("1234"); author.setAddress(""); author.setEmail(""); author.setArticles(null); author.setAge(-20); Set<ConstraintViolation<Author>> set = validator.validate(author); for (ConstraintViolation<Author> c : set) { logger.info(c.toString()); } } @Test public void testAllRight() { Author author = new Author(); author.setUsername("yitian"); author.setPassword("12345678"); author.setAddress(""); author.setNickname(""); author.setEmail("yitian@yitian.com"); author.setBirthday(new Date()); Set<ConstraintViolation<Author>> set = validator.validate(author); for (ConstraintViolation<Author> c : set) { logger.info(c.toString()); } Assert.assertEquals(0, set.size()); } @Test public void testOneProperty() { Author author = new Author(); author.setUsername("yitian"); Set<ConstraintViolation<Author>> set = validator.validateProperty(author, "username"); for (ConstraintViolation<Author> c : set) { logger.info(c.toString()); } } @Test public void testCustomMessage() { Article article = new Article(); LocalDate date = LocalDate.of(2099, 1, 1); article.setModifyTime(Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant())); Set<ConstraintViolation<Article>> set = validator.validateProperty(article, "modifyTime"); for (ConstraintViolation<Article> c : set) { logger.info(c.toString()); } } } 以上就是一个简单的验证的例子。通过这个例子,大家应该明白了Hibernate Validator的基本内容。很多框架比如Spring也提供了相关的内容,能方便的将Hibernate Validator整合到项目中。如果希望了解更多信息,可以查看一下它们的相关文档。这里就起到一个抛砖引玉的作用。