動態查詢

一.概述

JpaSpecificationExecuto是通過方法的參數類型進行查詢。

二.常用方法

T findOne(Specification spec);  //查詢單個對象

List findAll(Specification spec);  //查詢列表

	//查詢全部,分頁

	//pageable:分頁參數

	//返回值:分頁pageBean(page:是springdatajpa提供的)

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

	//查詢列表

	//Sort:排序參數

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

	long count(Specification<T> spec);//統計查詢

三.常用對象【查詢條件】

  • Specification :查詢條件

      自定義我們自己的Specification實現類
    
      	實現
    
      		//root:查詢的根對象(查詢的任何屬性都可以從根對象中獲取)
    
      		//CriteriaQuery:頂層查詢對象,自定義查詢方式(瞭解:一般不用)
    
      		//CriteriaBuilder:查詢的構造器,封裝了很多的查詢條件
    
Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb); //封裝查詢條件

四.範例

1.測試類

(1)代碼塊

import cn.dao.CustomerDao;
import cn.pojo.Customer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.persistence.criteria.*;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpecTest {
    @Autowired
    private CustomerDao customerDao;
    @Test
    /**
     * 查詢單個對象
     */
    public void test1(){
        //設置查詢的條件
        /**
         * 自定義查詢條件
         *  1.實現了Specification接口,泛型是操作的實體類對象
         *  2.實現了toPredicate方法(構造查詢條件)
         *  3.需要藉助方法的倆個參數
         *      Root:獲取需要查詢的對象屬性
         *      CriteriaBuilder:構造查詢條件,內部封裝了很多的查詢條件(模糊查詢,精準查詢等)
         *
         *  案例:根據客戶名稱查詢,查詢客戶名爲李明的客戶
         *      查詢條件:
         *          1.查詢方法:CriteriaBuilder對象
         *          2.比較的屬性名稱:Root對象
         */
        Specification<Customer> spec = new Specification<Customer>() {
            @Override
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //1.獲取比較的屬性
                Path<Object> custName = root.get("custName");//參數是實體類的屬性名稱
                //2.構造查詢方式:select * from cst_customer where cust_name = "小李"
                //方法:equal是查詢條件
                //參數一:是path對象,比較的屬性
                //參數二:是比較的取值
                Predicate predicate = criteriaBuilder.equal(custName, "小李");
                return predicate;
            }
        };
        //使用的JpaSpecificationExecuto類中的findOne
        Customer customer = customerDao.findOne(spec);
        //驗證結果
        System.out.println(customer);
    }
    @Test
    /**
     * lambda表達式實現
     */
    public void test2(){
        Specification<Customer> spec = (Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder)->{
            //1.獲取比較的屬性
            Path<Object> custName = root.get("custName");//參數是實體類的屬性名稱
            //2.構造查詢方式:select * from cst_customer where cust_name = "小李"
            //方法:equal是查詢條件
            //參數一:是path對象,比較的屬性
            //參數二:是比較的取值
            Predicate predicate = criteriaBuilder.equal(custName, "小李");
            return predicate;
        };
        //使用的JpaSpecificationExecuto類中的findOne
        Customer customer = customerDao.findOne(spec);
        //驗證結果
        System.out.println(customer);
    }
    @Test
    /**
     * 多條件查詢
     */
    public void test3(){
        Specification<Customer> spec = new Specification<Customer>() {
            @Override
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //1.獲取比較的屬性
                Path<Object> custName = root.get("custName");//參數是實體類的屬性名稱
                Path<Object> custId = root.get("custId");//參數是實體類的屬性名稱
                //2.構造查詢方式:精準查詢
                // select * from cst_customer where cust_name = "小李" and cust_id = 1l
                //2.1查詢條件一
                Predicate predicate = criteriaBuilder.equal(custName, "小李");
                //2.2查詢條件二
                Predicate predicate2 = criteriaBuilder.equal(custId, 1l);
                //2.3組合條件or,and
                Predicate and = criteriaBuilder.and(predicate, predicate2);//以與的形式拼接條件
//                criteriaBuilder.or();//以或的形式拼接條件
                return and;
            }
        };

        //使用的JpaSpecificationExecuto類中的findOne
        Customer customer = customerDao.findOne(spec);
        //驗證結果
        System.out.println(customer);
    }
    @Test
    /**
     * 模糊查詢
     */
    public void test4(){
        Specification<Customer> spec = new Specification<Customer>() {
            @Override
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //1.獲取比較的屬性
                Path<Object> custName = root.get("custName");//參數是實體類的屬性名稱
                //2.構造查詢方式:精準查詢
                // select * from cst_customer where cust_name like "%李%"
                //2.1查詢條件
                //模糊參數的參數一爲字段的數據類型(需要通過Path對象【實體類對象】的as方法進行設置)
                //模糊參數的參數二爲字段的取值
                Predicate predicate = criteriaBuilder.like(custName.as(String.class),"%李%");
                return predicate;
            }
        };

        //使用的JpaSpecificationExecuto類中的findOne
        List<Customer> list = customerDao.findAll(spec);
        for(Customer customer : list) {
            //驗證結果
            System.out.println(customer);
        }
    }
    @Test
    /**
     * 排序查詢
     */
    public void test5(){
        Specification<Customer> spec = new Specification<Customer>() {
            @Override
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<Object> custName = root.get("custName");//參數是實體類的屬性名稱
                Predicate predicate = criteriaBuilder.like(custName.as(String.class),"%李%");
                return predicate;
            }
        };
        //設置排序
        //參數一,設置排序
        //參數二:排序的屬性名
        Sort sort = new Sort(Sort.Direction.DESC,"custId");//實體類的屬性名:custId
        List<Customer> list = customerDao.findAll(spec,sort);
        for(Customer customer : list) {
            //驗證結果
            System.out.println(customer);
        }
    }
    @Test
    /**
     * 分頁查詢
     * findAll方法
     *      參數一:查詢條件
     *      參數二:分頁信息,
     *          屬性有分頁條數,分頁起始點的記錄
     */
    public void test6(){
        Specification<Customer> spec = new Specification<Customer>() {
            @Override
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<Object> custName = root.get("custName");//參數是實體類的屬性名稱
                Predicate predicate = criteriaBuilder.like(custName.as(String.class),"%李%");
                return predicate;
            }
        };
        //創建分頁對象
        //參數一:當前查詢的頁數【起始點】
        //參數二:每頁顯示的記錄數
        Pageable pageable = new PageRequest(0,2);
        Page<Customer> page = customerDao.findAll(spec, pageable);      //有查詢條件使用的方法
