QueryDSL,Spring 数据:Select 常量和带有 Predicate 的数据库值之间的日期时间
QueryDSL, Spring Data: Select datetime between constant and database value with Predicate
您好,我想为 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
这个查询的意思是:
给我所有密码即将过期的用户
我的意思是即将过期 - 密码过期日期介于现在和(现在 - EXPIRATION_WARN_PERIOD_IN_DAYS 来自 PASSWORD_POLICY table)
可以吗?
这可能无法通过仅使用 Spring 数据谓词运行器来完成。 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 < currentTimeStamp 来满足逻辑,但我会留给你:)
PS
userPasswordPolicyOidPath 很难看,但我不知道如何摆脱它:(
您好,我想为 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
这个查询的意思是: 给我所有密码即将过期的用户
我的意思是即将过期 - 密码过期日期介于现在和(现在 - EXPIRATION_WARN_PERIOD_IN_DAYS 来自 PASSWORD_POLICY table)
可以吗?
这可能无法通过仅使用 Spring 数据谓词运行器来完成。 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 < currentTimeStamp 来满足逻辑,但我会留给你:)
PS userPasswordPolicyOidPath 很难看,但我不知道如何摆脱它:(