Spring Data Jpa Specifications 还有另一种有趣的实现方式。
首先使用JpaSpecificationExecutor<Employee> 扩展您的存储库,如下所示:
public interface EmployeeRepository
extends JpaRepository<Employee, EmployeeId>, JpaSpecificationExecutor<Employee> {}
然后,假设您在地图中有员工姓名和位置(任何可迭代都可以):
Map<String, String> nameLocations = Map.of("Bob", "Nowhere", "Jules", "Here");
Specification<Employee> employeeSpec = Specification.where((root, query,
builder) -> builder.or(nameLocations.entrySet().stream()
.map(nameLocation -> builder.and(
builder.equal(root.get("id").get("name"), nameLocation.getKey()),
builder.equal(root.get("id").get("location"), nameLocation.getValue())))
.toArray(Predicate[]::new)));
List<Employees> employeesByNameAndLocation = employeeRepository.findAll(employeeSpec);
这将通过生成以下单个查询为您提供位置为“Nowhere”的名为“Bob”的员工和位置为“Here”的名为“Jules”的员工:
select employee0_.location as location1_0_, employee0_.name as name2_0_, employee0_.status as status3_0_, employee0_.desc as desc4_0_ from EMPLOYEE employee0_ where employee0_.name='Bob' and employee0_.location='Nowhere' or employee0_.name='Jules' and employee0_.location='Here'
如果您不喜欢规范,您也可以使用像 @Pranay Srivastava 建议的嵌入式对象:
@Embeddable
@Immutable
public class PartialEmployeeId implements Serializable {
@Column(name = "name", insertable = false, updatable = false)
private String name;
@Column(name = "location", insertable = false, updatable = false)
private String location;
public PartialEmployeeId(String name, String location) {
this.name = name;
this.location = location;
}
public PartialEmployeeId() {}
}
注意insertable 和updatable 标志以防止重复的列映射。然后将其嵌入到您的员工中
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
@EmbeddedId
EmployeeId id;
@Embedded
PartialEmployeeId partialId;
@Column(name = "DESC")
String desc;
}
,使用来自 Spring 数据 JPA 的派生查询更新您的存储库:
public interface EmployeeRepository
extends JpaRepository<Employee, EmployeeId>{
List<Employee> findByPartialIdIn(List<PartialEmployeeId> partialEmployeeIds);
}
并像这样使用它:
PartialEmployeeId nameAndLocation1 = new PartialEmployeeId("Bob", "Nowhere");
PartialEmployeeId nameAndLocation2 = new PartialEmployeeId("Jules", "Here");
List<Employees> employeesByNameAndLocation = employeeRepository.findByPartialIdIn(List.of(nameAndLocation1, nameAndLocation2));
这会生成与规范相同的单个 SQL 查询。