Example官方介绍

Query by Example (QBE) is a user-friendly querying technique with a simple interface. It allows dynamic query creation and does not require to write queries containing field names. In fact, Query by Example does not require to write queries using store-specific query languages at all.

谷歌翻译:

按例查询(QBE)是一种用户界面友好的查询技术。 它允许动态创建查询,并且不需要编写包含字段名称的查询。 实际上,按示例查询不需要使用特定的数据库的查询语言来编写查询语句。

Example api的组成

  1. Probe: 含有对应字段的实例对象。
  2. ExampleMatcher:ExampleMatcher携带有关如何匹配特定字段的详细信息,相当于匹配条件。
  3. Example:由Probe和ExampleMatcher组成,用于查询。

限制

  1. 属性不支持嵌套或者分组约束,比如这样的查询 firstname = ?0 or (firstname = ?1 and lastname = ?2)
  2. 灵活匹配只支持字符串类型,其他类型只支持精确匹配

Limitations

1. No support for nested/grouped property constraints like firstname = ?0 or (firstname = ?1 and lastname = ?2)

2. Only supports starts/contains/ends/regex matching for strings and exact matching for other property types

使用

创建实体映射:

@Entity
@Table(name="t_user")
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User { @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id; @Column(name="username")
private String username; @Column(name="password")
private String password; @Column(name="email")
private String email; @Column(name="phone")
private String phone; @Column(name="address")
private String address;
}

测试查询:

@Test
public void contextLoads() {
User user = new User();
user.setUsername("admin");
Example<User> example = Example.of(user);
List<User> list = userRepository.findAll(example);
System.out.println(list);
} 打印的sql语句如下: Hibernate:
select
user0_.id as id1_0_,
user0_.address as address2_0_,
user0_.email as email3_0_,
user0_.password as password4_0_,
user0_.phone as phone5_0_,
user0_.username as username6_0_
from
t_user user0_
where
user0_.username=?

可以发现,试用Example查询,默认情况下会忽略空值,官方文档也有说明:

This is a simple domain object. You can use it to create an Example. By default, fields having null values are ignored, and strings are matched using the store specific defaults. Examples can be built by either using the of factory method or by using ExampleMatcher. Example is immutable.

在上面的测试之中,我们只是只是定义了Probe而没有ExampleMatcher,是因为默认会不传时会使用默认的匹配器。点进方法可以看到下面的代码:

static <T> Example<T> of(T probe) {
return new TypedExample(probe, ExampleMatcher.matching());
} static ExampleMatcher matching() {
return matchingAll();
} static ExampleMatcher matchingAll() {
return (new TypedExampleMatcher()).withMode(ExampleMatcher.MatchMode.ALL);
}

自定匹配器规则

@Test
public void contextLoads() {
User user = new User();
user.setUsername("y");
user.setAddress("sh");
user.setPassword("admin");
ExampleMatcher matcher = ExampleMatcher.matching()
.withMatcher("username", ExampleMatcher.GenericPropertyMatchers.startsWith())//模糊查询匹配开头,即{username}%
.withMatcher("address" ,ExampleMatcher.GenericPropertyMatchers.contains())//全部模糊查询,即%{address}%
.withIgnorePaths("password");//忽略字段,即不管password是什么值都不加入查询条件
Example<User> example = Example.of(user ,matcher);
List<User> list = userRepository.findAll(example);
System.out.println(list);
} 打印的sql语句如下:
select
user0_.id as id1_0_,
user0_.address as address2_0_,
user0_.email as email3_0_,
user0_.password as password4_0_,
user0_.phone as phone5_0_,
user0_.username as username6_0_
from
t_user user0_
where
(
user0_.username like ?
)
and (
user0_.address like ?
) 参数如下:
2018-03-24 13:26:57.425 TRACE 5880 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [y%]
2018-03-24 13:26:57.425 TRACE 5880 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [%sh%]

补充

官方创建ExampleMatcher例子(1.8 lambda)

ExampleMatcher matcher = ExampleMatcher.matching()
.withMatcher("firstname", match -> match.endsWith())
.withMatcher("firstname", match -> match.startsWith());
}

StringMatcher 参数

Matching 生成的语句 说明
DEFAULT (case-sensitive) firstname = ?0 默认(大小写敏感)
DEFAULT (case-insensitive) LOWER(firstname) = LOWER(?0) 默认(忽略大小写)
EXACT (case-sensitive) firstname = ?0 精确匹配(大小写敏感)
EXACT (case-insensitive) LOWER(firstname) = LOWER(?0) 精确匹配(忽略大小写)
STARTING (case-sensitive) firstname like ?0 + ‘%’ 前缀匹配(大小写敏感)
STARTING (case-insensitive) LOWER(firstname) like LOWER(?0) + ‘%’ 前缀匹配(忽略大小写)
ENDING (case-sensitive) firstname like ‘%’ + ?0 后缀匹配(大小写敏感)
ENDING (case-insensitive) LOWER(firstname) like ‘%’ + LOWER(?0) 后缀匹配(忽略大小写)
CONTAINING (case-sensitive) firstname like ‘%’ + ?0 + ‘%’ 模糊查询(大小写敏感)
CONTAINING (case-insensitive) LOWER(firstname) like ‘%’ + LOWER(?0) + ‘%’ 模糊查询(忽略大小写)

说明:

