Hibernate从其他表中获取列的值

时间:2017-04-21 09:06:27

标签: java hibernate hibernate-mapping

我有一个名为Trade的实体,可以映射到包含属性的表。此实体也有一个字段,用于存储另一个表中的值。我的交易表包含第二个表的主键。我知道如何将整个第二个表作为我的Trade实体中的实体,但我只想要那一列。

@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,但是联接是在Trade实体的primaryKey上执行的。如何使用注释从交易表中选择外键,将其连接到第2 /第3表并直接从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

现在我的Trade类应具有属性:

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生成这个语句。

3 个答案:

答案 0 :(得分: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 :(得分:0)

我不明白你为什么这样做?如果您的Trade课程中有映射的实体,则可以随时访问其属性,但我会尝试提供解决方案来回答您的问题。

您可以这样做,但您应该在两个实体之间使用OneToMany映射(因此您也应该存储整个映射的实体),并使用此表中的FK作为实体和地图中的属性它是这样的:

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

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

答案 2 :(得分: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实体列表,而不返回其他类中的整个对象