跳到主要内容

Query Methods

QWen Flash 中英对照 Query Methods

你在仓储上通常触发的数据访问操作中的大多数都会导致针对 LDAP 目录运行一个查询。定义这样一个查询只需在仓储接口上声明一个方法即可,如下例所示:

interface PersonRepository extends PagingAndSortingRepository<Person, String> {

List<Person> findByLastname(String lastname); 1

List<Person> findByLastnameFirstname(String lastname, String firstname); 2
}
java
  • 该方法显示查询所有具有给定 lastname 的人员。该查询通过解析方法名称推导得出,其中可以包含可用 And 和 Or 连接的条件。因此,方法名称生成的查询表达式为 (&(objectclass=person)(lastname=lastname))。

  • 该方法显示查询所有具有给定 lastname 和 firstname 的人员。该查询通过解析方法名称推导得出。因此,方法名称生成的查询表达式为 (&(objectclass=person)(lastname=lastname)(firstname=firstname))。

下表提供了你可以与查询方法一起使用的关键字示例:

表 1. 查询方法支持的关键字

关键字示例逻辑结果
LessThanEqualfindByAgeLessThanEqual(int age)(attribute⇐age)
GreaterThanEqualfindByAgeGreaterThanEqual(int age)(attribute>=age)
IsNotNull, NotNullfindByFirstnameNotNull()(firstname=*)
IsNull, NullfindByFirstnameNull()(!(firstname=*))
LikefindByFirstnameLike(String name)(firstname=name)
NotLike, IsNotLikefindByFirstnameNotLike(String name)(!(firstname=name*))
StartingWithfindByStartingWith(String name)(firstname=name*)
EndingWithfindByFirstnameLike(String name)(firstname=*name)
ContainingfindByFirstnameLike(String name)(firstname=*name*)
(No keyword)findByFirstname(String name)(Firstname=name)
NotfindByFirstnameNot(String name)(!(Firstname=name))

使用 @Query​

如果你需要使用无法从方法名推导的自定义查询,可以使用 @Query 注解来定义查询。由于查询与运行它的 Java 方法绑定,因此实际上可以将参数绑定并传递给查询。

以下示例展示了使用 @Query 注解创建的查询:

示例 1. 在查询方法中使用 @Query 声明查询

interface PersonRepository extends LdapRepository<Person, Long> {

@Query("(&(employmentType=*)(!(employmentType=Hired))(mail=:emailAddress))")
Person findEmployeeByEmailAddress(String emailAddress);

}
java
备注

Spring Data 支持命名参数(参数名前缀为 :)和位置参数绑定(形式为从 0 开始的 ?0)。我们建议使用命名参数以提高可读性。此外,在重构涉及参数位置时,使用位置参数会使查询方法更容易出错。

参数编码​

基于字符串的查询的查询参数会根据 RFC 2254 进行编码。这可能导致某些字符被意外转义。你可以通过 @LdapEncode 注解指定自己的编码器,该注解定义了要使用的 LdapEncoder。

@LdapEncode 适用于查询方法的各个参数。它不适用于派生查询或值表达式(SpEL、Property Placeholders)。

示例 2. 为查询方法声明自定义 LdapEncoder

interface PersonRepository extends LdapRepository<Person, Long> {

@Query("(&(employmentType=*)(!(employmentType=Hired))(firstName=:firstName))")
Person findEmployeeByFirstNameLike(@LdapEncode(MyLikeEncoder.class) String firstName);

}
java

使用 SpEL 表达式​

Spring Data 允许你在查询方法中使用 SpEL 表达式。SpEL 表达式是 Spring Data’s Value Expressions 支持的一部分。SpEL 表达式可用于操作查询方法参数以及调用 bean 方法。方法参数可以通过名称或索引访问,如下例所示。

示例 3. 在 Repository Query Methods 中使用 SpEL 表达式

@Query("(&(firstName=?#{[0]})(mail=:?#{principal.emailAddress}))")
List<Person> findByFirstnameAndCurrentUserWithCustomQuery(String firstname);
java
备注

由 SpEL 表达式提供的值不会按照 RFC2254 进行转义。如有需要,你必须确保这些值被正确转义。可以考虑使用 Spring Ldap 的 org.springframework.ldap.support.LdapEncoder 辅助类。

使用属性占位符​

Property Placeholders(参见 值表达式)可帮助您根据来自 Spring’s Environment 的配置属性轻松自定义查询。这些占位符适用于需要根据环境或配置进行自定义的查询。

示例 4. 在 Repository Query Methods 中使用 Property Placeholders

@Query("(&(firstName=?0)(stage=:?${myapp.stage:dev}))")
List<Person> findByFirstnameAndStageWithCustomQuery(String firstname);
java
备注

由 Property Placeholders 提供的值不会按照 RFC2254 进行转义。如果必要,你需要确保这些值已正确转义。可以考虑使用 Spring Ldap’s org.springframework.ldap.support.LdapEncoder 辅助类。