【问题标题】:QueryDSL and date diffQueryDSL 和日期差异
【发布时间】:2015-10-08 16:13:23
【问题描述】:

我正在尝试使用 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 都会出现此错误。

那段代码有什么问题?

谢谢

【问题讨论】:

    标签: mysql jpa spring-data-jpa querydsl


    【解决方案1】:

    很遗憾,Querydsl JPA 尚不支持 diff_years

    【讨论】:

      【解决方案2】:

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

      自定义查询请求(计算 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();
      

      【讨论】:

        猜你喜欢
        • 2015-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-26
        • 2022-01-19
        • 2012-12-13
        • 1970-01-01
        相关资源
        最近更新 更多