1. 在默认情况下(没有调用withIgnoreCase())都是大小写敏感的。

2. api之中还有个regex,但是我在mysql下测试报错,不了解具体作用。

总结

  1. 通过在使用springdata jpa时可以通过Example来快速的实现动态查询,同时配合Pageable可以实现快速的分页查询功能。
  2. 对于非字符串属性的只能精确匹配,比如想查询在某个时间段内注册的用户信息,就不能通过Example来查询

原文地址:https://blog.csdn.net/long476964/article/details/79677526

springdata jpa使用Example快速实现动态查询的更多相关文章

  1. 一篇 SpringData+JPA 总结

    概述 SpringData,Spring 的一个子项目,用于简化数据库访问,支持 NoSQL 和关系数据库存储 SpringData 项目所支持 NoSQL 存储 MongDB(文档数据库) Neo4 ...

  2. 小技巧 Mongodb 动态查询 除去 _class 条件

    最近在做通用模板标准示例项目,在使用  spring data jpa  Mongodb 的时候,动态查询会代入 _class条件. 为什么这么做其实也很好理解,写入数据库的数据中是有这个字段的.接受 ...

  3. SpringData JPA快速入门和基本的CRUD操作以及Specifications条件查询

    SpringData JPA概述: SpringData JPA 是 Spring 基于 ORM 框架.JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问和操作 ...

  4. SpringData JPA查询分页demo

    SpringData JPA 的 PagingAndSortingRepository接口已经提供了对分页的支持,查询的时候我们只需要传入一个 org.springframework.data.dom ...

  5. spring data jpa封装specification实现简单风格的动态查询

    github:https://github.com/peterowang/spring-data-jpa-demo 单一实体的动态查询: @Servicepublic class AdvancedUs ...

  6. SpringData JPA进阶查询—JPQL/原生SQL查询、分页处理、部分字段映射查询

    上一篇介绍了入门基础篇SpringDataJPA访问数据库.本篇介绍SpringDataJPA进一步的定制化查询,使用JPQL或者SQL进行查询.部分字段映射.分页等.本文尽量以简单的建模与代码进行展 ...

  7. springdata 动态查询 是用来查询的 仅提供查询功能

    springdata 动态查询 是用来查询的 仅提供查询功能

  8. spring jpa 动态查询(Specification)

    //dao层 继承 扩展仓库接口JpaSpecificationExecutor (JPA 2引入了一个标准的API)public interface CreditsEventDao extends ...

  9. Spring Data JPA中的动态查询 时间日期

    功能:Spring Data JPA中的动态查询 实现日期查询 页面对应的dto类private String modifiedDate; //实体类 @LastModifiedDate protec ...

随机推荐

  1. 51nod1196 字符串的数量

    用N个不同的字符(编号1 - N),组成一个字符串,有如下要求:(1) 对于编号为i的字符,如果2 * i > n,则该字符可以作为结尾字符.如果不作为结尾字符而是中间的字符,则该字符后面可以接 ...

  2. fedora下eclipse安装tomcat插件

    首先下载tomcat插件: http://www.eclipsetotale.com/tomcatPlugin.html,下载最新的3.3版本: 由于我的eclipse是通过yum自动安装的,因此ec ...

  3. bzoj1231 混乱的奶牛

    Description 混乱的奶牛 [Don Piele, 2007] Farmer John的N(4 <= N <= 16)头奶牛中的每一头都有一个唯一的编号S_i (1 <= S ...

  4. QT 捕获事件(全局拦截)

    QT 捕获应用键盘事件(全局拦截) 主窗口只有一个QTabWidget,每个tab中嵌入相应的窗口,在使用的过程中,需要主窗口响应键盘事件,而不是tab中的控件响应.故采取以下方式. 重写QAppli ...

  5. Maven学习总结--maven入门(一)

    一.Maven的基本概念 Maven(翻译为"专家","内行")是跨平台的项目管理工具.主要服务于基于Java平台的项目构建,依赖管理和项目信息管理.

  6. mysql 使用concat模糊查询

    如果这三个字段中有值为NULL,则返回的也是NULL,那么这一条记录可能就会被错过,使用IFNULL进行判断 SELECT * FROM `magazine` WHERE CONCAT(IFNULL( ...

  7. 用预编译包安装zabbix-agent

    如果主机无法上网,安装rpm又缺少依赖时,可以通过预编译包进行安装zabbix-agent,下载地址 https://www.zabbix.com/download 下载后,执行如下命令: wget ...

  8. java连接oracle jdbc连接

    Class.forName("oracle.jdbc.driver.OracleDriver"); Connection ct=Driver.Magager.getConnecti ...

  9. 机房收费系统之【只允许一个MDI窗体 错误:426】 标签: vb 2014-08-15 10:36 1149人阅读 评论(23)

    机房收费系统的主窗体是MDI窗体,为了在这个窗体上添加控件,所以我们在窗体上添加了picture控件,在MDI窗体中,子窗体实际上位于MDIClient里,即子窗体的父窗体就是MDIClient,而放 ...

  10. C# —— 枚举

    一.使用枚举的优点 枚举能够使代码更加的清晰,它允许使用描述性的名称表示整数值. 枚举使代码更易于维护,有助于确保给变量指定合法的.期望的值. 枚举使代码更易输入. 二.枚举说明 1.简单枚举 枚举使 ...