java - 如何构建一个动态查询,添加迄今为止的天数并使用条件 API 将该日期与另一个日期进行比较?

标签 java hibernate jpa criteria-api

我有一张 A 表和一张 B 表。 JPA 实体,A 和 B 类都有 joda.time.datetime Persistent FieldretentionDate lastmodifiedDate 分别。 A 有一个 int 类型的 Persistent Field 表示 days。现在我想将 add number of a.daysa.retentionDate 中,然后使用 JPA 标准将其与 b.lastmodifiedDate 进行比较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)
);

请在上述查询中帮助我在 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

关于java - 如何构建一个动态查询,添加迄今为止的天数并使用条件 API 将该日期与另一个日期进行比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46340025/

相关文章:

Java hibernate : How to set column varchar to max?

java - 如何在Spring Gradle项目中将Lombok与JPA元模型一起使用?

spring - 我如何使用带有 jpa 的 spring 调用存储过程

java - 无法在java中包含自己创建的包

java - Freemarker 未在哈希中找到现有元素

java - 在 Dao 方法中使用参数来获取实体是只读访问的最有效方法

java - 更新 hibernate 对象时将数据类型 nvarchar 转换为十进制错误时出错

java - Hibernate + c3p0 Pool + ehcache 启动失败

java - glassfish 7 + jakarta ee 10 + hibernate 实体管理器 java.lang.NoClassDefFoundError : org/hibernate/annotations/common/reflection/ReflectionManager

java - ElasticSearch - 使用 FilterBuilder