How to Handle Date in Jooq?

2019-05-04 18:26发布

问题:

When we are using plain JDBC connection we are using below code to format date or convert date

 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)");
           }

Now we are using JOOQ Do you think we have to convert date like we did previously or JOOQ can handle this type of problem internally.? As i checked right now JOOQ not supported TO_CHAR method of Oracle and Lukas given some alternative of this Here

回答1:

A better way to write your predicate

Since you're formatting dates only to compare them, you should probably just compare the date values themselves, which will be much faster as your database will be able to use an index:

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

Implementing a dialect-independent custom TO_CHAR() function.

You should create a CustomField for this purpose. This will allow you to interact with jOOQ's query rendering and variable binding lifecycle in order to render SQL dialect specific clauses depending on the RenderContext's underlying SQLDialect. Essentially this boils down to writing (assuming 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");
        }
    }
}

And then, you can write your own static utility methods as such:

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


标签: java sql jooq