1.  
  1. package com.ytkj.entity;
  2.  
  3. import javax.persistence.*;
  4. import java.io.Serializable;
  5.  
  6. /**
  7. * @Entity
  8. * 作用:指定当前类是实体类。
  9. * @Table
  10. * 作用:指定实体类和表之间的对应关系。
  11. * 属性:
  12. * name:指定数据库表的名称
  13. * @Id
  14. * 作用:指定当前字段是主键。
  15. * @GeneratedValue
  16. * 作用:指定主键的生成方式。。
  17. * 属性:
  18. * strategy :指定主键生成策略。
  19. * @Column
  20. * 作用:指定实体类属性和数据库表之间的对应关系
  21. * 属性:
  22. * name:指定数据库表的列名称。
  23. * unique:是否唯一
  24. * nullable:是否可以为空
  25. * inserttable:是否可以插入
  26. * updateable:是否可以更新
  27. * columnDefinition: 定义建表时创建此列的DDL
  28. * secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字搭建开发环境[重点]
  29. *
  30. * 客户实体类
  31. * 配置映射关系
  32. * 实体类和表映射
  33. * 实体类属性和表字段映射
  34. */
  35. @Entity
  36. @Table(name = "cst_customer")
  37. public class Customer implements Serializable {
  38. /**
  39. * 声明主键配置
  40. */
  41. @Id
  42. /**
  43. * 配置主键的生成策略
  44. */
  45. @GeneratedValue(strategy = GenerationType.IDENTITY)
  46. /**
  47. * 指定实体类属性和数据库表之间的对应关系
  48. */
  49. @Column(name ="cust_id")
  50. private Long custId;//客户主键
  51. @Column(name = "cust_name")
  52. private String custName;//客户名称
  53. @Column(name ="cust_source" )
  54. private String custSource;//客户来源
  55. @Column(name = "cust_industry")
  56. private String custIndustry;//客户行业
  57. @Column(name ="cust_level")
  58. private String custLevel;//客户级别
  59. @Column(name ="cust_address")
  60. private String custAddress;//客户地址
  61. @Column(name = "cust_phone")
  62. private String custPhone;//客户电话
  63.  
  64. public Long getCustId() {
  65. return custId;
  66. }
  67.  
  68. public void setCustId(Long custId) {
  69. this.custId = custId;
  70. }
  71.  
  72. public String getCustName() {
  73. return custName;
  74. }
  75.  
  76. public void setCustName(String custName) {
  77. this.custName = custName;
  78. }
  79.  
  80. public String getCustSource() {
  81. return custSource;
  82. }
  83.  
  84. public void setCustSource(String custSource) {
  85. this.custSource = custSource;
  86. }
  87.  
  88. public String getCustIndustry() {
  89. return custIndustry;
  90. }
  91.  
  92. public void setCustIndustry(String custIndustry) {
  93. this.custIndustry = custIndustry;
  94. }
  95.  
  96. public String getCustLevel() {
  97. return custLevel;
  98. }
  99.  
  100. public void setCustLevel(String custLevel) {
  101. this.custLevel = custLevel;
  102. }
  103.  
  104. public String getCustAddress() {
  105. return custAddress;
  106. }
  107.  
  108. public void setCustAddress(String custAddress) {
  109. this.custAddress = custAddress;
  110. }
  111.  
  112. public String getCustPhone() {
  113. return custPhone;
  114. }
  115.  
  116. public void setCustPhone(String custPhone) {
  117. this.custPhone = custPhone;
  118. }
  119.  
  120. @Override
  121. public String toString() {
  122. return "Customer{" +
  123. "custId=" + custId +
  124. ", custName='" + custName + '\'' +
  125. ", custSource='" + custSource + '\'' +
  126. ", custIndustry='" + custIndustry + '\'' +
  127. ", custLevel='" + custLevel + '\'' +
  128. ", custAddress='" + custAddress + '\'' +
  129. ", custPhone='" + custPhone + '\'' +
  130. '}';
  131. }
  132. }
  1.  

  

  1.  
  2. Specifications动态查询
  3.  
  4. JpaSpecificationExecutor 方法列表
  5.  
  6. T findOne(Specification<T> spec); //查询单个对象
  7.  
  8. List<T> findAll(Specification<T> spec); //查询列表
  9.  
  10. //查询全部,分页
  11. //pageable:分页参数
  12. //返回值:分页pageBean(page:是springdatajpa提供的)
  13. Page<T> findAll(Specification<T> spec, Pageable pageable);
  14.  
  15. //查询列表
  16. //Sort:排序参数
  17. List<T> findAll(Specification<T> spec, Sort sort);
  18.  
  19. long count(Specification<T> spec);//统计查询
  20.  
  21. * Specification :查询条件
  22. 自定义我们自己的Specification实现类
  23. 实现
  24. //root:查询的根对象(查询的任何属性都可以从根对象中获取)
  25. //CriteriaQuery:顶层查询对象,自定义查询方式(了解:一般不用)
  26. //CriteriaBuilder:查询的构造器,封装了很多的查询条件
  27. Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb); //封装查询条件

