我想使用JOOQ递归地获取自引用表的父级和子级。
目标是直接在POJO中获取。
我没有在JOOQ留档或其他任何地方找到任何这样的例子,但我认为结合多集和递归JOOQ方法是可能的。https://www.jooq.org/doc/3.14/manual/sql-building/sql-statements/with-recursive-clause/https://www.jooq.org/doc/latest/manual/sql-building/column-expressions/multiset-value-constructor/
到目前为止,我的问题和我所做的细节(我在这里简化了表格和对象):
自引用表视图项:
POJO:
public class ViewItem {
private final String id;
private final List<ViewItem> childrens;
public ViewItem(final String id) {
this.id = id;
this.childrens = new ArrayList<>();
}
public Integer getId() {
return id;
}
public void addChild(final ViewItem child) {
this.childrens.add(child);
}
public List<ViewItem> getChildrens() {
return childrens;
}
}
用JOOQ选择:
public List<ViewItem> getViewItems(final String viewId) throws IOException {
final CommonTableExpression<?> cte = DSL.name("t")
.as(DSL
.select(Tables.VIEW_ITEM.ID, Tables.VIEW_ITEM.PARENT_ID,
DSL.multiset(DSL.select().from(DSL.table("t")).join(Tables.VIEW_ITEM)
.on((DSL.field(DSL.name("t", "parent_id")))
.eq(Tables.VIEW_ITEM.ID)))
.as("childrens"))
.from(Tables.VIEW_ITEM).where(Tables.VIEW_ITEM.ID.eq(viewItemId)));
final List<ViewItem> items =
dslContext.withRecursive(cte).selectFrom(cte).fetch().into(ViewItem.class);
return items;
}
但在运行查询时接收堆栈以下跟踪:
org.jooq.exception.DataAccessException: SQL [set @t = @@group_concat_max_len; set @@group_concat_max_len = 4294967295; with recursive `t2` as (select `tedcvsrepo`.`view_item`.`sort_order`, `tedcvsrepo`.`view_item`.`structure_id`, `tedcvsrepo`.`view_item`.`template_id`, `tedcvsrepo`.`view_item`.`parent_structure_id`, `tedcvsrepo`.`view_item`.`template`, `tedcvsrepo`.`view_item`.`draft`, `tedcvsrepo`.`view_item`.`draft_reason`, (select coalesce(json_merge_preserve('[]', concat('[', group_concat(json_array() separator ','), ']')), json_array()) from (select * from t2 join `tedcvsrepo`.`view_item` on `t2`.`parent_structure_id` = `tedcvsrepo`.`view_item`.`structure_id`) as `t`) as `childrens` from `tedcvsrepo`.`view_item` where (`tedcvsrepo`.`view_item`.`view_id` = ? and `tedcvsrepo`.`view_item`.`parent_structure_id` = ?) order by `tedcvsrepo`.`view_item`.`sort_order` asc) select `t2`.`sort_order`, `t2`.`structure_id`, `t2`.`template_id`, `t2`.`parent_structure_id`, `t2`.`template`, `t2`.`draft`, `t2`.`draft_reason`, `t2`.`childrens` from `t2`; set @@group_concat_max_len = @t;]; In recursive query block of Recursive Common Table Expression 't2', the recursive table must be referenced only once, and not in any subquery
at org.jooq_3.16.5.MYSQL.debug(Unknown Source)
at org.jooq.impl.Tools.translate(Tools.java:3102)
at org.jooq.impl.DefaultExecuteContext.sqlException(DefaultExecuteContext.java:670)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:354)
at org.jooq.impl.AbstractResultQuery.fetch(AbstractResultQuery.java:284)
at org.jooq.impl.SelectImpl.fetch(SelectImpl.java:2843)
at eu.europa.ec.mdm.repository.ViewRepository.getViewMultiselect(ViewRepository.java:116)
at eu.europa.ec.mdm.repository.ViewRepository$$FastClassBySpringCGLIB$$99dace9d.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)
at eu.europa.ec.mdm.repository.ViewRepository$$EnhancerBySpringCGLIB$$80c1116d.getViewMultiselect(<generated>)
at eu.europa.ec.mdm.repository.ViewRepositoryIt.getViewMultiselectTest(ViewRepositoryIt.java:33)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:95)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:91)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:60)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.sql.SQLException: In recursive query block of Recursive Common Table Expression 't2', the recursive table must be referenced only once, and not in any subquery
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:371)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.execute(HikariProxyPreparedStatement.java)
at org.jooq.tools.jdbc.DefaultPreparedStatement.execute(DefaultPreparedStatement.java:219)
at org.jooq.impl.Tools.executeStatementAndGetFirstResultSet(Tools.java:4327)
at org.jooq.impl.AbstractResultQuery.execute(AbstractResultQuery.java:230)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:340)
... 83 more
我是做错了什么,还是根本没有办法实现我想用JOOQ做的事情?
您的问题非常相似,但与此不完全相同:从Postgres和jOOQ中的分层表递归生成JSON树
这个问题没有一个非常方便的jOOQ答案,它在PostgreSQL上只使用SQL/JSON,这在递归方面比MySQL更强大。在jOOQ中完全使用递归和多重集将非常困难。也许,只需以平面格式获取数据,然后将其组装到实用程序中?
有一个功能请求可以帮助您在jOOQ中开箱即用,但对于jOOQ 3.17,考虑到复杂性,它还不是优先事项:https://github.com/jOOQ/jOOQ/issues/12341
问题内容: 使用MySQL,我想从具有此类字段结构的表中返回父母列表。ID,PARENTID,NAME(标准的父子层次结构)。我想遍历树以返回所有“父母”的列表。 我意识到“嵌套集”可能是处理此问题的更好方法-但目前我无法更改数据的结构。我将来会希望这样做。当前-我的数据集实际上将包含一些深度级别- 没什么疯狂的……也许2-5,所以我的递归命中不应太“昂贵”。 我已经看过SQL Server获取父
问题内容: 我的数据库看起来像(pligg cms,样本数据) 假设,如何获取芝加哥的顶级parentID,它应该是位置。 我是否在php中编写了递归函数,或者在mysql中可行? 问题答案: 该网站非常好地概述了在mysql和PHP中存储分层数据的不同方法。要回答您的问题,最简单的方法是使用php和递归。您可以使用其他方法,例如,不需要多个数据库查询。但是,在处理大量插入和更新时,此方法的实现可
我一直在使用模式。方法来获取模式中的表列表,但今天我发现该方法返回的是执行jOOQ代码生成时存在的表列表,而不是此时存在的表。 我的具体用例是随着时间的推移创建表(自动分区),我们的Java服务对它们执行一些操作。 在jOOQ中有没有办法从DB中获取当前的表列表? 我可以求助于查询信息模式。直接使用表,但我更愿意重用来自jOOQ的方法(如果可用的话)。
问题内容: 我有这个小问题。 该表基本上如下所示 学科 SubjectId SubjectName ParentSubjectId 引用主题表本身。并且可以下降很多级别(没有特定数量的级别) 示例(仅出于示例目的,使用国家/地区): 等等.. SubjectID是GUID ParentSubjectID也是GUID。 样本概述:http : //i.imgur.com/a2u2CfT.png 它甚
问题内容: 嗨,我有一个引用自己的表,我需要能够从给定的父ID中选择父及其所有子记录。 我的表如下: 因此,对于上面的示例,我希望能够传递值1并获取上面的所有记录。 到目前为止,我已经提出了以下递归表值函数,但是它的行为不符合预期(仅返回第一条记录)。 问题答案: 你可以试试这个
我有内部节点和终端节点的树状结构: 我现在有一个