spring boot学习(5) SpringBoot 之Spring Data Jpa 支持(2)

第三节:自定义查询@Query
有时候复杂sql使用hql方式无法查询,这时候使用本地查询,使用原生sql的方式;
 
第四节:动态查询Specification 使用
什么时候用呢?比如搜索有很多条件,有时候用户只填了一个,有时候填很多,不确定条件的数目,这时候动态判断,拼接sql,使用Specification
 
下面是例子讲解:
com.cy.dao.BookDao.java:
package com.cy.dao;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;

import com.cy.entity.Book;

public interface BookDao extends JpaRepository<Book, Integer>, JpaSpecificationExecutor<Book>{
    
    // ?1代表第一个参数
    // 这种是hql形式
    @Query("select b from Book b where b.name like %?1%")
    public List<Book> findByName(String name);
    
    /**
     * 随机查询n条图书
     * nativeQuery默认是hql查询,这里true表示使用本地查询,就是原生的sql方式
     * @param n
     * @return
     */
    @Query(value="select * from t_book order by RAND() limit ?1", nativeQuery=true)
    public List<Book> randomList(Integer n);
    
}

注意:

上面BookDao继承了JpaSpecificationExecutor,这个接口里面才可以动态条件查询;继承这个是为了动态查询Specification 使用

BookController:

package com.cy.controller;

import java.util.List;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.cy.dao.BookDao;
import com.cy.entity.Book;

@Controller
@RequestMapping("/book")
public class BookController {
    
    @Resource
    private BookDao bookDao;
    /**
     * 根据条件动态查询
     */
    @RequestMapping("/list2")
    public ModelAndView list2(Book book){
        ModelAndView mav = new ModelAndView();
        List<Book> bookList = bookDao.findAll(new Specification<Book>(){
            @Override
            public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate predicate = cb.conjunction();
                if(book!=null){
                    if(book.getName()!=null && !"".equals(book.getName())){
                        predicate.getExpressions().add(cb.like(root.get("name"), "%"+book.getName()+"%"));
                    }
                    if(book.getAuthor()!=null && !"".equals(book.getAuthor())){
                        predicate.getExpressions().add(cb.like(root.get("author"), "%"+book.getAuthor()+"%"));
                    }
                }
                return predicate;
            }
        });
        mav.addObject("book", book);
        mav.addObject("bookList", bookList);
        mav.setViewName("bookList");
        return mav;
    }
    
/**
     * 根据名字查找图书
     * @return
     */
    @ResponseBody
    @GetMapping("/queryByName")
    public List<Book> queryByName(){
        return bookDao.findByName("编程");
    }
    
    //随机查询一条图书
    @ResponseBody
    @GetMapping("/randomList")
    public List<Book> randomList(){
        return bookDao.randomList(1);
    }
}

src/main/resouces/templates/bookList.ftl里面增加两个搜索框:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图书管理</title>
</head>
<body>
<a href="/bookAdd.html">添加</a>
<!-- 这个book返回来是为了搜素框回显使用的 -->
<form method="post" action="/book/list2"> 图书名称:<input type="text" name="name" value="${book.name}"/>&nbsp; 图书作者:<input type="text" name="author" value="${book.author}" />&nbsp; <input type="submit" value="搜索"/> </form> <table> <tr> <th>编号</th> <th>图书名称</th> <th>图书作者</th> <th>操作</th> </tr> <#list bookList as book> <tr> <td>${book.id}</td> <td>${book.name}</td> <td>${book.author}</td> <td> <a href="/book/preUpdate/${book.id}">修改</a> <a href="/book/delete?id=${book.id}">删除</a> </td> </tr> </#list> </table> </body> </html>

测试:

数据表情况:

mysql> select * from t_book;
+----+--------+--------------+
| id | author | name         |
+----+--------+--------------+
|  2 | 作者1  | 图书五       |
|  7 | 外国佬 | java编程思想 |
|  8 | 王五   | 大刀王五     |
|  9 | 有人   | php编程      |
+----+--------+--------------+

1.http://localhost/book/queryByName显示:  [{"id":7,"name":"java编程思想","author":"外国佬"},{"id":9,"name":"php编程","author":"有人"}]

2.http://localhost/book/randomList,  随机查询一条图书;

3.http://localhost/book/list2,搜索图书名称:五:

 
原文地址:https://www.cnblogs.com/tenWood/p/8644304.html