package com.ytkj.entity;

import javax.persistence.*;
import java.io.Serializable;

/**
 *          @Entity
 *         	作用:指定当前类是实体类。
 *         @Table
 *         	作用:指定实体类和表之间的对应关系。
 *         	属性:
 *         		name:指定数据库表的名称
 *         @Id
 *         	作用:指定当前字段是主键。
 *         @GeneratedValue
 *         	作用:指定主键的生成方式。。
 *         	属性:
 *         		strategy :指定主键生成策略。
 *         @Column
 *         	作用:指定实体类属性和数据库表之间的对应关系
 *         	属性:
 *         		name:指定数据库表的列名称。
 *         		unique:是否唯一
 *         		nullable:是否可以为空
 *         		inserttable:是否可以插入
 *         		updateable:是否可以更新
 *         		columnDefinition: 定义建表时创建此列的DDL
 *         		secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字搭建开发环境[重点]
 *
 * 客户实体类
 *      配置映射关系
 *          实体类和表映射
 *          实体类属性和表字段映射
 */
@Entity
@Table(name = "cst_customer")
public class Customer implements Serializable {
    /**
     * 声明主键配置
     */
    @Id
    /**
     * 配置主键的生成策略
     */
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    /**
     * 指定实体类属性和数据库表之间的对应关系
     */
    @Column(name ="cust_id")
    private Long custId;//客户主键
    @Column(name = "cust_name")
    private String custName;//客户名称
    @Column(name ="cust_source" )
    private String custSource;//客户来源
    @Column(name = "cust_industry")
    private String custIndustry;//客户行业
    @Column(name ="cust_level")
    private String custLevel;//客户级别
    @Column(name ="cust_address")
    private String custAddress;//客户地址
    @Column(name = "cust_phone")
    private String 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;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "custId=" + custId +
                ", custName='" + custName + '\'' +
                ", custSource='" + custSource + '\'' +
                ", custIndustry='" + custIndustry + '\'' +
                ", custLevel='" + custLevel + '\'' +
                ", custAddress='" + custAddress + '\'' +
                ", custPhone='" + custPhone + '\'' +
                '}';
    }
}

  




Specifications动态查询 JpaSpecificationExecutor 方法列表 T findOne(Specification
<T> spec); //查询单个对象 List<T> findAll(Specification<T> 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); //封装查询条件

Demo

/**
 * JpaRepository<实体类类型,主键类型>:用来完成基本CRUD操作
 * JpaSpecificationExecutor<实体类类型>:用于复杂查询(分页等查询操作)
 */
public interface CustomerDao extends JpaRepository<Customer,Long>, JpaSpecificationExecutor<Customer> {


}

  

import com.ytkj.dao.CustomerDao;
import com.ytkj.entity.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;

/**
 * Specifications动态查询
 */
@RunWith(SpringJUnit4ClassRunner.class)//声明spring提供的单元测试环境
@ContextConfiguration(locations = "classpath:applicationContext.xml")//指定spring容器的配置信息
public class SpringdatajpaSpecification {

    @Autowired
    CustomerDao customerDao;

