您的位置:首页 > 编程语言 > Java开发

Spring Data JPA进阶——Specifications和Querydsl

2018-01-23 16:55 387 查看


spring data jpa 通过创建方法名来做查询,只能做简单的查询,那如果我们要做复杂一些的查询呢,多条件分页怎么办,这里,spring data jpa为我们提供了JpaSpecificationExecutor接口,只要简单实现toPredicate方法就可以实现复杂的查询
1.首先让我们的接口继承于JpaSpecificationExecutor
public interface TaskDao extends JpaSpecificationExecutor<Task>{

}
1
2
3
2.JpaSpecificationExecutor提供了以下接口
public interface JpaSpecificationExecutor<T> {

T findOne(Specification<T> spec);

List<T> findAll(Specification<T> spec);

Page<T> findAll(Specification<T> spec, Pageable pageable);

List<T> findAll(Specification<T> spec, Sort sort);

long count(Specification<T> spec);
}
1
2
3
4
5
6
7
8
9
10
11
12
其中Specification就是需要我们传进去的参数,它是一个接口
public interface Specification<T> {

Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
}
1
2
3
4
5
6
提供唯一的一个方法toPredicate,我们只要按照JPA 2.0 criteria api写好查询条件就可以了,关于JPA 2.0 criteria api的介绍和使用,欢迎参考 
http://blog.csdn.net/dracotianlong/article/details/28445725 
http://developer.51cto.com/art/200911/162722.htm
2.接下来我们在service bean 
@Service
public class TaskService {

@Autowired TaskDao taskDao ;

/**
* 复杂查询测试
* @param page
* @param size
* @return
*/
public Page<Task> findBySepc(int page, int size){

PageRequest pageReq = this.buildPageRequest(page, size);
Page<Task> tasks = this.taskDao.findAll(new MySpec(), pageReq);

return tasks;

}

/**
* 建立分页排序请求
* @param page
* @param size
* @return
*/
private PageRequest buildPageRequest(int page, int size) {
Sort sort = new Sort(Direction.DESC,"createTime");
return new PageRequest(page,size, sort);
}

/**
* 建立查询条件
* @author liuxg
* @date 2016年3月30日 下午2:04:39
*/
private class MySpec implements Specification<Task>{

@Override
public Predicate toPredicate(Root<Task> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

//1.混合条件查询
/*Path<String> exp1 = root.get("taskName");
Path<Date>  exp2 = root.get("createTime");
Path<String> exp3 = root.get("taskDetail");
Predicate predicate = cb.and(cb.like(exp1, "%taskName%"),cb.lessThan(exp2, new Date()));
return cb.or(predicate,cb.equal(exp3, "kkk"));

类似的sql语句为:
Hibernate:
select
count(task0_.id) as col_0_0_
from
tb_task task0_
where
(
task0_.task_name like ?
)
and task0_.create_time<?
or task0_.task_detail=?
*/

//2.多表查询
/*Join<Task,Project> join = root.join("project", JoinType.INNER);
Path<String> exp4 = join.get("projectName");
return cb.like(exp4, "%projectName%");

Hibernate:
select
count(task0_.id) as col_0_0_
from
tb_task task0_
inner join
tb_project project1_
on task0_.project_id=project1_.id
where
project1_.project_name like ?*/
return null ;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
3.实体类task代码如下
@Entity
@Table(name = "tb_task")
public class Task {

private Long id ;
private String taskName ;
private Date createTime ;
private Project project;
private String taskDetail ;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}

@Column(name = "task_name")
public String getTaskName() {
return taskName;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}

@Column(name = "create_time")
@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}

@Column(name = "task_detail")
public String getTaskDetail() {
return taskDetail;
}
public void setTaskDetail(String taskDetail) {
this.taskDetail = taskDetail;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "project_id")
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
通过重写toPredicate方法,返回一个查询 Predicate,spring data jpa会帮我们进行查询。
也许你觉得,每次都要写一个类来实现Specification很麻烦,那或许你可以这么写
public class TaskSpec {

public static Specification<Task> method1(){

return new Specification<Task>(){
@Override
public Predicate toPredicate(Root<Task> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return null;
}

};
}

public static Specification<Task> method2(){

return new Specification<Task>(){
@Override
public Predicate toPredicate(Root<Task> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return null;
}

};
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
那么用的时候,我们就这么用
Page<Task> tasks = this.taskDao.findAll(TaskSpec.method1(), pageReq);
1
JpaSpecificationExecutor的介绍就到这里,下次再看看怎么通过写hql或者sql语句来进行查询
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: