小编典典

如何在Jooq中处理日期?

sql

当我们使用普通的JDBC连接时,我们使用下面的代码格式化日期或转换日期

 if(argDB.equals("Oracle")){
       sb.append(" AND TO_CHAR(PaymentDate, 'YYYY-MM-DD') <= TO_CHAR(SYSDATE,'YYYY-MM-DD')");
          }
 else {
       sb.append(" AND CONVERT(VARCHAR(8), PaymentDate, 112) <= CONVERT(varchar(8), dbo.getdate(), 112)");
           }

现在我们正在使用JOOQ吗?您认为我们是否必须像以前一样转换日期,或者JOOQ可以在内部处理这种类型的问题??由于我现在检查JOOQ不支持TO_CHAROracle和卢卡斯的方法给出了这个有些另类这里


阅读 241

收藏
2021-04-22

共1个答案

小编典典

编写谓词的更好方法

由于您仅格式化日期以比较日期,因此您可能应该只比较日期值本身,因为数据库将能够使用索引,所以这将更快得多:

-- In SQL
ACCOUNT_PAYMENT.PAYMENT_DATE <= SYSDATE



// In jOOQ
ACCOUNT_PAYMENT.PAYMENT_DATE.le(DSL.currentDate())

实现与方言无关的自定义TO_CHAR()功能。

CustomField为此,您应该创建一个。这将允许您与jOOQ的查询呈现和变量绑定生命周期进行交互,以便根据RenderContext的基础呈现SQL方言特定的子句SQLDialect。从本质上讲,这可以归结为编写(假设使用jOOQ
3.2 API):

class ToChar extends CustomField<String> {
    final Field<?> arg0;
    final Field<?> arg1;
    ToChar(Field<?> arg0, Field<?> arg1) {
        super("to_char", SQLDataType.VARCHAR);
        this.arg0 = arg0;
        this.arg1 = arg1;
    }
    @Override
    public void toSQL(RenderContext context) {
        context.visit(delegate(context.configuration()));
    }
    @Override
    public void bind(BindContext context) {
        context.visit(delegate(context.configuration()));
    }
    private QueryPart delegate(Configuration configuration) {
        switch (configuration.dialect().family()) {
            case ORACLE:
                return DSL.field("TO_CHAR({0}, {1})", 
                    String.class, arg0, arg1);

            case SQLSERVER:
                return DSL.field("CONVERT(VARCHAR(8), {0}, {1})", 
                    String.class, arg0, arg1);

            default:
                throw new UnsupportedOperationException("Dialect not supported");
        }
    }
}

然后,您可以编写自己的静态实用程序方法,如下所示:

public class MyDSL {
    public static Field<String> toChar(Field<?> field, String format) {
        return new ToChar(field, DSL.inline(format));
    }
}
2021-04-22