我的任务是为jooq例程创建一个日志生成器。 我开始周围的Googling,结束了使用这个:http://www.jooq.org/doc/latest/manual/sql-execution/execute-listeners/漂亮的登录jooq
在给定的例子笔者利用现成可用
DSL.using(configuration).renderInlined(ctx.routine());
这看起来有前途的,但还不够,因为jooq没有显示例程中的字段名称,只是值。大的例程很难理解结果。我试图玩弄其他的可能性,但无济于事...
我写了我自己的日志格式化程序,它甚至工作。 现在:)
因此,我的问题来了:它只适用于结果。
为什么?因为我只能访问ctx.routine().getReturnValue()
。 ctx.routine().getInValues()
受保护。
所以这里来一些问题:为什么getInValues()
是受保护的?它可以改为公开吗?或者,也许有一个解决方法...?
作为解决方法,我尝试使用反射,这显示了另一个问题。 getReturnValue()
给我一个UDTRecord
,它有intoMap()
方法返回Map<String, Object>
。 getInValues
返回Map<Parameter<?>, Field<?>>
。我不知道如何与后者合作...我决定不乱用全库,在这里问我的问题:)
期待您的答复
问候
编辑:在下面粘贴我的代码的第一稿。也许它会帮助你理解我想要达到的目标。
import org.jooq.*;
import org.jooq.impl.*;
import java.util.Map;
public class OutputLogBuilder
{
private final static String NEW_LINE = System.getProperty("line.separator");
private final static String TAB = "\t";
private final static String COL_RECORD_SEPARATOR = " --> ";
static String buildOutputLog(final ExecuteContext ctx)
{
StringBuilder sb = new StringBuilder(NEW_LINE);
handleUDTRecord(sb, ctx.routine().getReturnValue(), 0);
return sb.toString();
}
private static void handleUDTRecord(final StringBuilder sb, final Object input, int depth)
{
UDTRecordImpl record = (UDTRecordImpl) input;
appendData(sb, record.getUDT().getName(), "", depth);
depth++;
for (Map.Entry<String, Object> entry : record.intoMap().entrySet()) {
String entryKey = entry.getKey();
Object entryValue = entry.getValue();
if (isArrayUDTRecord(entryValue)) {
handleArrayUDTRecord(sb, entryValue, depth);
} else if (isUDTRecord(entryValue)) {
handleUDTRecord(sb, entryValue, depth);
} else {
appendData(sb, entryKey, entryValue, depth);
}
}
}
private static boolean isArrayUDTRecord(final Object object)
{
return object instanceof ArrayRecordImpl;
}
private static boolean isUDTRecord(final Object object)
{
return object instanceof UDTRecordImpl;
}
private static void handleArrayUDTRecord(final StringBuilder sb, final Object input, int depth)
{
ArrayRecordImpl arrayRecord = (ArrayRecordImpl) input;
appendData(sb, arrayRecord.getName(), "", depth);
depth++;
for (Object arrayElement : arrayRecord.getList()) {
if (isArrayUDTRecord(arrayElement)) {
handleArrayUDTRecord(sb, arrayElement, depth);
} else if (isUDTRecord(arrayElement)) {
handleUDTRecord(sb, arrayElement, depth);
} else {
appendData(sb, input, "", depth);
}
}
}
private static void appendData(final StringBuilder sb, final Object key, final Object value, int depth)
{
for (int i = 0; i < depth; i++) {
sb.append(TAB);
}
sb.append(key + COL_RECORD_SEPARATOR + value);
sb.append(NEW_LINE);
}
}
EDIT2:与反思我设法弄清楚如何建立我的日志,AbstractParam
,UDTConstant
等,但它们是包保护... 下面是示例代码片段来检查元素的类型
for (Map.Entry<Parameter<?>, Field<?>> entry : inValues.entrySet()) {
Parameter entryKey = entry.getKey();
Field entryValue = entry.getValue();
if(entryValue instanceof UDTConstant){ //access error
//do smth
}
}
所以每当我检查自己的类型,我得到
Caused by: java.lang.IllegalAccessError: tried to access class org.jooq.impl.UDTConstant from class org.jooq.impl.OutputLogBuilder
即使(如u可以看到),我把我的代码是在同一个包...
如此 - 这些类为什么不公开?它可以改变吗?有没有解决方法?
@Lukas Eder - 有什么想法? :) – WrRaThY
[看我的回答](http://stackoverflow.com/a/31389243/521799)。虽然,你自己的答案是更好的,所以你可以实际移动你的问题的一部分,并回答自己的问题,在这里堆栈溢出 –