我有一个A桌子和一个B桌子。两者JPA entity,A和B类已经joda.time.datetime Persistent Field说的retentionDate和lastmodifiedDate分别。A还有一个Persistent Field类型的int说days。现在,我想add number of a.days进入a.retentionDate,然后将其与b.lastmodifiedDateusing 进行比较JPA criteria API。
JPA entity
joda.time.datetime
Persistent Field
retentionDate
lastmodifiedDate
int
days
add number of a.days
a.retentionDate
b.lastmodifiedDate
JPA criteria API
实体类
@Entity @Table(name = "A") @Data @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @EqualsAndHashCode(of = "id", callSuper = false) public class A extends AbstractBaseEntity { @Id @GeneratedValue(generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid2") @Column(unique = true, length = 36) private String id; @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") @JsonDeserialize(using = DateTimeDeserializer.class) @JsonSerialize(using = DateTimeSerializer.class) private DateTime retentionDate; private int days; }
B实体类
@Entity @Table(name = "B") @Data @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @EqualsAndHashCode(of = "id", callSuper = false) public class B extends AbstractBaseEntity { @Id @GeneratedValue(generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid2") @Column(unique = true, length = 36) private String id; @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") @JsonDeserialize(using = DateTimeDeserializer.class) @JsonSerialize(using = DateTimeSerializer.class) private DateTime lastmodifiedDate ; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "A_ID") private A a; }
JPA标准查询:
CriteriaQuery<B> b = builder.createQuery(B.class); Root<B> fromB = criteria.from(B.class); Expression<DateTime> lastmodifiedDate = fromB.get(B_.lastmodifiedDate); Expression<DateTime> retentionDate = fromB.get(B_.a).get("retentionDate"); Expression<int> days = fromB.get(B_.a).get("days"); Expression<DateTime> newDate = // how to add days in retentionDate here so it became a newDate? b.select(fromB); b.where(builder.greaterThanOrEqualTo(newDate , lastmodifiedDate) );
请在上述查询中为我提供帮助,以在保留日期中添加天数。 谢谢。
您可以使用CriteriaBuilder#function()执行要添加days到中的数据库函数retentionDate。我已经使用DATEADD()制作了一个示例,因为我的测试项目使用H2数据库运行。
ParameterExpression<String> dayUnit = builder.parameter(String.class, "dayUnit"); Expression<DateTime> newDate = builder.function("DATEADD", DateTime.class, dayUnit, days, retentionDate);
完整的示例:
CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<B> cq = builder.createQuery(B.class); Root<B> fromB = cq.from(B.class); Expression<DateTime> lastmodifiedDate = fromB.get(B_.lastmodifiedDate); Expression<DateTime> retentionDate = fromB.get(B_.a).get("retentionDate"); Expression<Integer> days = fromB.get(B_.a).get("days"); ParameterExpression<String> dayUnit = builder.parameter(String.class, "dayUnit"); Expression<DateTime> newDate = builder.function("DATEADD", DateTime.class, dayUnit, days, retentionDate); cq.where(builder.greaterThanOrEqualTo(newDate, lastmodifiedDate)); TypedQuery<B> tq = entityManager.createQuery(cq.select(fromB)); tq.setParameter("dayUnit", "DAY"); List<B> results = tq.getResultList();
该查询将转换为SQL,如下所示:
select b0_.id as id1_1_, b0_.a_id as a_id3_1_, b0_.lastmodified_date as lastmodi2_1_ from b b0_ cross join a a1_ where b0_.a_id=a1_.id and DATEADD(?, a1_.days, a1_.retention_date)>=b0_.lastmodified_date