SpringBoot动态查询 Specification使用

有时候需要用到动态查询。动态查询 Specification  使用需实现接口JpaSpecificationExecutor

 1 package com.hik.dao;
 2
 3 import java.util.List;
 4
 5 import org.springframework.data.jpa.repository.JpaRepository;
 6 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 7 import org.springframework.data.jpa.repository.Query;
 8
 9 import com.hik.entity.Book;
10
11 /**
12  * 图书Dao接口
13  * @author jed
14  *
15  */
16 public interface BookDao extends JpaRepository<Book, Integer>,JpaSpecificationExecutor<Book> {
17
18     //Hql语句查询
19     @Query("select b from Book b where b.bookName like %?1%")
20     public List<Book> findByBookName(String bookName);
21
22     //本地sql语句查询
23     @Query(value="select * from t_book order by RAND() limit ?1",nativeQuery=true)
24     public List<Book> randomList(Integer n);
25 }

JpaSpecificationExecutor接口方法

 1 /*
 2  * Copyright 2008-2011 the original author or authors.
 3  *
 4  * Licensed under the Apache License, Version 2.0 (the "License");
 5  * you may not use this file except in compliance with the License.
 6  * You may obtain a copy of the License at
 7  *
 8  *      http://www.apache.org/licenses/LICENSE-2.0
 9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.springframework.data.jpa.repository;
17
18 import java.util.List;
19
20 import org.springframework.data.domain.Page;
21 import org.springframework.data.domain.Pageable;
22 import org.springframework.data.domain.Sort;
23 import org.springframework.data.jpa.domain.Specification;
24
25 /**
26  * Interface to allow execution of {@link Specification}s based on the JPA criteria API.
27  *
28  * @author Oliver Gierke
29  */
30 public interface JpaSpecificationExecutor<T> {
31
32     /**
33      * Returns a single entity matching the given {@link Specification}.
34      *
35      * @param spec
36      * @return
37      */
38     T findOne(Specification<T> spec);
39
40     /**
41      * Returns all entities matching the given {@link Specification}.
42      *
43      * @param spec
44      * @return
45      */
46     List<T> findAll(Specification<T> spec);
47
48     /**
49      * Returns a {@link Page} of entities matching the given {@link Specification}.
50      *
51      * @param spec
52      * @param pageable
53      * @return
54      */
55     Page<T> findAll(Specification<T> spec, Pageable pageable);
56
57     /**
58      * Returns all entities matching the given {@link Specification} and {@link Sort}.
59      *
60      * @param spec
61      * @param sort
62      * @return
63      */
64     List<T> findAll(Specification<T> spec, Sort sort);
65
66     /**
67      * Returns the number of instances that the given {@link Specification} will return.
68      *
69      * @param spec the {@link Specification} to count instances for
70      * @return the number of instances
71      */
72     long count(Specification<T> spec);
73 }

Specification接口

 1 /*
 2  * Copyright 2008-2017 the original author or authors.
 3  *
 4  * Licensed under the Apache License, Version 2.0 (the "License");
 5  * you may not use this file except in compliance with the License.
 6  * You may obtain a copy of the License at
 7  *
 8  *      http://www.apache.org/licenses/LICENSE-2.0
 9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.springframework.data.jpa.domain;
17
18 import javax.persistence.criteria.CriteriaBuilder;
19 import javax.persistence.criteria.CriteriaQuery;
20 import javax.persistence.criteria.Predicate;
21 import javax.persistence.criteria.Root;
22
23 /**
24  * Specification in the sense of Domain Driven Design.
25  *
26  * @author Oliver Gierke
27  * @author Thomas Darimont
28  * @author Krzysztof Rzymkowski
29  */
30 public interface Specification<T> {
31
32     /**
33      * Creates a WHERE clause for a query of the referenced entity in form of a {@link Predicate} for the given
34      * {@link Root} and {@link CriteriaQuery}.
35      *
36      * @param root
37      * @param query
38      * @return a {@link Predicate}, may be {@literal null}.
39      */
40     Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
41 }

BookDao接口类:

 1 package com.hik.dao;
 2
 3 import java.util.List;
 4
 5 import org.springframework.data.jpa.repository.JpaRepository;
 6 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 7 import org.springframework.data.jpa.repository.Query;
 8
 9 import com.hik.entity.Book;
