我有一個 Employee(Employee 表)物體類,其中包含復合主鍵 EmployeeId(名稱、位置、狀態)。我只需要按選定的主鍵(名稱、位置)進行過濾。
@Entity
@Table(name = "EMPLOYEE")
class Employee {
@EmbeddedId
EmployeeId id;
@Column(name = "DESC")
String desc;
}
public class EmployeeId implements Serializable {
@Column(name = "name")
private String name;
@Column(name = "location")
private String location;
@Column(name = "status")
private String status;
}
但我不能使用以下,因為我沒有狀態值:
interface EmployeeJpaRepository extends JpaRepository<Employee, EmployeeId > {
List<Employee> findAllByIdIn(Set<EmployeeId > employeeId);
}
我可以用這個:
interface EmployeeJpaRepository extends JpaRepository<Employee, EmployeeId > {
List<Employee> findAllByIdNameAndIdPlanLocation(String name, String location);
}
這是我每次需要查詢的時候。對性能太差了。
基于性能的任何更好的方法?
uj5u.com熱心網友回復:
使用Spring Data Jpa 規范還有另一種有趣的方式來實作這一點。
首先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'
如果你不喜歡 Specifications,你也可以使用像 @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 查詢。
uj5u.com熱心網友回復:
您可以考慮不同的方法:
1.制作2個復合主鍵 制作一個帶有名稱和位置的復合主鍵。另一個具有所有屬性(名稱、位置和狀態)。
2.撰寫您正在使用的各自資料庫供應商(MySQL、PostgreSQL 等)的自定義查詢。@Query在您在 Repository 類中呼叫的方法上方使用Annotation。
例子:
@Query("Select e from EmployeeId where e.name like %?1% and e.location like %?1%")
List<Employee> findAllByIdNameAndIdPlanLocation(String name, String location);
我不確定他們是否會按照您的要求提高性能。但你也可以考慮它們。
更新
有關該主題的更多報道,請參閱鏈接。
JPA
Spring JPA 中的復合主鍵和@Embedded@EmbeddedId
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/346557.html
