2009-11-03 99 views
3

我需要将两个表映射到一个类,无法解决这个问题。一张桌子是ROOMS,另一个是TRAINERS。休眠映射两个表到一个类

室表:

OOC_UNIT_ID   NUMBER(6,0) 
OOC_START_DT   DATE 
OOC_START_TM   DATE 
OOC_DT_MOD   DATE 
OOC_USER_MOD   VARCHAR2(30 BYTE) 
OOC_END_DT   DATE 
OOC_END_TM   DATE 
OOC_REASON_TX  VARCHAR2(250 BYTE) 
OOC_RESERVED_FOR  VARCHAR2(30 BYTE) 
OOC_CLS_ID   NUMBER(9,0) 
OOC_TIMEFRAME  VARCHAR2(1 BYTE) 
OOC_WSD_CD   VARCHAR2(2 BYTE) 
OOC_TEAM_UNIT_ID  NUMBER(6,0) 
OOC_WSD_ACT_RMAT_ID NUMBER(6,0) 

训练者表:

TRSC_ID    NUMBER(9,0) -- generated sequence 
TRSC_OOC_UNIT_ID  NUMBER(6,0) 
TRSC_OOC_START_DT  DATE 
TRSC_OOC_START_TM  DATE 
TRSC_OOC_RESERVED_FOR VARCHAR2(30 BYTE) 
TRSC_TPOC_ID   NUMBER(6,0) 
TRSC_DT_CREATED  DATE 
TRSC_USER_CREATED  VARCHAR2(30 BYTE) 
TRSC_DT_MOD   DATE 
TRSC_USER_MOD   VARCHAR2(30 BYTE) 
TRSC_REMARKS   VARCHAR2(250 BYTE) 
TRSC_NOSHOW_REASON  VARCHAR2(100 BYTE) 

表格应于OOC_UNIT_ID=TRSC_OOC_UNIT_IDOOC_START_DT=TRSC_OOC_START_DTOOC_START_TM=TRSC_OOC_START_TM接合。

ROOMS表的主键为:OOC_UNIT_ID, OOC_START_DT, OOC_START_TM。 TRAINERS表的主键是:TRSC_ID

我需要OOC_UNIT_IDOOC_START_DTOOC_START_TMOOC_END_DTOOC_END_TMOOC_WSD_ACT_RMAT_ID查询这个数据。

在SQL它可能是这样的:

SELECT * 
    FROM TRAINERS t, ROOMS r 
WHERE t.TRSC_OOC_UNIT_ID = r.OOC_UNIT_ID 
    AND t.TRSC_OOC_START_DT = r.OOC_START_DT 
    AND t.TRSC_OOC_START_TM = r.OOC_START_TM 
    AND ... 

我使用的客房表中的项目和其他地方它已经被映射为一个独立的对象。会不会有一种方法可以将其作为TRAINERS对象上的子对象使用,还是将这两个表映射为一个扁平对象会更容易?地图的外观如何?使用包括Hibernate任何ORM时

感谢, 尼克

回答

6

要单类映射到两个(或更多)单独的表,你需要使用一个@SecondaryTable注释:

@Table(name="ROOMS") 
@SecondaryTable(name="TRAINERS", pkJoinColumns={ 
    @PrimaryKeyJoinColumn(name="TRSC_OOC_UNIT_ID", referencedColumnName="OOC_UNIT_ID"), 
    @PrimaryKeyJoinColumn(name="TRSC_OOC_START_DT", referencedColumnName="OOC_START_DT"), 
    @PrimaryKeyJoinColumn(name="TRSC_OOC_START_TM", referencedColumnName="OOC_START_TM") 
}) 
public class MyMergedEntity { 

然后,您需要注释映射到TRAINERS表中的每一个人的财产与@Column(table="TRAINERS")指定它属于哪个表。如果您使用的是XML映射,则可以通过join元素完成上述所有操作。

所有这一切说,在我看来,你的两个表在本质上是相当不同的,不应该映射到一个类(特别是因为你已经说过你已经在其他地方映射了ROOMS)。也许你应该将你的训练器映射为ManyToOne关联。

0

在我的经验,简单是关键。我会根据你的SQL创建一个数据库视图让我们调用TRAINERS_ROOMS然后简单地将该数据库视图映射到一个新的Java对象让我们调用TrainersRooms

你可以很容易地管理hibernate映射,但是当然你可以使用这个新对象来执行任何更新,所以如果你需要的话,这个解决方案不会为你工作。

1

解决方案我想出的解决方案似乎工作至于查询数据,我还没有尝试任何插入/更新/删除。

我创建了TRAINER对象来扩展ROOM对象。

public class Trainer extends Room { 
    ... 
} 

然后我修改了映射ROOM包括一个连接子类:

<hibernate-mapping> 
    <class name="Room" table="ROOMS"> 
     <composite-id> ... 
     <property ...> 
     ... 

     <joined-subclass name="Trainer" table="TRAINERS"> 
     <key> 
       <column ...> 
       ... 
     </key> 
     <property ...> 
     ... 
     </joined-subclass> 
    </class> 
... 

到目前为止,这似乎是工作。

感谢,

尼克

+0

看起来**真的很奇怪,因为ROOMS和TRAINERS似乎是非常不同的概念。培训师和房间之间的关系是什么?训练师是一个房间吗? – 2009-11-03 23:41:30

+0

这是非常错误的。插入/删除会同时影响两个表格,每当您尝试使用“房间”对象时,您都会加入“TRAINERS”。房间和培训师有一对多(或多对多)协会,他们当然不属于一个等级。 – ChssPly76 2009-11-04 06:32:05

0

您可以创建绑定到一个自定义对象命名查询。这是我将要采用的解决方案,因为不需要更改数据库。