Demo

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

  

  1. import com.ytkj.dao.CustomerDao;
  2. import com.ytkj.entity.Customer;
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.data.domain.Page;
  7. import org.springframework.data.domain.PageRequest;
  8. import org.springframework.data.domain.Pageable;
  9. import org.springframework.data.domain.Sort;
  10. import org.springframework.data.jpa.domain.Specification;
  11. import org.springframework.test.context.ContextConfiguration;
  12. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  13.  
  14. import javax.persistence.criteria.*;
  15. import java.util.List;
  16.  
  17. /**
  18. * Specifications动态查询
  19. */
  20. @RunWith(SpringJUnit4ClassRunner.class)//声明spring提供的单元测试环境
  21. @ContextConfiguration(locations = "classpath:applicationContext.xml")//指定spring容器的配置信息
  22. public class SpringdatajpaSpecification {
  23.  
  24. @Autowired
  25. CustomerDao customerDao;
  26.  
  27. /**
  28. *
  29. * 根据单个条件查询
  30. */
  31. @Test
  32. public void test(){
  33. //匿名内部类
  34. /**
  35. * 自定义查询条件
  36. * 1:实现Specification接口(提供泛型,查询对象的类型)
  37. * 2.实现Specification接口中的toPredicate方法(构造查询条件)
  38. * 3.根据方法中的两个参数:
  39. * root:获取需要查询对象的属性名称
  40. * criteriaBuilder:构造查询条件,内部封装了很多查询条件
  41. * 根据名称查询
  42. *
  43. */
  44. Specification<Customer> specification=new Specification<Customer>() {
  45. @Override
  46. public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  47. //1.获取查询属性名称
  48. Path<Object> custName = root.get("custName");
  49. //2.构造查询条件 select * from cst_customer where cust_name='者超超'
  50. /**
  51. * 第一个参数:需要比较的属性
  52. * 第二个参数:当前需要比较的取值
  53. */
  54. Predicate predicate = criteriaBuilder.equal(custName, "者超超");//精准匹配
  55. return predicate;
  56. }
  57. };
  58. Customer customer = customerDao.findOne(specification);
  59. System.out.println(customer);
  60. }
  61.  
  62. /**
  63. *
  64. * 根据多个条件查询
  65. */
  66. @Test
  67. public void test2(){
  68. //匿名内部类
  69. /**
  70. * 自定义查询条件
  71. * 1:实现Specification接口(提供泛型,查询对象的类型)
  72. * 2.实现Specification接口中的toPredicate方法(构造查询条件)
  73. * 3.根据方法中的两个参数:
  74. * root:获取需要查询对象的属性名称
  75. * criteriaBuilder:构造查询条件,内部封装了很多查询条件
  76. * 根据名称和地址查询
  77. *
  78. */
  79. Specification<Customer> specification=new Specification<Customer>() {
  80. @Override
  81. public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  82. //1.获取查询属性名称
  83. Path<Object> custName = root.get("custName");
  84. Path<Object> custAddress = root.get("custAddress");
  85. //2.构造查询条件
  86. /**
  87. * 第一个参数:path对象需要比较的属性
  88. * 第二个参数:当前需要比较的取值
  89. */
  90. Predicate predicate = criteriaBuilder.equal(custName, "者超超");//精准匹配
  91. Predicate predicate2 = criteriaBuilder.equal(custAddress, "昆明");//精准匹配
  92. //3.将多个查询条件组合起来:组合(根据自己的业务而定)比如:满足条件一并且满足条件二,满足条件一或者满足条件二
  93. Predicate and = criteriaBuilder.and(predicate, predicate2);
  94. return and;
  95. }
  96. };
  97. Customer customer = customerDao.findOne(specification);
  98. System.out.println(customer);
  99. }
  100.  
  101. /**
  102. * 更具电话号码模糊查询
  103. * equal :直接的到path对象(属性),然后进行比较即可
  104. * gt,lt,ge,le,like : 得到path对象,根据path指定比较的参数类型,再去进行比较
  105. * 指定参数类型:path.as(类型的字节码对象)
  106. */
  107. @Test
  108. public void test3(){
  109. Specification<Customer> specification=new Specification<Customer>() {
  110. @Override
  111. public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  112. //1.获取查询对象的属性
  113. Path<Object> custPhone = root.get("custPhone");
  114. //2.拼接查询条件
  115. Predicate like = criteriaBuilder.like(custPhone.as(String.class), "18%");
  116. return like;
  117. }
  118. };
  119. List<Customer> list = customerDao.findAll(specification);
  120. for (Customer customer : list) {
  121. System.out.println(customer);
  122. }
  123.  
  124. }
  125.  
  126. /**
  127. * 排序查询
  128. * 更具电话号码模糊 降序查询
  129. * equal :直接的到path对象(属性),然后进行比较即可
  130. * gt,lt,ge,le,like : 得到path对象,根据path指定比较的参数类型,再去进行比较
  131. * 指定参数类型:path.as(类型的字节码对象)
  132. */
  133. @Test
  134. public void test4(){
  135. Specification<Customer> specification=new Specification<Customer>() {
  136. @Override
  137. public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  138. //1.获取查询对象的属性
  139. Path<Object> custPhone = root.get("custPhone");
  140. //2.拼接查询条件
  141. Predicate like = criteriaBuilder.like(custPhone.as(String.class), "18%");
  142. return like;
  143. }
  144. };
  145. //添加排序
  146. //创建排序对象,需要调用构造方法实例化sort对象
  147. //第一个参数:排序的顺序(倒序,正序)
  148. // Sort.Direction.DESC:倒序
  149. // Sort.Direction.ASC : 升序
  150. //第二个参数:排序的属性名称
  151. Sort sort=new Sort(Sort.Direction.DESC,"custId");
  152. List<Customer> list = customerDao.findAll(specification, sort);
  153. for (Customer customer : list) {
  154. System.out.println(customer);
  155. }
  156. }
  157.  
  158. /**
  159. * 根据id分页查询
  160. * Specification: 查询条件
  161. * Pageable:分页参数
  162. * 分页参数:查询的页码,每页查询的条数
  163. * findAll(Specification,Pageable):带有条件的分页
  164. * findAll(Pageable):没有条件的分页
  165. * 返回:Page(springDataJpa为我们封装好的pageBean对象,数据列表,共条数)
  166. */
  167. @Test
  168. public void test5(){
  169. //匿名内部类
  170. /**
  171. * 自定义查询条件
  172. * 1:实现Specification接口(提供泛型,查询对象的类型)
  173. * 2.实现Specification接口中的toPredicate方法(构造查询条件)
  174. * 3.根据方法中的两个参数:
  175. * root:获取需要查询对象的属性名称
  176. * criteriaBuilder:构造查询条件,内部封装了很多查询条件
  177. * 根据名称查询
  178. *
  179. */
  180. Specification<Customer> specification=new Specification<Customer>() {
  181. @Override
  182. public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  183. //1.获取查询属性名称
  184. Path<Object> custId = root.get("custId");
  185. //2.构造查询条件 select * from cst_customer where custId>3 limit 0,5
  186. /**
  187. * 第一个参数:需要比较的属性
  188. * 第二个参数:当前需要比较的取值
  189. */
  190. Predicate predicate = criteriaBuilder.gt(custId.as(Long.class), 3L);//精准匹配
  191. return predicate;
  192. }
  193. };
  194.  
  195. /**
  196. * public PageRequest(int page, int size) {
  197. * this(page, size, null);
  198. * }
  199. */
  200. Pageable pageable=new PageRequest(0,2);
  201. //分页查询
  202. Page<Customer> page = customerDao.findAll(specification, pageable);
  203. List<Customer> list = page.getContent();
  204. for (Customer customer : list) {
  205. System.out.println(customer);
  206. }
  207. System.out.println(page.getContent()); //得到数据集合列表
  208. System.out.println(page.getTotalElements());//得到总条数
  209. System.out.println(page.getTotalPages());//得到总页数
  210.  
  211. }
  212.  
  213. }

  

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. java中关于异常的处理

    初学java的时候,当我们碰到异常时,一般会把异常直接throws抛出去,或则在catch的时候,简单的写一句打印异常信息,但是在实际开发中,是不能这么做的.如果我们将底层的某一个异常简单的print ...

  2. C# Base64编码解码 ,Md5、Rsa加密解密

    using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace Clas ...

  3. 【学习总结】GirlsInAI ML-diary day-20-初识 Kaggle

    [学习总结]GirlsInAI ML-diary 总 原博github链接-day20 初识kaggle 1-注册一个账号(由于被谷歌收购,因此可能需要梯子) 2-Competition - 学会看一 ...

  4. C#学习大纲

    一.C#:    1.进制转换    2.vs界面内容 熟悉软件    3.数据类型 :引用类型 值类型    4.变量 (存储数据)一个变量存储一个数据    5.类型转换    6.运算符:算数运 ...

  5. 一、AJAX

    一. (function ($) { //1.得到$.ajax的对象 var _ajax = $.ajax; $.ajax = function (options) { //2.每次调用发送ajax请 ...

  6. Codeforces Round #393 (Div. 2) - A

    题目链接:http://codeforces.com/contest/760/problem/A 题意:给定一个2017年的月份和该月的第一天的星期,问该月份的日历表中需要多少列.行有7列表示星期一~ ...

  7. 树的计数 Prüfer编码与Cayley公式 学习笔记

    最近学习了Prüfer编码与Cayley公式,这两个强力的工具一般用于解决树的计数问题.现在博主只能学到浅层的内容,只会用不会证明. 推荐博客:https://blog.csdn.net/moreja ...

  8. Sass Maps的函数-map-keys($map)

    map-keys($map) 函数将会返回 $map 中的所有 key.这些值赋予给一个变量,那他就是一个列表.如: map-keys($social-colors); 其返回的值为: "d ...

  9. 三栏布局只知道圣杯、双飞翼,最终评级是……F

    三栏布局,面试与工作中的常见布局.分左中右三部分,其中左右宽度已知,中间宽度自适应.根据不同的DOM顺序与CSS处理,这里写下了五类布局方式. 一.浮动布局 1 圣杯布局 L:"我问你,你就 ...

  10. 您的加密USB驱动器是否安全?黑客又是如何攻破的?

    您如何确定您使用的“安全”USB驱动器是否真的安全,并且您存储的数据无法提取?这正是Google公司和中国网络安全研究人员在最近的2018年黑帽美国大会上以艰难的方式攻击加密的USB密钥”的问题. 研 ...