spring data jpa Specification动态查询
- 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动态查询的更多相关文章
- Spring data jpa 复杂动态查询方式总结
一.Spring data jpa 简介 首先我并不推荐使用jpa作为ORM框架,毕竟对于负责查询的时候还是不太灵活,还是建议使用mybatis,自己写sql比较好.但是如果公司用这个就没办法了,可以 ...
- spring data jpa Specification 复杂查询+分页查询
当Repository接口继承了JpaSpecificationExecutor后,我们就可以使用如下接口进行分页查询: /** * Returns a {@link Page} of entitie ...
- spring data jpa hql动态查询案例
目的:根据入参条件不同,动态组装hql里的where语句. 1. 实现代码 public List<WrapStatis> queryStatisCriteriaBuilder(Strin ...
- 【Spring Data 系列学习】Spring Data JPA @Query 注解查询
[Spring Data 系列学习]Spring Data JPA @Query 注解查询 前面的章节讲述了 Spring Data Jpa 通过声明式对数据库进行操作,上手速度快简单易操作.但同时 ...
- Spring data JPA 理解(默认查询 自定义查询 分页查询)及no session 三种处理方法
简介:Spring Data JPA 其实就是JDK方式(还有一种cglib的方式需要Class)的动态代理 (需要一个接口 有一大堆接口最上边的是Repository接口来自org.springfr ...
- spring data jpa 多对多查询
package com.ytkj.dao; import com.ytkj.entity.Customer; import com.ytkj.entity.Role; import org.sprin ...
- spring data jpa 一对多查询
在一对多关系中,我们习惯把一的一方称之为主表,把多的一方称之为从表.在数据库中建立一对多的关系,需要使用数据库的外键约束. 什么是外键? 指的是从表中有一列,取值参照主表的主键,这一列就是外键. pa ...
- Spring Data JPA应用 之查询分析
在Spring Data JPA应用之常规CRUD操作初体验 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)尾附上了JpaRepository接口继承关系及方法,可以知道JpaRepos ...
- 记: Spring Data Jpa @OneToMany 级联查询被动触发的问题
I have encountered a bug in using Spring Data Jpa. Specifically,when @OneToMany was used to maintain ...
随机推荐
- java中关于异常的处理
初学java的时候,当我们碰到异常时,一般会把异常直接throws抛出去,或则在catch的时候,简单的写一句打印异常信息,但是在实际开发中,是不能这么做的.如果我们将底层的某一个异常简单的print ...
- C# Base64编码解码 ,Md5、Rsa加密解密
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace Clas ...
- 【学习总结】GirlsInAI ML-diary day-20-初识 Kaggle
[学习总结]GirlsInAI ML-diary 总 原博github链接-day20 初识kaggle 1-注册一个账号(由于被谷歌收购,因此可能需要梯子) 2-Competition - 学会看一 ...
- C#学习大纲
一.C#: 1.进制转换 2.vs界面内容 熟悉软件 3.数据类型 :引用类型 值类型 4.变量 (存储数据)一个变量存储一个数据 5.类型转换 6.运算符:算数运 ...
- 一、AJAX
一. (function ($) { //1.得到$.ajax的对象 var _ajax = $.ajax; $.ajax = function (options) { //2.每次调用发送ajax请 ...
- Codeforces Round #393 (Div. 2) - A
题目链接:http://codeforces.com/contest/760/problem/A 题意:给定一个2017年的月份和该月的第一天的星期,问该月份的日历表中需要多少列.行有7列表示星期一~ ...
- 树的计数 Prüfer编码与Cayley公式 学习笔记
最近学习了Prüfer编码与Cayley公式,这两个强力的工具一般用于解决树的计数问题.现在博主只能学到浅层的内容,只会用不会证明. 推荐博客:https://blog.csdn.net/moreja ...
- Sass Maps的函数-map-keys($map)
map-keys($map) 函数将会返回 $map 中的所有 key.这些值赋予给一个变量,那他就是一个列表.如: map-keys($social-colors); 其返回的值为: "d ...
- 三栏布局只知道圣杯、双飞翼,最终评级是……F
三栏布局,面试与工作中的常见布局.分左中右三部分,其中左右宽度已知,中间宽度自适应.根据不同的DOM顺序与CSS处理,这里写下了五类布局方式. 一.浮动布局 1 圣杯布局 L:"我问你,你就 ...
- 您的加密USB驱动器是否安全?黑客又是如何攻破的?
您如何确定您使用的“安全”USB驱动器是否真的安全,并且您存储的数据无法提取?这正是Google公司和中国网络安全研究人员在最近的2018年黑帽美国大会上以艰难的方式攻击加密的USB密钥”的问题. 研 ...