此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Data LDAP 3.4.4spring-doc.cadn.net.cn

查询方法

通常在存储库上触发的大多数数据访问作都会导致对 LDAP 目录运行查询。 定义此类查询就是在存储库接口上声明方法,如下例所示:spring-doc.cadn.net.cn

PersonRepository 与查询方法
interface PersonRepository extends PagingAndSortingRepository<Person, String> {

    List<Person> findByLastname(String lastname);                            (1)

    List<Person> findByLastnameFirstname(String lastname, String firstname); (2)
}
1 该方法显示具有给定lastname. 查询是通过解析可与AndOr. 因此,方法名称会生成(&(objectclass=person)(lastname=lastname)).
2 该方法显示具有给定lastnamefirstname. 查询是通过解析方法名称派生的。 因此,方法名称会生成(&(objectclass=person)(lastname=lastname)(firstname=firstname)).

下表提供了可用于查询方法的关键字示例:spring-doc.cadn.net.cn

表 1.查询方法支持的关键字
关键词 样本 逻辑结果

LessThanEqualspring-doc.cadn.net.cn

findByAgeLessThanEqual(int age)spring-doc.cadn.net.cn

(attribute⇐age)spring-doc.cadn.net.cn

GreaterThanEqualspring-doc.cadn.net.cn

findByAgeGreaterThanEqual(int age)spring-doc.cadn.net.cn

(attribute>=age)spring-doc.cadn.net.cn

IsNotNull,NotNullspring-doc.cadn.net.cn

findByFirstnameNotNull()spring-doc.cadn.net.cn

(firstname=*)spring-doc.cadn.net.cn

IsNull,Nullspring-doc.cadn.net.cn

findByFirstnameNull()spring-doc.cadn.net.cn

(!(firstname=*))spring-doc.cadn.net.cn

Likespring-doc.cadn.net.cn

findByFirstnameLike(String name)spring-doc.cadn.net.cn

(firstname=name)spring-doc.cadn.net.cn

NotLike,IsNotLikespring-doc.cadn.net.cn

findByFirstnameNotLike(String name)spring-doc.cadn.net.cn

(!(firstname=name*))spring-doc.cadn.net.cn

StartingWithspring-doc.cadn.net.cn

findByStartingWith(String name)spring-doc.cadn.net.cn

(firstname=name*)spring-doc.cadn.net.cn

EndingWithspring-doc.cadn.net.cn

findByFirstnameLike(String name)spring-doc.cadn.net.cn

(firstname=*name)spring-doc.cadn.net.cn

Containingspring-doc.cadn.net.cn

findByFirstnameLike(String name)spring-doc.cadn.net.cn

(firstname=*name*)spring-doc.cadn.net.cn

(No keyword)spring-doc.cadn.net.cn

findByFirstname(String name)spring-doc.cadn.net.cn

(Firstname=name)spring-doc.cadn.net.cn

Notspring-doc.cadn.net.cn

findByFirstnameNot(String name)spring-doc.cadn.net.cn

(!(Firstname=name))spring-doc.cadn.net.cn

@Query

如果需要使用无法从方法名称派生的自定义查询,可以使用@Query注解来定义查询。 由于查询与运行它们的 Java 方法相关联,因此您实际上可以绑定要传递给查询的参数。spring-doc.cadn.net.cn

以下示例显示了使用@Query注解:spring-doc.cadn.net.cn

示例 1.使用@Query
interface PersonRepository extends LdapRepository<Person, Long> {

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

}
Spring Data 支持以:)和位置参数绑定(以从 0 开始的形式?0). 我们建议使用命名参数,以便于阅读。 此外,使用位置参数会使查询方法在重构参数位置时更容易出错。

参数编码

String 查询的查询参数按照 RFC2254 进行编码。 这可能会导致某些字符意外转义。 您可以通过@LdapEncode注解,定义哪个LdapEncoder使用。spring-doc.cadn.net.cn

@LdapEncode适用于查询方法的单个参数。 它不适用于派生查询或值表达式(SPEL、属性占位符)。spring-doc.cadn.net.cn

示例 2.声明自定义LdapEncoder对于查询方法
interface PersonRepository extends LdapRepository<Person, Long> {

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

}

使用 SPEL 表达式

Spring Data 允许您在查询方法中使用 SPEL 表达式。 SPEL 表达式是 Spring Data 的值表达式支持的一部分。 SPEL 表达式可用于作查询方法参数以及调用 Bean 方法。 方法参数可以按名称或索引进行访问,如以下示例所示。spring-doc.cadn.net.cn

例 3.在存储库查询方法中使用 SPEL 表达式
@Query("(&(firstName=?#{[0]})(mail=:?#{principal.emailAddress}))")
List<Person> findByFirstnameAndCurrentUserWithCustomQuery(String firstname);
根据 RFC2254,不会对 SPEL 表达式提供的值进行转义。 如果需要,您必须确保正确转义这些值。 考虑使用 Spring LDAP 的org.springframework.ldap.support.LdapEncoderhelper 类。

使用属性占位符

属性占位符(请参阅值表达式)可以帮助根据 Spring 的Environment. 这些选项对于需要根据环境或配置自定义的查询非常有用。spring-doc.cadn.net.cn

示例 4.在存储库查询方法中使用属性占位符
@Query("(&(firstName=?0)(stage=:?${myapp.stage:dev}))")
List<Person> findByFirstnameAndStageWithCustomQuery(String firstname);
Property Placeholders 提供的值不会根据 RFC2254 进行转义。 如果需要,您必须确保正确转义这些值。 考虑使用 Spring LDAP 的org.springframework.ldap.support.LdapEncoderhelper 类。