有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Hibernate将两个表映射到一个类

我需要将两个表映射到一个类,但很难弄清楚这一点。一张桌子是房间,另一张是教练台

房间表:

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。培训师表的主键是: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 ...

我正在项目的其他地方使用ROOMS表,它已经映射为独立对象。是否有一种方法可以将其作为训练器对象上的子对象,或者更容易将这两个表映射到一个平面对象?映射看起来如何

谢谢, 尼克


共 (4) 个答案

  1. # 1 楼答案

    可以创建绑定到自定义对象的命名查询。这是我将采用的解决方案,因为不需要对DB进行任何更改

  2. # 2 楼答案

    我提出的解决方案似乎可以查询数据,我还没有尝试过任何插入/更新/删除操作

    我创建了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>
     ...
    

    到目前为止,它似乎正在发挥作用

    谢谢

    尼克

  3. # 3 楼答案

    根据我的经验,简单是使用任何ORM(包括Hibernate)的关键。我会根据您的SQL let调用TRAINERS_ROOMS创建一个数据库视图,然后简单地将该数据库视图映射到一个新的Java对象,让我们调用TrainersRooms

    您可以获得简单、易于管理的hibernate映射,但当然,您可以使用这个新对象执行任何更新,因此如果您需要,这个解决方案将不适合您

  4. # 4 楼答案

    要将单个类映射到两个(或多个)单独的表,需要使用@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 {
    

    然后需要用@Column(table="TRAINERS")注释映射到TRAINERS表的每个属性,以指定它属于哪个表。如果改用XML映射,以上所有操作都可以通过join元素完成

    尽管如此,在我看来,您的两个表在本质上是相当不同的,不应该映射到单个类(尤其是因为您已经说过您已经在其他地方映射了ROOMS)。也许你应该将你的教练映射为ManyToOne协会