4

当我们使用纯 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 和 Lukas 的方法给出了一些替代方法

4

1 回答 1

6

编写谓词的更好方法

由于您格式化日期只是为了比较它们,您可能应该只比较日期值本身,这会更快,因为您的数据库将能够使用索引:

-- In SQL
ACCOUNT_PAYMENT.PAYMENT_DATE <= SYSDATE
// In jOOQ
ACCOUNT_PAYMENT.PAYMENT_DATE.le(DSL.currentDate())

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

CustomField您应该为此创建一个。这将允许您与 jOOQ 的查询渲染和变量绑定生命周期进行交互,以便根据RenderContext底层的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));
    }
}
于 2013-11-11T07:02:09.960 回答