Spring Boot 2 - JPA + 多对多表上的可分页问题
Spring Boot 2 - JPA + Pagable problem on ManyToMany tables
在 Spring Boot 2 JPA 中,我有以下两个多对多实体。
1- 劳动力:
@Entity
public class Labor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(length = 100, nullable = false)
private String name;
@Column(length = 50)
private String mobile;
private Date dateOfBirth;
private boolean male;
private boolean active;
private String brife;
@Column(length = 500)
private String specifcation;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "labor_tag",
joinColumns = @JoinColumn(name = "labor_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id"))
private Set<Tag> tags = new HashSet<>();
}
和标记 table:
@Entity
public class Tag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(length = 100, unique = true)
private String name;
private boolean active = true;
@ManyToMany(cascade = CascadeType.ALL, mappedBy = "tags")
@JsonIgnore
private Set<Labor> labors = new HashSet<>();
}
然后我定义了 Labor Repository 来查询具有特定标签 ID、性别或年龄的 Labors
@Repository
public interface LaborReoistory extends JpaRepository<Labor, Long> {
@Query("select l from Labor l join l.tags t where (:tid is null or t.id in :tid) and " +
"(:isMale is null or :isMale = TRUE) and " +
"((:startYear is null or :endYear is null or :startYear > :endYear) or year(l.dateOfBirth) >= :startYear and year(l.dateOfBirth) <= :endYear)")
Page<Labor> findLaborsByCondition(@Param("tid") final long[] tid,
@Param("isMale") final Boolean isMale,
@Param("startYear") final Integer startYear,
@Param("endYear") final Integer endYear,
final Pageable pageable);
}
当我在我的控制器中使用这个存储库时,我发现 totalElements 属性 的 Pagable 返回计数到 [=32= 中的记录](在本例中为 16 条记录),但我真正想要的是 totalElements 在给定条件下依靠 Labors。 JPA Pagable 是否支持此类查询,或者我如何找到解决方法?
谢谢
加入后会有重复的Labor
,但totalElements
是使用查询的总行数。因此,您应该在 Labour
上使用 Distinct
来获取不同 Labour
的计数
@Query("select distinct l from Labor l join l.tags t where (:tid is null or t.id in :tid) and " +
"(:isMale is null or :isMale = TRUE) and " +
"((:startYear is null or :endYear is null or :startYear > :endYear) or year(l.dateOfBirth) >= :startYear and year(l.dateOfBirth) <= :endYear)")
在 Spring Boot 2 JPA 中,我有以下两个多对多实体。
1- 劳动力:
@Entity
public class Labor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(length = 100, nullable = false)
private String name;
@Column(length = 50)
private String mobile;
private Date dateOfBirth;
private boolean male;
private boolean active;
private String brife;
@Column(length = 500)
private String specifcation;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "labor_tag",
joinColumns = @JoinColumn(name = "labor_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id"))
private Set<Tag> tags = new HashSet<>();
}
和标记 table:
@Entity
public class Tag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(length = 100, unique = true)
private String name;
private boolean active = true;
@ManyToMany(cascade = CascadeType.ALL, mappedBy = "tags")
@JsonIgnore
private Set<Labor> labors = new HashSet<>();
}
然后我定义了 Labor Repository 来查询具有特定标签 ID、性别或年龄的 Labors
@Repository
public interface LaborReoistory extends JpaRepository<Labor, Long> {
@Query("select l from Labor l join l.tags t where (:tid is null or t.id in :tid) and " +
"(:isMale is null or :isMale = TRUE) and " +
"((:startYear is null or :endYear is null or :startYear > :endYear) or year(l.dateOfBirth) >= :startYear and year(l.dateOfBirth) <= :endYear)")
Page<Labor> findLaborsByCondition(@Param("tid") final long[] tid,
@Param("isMale") final Boolean isMale,
@Param("startYear") final Integer startYear,
@Param("endYear") final Integer endYear,
final Pageable pageable);
}
当我在我的控制器中使用这个存储库时,我发现 totalElements 属性 的 Pagable 返回计数到 [=32= 中的记录](在本例中为 16 条记录),但我真正想要的是 totalElements 在给定条件下依靠 Labors。 JPA Pagable 是否支持此类查询,或者我如何找到解决方法?
谢谢
加入后会有重复的Labor
,但totalElements
是使用查询的总行数。因此,您应该在 Labour
上使用 Distinct
来获取不同 Labour
@Query("select distinct l from Labor l join l.tags t where (:tid is null or t.id in :tid) and " +
"(:isMale is null or :isMale = TRUE) and " +
"((:startYear is null or :endYear is null or :startYear > :endYear) or year(l.dateOfBirth) >= :startYear and year(l.dateOfBirth) <= :endYear)")