SpringDataJpa的Specification查询

spring data jpa 通过创建方法名来做查询,只能做简单的查询,那如果我们要做复杂一些的查询呢,多条件分页怎么办,这里,spring data jpa为我们提供了JpaSpecificationExecutor接口,只要简单实现toPredicate方法就可以实现复杂的查询

1.首先让我们的接口继承于JpaSpecificationExecutor


    
    
  1. public interface TaskDao extends JpaSpecificationExecutor<Task>{
  2. }
  • 1
  • 2
  • 3


2.JpaSpecificationExecutor提供了以下接口


    
    
  1. public interface JpaSpecificationExecutor<T> {
  2. T findOne(Specification<T> spec);
  3. List<T> findAll(Specification<T> spec);
  4. Page<T> findAll(Specification<T> spec, Pageable pageable);
  5. List<T> findAll(Specification<T> spec, Sort sort);
  6. long count(Specification<T> spec);
  7. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

其中Specification就是需要我们传进去的参数,它是一个接口


    
    
  1. public interface Specification<T> {
  2. Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
  3. }
  • 1
  • 2
  • 3
  • 4

提供唯一的一个方法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


    
    
  1. @Service
  2. public class TaskService {
  3. @Autowired TaskDao taskDao ;
  4. /**
  5. * 复杂查询测试
  6. * @param page
  7. * @param size
  8. * @return
  9. */
  10. public Page<Task> findBySepc(int page, int size){
  11. PageRequest pageReq = this.buildPageRequest(page, size);
  12. Page<Task> tasks = this.taskDao.findAll( new MySpec(), pageReq);
  13. return tasks;
  14. }
  15. /**
  16. * 建立分页排序请求
  17. * @param page
  18. * @param size
  19. * @return
  20. */
  21. private PageRequest buildPageRequest(int page, int size) {
  22. Sort sort = new Sort(Direction.DESC, "createTime");
  23. return new PageRequest(page,size, sort);
  24. }
  25. /**
  26. * 建立查询条件
  27. * @author liuxg
  28. * @date 2016年3月30日 下午2:04:39
  29. */
  30. private class MySpec implements Specification<Task>{
  31. @Override
  32. public Predicate toPredicate(Root<Task> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
  33. //1.混合条件查询
  34. /*Path<String> exp1 = root.get("taskName");
  35. Path<Date> exp2 = root.get("createTime");
  36. Path<String> exp3 = root.get("taskDetail");
  37. Predicate predicate = cb.and(cb.like(exp1, "%taskName%"),cb.lessThan(exp2, new Date()));
  38. return cb.or(predicate,cb.equal(exp3, "kkk"));
  39. 类似的sql语句为:
  40. Hibernate:
  41. select
  42. count(task0_.id) as col_0_0_
  43. from
  44. tb_task task0_
  45. where
  46. (
  47. task0_.task_name like ?
  48. )
  49. and task0_.create_time<?
  50. or task0_.task_detail=?
  51. */
  52. //2.多表查询
  53. /*Join<Task,Project> join = root.join("project", JoinType.INNER);
  54. Path<String> exp4 = join.get("projectName");
  55. return cb.like(exp4, "%projectName%");
  56. Hibernate:
  57. select
  58. count(task0_.id) as col_0_0_
  59. from
  60. tb_task task0_
  61. inner join
  62. tb_project project1_
  63. on task0_.project_id=project1_.id
  64. where
  65. project1_.project_name like ?*/
  66. return null ;
  67. }
  68. }
  69. }
  • 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代码如下


    
    
  1. @Entity
  2. @Table(name = "tb_task")
  3. public class Task {
  4. private Long id ;
  5. private String taskName ;
  6. private Date createTime ;
  7. private Project project;
  8. private String taskDetail ;
  9. @Id
  10. @GeneratedValue(strategy = GenerationType.IDENTITY)
  11. public Long getId() {
  12. return id;
  13. }
  14. public void setId(Long id) {
  15. this.id = id;
  16. }
  17. @Column(name = "task_name")
  18. public String getTaskName() {
  19. return taskName;
  20. }
  21. public void setTaskName(String taskName) {
  22. this.taskName = taskName;
  23. }
  24. @Column(name = "create_time")
  25. @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
  26. public Date getCreateTime() {
  27. return createTime;
  28. }
  29. public void setCreateTime(Date createTime) {
  30. this.createTime = createTime;
  31. }
  32. @Column(name = "task_detail")
  33. public String getTaskDetail() {
  34. return taskDetail;
  35. }
  36. public void setTaskDetail(String taskDetail) {
  37. this.taskDetail = taskDetail;
  38. }
  39. @ManyToOne(fetch = FetchType.LAZY)
  40. @JoinColumn(name = "project_id")
  41. public Project getProject() {
  42. return project;
  43. }
  44. public void setProject(Project project) {
  45. this.project = project;
  46. }
  47. }
  • 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


通过重写toPredicate方法,返回一个查询 Predicate,spring data jpa会帮我们进行查询。

也许你觉得,每次都要写一个类来实现Specification很麻烦,那或许你可以这么写


    
    
  1. public class TaskSpec {
  2. public static Specification<Task> method1(){
  3. return new Specification<Task>(){
  4. @Override
  5. public Predicate toPredicate(Root<Task> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
  6. return null;
  7. }
  8. };
  9. }
  10. public static Specification<Task> method2(){
  11. return new Specification<Task>(){
  12. @Override
  13. public Predicate toPredicate(Root<Task> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
  14. return null;
  15. }
  16. };
  17. }
  18. }
  • 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语句来进行查询

转自:http://blog.csdn.net/yingxiake/article/details/51014223

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值