动态查询

一.概述

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值