JPA 是 JCP 组织发布的 Java EE 标准之一,因此任何声称符合 JPA 标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。
容器级特性的支持
JPA框架中支持大数据集、事务、并发等容器级事务,这使得 JPA 超越了简单持久化框架的局限,在企业应用发挥更大的作用。
简单方便
JPA的主要目标之一就是提供更加简单的编程模型:在JPA框架下创建实体和创建Java 类一样简单,没有任何的约束和限制,只需要使用 javax.persistence.Entity进行注释,JPA的框架和接口也都非常简单,没有太多特别的规则和设计模式的要求,开发者可以很容易地掌握。JPA基于非侵入式原则设计,因此可以很容易地和其它框架或者容器集成。
查询能力
JPA的查询语言是面向对象而非面向数据库的,它以面向对象的自然语法构造查询语句,可以看成是Hibernate HQL的等价物。JPA定义了独特的JPQL(Java Persistence Query Language),JPQL是EJB QL的一种扩展,它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。
高级特性
JPA 中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用,而不需要自行处理这些特性在关系数据库的持久化。
@Test void getBook() { Book book = Book.builder() .id(13) .name("程序") .description("think") .build(); ExampleMatcher matcher = ExampleMatcher.matching() // .withIgnorePaths("id","name") // 忽略 id,name 字段 .withIgnorePaths("id", "name") // 忽略 id 字段,即不管 id 是什么值都不加入查询条件 // .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains()) // 全部模糊查询 .withMatcher("name", m -> m.startsWith()) // 模糊查询匹配开头 // .withMatcher("name",ExampleMatcher.GenericPropertyMatchers.exact()) // 精准匹配 .withIgnoreCase("name") // 忽略大小写 .withMatcher("description", m -> m.endsWith()) .withIgnoreNullValues(); Example example = Example.of(book, matcher); boolean exists = bookRepository.exists(example); System.out.println("exists = " + exists); }
@Test public void testSpecificationQueryExists() { Specification specification = (root, query, builder) -> { // 获取比较属性 Path id = root.get("id"); return builder.equal(id, 4); }; boolean exists = this.helpRepository.exists(specification); System.out.println(exists?"exists":"not exists"); } @Test public void testSpecificationMoreParam() { Specification specification = (root, query, criteriaBuilder) -> { //获取比较属性 Path title = root.get("title"); Path content = root.get("content"); //构造条件查询 Predicate preTitle = criteriaBuilder.equal(title, "123"); Predicate preContent = criteriaBuilder.equal(content, "efg is help ...123 ... "); //与相连 Predicate condition = criteriaBuilder.and(preTitle, preContent); return condition; }; long count = this.helpRepository.count(specification); System.out.println("count = " + count); List helps = this.helpRepository.findAll(specification); helps.forEach((help) -> System.out.println(help)); } @Test public void testSpecificationLike() { Specification specification = (root, query, criteriaBuilder) -> { //获取比较属性 Path title = root.get("title"); //构建查询条件 //Predicate condition = criteriaBuilder.like(title.as(String.class), "%12__"); Predicate condition = criteriaBuilder.like(title.as(String.class), "%oo%"); Path id = root.get("id"); // Predicate condition 1 = criteriaBuilder.lessThan(id.as(Integer.class), 5); // criteriaBuilder.ge 相当于 >= // criteriaBuilder.greaterThan 相当于 > // criteriaBuilder.lt (lessThan) 相当于 < // criteriaBuilder.notEqual 相当于 <> // Predicate condition 2 = criteriaBuilder.notEqual(id.as(Integer.class), 5); return condition; }; List helps = this.helpRepository.findAll(specification); helps.forEach(help -> System.out.println(help)); }
Specification 表达式 :