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());//得到总页数 } }

  

spring data jpa Specification动态查询的更多相关文章

  1. Spring data jpa 复杂动态查询方式总结

    一.Spring data jpa 简介 首先我并不推荐使用jpa作为ORM框架,毕竟对于负责查询的时候还是不太灵活,还是建议使用mybatis,自己写sql比较好.但是如果公司用这个就没办法了,可以 ...

  2. spring data jpa Specification 复杂查询+分页查询

    当Repository接口继承了JpaSpecificationExecutor后,我们就可以使用如下接口进行分页查询: /** * Returns a {@link Page} of entitie ...

  3. spring data jpa hql动态查询案例

    目的:根据入参条件不同,动态组装hql里的where语句. 1. 实现代码 public List<WrapStatis> queryStatisCriteriaBuilder(Strin ...

  4. 【Spring Data 系列学习】Spring Data JPA @Query 注解查询

    [Spring Data 系列学习]Spring Data JPA @Query 注解查询 前面的章节讲述了 Spring Data Jpa 通过声明式对数据库进行操作,上手速度快简单易操作.但同时 ...

  5. Spring data JPA 理解(默认查询 自定义查询 分页查询)及no session 三种处理方法

    简介:Spring Data JPA 其实就是JDK方式(还有一种cglib的方式需要Class)的动态代理 (需要一个接口 有一大堆接口最上边的是Repository接口来自org.springfr ...

  6. spring data jpa 多对多查询

    package com.ytkj.dao; import com.ytkj.entity.Customer; import com.ytkj.entity.Role; import org.sprin ...

  7. spring data jpa 一对多查询

    在一对多关系中,我们习惯把一的一方称之为主表,把多的一方称之为从表.在数据库中建立一对多的关系,需要使用数据库的外键约束. 什么是外键? 指的是从表中有一列,取值参照主表的主键,这一列就是外键. pa ...

  8. Spring Data JPA应用 之查询分析

    在Spring Data JPA应用之常规CRUD操作初体验 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)尾附上了JpaRepository接口继承关系及方法,可以知道JpaRepos ...

  9. 记: Spring Data Jpa @OneToMany 级联查询被动触发的问题

    I have encountered a bug in using Spring Data Jpa. Specifically,when @OneToMany was used to maintain ...

随机推荐

  1. noip2018考后反思之爆0

    今年又被Han老师鞭尸了TAT noip普及组比齐同学考的都差,正在准备退役Orz 哎,算了,该放题解还是要放的:( 普及第一题我觉得没有放的必要还是放一下 Code: #include<ios ...

  2. Educational Codeforces Round 69 (Rated for Div. 2) A~D Sloution

    A. DIY Wooden Ladder 题意:有一些不能切的木板,每个都有一个长度,要做一个梯子,求梯子的最大台阶数 做梯子的木板分为两种,两边的两条木板和中间的若干条台阶木板 台阶数为 $k$ 的 ...

  3. k8s常用笔记

    安装docker // 安装docker $ yum install -y docker-ce // 开机启动 && 启动服务 $ systemctl enable docker &a ...

  4. HttpGet请求传递数组(集合)

    在HttpGet请求是传递数组(集合)的方法: 1.使用Ajax方法传递 eg: ajax.({ url:/test, data:["], type:"get" }); ...

  5. Dubbo源码学习总结系列一 总体认识

    本文写作时,dubbo最高版本是V2.6.0.  写这篇文章主要想回答以下4个问题: 一.dubbo是什么?完成了哪些主要需求? 二.dubbo适用于什么场景? 三.dubbo的总体架构是什么样的? ...

  6. ROLLBACK - 退出当前事务

    SYNOPSIS ROLLBACK [ WORK | TRANSACTION ] DESCRIPTION 描述 ROLLBACK 回卷当前事务并取消当前事务中的所有更新. PARAMETERS 参数 ...

  7. mysql的一些基本常识

    1.主键的选取 主键的字段不能有null存在 主键应该使用bigint自增,而不是int 主键的选取默认为id 联合主键:就是多个字段被设置为主键,这里主键字段的值是允许相同的,只要不是所有字段相同即 ...

  8. python常用函数 S

    slice(int,int) 切片,可以为切片命名增加可读性. 例子: sorted(iterable, key) 排序,支持传入参数,例如通过itemgetter传入参数(itemgetter可以传 ...

  9. 【LeetCode】栈 stack(共40题)

    [20]Valid Parentheses (2018年11月28日,复习, ko) 给了一个字符串判断是不是合法的括号配对. 题解:直接stack class Solution { public: ...

  10. 【LeetCode】贪心 greedy(共38题)

    [44]Wildcard Matching [45]Jump Game II (2018年11月28日,算法群衍生题) 题目背景和 55 一样的,问我能到达最后一个index的话,最少走几步. 题解: ...