    /**
     *
     * 根据单个条件查询
     */
    @Test
    public void  test(){
        //匿名内部类
        /**
         * 自定义查询条件
         *              1:实现Specification接口(提供泛型,查询对象的类型)
         *              2.实现Specification接口中的toPredicate方法(构造查询条件)
         *              3.根据方法中的两个参数:
         *                                  root:获取需要查询对象的属性名称
         *                                  criteriaBuilder:构造查询条件,内部封装了很多查询条件
         * 根据名称查询
         *
         */
        Specification<Customer> specification=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='者超超'
                /**
                 * 第一个参数:需要比较的属性
                 * 第二个参数:当前需要比较的取值
                 */
                Predicate predicate = criteriaBuilder.equal(custName, "者超超");//精准匹配
                return predicate;
            }
        };
        Customer customer = customerDao.findOne(specification);
        System.out.println(customer);
    }


    /**
     *
     * 根据多个条件查询
     */
    @Test
    public void  test2(){
        //匿名内部类
        /**
         * 自定义查询条件
         *              1:实现Specification接口(提供泛型,查询对象的类型)
         *              2.实现Specification接口中的toPredicate方法(构造查询条件)
         *              3.根据方法中的两个参数:
         *                                  root:获取需要查询对象的属性名称
         *                                  criteriaBuilder:构造查询条件,内部封装了很多查询条件
         * 根据名称和地址查询
         *
         */
        Specification<Customer> specification=new Specification<Customer>() {
            @Override
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //1.获取查询属性名称
                Path<Object> custName = root.get("custName");
                Path<Object> custAddress = root.get("custAddress");
                //2.构造查询条件
                /**
                 * 第一个参数:path对象需要比较的属性
                 * 第二个参数:当前需要比较的取值
                 */
                Predicate predicate = criteriaBuilder.equal(custName, "者超超");//精准匹配
                Predicate predicate2 = criteriaBuilder.equal(custAddress, "昆明");//精准匹配
                //3.将多个查询条件组合起来:组合(根据自己的业务而定)比如:满足条件一并且满足条件二,满足条件一或者满足条件二
                Predicate and = criteriaBuilder.and(predicate, predicate2);
                return and;
            }
        };
        Customer customer = customerDao.findOne(specification);
        System.out.println(customer);
    }


    /**
     * 更具电话号码模糊查询
     * equal :直接的到path对象(属性),然后进行比较即可
     *      gt,lt,ge,le,like : 得到path对象,根据path指定比较的参数类型,再去进行比较
     *           指定参数类型:path.as(类型的字节码对象)
     */
    @Test
    public void  test3(){
        Specification<Customer> specification=new Specification<Customer>() {
            @Override
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //1.获取查询对象的属性
                Path<Object> custPhone = root.get("custPhone");
                //2.拼接查询条件
                Predicate like = criteriaBuilder.like(custPhone.as(String.class), "18%");
                return like;
            }
        };
        List<Customer> list = customerDao.findAll(specification);
        for (Customer customer : list) {
            System.out.println(customer);
        }

    }

    /**
     * 排序查询
     * 更具电话号码模糊 降序查询
     * equal :直接的到path对象(属性),然后进行比较即可
     *      gt,lt,ge,le,like : 得到path对象,根据path指定比较的参数类型,再去进行比较
     *           指定参数类型:path.as(类型的字节码对象)
     */
    @Test
    public void  test4(){
        Specification<Customer> specification=new Specification<Customer>() {
            @Override
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //1.获取查询对象的属性
                Path<Object> custPhone = root.get("custPhone");
                //2.拼接查询条件
                Predicate like = criteriaBuilder.like(custPhone.as(String.class), "18%");
                return like;
            }
        };
        //添加排序
        //创建排序对象,需要调用构造方法实例化sort对象
        //第一个参数:排序的顺序(倒序,正序)
        //   Sort.Direction.DESC:倒序
        //   Sort.Direction.ASC : 升序
        //第二个参数:排序的属性名称
        Sort sort=new Sort(Sort.Direction.DESC,"custId");
        List<Customer> list = customerDao.findAll(specification, sort);
        for (Customer customer : list) {
            System.out.println(customer);
        }
    }

    /**
     * 根据id分页查询
     *      Specification: 查询条件
     *      Pageable:分页参数
     *          分页参数:查询的页码,每页查询的条数
     *          findAll(Specification,Pageable):带有条件的分页
     *          findAll(Pageable):没有条件的分页
     *  返回:Page(springDataJpa为我们封装好的pageBean对象,数据列表,共条数)
     */
    @Test
    public void  test5(){
        //匿名内部类
        /**
         * 自定义查询条件
         *              1:实现Specification接口(提供泛型,查询对象的类型)
         *              2.实现Specification接口中的toPredicate方法(构造查询条件)
         *              3.根据方法中的两个参数:
         *                                  root:获取需要查询对象的属性名称
         *                                  criteriaBuilder:构造查询条件,内部封装了很多查询条件
         * 根据名称查询
         *
         */
        Specification<Customer> specification=new Specification<Customer>() {
            @Override
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //1.获取查询属性名称
                Path<Object> custId = root.get("custId");
                //2.构造查询条件 select * from cst_customer where custId>3 limit 0,5
                /**
                 * 第一个参数:需要比较的属性
                 * 第二个参数:当前需要比较的取值
                 */
                Predicate predicate = criteriaBuilder.gt(custId.as(Long.class), 3L);//精准匹配
                return predicate;
            }
        };

        /**
         * public PageRequest(int page, int size) {
         * 		this(page, size, null);
         *        }
         */
        Pageable pageable=new PageRequest(0,2);
        //分页查询
        Page<Customer> page = customerDao.findAll(specification, pageable);
        List<Customer> list = page.getContent();
        for (Customer customer : list) {
            System.out.println(customer);
        }
        System.out.println(page.getContent()); //得到数据集合列表
        System.out.println(page.getTotalElements());//得到总条数
        System.out.println(page.getTotalPages());//得到总页数

    }

}

  

posted on 2019-12-08 21:47  西门夜说  阅读(1767)  评论(0编辑  收藏  举报