如何在Jooq处理日期?

当我们使用普通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不支持Oracle和Lukas的TO_CHAR方法给出了一些替代方法

编写谓词的更好方法

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

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

实现与方言无关的自定义TO_CHAR()函数。

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

 class ToChar extends CustomField { 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 toChar(Field field, String format) { return new ToChar(field, DSL.inline(format)); } }