10
11 /**
12  * 图书Dao接口
13  * @author jed
14  *
15  */
16 public interface BookDao extends JpaRepository<Book, Integer>,JpaSpecificationExecutor<Book> {
17
18     //Hql语句查询
19     @Query("select b from Book b where b.bookName like %?1%")
20     public List<Book> findByBookName(String bookName);
21
22     //本地sql语句查询
23     @Query(value="select * from t_book order by RAND() limit ?1",nativeQuery=true)
24     public List<Book> randomList(Integer n);
25 }

BookController类

  1 package com.hik.Controller;
  2
  3 import java.util.List;
  4
  5 import javax.annotation.Resource;
  6 import javax.persistence.criteria.CriteriaBuilder;
  7 import javax.persistence.criteria.CriteriaQuery;
  8 import javax.persistence.criteria.Predicate;
  9 import javax.persistence.criteria.Root;
 10
 11 import org.springframework.data.jpa.domain.Specification;
 12 import org.springframework.stereotype.Controller;
 13 import org.springframework.web.bind.annotation.GetMapping;
 14 import org.springframework.web.bind.annotation.PathVariable;
 15 import org.springframework.web.bind.annotation.PostMapping;
 16 import org.springframework.web.bind.annotation.RequestMapping;
 17 import org.springframework.web.bind.annotation.RequestMethod;
 18 import org.springframework.web.bind.annotation.ResponseBody;
 19 import org.springframework.web.servlet.ModelAndView;
 20
 21 import com.hik.dao.BookDao;
 22 import com.hik.entity.Book;
 23
 24 /**
 25  * Book控制类
 26  * @author jed
 27  *
 28  */
 29 @Controller
 30 @RequestMapping("/book")
 31 public class BookController {
 32
 33     @Resource
 34     private BookDao bookDao;
 35
 36     /**
 37      * 查询所有图书
 38      * @return
 39      */
 40     @RequestMapping(value="/list")
 41     public ModelAndView list() {
 42         ModelAndView mav = new ModelAndView ();
 43         mav.addObject("bookList", bookDao.findAll());
 44         mav.setViewName("bookList");
 45         return mav;
 46     }
 47
 48     /**
 49      * 根据条件动态查询
 50      * @param book
 51      * @return
 52      */
 53     @RequestMapping(value="/list2")
 54     public ModelAndView list2(Book book) {
 55         ModelAndView mav = new ModelAndView();
 56         List<Book> bookList = bookDao.findAll(new Specification<Book>() {
 57
 58             @Override
 59             public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
 60                 Predicate predicate= cb.conjunction();
 61                 if(book!=null) {
 62                     if(book.getBookName()!=null && !"".equals(book.getBookName())) {
 63                         predicate.getExpressions().add(cb.like(root.get("bookName"), "%"+book.getBookName()+"%"));
 64                     }
 65                 }
 66                 return predicate;
 67             }
 68
 69         });
 70         mav.addObject("bookList",bookList);
 71         mav.setViewName("bookList");
 72         return mav;
 73     }
 74
 75     /**
 76      * 添加图书
 77      * @param book
 78      * @return
 79      */
 80     @RequestMapping(value="/add", method=RequestMethod.POST)
 81     public String add(Book book) {
 82         bookDao.save(book);
 83         return "forward:/book/list";
 84     }
 85
 86     @GetMapping(value="/preUpdate/{id}")
 87     public ModelAndView preUpdate(@PathVariable("id") Integer id) {
 88         ModelAndView mav = new ModelAndView();
 89         mav.addObject("book", bookDao.getOne(id));
 90         mav.setViewName("bookUpdate");
 91         return mav;
 92     }
 93
 94     /**
 95      * 修改图书
 96      * @param book
 97      * @return
 98      */
 99     @PostMapping(value="/update")
100     public String update(Book book) {
101         bookDao.save(book);
102         return "forward:/book/list";
103     }
104
105     /**
106      * 删除图书
107      * @param id
108      * @return
109      */
110     @RequestMapping(value="/delete",method = RequestMethod.GET)
111     public String delete(Integer id) {
112         bookDao.delete(id);
113         return "forward:/book/list";
114     }
115
116     @ResponseBody
117     @GetMapping(value="/queryByName")
118     public List<Book> queryByName() {
119         return bookDao.findByBookName("思想");
120     }
121
122     @ResponseBody
123     @GetMapping(value="/randomList")
124     public List<Book> randomList(){
125         return bookDao.randomList(2);
126     }
127 }

bookList.ftl

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta charset="UTF-8">
 5 <title>图书管理页面</title>
 6 </head>
 7 <body>
 8 <a href="/bookAdd.html">添加图书</a></br>
 9 <form method="post" action="/book/list2">
10     图书名称:<input type="text" name="bookName" />&nbsp;
11     <input type="submit" value="搜索"/>
12 </form>
13     <table>
14         <tr>
15             <th>编号</th>
16             <th>图书名称</th>
17             <th>操作</th>
18         </tr>
19         <#list bookList as book>
20         <tr>
21             <td>${book.id}</td>
22             <td>${book.bookName}</td>
23             <td>
24                 <a href="/book/preUpdate/${book.id}">修改</a>
25                 <a href="/book/delete?id=${book.id}">删除</a>
26             </td>
27         </tr>
28        </#list>
29     </table>
30 </body>
31 </html>

访问:http://localhost:8888/book/list2

输入查询条件,点击搜索

查询结果:

原文地址:https://www.cnblogs.com/jedjia/p/Specification.html

时间: 2024-10-27 07:42:17

SpringBoot动态查询 Specification使用的相关文章

SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法

首先谢谢大佬的简书文章:http://www.jianshu.com/p/45ad65690e33# 这篇文章中讲的是spring中使用spring data jpa,使用了xml配置文件.我现在使用的是spring boot ,没有了xml文件配置就方便多了.我同样尝试了两种方式,也都是简单的查询,需要更复杂的查询,还需要我研究研究.往下看,需要先配置springboot的开发环境,需要大致了解springboot,这里可以看下面两篇文章: springboot 项目新建 springboot

Spring data jpa 实现简单动态查询的通用Specification方法

本篇前提: SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法 这篇文章中的第二种方法 实现Specification 这块的方法 只适用于一个对象针对某一个固定字段查询,下面通过泛型改写了这个方法: import java.util.List; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import j

spring data jpa封装specification实现简单风格的动态查询

github:https://github.com/peterowang/spring-data-jpa-demo Spring Data JPA已经帮助我们很大程度上简化了我们的查询操作,我们甚至只要写一个接口,然后单纯的写一些方法就可以完成各式各样的查询,但是对于我们程序设计人员而言,总希望所有的查询变得更加的简单方便,为了给程序人员进行再一次的封装,Spring Data JPA提供了Specification的方式进行查询,在前面的内容已经演示过这种查询了,但是,我们在使用的过程中发现这

spring data jpa的动态查询封装(转)

最近使用spring data jpa做了两个项目,对于动态查询的不友好做了个类似hibernate的封装,记录也分享下 首先定义一个所有条件的容器,继承Specification Java代码   /** * 定义一个查询条件容器 * @author lee * * @param <T> */ public class Criteria<T> implements Specification<T>{ private List<Criterion> crit

JPA动态查询封装

一.定义一个查询条件容器 /** * 定义一个查询条件容器 * * @param <T> */ public class Criteria<T> implements Specification<T> { private List<Criterion> criterions = new ArrayList<Criterion>(); public Predicate toPredicate(Root<T> root, Criteria

Hibernate与Jpa的关系,以及使用分页和动态查询

最近由于项目调动,我去了使用JPA的项目组, 因为之前的项目组使用MyBatis,所以一时间关于JPA和Hibernate的知识体系记得不熟,导致出现了混乱:在网上看到了这篇文章,终于解决了我心中的疑惑:JPA是一种规范,Hibernate实现了这种规范 . 这篇短小精悍的文章给了我很多的启发,于是,我把它"复制"到了本文! http://blog.sina.com.cn/s/blog_5f1619e80100yoxz.html 我知道Jpa是一种规范,而Hibernate是它的一种实

Spring Data JPA 的 Specifications动态查询

主要的结构: 有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询.相比JPQL,其优势是类型安全,更加的面向对象. import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import o

22 Specifications动态查询

Specifications动态查询 有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询.相比JPQL,其优势是类型安全,更加的面向对象. import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageab

Entity Framework多表多条件动态查询

方式一  Linq To Entity形式: /// <summary> /// 查询的数据 /// </summary> /// <param name="order">升序asc(默认)还是降序desc</param> /// <param name="sort">排序字段</param> /// <param name="search">查询条件</p