java - 在 JOOQ 中建立动态表连接
问题描述
我使用 JOOQ 作为 SQL 构建器工具,然后在 jdbcTemplate 中执行。我需要动态地将表连接添加到 from 子句。目前我正在这样做..
SelectJoinStep<?> selectClause = select(field("ColumnA"), field("ColumnB"))
.from(table("TableA"));
if(condition) {
selectClause.join(table("TableB), JoinType.JOIN).on(field("columnA").eq(field("columnB")));
}
然后我将 select 子句与 where 子句结合起来。
org.jooq.Query ps = selectClause.where(whereClause);
这工作正常,但现在我想引入分页,所以我需要将所选字段换出一个简单的计数,如果我可以在这个计数查询中重用 from 子句会很好,但我不能因为 select 和 from 子句在同一个变量中。
更新..为什么我不能像这样动态地建立 from 子句......
List<Field<?>> fields = new ArrayList<Field<?>>();
fields.add(...);
Table<?> from = table("TableA");
if(condition) {
from.join(table("TableB), JoinType.JOIN).on(field("columnA").eq(field("columnB")));
}
org.jooq.Query ps = select(fields).from(from);
如果条件为真,表连接不会出现在生成的 SQL 中?
解决方案
将 jOOQ 用于动态 SQL 的最佳方法是功能性更强的方法。不要考虑在某些条件下“交换”部分查询。想想你的查询的哪些部分是由谁通过函数提供的?例如:
ResultQuery<?> query(
Supplier<Collection<SelectField<?>>> select,
boolean condition,
boolean paginate
) {
Condition whereClause = ...;
Table<?> from = table("TableA");
if (condition)
from = from.join(table("TableB")).on(field("ColumnA").eq(field("ColumnB")));
return select(select.get())
.from(from)
.where(whereClause)
.limit(paginate ? 10 : Integer.MAX_VALUE); // Could be done differently
}
现在调用上面的:
query(() -> Arrays.asList(field("ColumnA"), field("ColumnB")), true, true);
query(() -> Arrays.asList(count()), true, false);
当然,另一种选择是使用窗口函数来计算该计数值,而不是运行两个查询:
count().over()
推荐阅读
- ruby-on-rails - Heroku/Bootstrap/Rails 下拉菜单
- android - Android Inject Dependency (Dagger 2) Inside Fragment Using @ContributesAndroidInjector
- wordpress - 卸载后恢复wordpress插件
- arrays - 在 ngFor 的帮助下迭代 Angular5 中的 JSON 数组
- php - PHP:如何在本地套接字上启用 socket_connect 超时?
- wordpress - 如何在前端的可视化作曲家中显示新的自定义元框
- c++ - 计算大斐波那契数时还有精度误差
- python-3.x - aiohttp 中的 os.kill 与 process.terminate
- bazel - 如果我的 bazel 目标生成未在其输出中指定的文件,我会出错吗?
- laravel-5 - 拉拉维尔 5.6。文件属性不来