2017-01-02 84 views
2

我有3個表ABC這是一個繼承鏈的一部分:誤區場jOOQ記錄

A 
/\ 
B C 

,看起來像:

A(row_id) 
B(row_id, a_row_id REFERENCES A(row_id)) 
C(row_id, a_row_id REFERENCES A(row_id)) 

注意,列名的相同(a_row_id

現在,我取Record s的BC做:

ctx.select() 
    .from(
     Tables.A 
     .leftOuterJoin(Tables.B).onKey() 
     .leftOuterJoin(Tables.C).onKey() 
    ) 
    .where(someCondition) 
    .fetch() 

我參加過兩個BC因爲我沒有(在這一點上)知道我要找的是哪一個。

但是,當我知道我需要獲取B並做到這一點:

ctx.select() 
    .from(
     Tables.A 
     .leftOuterJoin(Tables.B).onKey() 
    ) 
    .where(someCondition) 
    .fetch() 

我得到一個Record上,如果我這樣做record.field(Tables.B.A_ROW_ID).toString(),我得到"b.a_row_id",如果我做record.getValue(Tables.B.A_ROW_ID)我得到的預期值。

但是,如果我做record.field(Tables.C.A_ROW_ID).toString(),我得到"b.a_row_id"record.getValue(Tables.C.A_ROW_ID)給我期望值record.getValue(Tables.B.A_ROW_ID)

我覺得這是發生因爲引用父表的列名是相同的。

是jOOQ僅使用表(而不是完全合格的「table.field_name」)的FIELD_NAME,如果這是在連接的唯一表?

任何幫助,將不勝感激。

回答

1

Record.field(Field)Record.field(Name),並且Record.field(String)所有的語義遵循相同的,一致的邏輯:

在SQL中,記錄的列都有一個名稱。如果該名稱源自表/視圖(在模式中(在目錄中)),則該名稱可以被限定,但這是可選的。不合格的柱子也很好,例如當:其中

  • 混疊柱
  • 創建表達式,如col + 1
  • 使用JOIN .. USING,萬一列不合格
  • 使用派生表(其可以有一個表的名稱,但當然不是模式/目錄)
  • 使用SELECT *與供應商特定的列發射運算符如PIVOT,MODEL,MATCH_RECOGNIZE
  • 等等

正如你可以看到,從語法的角度來看,有合格的列名是例外,而不是規則。因此,最合理,最普遍有用的實施Record.field(Field)是:

所以,你已經觀察到的行爲是正確的。

1

Lukas已經回答了主要問題,但我只是想告訴你,最後jOOQ正在運行一個SQL語句。它的安全和緩存是有限的,但它仍然是一個SQL語句。如果你打開日誌記錄,你可以看到SQL本身。
如果您希望返回一個動態記錄,並且希望列爲X,則始終可以執行.as(「X」),以便更容易地讀取數據。