SpringBoot动态查询 Specification使用

Posted 心和梦的方向

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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>
View Code

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

输入查询条件,点击搜索

查询结果:

 

以上是关于SpringBoot动态查询 Specification使用的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot-- 动态数据源

springboot JPA 一对多关联查询 ,动态复杂查询 去除重复数据 in语句使用

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

springboot2.x+MyBatis-Plus+mysql5.7 动态拼接sql语句 分页查询 自定义sql 查询条件 分组 排序

springboot2.x+MyBatis-Plus+mysql5.7 动态拼接sql语句 分页查询 自定义sql 查询条件 分组 排序

springboot对于数据源的动态管理实践