如何构建一个动态查询,添加迄今为止的天数并使用条件 API 将该日期与另一个日期进行比较?
How to build a dynamic query which add number of days to date and compare that date with another date using criteria API?
我有一个 A table 和一个 B table。 JPA entity
、A 和 B classes 分别有 joda.time.datetime
Persistent Field
说 retentionDate
和 lastmodifiedDate
。 A 还有一个 Persistent Field
类型 int
表示 days
。现在我想将 add number of a.days
转换为 a.retentionDate
,然后使用 JPA criteria API
将其与 b.lastmodifiedDate
进行比较。
一个实体class
@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实体class
@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)
);
请在上述查询中帮助我在 retentionDate 中添加天数。谢谢
您可以使用 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
我有一个 A table 和一个 B table。 JPA entity
、A 和 B classes 分别有 joda.time.datetime
Persistent Field
说 retentionDate
和 lastmodifiedDate
。 A 还有一个 Persistent Field
类型 int
表示 days
。现在我想将 add number of a.days
转换为 a.retentionDate
,然后使用 JPA criteria API
将其与 b.lastmodifiedDate
进行比较。
一个实体class
@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实体class
@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)
);
请在上述查询中帮助我在 retentionDate 中添加天数。谢谢
您可以使用 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