@TOC~~~java
DAO接口继承的接口中有一个接口:JpaSpecificationExecutor
,在这个接口中有几个关键方法和对象对象:
public void specTest3() {
// 构造查询条件,null表示无条件
Specification spec = null;
// 构造分页对象,当前第一页,每页2条
Pageable pageable = PageRequest.of(0, 2);
// 执行查询操作
Page page = dao.findAll(spec, pageable);
System.out.println(page.getContent()); // 当前页数据
System.out.println(page.getTotalElements()); // 总条数
System.out.println(page.getTotalPages()); // 总页数
}
**`Sort`:排序对象**
构造排序对象,使用静态方法 `Sort.by(Sort.Direction,String... properties)`
第一个参数:`Direction`
* Sort.Direction.DESC 降序
* Sort.Direction.ASC 升序
第二个参数:`properties` 需要排序的属性名称
```java
// sql: select * from user_demo where user_age <> 0 order by user_age desc
@Test
public void specTest2() {
Specification<UserDemo> spec = new Specification<UserDemo>() {
@Override
public Predicate toPredicate(Root<UserDemo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Path<Object> userAge = root.get("userAge");
return criteriaBuilder.notEqual(userAge, 0);
}
};
Sort sort = Sort.by(Sort.Direction.DESC, "userAge");
List<UserDemo> list = dao.findAll(spec, sort);
for (UserDemo userDemo : list) {
System.out.println(userDemo);
}
}
DAO接口继承的接口中有一个接口:`JpaSpecificationExecutor`,在这个接口中有几个关键方法和对象对象:
**方法**
```java
// 查询单条
Optional<T> findOne(@Nullable Specification<T> var1);
// 查询所有
List<T> findAll(@Nullable Specification<T> var1);
// 查询所有,返回分页
Page<T> findAll(@Nullable Specification<T> var1, Pageable var2);
// 按照排序规则返回所有
List<T> findAll(@Nullable Specification<T> var1, Sort var2);
// 统计
long count(@Nullable Specification<T> var1);
```
**对象**
`Specification`:查询条件对象
在实现的的时候需要实现其中一个方法:`toPredicate`,其中有三个参数:`root`、`criteriaQuery`、`criteriaBuilder`
- root:查询的根对象(查询任何属性都可以从根对象中获取,方法`get(String name)`,这里的name指的是数据库字段对应的属性名,并非数据库字段名称)
- criteriaQuery:顶层查询对象,自定义查询方式(一般不用)
- criteriaBuilder:查询的构造器,内部封装了很多查询条件
```java
@Test
public void specTest1() {
/*
匿名内部类,自定义查询条件
1、实现 Specification 接口,提供泛型(查询的对象类型)
2、实现 toPredicate 方法(构造查询条件)
参数1:root - 获取需要查询的对象属性
参数2:criteriaQuery - ?
参数3:criteriaBuilder - 构造查询条件,内部封装了很多查询条件(例如模糊匹配,精准匹配)
sql:select * from user_demo where user_name = '张三' and user_age = 20
*/
Specification<UserDemo> specification = new Specification<UserDemo>() {
@Override
public Predicate toPredicate(Root<UserDemo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
// 1.获取比较的属性
Path<Object> userName = root.get("userName");
Path<Object> userAge = root.get("userAge");
// 2.构造查询条件执行并返回
Predicate p1 = criteriaBuilder.equal(userName, "张三");
Predicate p2 = criteriaBuilder.equal(userAge, 20);
// 3.将多个条件联系起来
return criteriaBuilder.and(p1, p2);
}
};
System.out.println(dao.findOne(specification));
}
```
**`criteriaBuilder`常用构造条件:**
```
between:between and
equal:相等 =
like:like
eq:equal(相等)
ne:not equal(不等)
gt:greater than(大于)
ge:greater than or equal(大于或等于)
lt:less than(小于)
le:less than or equal(小于或等于)
```
- `equal`:直接得到Path对象,然后进行比较
```java
Path<Object> userName = root.get("userName");
Predicate p = criteriaBuilder.equal(userName, "张三");
```
- `gt,ge,lt,le,like`:得到path对象,根据Path指定参数类型(path.as(class))字节码进行比较
```java
Path<Object> userName = root.get("userName");
Predicate p = criteriaBuilder.like(userName.as(String.class), "%张三%");
```
**`Pageable`:分页对象**
spring data jpa 中提供了1个分页查询方法:
```
Page<T> findAll(@Nullable Specification<T> var1, Pageable var2);
```
`@Nullable` 表示参数var1可以传入null
`Pageable`对象是一个接口,实现类为:org.springframework.data.domain.PageRequest,可以调用静态方法`PageRequest.of(int page, int size)`进行实例化,page表示当前页,从0开始,size表示每页查询数量
```java
@Test
public void specTest3() {
// 构造查询条件,null表示无条件
Specification<UserDemo> spec = null;
// 构造分页对象,当前第一页,每页2条
Pageable pageable = PageRequest.of(0, 2);
// 执行查询操作
Page<UserDemo> page = dao.findAll(spec, pageable);
System.out.println(page.getContent()); // 当前页数据
System.out.println(page.getTotalElements()); // 总条数
System.out.println(page.getTotalPages()); // 总页数
}
```
**`Sort`:排序对象**
构造排序对象,使用静态方法 `Sort.by(Sort.Direction,String... properties)`
第一个参数:`Direction`
- Sort.Direction.DESC 降序
- Sort.Direction.ASC 升序
第二个参数:`properties` 需要排序的属性名称
```java
// sql: select * from user_demo where user_age <> 0 order by user_age desc
@Test
public void specTest2() {
Specification<UserDemo> spec = new Specification<UserDemo>() {
@Override
public Predicate toPredicate(Root<UserDemo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Path<Object> userAge = root.get("userAge");
return criteriaBuilder.notEqual(userAge, 0);
}
};
Sort sort = Sort.by(Sort.Direction.DESC, "userAge");
List<UserDemo> list = dao.findAll(spec, sort);
for (UserDemo userDemo : list) {
System.out.println(userDemo);
}
}
```