我的任務是爲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)。雖然,你自己的答案是更好的,所以你可以實際移動你的問題的一部分,並回答自己的問題,在這裏堆棧溢出 –