5. JPA的标准API

JPA的标准API

标准的API提供了一套基于Java语言的数据库操作方法。
标准API提供的调教查询主要依靠CriteriaBuilder、CriteriaQuery两个类;
CriteriaBuilder构造条件,主要提供:and、or、between、like等;
CriteriaQuery条件查询,主要提供:select、where、groupby、orderBy、having等。

使用基本步骤:

1
2
3
4
5
6
7
8
9
10
11
12
//1.通过entityManager获取条件构造器CriteriaBuilder
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
//2.创建条件查询CriteriaQuery实例
CriteriaQuery<Book> criteriaQuery = criteriaBuilder.createQuery(Book.class);
//3.创建查询根root,即select语句中from部分,对应SQL:from book
Root<Book> root = criteriaQuery.from(Book.class);
//4.创建查询字段,即select语句中select部分,参数意为select
CriteriaQuery<Book> select = criteriaQuery.select(root);
//5.创建查询语句
Query query = entityManager.createQuery(select);
//6.得到查询结果
List<Book> books = query.getResultList();

整个步骤中需要注意的是第四点,这一处可扩展出where、order by、group by、having等其他条件子句。具体阐述如下(只展示第4点代码):

SELECT

1
2
3
4
5
6
7
8
9
10
//1.查询所有属性
CriteriaQuery<Book> select = criteriaQuery.select(root);
//2.查询部分属性bookname、price。注意:Book类中需要有只有这两个属性对应的构造方法
CriteriaQuery<Book> select = criteriaQuery.multiselect(root.get("bookname"),root.get("price"));

//就是这段代码(对应查询的Book构造方法)
public Book(String bookname , String price) {
this.bookname = bookname;
this.price = price;
}

WHERE

where子句中有许多条件方法:between、like等,下面逐一介绍:

like

1
2
3
4
//1.构造查询所有属性的select语句,对应SQL:select *
CriteriaQuery<Book> select = criteriaQuery.select(root);
//2.构造 bookname like '%java%' 的where子句
criteriaQuer.where(criteriaBuilder.like(root.get("book"),"%java%"));

equals

1
2
3
4
//1.构造查询所有属性的select语句,对应SQL:select *
CriteriaQuery<Book> select = criteriaQuery.select(root);
//2.构造 bookname = 'java' 的where子句
criteriaQuer.where(criteriaBuilder.equals(root.get("book"),"java"));

between

1
2
3
4
//1.构造查询所有属性的select语句,对应SQL:select *
CriteriaQuery<Book> select = criteriaQuery.select(root);
//2.对应SQL:where price betwween 50 and 70;
criteriaQuer.where(criteriaBuilder.between(root.get("price"),"50","70"));

greaterThan、lessThan

1
2
3
4
5
6
//1.构造查询所有属性的select语句
CriteriaQuery<Book> select = criteriaQuery.select(root);
//2.构造 price>70 的where子句
criteriaQuer.where(criteriaBuilder.lessThan(root.get("price"),"70"));
// 同理下句含义为 price<70 的where子句
criteriaQuer.where(criteriaBuilder.greaterThan(root.get("price"),"70"));

不在举其他例子,分析上述几种条件查询,可以发现:

  1. AbstractQuery提供了where()方法,而CriteriaQuery继承了AbstractQuery提供了where,所以直接使用criteriaQuer.where(),即可开启where语句;
  2. 所有的条件语句都在CriteriaBuilder接口中,可以通过criteriaBuilder对象调用各种对比方法,参数接收一个属性名,和需要对比的值。
  3. 如果需要有多个查询条件怎么办?
    通过查看接口源码,发现where方法的参数为(Predicate… restrictions),可接受多个Predicate对象,所以得到如下写法:
1
2
//直接在where方法中,构造多个条件,对应SQL:where price>70 and price <80
criteriaQuer.where(criteriaBuilder.greaterThan(root.get("price"),"70"),criteriaBuilder.lessThan(root.get("price"),"80"));

ORDER BY

相比where,排序就显得十分简单

1
2
3
4
5
6
//1.构造查询所有属性的select语句
CriteriaQuery<Book> select = criteriaQuery.select(root);
//2.构造按price升序的order by子句,对应SQL:order by price asc
criteriaQuer.orderBy(criteriaBuilder.asc(root.get("price")));
// 同理下句对应SQL:order by price desc
criteriaQuer.orderBy(criteriaBuilder.desc(root.get("price")));

GROUP BY

1
2
3
4
//1.查询:select bookname,count(*)
CriteriaQuery<Book> select = criteriaQuery.multiselect(root.get("bookname"),criteriaBuilder.count(root));
//2.构造按price升序的orderby子句,对应SQL:group by bookname
criteriaQuer.groupBy(root.get("bookname"));

HAVING

待续…