//        Page<Customer> page = customerDao.findAll(null, pageable);    //沒有查詢條件使用的方法
        System.out.println(page.getTotalElements());//獲取每頁顯示記錄的個數方法:getTotalElements()
        System.out.println(page.getContent());//獲取查詢的結果集getContent()
        System.out.println(page.getTotalPages());//獲取總頁數getTotalPages()
    }
}

(2)返回值爲單個對象的查詢條件

圖片

圖片

(3)多條件查詢

圖片

(4)模糊查詢

圖片

(5)排序查詢

圖片

(6)分頁查詢

圖片

圖片

2.pojo實體類

(1)代碼塊

@Entity
@Table(name = "cst_customer")
public class Customer implements Serializable {
    /**
     * 主鍵聲明
     */
    @Id
    /*
    GeneratedValue聲明主鍵的自增加模式
        IDENTITY:是底層數據庫必須支持自動增長
        SEQUENCE:是底層數據庫必須支持序列
        TABLE:jpa提供的一種機制,通過一張數據庫表的形式完成主鍵增長
        AUTO:自動選擇類型IDENTITY或SEQUENCE
    */
    @GeneratedValue(strategy = GenerationType.TABLE)
    @Column(name="cust_id")
    private Long custId;
    @Column(name="cust_name") //指定和表中cust_name字段的映射關係
    private String custName;
    @Column(name="cust_source")//指定和表中cust_source字段的映射關係
    private String custSource;
    @Column(name="cust_industry")//指定和表中cust_industry字段的映射關係
    private String custIndustry;
    @Column(name="cust_level")//指定和表中cust_level字段的映射關係
    private String custLevel;
    @Column(name="cust_address")//指定和表中cust_address字段的映射關係
    private String custAddress;
    @Column(name="cust_phone")//指定和表中cust_phone字段的映射關係
    private String custPhone;
    @Override
    public String toString() {
        return "Customer{" +
                "custId=" + custId +
                ", custName='" + custName + '\'' +
                ", custSource='" + custSource + '\'' +
                ", custIndustry='" + custIndustry + '\'' +
                ", custLevel='" + custLevel + '\'' +
                ", custAddress='" + custAddress + '\'' +
                ", custPhone='" + custPhone + '\'' +
                '}';
    }
    public Long getCustId() {
        return custId;
    }
    public void setCustId(Long custId) {
        this.custId = custId;
    }
    public String getCustName() {
        return custName;
    }
    public void setCustName(String custName) {
        this.custName = custName;
    }
    public String getCustSource() {
        return custSource;
    }
    public void setCustSource(String custSource) {
        this.custSource = custSource;
    }
    public String getCustIndustry() {
        return custIndustry;
    }
    public void setCustIndustry(String custIndustry) {
        this.custIndustry = custIndustry;
    }
    public String getCustLevel() {
        return custLevel;
    }
    public void setCustLevel(String custLevel) {
        this.custLevel = custLevel;
    }
    public String getCustAddress() {
        return custAddress;
    }
    public void setCustAddress(String custAddress) {
        this.custAddress = custAddress;
    }
    public String getCustPhone() {
        return custPhone;
    }
    public void setCustPhone(String custPhone) {
        this.custPhone = custPhone;
    }
}

(2)範例

圖片

圖片

3.dao層

圖片

4.jpa配置文件

圖片

圖片

圖片

圖片

五.源碼

day03.rar

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章