简体   繁体   English

如何使用jOOQ按参数顺序从模板生成SQL?

[英]How to generate SQL from template with order by parameter using jOOQ?

I generate the SQL template like this with jOOQ 3.11.11.我用 jOOQ 3.11.11 生成了这样的 SQL 模板。

DSLContext context = new DefaultDSLContext(conf);
Query query = context.select()
    .from("table1")
    .where(DSL.field("report_date").eq(DSL.param("bizdate")))
    .orderBy(DSL.param("sort"));
String sqlTemp = context.renderNamedParams(query);

SQL template: SQL 模板:

select * 
from table1 
where report_date = :bizdate 
order by :sort

The SQL template is stored and the params are decided at realtime query condition.存储SQL模板,并根据实时查询条件决定参数。

ResultQuery resultQuery = context.resultQuery(sqlTemp, DSL.param("bizdate", "20190801"), DSL.param("sort", "id desc"));

The realtime SQL:实时 SQL:

select * 
from table1 
where report_date = '20190801' 
order by 'id desc'

There is something wrong with the order by clause. order by 子句有问题。

So.所以。 How to replace the order by param sort with "id desc" or "name asc" and eliminate the quotes?如何用“id desc”“name asc”替换参数排序的顺序并消除引号?

DSL.param() creates a bind variable, which is generated as ? DSL.param()创建一个绑定变量,生成为? in SQL, or :bizdate if you choose to use named parameters, or '20190801' if you choose to inline the bind variables.在 SQL 中,或者:bizdate如果您选择使用命名参数,或者'20190801'如果您选择内联绑定变量。 More about bind variables can be seen here . 可以在此处查看有关绑定变量的更多信息

You cannot use DSL.param() to generate column references or keywords.您不能使用DSL.param()生成列引用或关键字。 A column expression (eg a reference) is described in the jOOQ expression tree by the Field type.列表达式(例如引用)在 jOOQ 表达式树中由Field类型描述。 Keywords are described by theKeyword type, but you probably do not want to go this low level.关键字是由Keyword类型描述的,但您可能不想这么低级。 Instead you want to handle some of the logic in your query expression.相反,您希望处理查询表达式中的一些逻辑。 For example:例如:

String sortField = "id";
SortOrder sortOrder = SortOrder.ASC;

Query query = context.select()
    .from("table1")
    .where(DSL.field("report_date").eq(DSL.param("bizdate")))
    .orderBy(DSL.field(sortField).sort(sortOrder));

The mistake you're making is to think that you can use a single SQL template for all sorts of different dynamic SQL queries, but what if you're dynamically adding another predicate?您所犯的错误是认为您可以将单个 SQL 模板用于各种不同的动态 SQL 查询,但是如果您要动态添加另一个谓词呢? Or another join?还是另一种加入? Or another column?还是另一列? You'd have to build a different jOOQ expression tree anyway.无论如何,您必须构建不同的 jOOQ 表达式树。 Just like here.就像这里一样。 You could store two SQL strings (one for each sort order), and repeat that for each sort column.您可以存储两个 SQL 字符串(每个排序顺序一个),并为每个排序列重复该操作。

But, instead of pre-generating a single SQL string, I recommend you extract a function that takes the input parameters and generates the query every time afresh, eg:但是,我建议您提取一个接受输入参数并每次重新生成查询的函数,而不是预先生成单个 SQL 字符串,例如:

ResultQuery<?> query(String bizDate, Field<?> sortField, SortOrder sortOrder) {
    return context.selectFrom("table1")
                  .where(field("report_date").eq(bizDate))
                  .orderBy(sortField.sort(sortOrder));
}

Here is some further reading about using jOOQ for dynamic SQL:以下是有关使用 jOOQ 进行动态 SQL 的进一步阅读:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM