QueryDSL,Spring Data:使用Predicate在常量和数据库值之间选择日期时间

时间:2016-02-15 15:09:43

标签: spring-data querydsl mysema

您好我想为Spring数据生成谓词QueryDSLRepository,它会生成以下查询(或等效的):

SELECT * FROM USER user JOIN PASSWORD_POLICY policy
ON
    user.password_policy_oid = policy.password_policy_oid
WHERE
    user.password_expiration_date BETWEEN CURRENT TIMESTAMP - (SELECT EXPIRATION_WARN_PERIOD_IN_DAYS FROM PASSWORD_POLICY subQueryPolicy WHERE subQueryPolicy.password_policy_oid = policy.password_policy_oid) DAYS AND CURRENT TIMESTAMP

此查询的含义是: 给我所有密码即将过期的用户

即将到期我的意思是 - 密码到期日期介于现在和之间(现在 - 来自PASSWORD_POLICY表的EXPIRATION_WARN_PERIOD_IN_DAYS)

有可能吗?

1 个答案:

答案 0 :(得分:1)

这可能只能通过使用Spring Data谓词运行器来完成。 AFAIK jpql不支持这样的日期时间操作(添加天等)。所以如果你仍然想要使用Querydsl你可以做的是使用原生JPASQLQuery。不幸的是,加入映射实体并不容易,另一个缺点是在Querydsl中日期时间操作功能也不太好。但我能够解决你的问题。

假设:

用户包含@ManyToOne PassworPolicy字段,该字段由PASSWORD_POLICY_OID列映射。

DB2数据库

import static model.QPasswordPolicy.passwordPolicy;
import static model.QUser.user;
import static com.mysema.query.sql.SQLExpressions.datediff;
import static com.mysema.query.types.expr.DateTimeExpression.currentTimestamp;
...
NumberPath<Integer> userPasswordPolicyOidPath = new NumberPath<>(Integer.class, QUser.user, "PASSWORD_POLICY_OID");
    QPasswordPolicy subQueryPolicy = new QPasswordPolicy("subQueryPolicy");

    List<Integer> userIds =
            new JPASQLQuery(entityManager, new DB2Templates())
                    .from(user)
                    .join(passwordPolicy).on(passwordPolicy.passwordPolicyOid.eq(userPasswordPolicyOidPath))
                    .where(datediff(DatePart.day, currentTimestamp(DateTime.class), user.passwordExpirationDate)
                            .lt(new JPASubQuery().from(subQueryPolicy)
                                    .where(passwordPolicy.passwordPolicyOid.eq(subQueryPolicy.passwordPolicyOid))
                                    .unique(passwordPolicy.expirationPeriodInDays)))
                    .list(user.userOid);

可能还有一个条件expirationDate&lt;需要currentTimeStamp来满足逻辑,但我会留给你:)

PS userPasswordPolicyOidPath很丑,但我不知道如何摆脱这个:(