2017-04-21 65 views
2

我有一個名爲Trade的實體可以映射到包含屬性的表。此實體也有一個字段,用於存儲來自另一個表的值。我的Trade表包含第二個表的主鍵。我知道如何在整個Trade實體中將整個第二個表作爲實體,但我只想要這1列。Hibernate從其他表中獲取列的值

@Entity 
@Immutable 
@Table(name = "Trade table") 
@SecondaryTables(value = { 
    @SecondaryTable(name = "2nd table", pkJoinColumns = @PrimaryKeyJoinColumn(referencedColumnName = "id", foreignKey = @ForeignKey(name = "2ndtableID"))), 
    @SecondaryTable(name = "3rd table", pkJoinColumns = @PrimaryKeyJoinColumn(referencedColumnName = "id", foreignKey = @ForeignKey(name = "3rdtableID"))) }) 
public class TradeSearchResult { 
    @Id 
    @Column(name = "ID") 
    private Long primaryKey; 
    @Column(name = "col2", table = "2nd table") 
    private String valuefrom2ndtable; 
    @Column(name = "col3", table = "3rd table") 
    private String valuefrom3ndtable; 
} 

,你可以看到我試着用@SecondaryTables,但聯接的樣品從貿易實體的PrimaryKey執行。我如何使用註釋從交易表中選擇外鍵,將它加入到第二/第三表,並直接從col2/col3中直接得到值?任何建議表示讚賞

表貿易:

ID col1 fk1 fk2 
------------------------ 
1  abc 12  43  
2  def 23  32 
3  ghi 34  21 

表2:

ID col2 
---------- 
12 a 
23 b 
34 c 

表3:

ID col3 
----------- 
43 d 
32 e 
21 f 

現在我的貿易類應該具有的屬性:

Long id; 
String col1; 
String col2; 
String col3; 

Hibernate查詢:from Trade應該給我在這個例子中3個交易與屬性:

Trade1: 1, "abc","a","d" 
Trade2: 2, "def","b","e" 
Trade3: 3, "ghi","c","f" 

,我不希望只創建一個實體,以達到屬性col2col3

編輯:

select語句應該是這樣的:

select trade.ID,TICKET,table2.col2,table3.col2 from trade join table 3 on table3.ID=trade.FKtable3 join table2 on table2.ID=trade.FKtable2 

如果我在sql server中執行這個語句,它會給我我想要的結果。我想映射我的類,以便hibernate生成此語句。

+0

名單我有類似的情況。你是否終於找到了一種方法來連接另一個表的值而不用聲明一個描述另一個表的實體? – Cryptor

+0

@Cryptor我使用了'Criteria' API並且以這種方式映射它。 'valuefrom2ndtable'是通過查詢內部的連接獲取的。請注意,我的TradeSearchResult不是直接映射到任何表,但是我的Trade類仍然是。 – XtremeBaumer

回答

0

我解決此問題的是不是映射TradeSearchResult任何表和使用Criteria/CriteriaQuery API來獲取我所需要的數據。我的Trade類完美映射到交易表並保存對其他表的對象的引用。現在到了查詢是如何構建:

CriteriaBuilder cb = emf.getCriteriaBuilder(); 
CriteriaQuery<TradeSearchResult> query = cb.createQuery(TradeSearchResult.class); //type is the entity you want to map to 
Root<Trade> r = query.from(Trade.class); //root must be entity from which you can access all data 

List<Predicate> predicates = new ArrayList<Predicate>(); //new list of predicates 

predicates.add(cb.like(r.join("2ndTableEntityName").<String>get("valuefrom2ndtable"),"value to search for")); 
//get the needed value from 2nd table and map it to the field 

query.multiselect(r.get("2ndTableEntityName")).where(predicates.toArray(new Predicate[] {})); 
//create the query and execute it 
EntityManager em = emf.createEntityManager(); 
List<TradeSearchResult> results = em.createQuery(query).getResultList(); 
em.close(); 
return results; //return results 

此代碼返回TradeSearchResult實體,只有需要的領域,而不是整個對象從其他類

0

根據javadoc example您應該使用pkJoinColumnforeignKey來定義女巫專欄應該用於加入您的表。

//編輯:

您的版本後,我試圖使一些魔術:

@Entity 
@Immutable 
@Table(name = "\"Trade table\"") 
@SecondaryTables(value = { 
     @SecondaryTable(name = "2nd table", pkJoinColumns = @PrimaryKeyJoinColumn(name = "col2", referencedColumnName = "id")), 
     @SecondaryTable(name = "3rd table", pkJoinColumns = @PrimaryKeyJoinColumn(name = "col3", referencedColumnName = "id")) 
}) 
public class Trade { 

    @Id 
    @Column(name = "id") 
    private Long primaryKey; 

    @Column(name = "col2") 
    private String valuefrom2ndtable; 

    @Column(name = "col3") 
    private String valuefrom3ndtable; 


} 

@Entity 
@Table(name = "\"2nd table\"") 
public class Table2 { 

    @Id 
    private long id; 
} 

@Entity 
@Table(name = "\"3rd table\"") 
public class Table3 { 

    @Id 
    private long id; 
} 

我也得到SQL這樣的:

create table "2nd table" (
    id bigint not null, 
    col2 bigint not null, 
    primary key (col2) 
); 

create table "3rd table" (
    id bigint not null, 
    col3 bigint not null, 
    primary key (col3) 
); 

create table "trade table" (
    id bigint not null, 
    col2 varchar(255), 
    col3 varchar(255), 
    primary key (id) 
); 

alter table "3rd table" 
    add constraint FK7tkn132p8joplte47ce169h82 
foreign key (col3) 
references "trade table"; 

alter table "2nd table" 
    add constraint FK9jsoykrvn4d0v4aor03g1l324 
foreign key (col2) 
references "trade table"; 

這看起來喜歡的事,你想要做,但我不是100%肯定...

+1

基於你的回答,我重寫了我的代碼,但它仍然在做同樣的事情。我更新了我的代碼以符合我現在的要求 – XtremeBaumer

+1

我不想爲table2和table3創建類。我發佈了一個應該由hibernate自動生成的select語句。不知何故,這必須是可能的... – XtremeBaumer

+0

我從休眠日誌中得到這個SQL。 –

0

我不明白你爲什麼要那樣做?如果您在Trade課程中有地圖實體,則可以隨時訪問其屬性,但我會盡力提供解決方案來回答您的問題。

那麼你可以做到這一點,但你應該在兩個實體之間使用OneToMany映射(所以你也應該存儲整個映射的實體),並使用該表中的FK作爲實體中的屬性,並像這樣映射它:

@JoinColumn(name="2ndtableID") 
@ManyToOne(targetEntity=SecondTable.class,fetch=FetchType.LAZY) 
private Message message; 

@Column(name="2ndtableID") 
private Long secondTableID; 
+0

我不希望在我的交易實體中擁有整個第二/第三個實體作爲屬性。我只想要這些的一個屬性。生病嘗試使它在我的問題中更容易理解 – XtremeBaumer

+0

@XtremeBaumer恐怕不可能將這些實體作爲持久字段來實現。 –

+0

我發佈了應該從休眠執行的select查詢。我認爲這是可以告訴冬眠做到這一點 – XtremeBaumer

相關問題