QueryDSL 和日期差异

QueryDSL and date diff

我正在尝试使用 QueryDSL 计算具有日期差异的用户年龄。

QPlayer $ = QPlayer.player;
BooleanBuilder builder = new BooleanBuilder();
builder.and(Expressions.dateOperation(Integer.class, Ops.DateTimeOps.DIFF_YEARS, Expressions.currentDate(), $.birthDate).between(3, 5));
playerRespository.findAll(builder);

但失败并出现此错误

Hibernate: select player0_.user_id as id1_31_, player0_1_.user_birthdate as user_bir2_31_, player0_1_.user_register_date as user_reg3_31_, player0_1_.user_delete_date as user_del4_31_, player0_1_.user_email as user_ema5_31_, player0_1_.user_first_name as user_fir6_31_, player0_1_.user_last_name as user_las7_31_, player0_1_.user_login as user_log8_31_, player0_1_.user_password as user_pas9_31_, player0_1_.user_status as user_st10_31_, player0_.player_description as player_d1_20_, player0_.player_height as player_h2_20_, player0_.player_picture as player_p3_20_, player0_.player_role as player_r4_20_, player0_.player_weight as player_w5_20_ from players player0_ inner join users player0_1_ on player0_.user_id=player0_1_.id where (diff_years(player0_1_.user_birthdate, current_date) between ? and ?) and (lower(player0_1_.user_first_name) like ? escape '!')
2015-07-19 14:22:16,881 [main] ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - FUNCTION xxx.diff_years does not exist

使用 MYSQL 数据库或 HSQL 时都会出现此错误。

该代码有什么问题?

谢谢

diff_years 很遗憾,Querydsl JPA 尚不支持

如何使用 queryDsl 自定义 MYSQL 方言。我展示了如何将 datediff 用于 select 语句。

自定义查询请求(计算now和createdDate之间的差异):

public List<MyDto> get() {
        JPAQuery<HotelShortDto> query = new JPAQuery<>(em, MySQLJPQLTemplates.DEFAULT)
                .select(Projections.constructor(MyDto.class,
                        Expressions.dateOperation(Integer.class, Ops.DateTimeOps.DIFF_MINUTES, Expressions.currentDate(), myEntity.createdDate),
                ))
                .from(myEntity)
        return query.fetch();

}

在 MYSQL 函数中获取分钟差异是 TIMESTAMPDIFF(对于 H2 db datediff)

配置:

public class MySQLJPQLTemplates extends JPQLTemplates {

    public static final MySQLJPQLTemplates DEFAULT = new MySQLJPQLTemplates();

    public MySQLJPQLTemplates() {
        this(DEFAULT_ESCAPE);
        add(Ops.DateTimeOps.DIFF_MINUTES, "TIMESTAMPDIFF(MINUTE,{0},{1})");
    }

    public void reconfigureForH2() {
        add(Ops.DateTimeOps.DIFF_MINUTES, "datediff(MINUTE,{0},{1})");
    }

    public MySQLJPQLTemplates(char escape) {
        super(escape);
    }
}

此外,TIMESTAMPDIFF 不是休眠的标准函数,因此需要注册

public class CustomMySQLDialect extends MySQL57Dialect {

    public CustomMySQLDialect() {
        super();
        registerFunction("TIMESTAMPDIFF", new StandardSQLFunction("TIMESTAMPDIFF"));
    }

}

和application.yaml

...
spring.jpa.database-platform=com.my.project.CustomMySQLDialect
...

用于在执行查询之前测试调用

MySQLJPQLTemplates.DEFAULT.reconfigureForH2();