public void testMyDataJPA(){
List<Person> people = personRepository.findByLastNameLike("%C%") ;
// List people = personRepository.findByLastNameNotLike("%C%") ;
System.out.println(people);
}
List<Person> persons = personRepository.getByLastNameStartingWithAndIdLessThan("A", 5);
System.out.println(persons);
List<Person> persons2 = personRepository.getByLastNameEndingWithAndIdLessThan("C", 40);
System.out.println(persons2);
从Spring Data JPA 1.4版开始,我们支持在手动定义的查询中使用受限制的SpEL模板表达式@Query。在执行查询时,将根据预定义的变量集评估这些表达式。Spring Data JPA支持一个名为的变量entityName。它的用法是select x from #{#entityName} x。它插入entityName与给定存储库关联的域类型。该entityName解决如下:如果域类型已设置的name属性@Entity的注释,它被使用。否则,使用域类型的简单类名。
当然,您可以User直接在查询声明中使用,但这也需要您更改查询。引用#entityName将User类的潜在未来重映射到不同的实体名称(例如,通过使用@Entity(name = “MyUser”)。
@Query("select p from #{#entityName} p where p.lastName = ?1")
List<Person> findByLastNameT(String lastName) ;
您可以使用Spring Framework的可空性注释来表达存储库方法的可空性约束。它们null在运行时提供了一种工具友好的方法和选择性检查,如下所示:
@NonNullApi:在包级别上使用,以声明参数和返回值的默认行为是不接受或生成null值。
@NonNull:用于必须不是的参数或返回值null (参数上不需要,返回值@NonNullApi适用)。
@Nullable:用于可以的参数或返回值null。
Spring注释是使用JSR 305注释进行元注释的(一种休眠但广泛传播的JSR)。JSR 305元注释允许IDEA,Eclipse和Kotlin等工具供应商以通用方式提供空安全支持,而无需对Spring注释进行硬编码支持。要为查询方法启用运行时检查可空性约束,需要使用Spring的@NonNullApiin 来激活包级别的非可空性
一旦存在非空默认,就会在运行时验证存储库查询方法调用的可空性约束。如果查询执行结果违反了定义的约束,则抛出异常。当方法返回null但声明为非可空时(默认情况下,存储库所在的包中定义了注释)会发生这种情况。如果您想再次选择可以为空的结果,请有选择地使用@Nullable单个方法。使用本节开头提到的结果包装器类型继续按预期工作:将空结果转换为表示缺席的值。
package com.acme;
import org.springframework.lang.Nullable;
interface UserRepository extends Repository<User, Long> {
// 在执行时不产生结果的查询时抛出一个EmptyResultDataAccessException。当emailAddress为null时抛出一个IllegalArgumentException。
User getByEmailAddress(EmailAddress emailAddress);
//null执行查询时不返回结果。也接受null作为的值emailAddress
@Nullable
User findByEmailAddress(@Nullable EmailAddress emailAdress);
//Optional.empty()执行查询时不返回结果。当emailAddress为null时抛出一个IllegalArgumentException
Optional<User> findOptionalByEmailAddress(EmailAddress emailAddress);
}
//方法名直接sql查询条件,参数中带有Pageable则会分页(同时可以带有排序)
Page<User> findByLastName(String lastName, Pageable pageable);
Slice<User> findByLastName(String lastName, Pageable pageable);
List<User> findByLastName(String lastName, Sort sort);
List<User> findByLastName(String lastName, Pageable pageable);
Page<Person> findByLastNameContaining(String lastName, Pageable pageable);
User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();
//方法名直接sql查询条件,参数中带有Pageable则会分页(同时可以带有排序)
Page<User> queryFirst10ByLastName(String lastName, Pageable pageable);
Slice<User> findTop3ByLastName(String lastName, Pageable pageable);
List<User> findFirst10ByLastName(String lastname, Sort sort);
List<User> findTop10ByLastName(String lastname, Pageable pageable);
Spring Data查询方法通常返回由存储库管理的聚合根的一个或多个实例。但是,有时可能需要根据这些类型的某些属性创建投影。Spring Data允许建模专用返回类型,以更有选择地检索托管聚合的部分视图。
Entity实体:
public class Person {
private Integer id ;
private String lastName ;
private String email ;
private Date birth ;
private Integer age ;
//...
//用于检索属性子集的投影接口
public interface LastNameAndEmailOnly {
String getLastName() ;
String getEmail() ;
}
//这里重要的一点是,此处定义的属性与聚合根中的属性完全匹配。这样做可以添加查询方法
List<LastNameAndEmailOnly> findByLastName(String lastName) ;
interface PersonSummary {
String getLastName() ;
String getEmail() ;
AddressSummary getAddress();
interface AddressSummary {
String getCity();
}
}
如果存储通过限制要加载的字段来优化查询执行,则要加载的字段将根据公开的构造函数的参数名称确定。
以下示例显示了投影DTO:
public class PersonDTO {
private final String lastName;
private final String email;
public PersonDTO(String lastName, String email) {
this.lastName = lastName;
this.email = email;
}
public String getLastName() {
return lastName;
}
public String getEmail() {
return email;
}
}
//避免投影DTO的样板代码您可以使用Project Lombok大大简化DTO的代码,
//它提供了一个@Value注释(不要与@Value之前的接口示例中显示的Spring的注释混淆)
按示例查询非常适合几种用例:
使用一组静态或动态约束查询数据存储。
频繁重构域对象,而不必担心破坏现有查询。
独立于底层数据存储API工作。
按示例查询也有几个限制:
不支持嵌套或分组的属性约束,例如firstname = ?0 or (firstname = ?1 and lastname = ?2)。
仅支持字符串的开始/包含/结束/正则表达式匹配以及其他属性类型的精确匹配。
例子:
erson person = new Person();
person.setLastName("Dave");
Example<Person> example = Example.of(person);
@Lock(LockModeType.READ)
PersonDTO findByLastName(String lastName) ;
//这个方法声明将导致触发查询中配备了LockModeType的READ
Spring Data提供了复杂的支持,可以透明地跟踪创建或更改实体的人员以及更改发生的时间。要从该功能中受益,您必须为您的实体类配备审计元数据,该元数据可以使用注释或通过实现接口来定义。
基于注释的审计元数据
我们提供@CreatedBy和@LastModifiedBy捕捉谁创建或修改的实体以及用户@CreatedDate和@LastModifiedDate捕捉时的变化发生了。
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener class="….data.jpa.domain.support.AuditingEntityListener" />
entity-listeners>
persistence-unit-defaults>
persistence-unit-metadata>
@Entity
@EntityListeners(AuditingEntityListener.class)
public class MyEntity {
}