使用hibernate连接两个表的最佳方法

使用hibernate连接两个表的最佳方法,hibernate,Hibernate,我有2个hibernate实体/表,需要将这两个实体/表中的信息组合起来,以便在视图中使用。桌子是空的 Table Client: clientId, firstName, lastName, phone, cellPhone Table Appointment: apptTime, clientId (and some other fields I don't need now) 基于clientID,客户和约会之间存在一对多关系。在常规SQL中,我只想说: S

我有2个hibernate实体/表,需要将这两个实体/表中的信息组合起来,以便在视图中使用。桌子是空的

Table Client:
  clientId,
  firstName,
  lastName,
  phone,
  cellPhone

Table Appointment:
  apptTime,
  clientId (and some other fields I don't need now)
基于clientID,客户和约会之间存在一对多关系。在常规SQL中,我只想说:

Select 
    client.clientId, 
    appt.apptTime,
    client.firstName,
    client.lastName 
from 
    Client  client, 
    Appointment app 
where 
    client.clientId = appt.clientId
并使用返回的记录集

我不知道如何在Hibernate中做到这一点。我是否应该创建一个ClientApp实体,然后执行类似于上面选择的操作(为HQL做了一些修改)

注意,我曾想过使用SecondaryTable方法,但我认为这需要1:1的关系?我想我可以把一个映射到多个,但是有其他选择吗?这是一次更改,映射一对多关系对于这么小的东西来说可能有点昂贵? 最好的方法是什么?
谢谢

您应该使用
Projections.alias
指定您感兴趣的列的列表。例如,请参阅hibernate手册。

是否使用关系元数据对代码进行了注释?如果您这样做了,您应该能够简单地查询客户列表,然后让他们的约会访问持有他们的字段。

您可以通过多种方式对此进行建模。我要做的是让客户成为一个实体,让各种约会成为一个元素集合。您没有指定语言,但在Java中,它类似于:

@Entity
@Table(name="person")
public class ClientAppts {
    ...

    @OneToMany(mappedBy="client")
    Set<Appointment> appointments;
}

@Entity
@Table(name="person")
public class Appointment {
    ....

    @ManyToOne
    @JoinColumn(name="person_id")
    private ClientAppts client;

    ....
}     
Hibernate将执行连接并返回一个带有一组约会的客户机对象。您可以进一步将集合设置为SortedSet,或向其中添加索引以使其成为列表。

最好的方法(imho)是不要考虑常规的SQL方法。不要考虑选择某些字段,因为您将加入一些表。您应该尝试创建有意义的业务实体,并且应该致力于这些业务实体

例如,下面是我要做的:

(不是实际代码,只是展示想法)

使用上述映射,您只需要从约会a执行HQL
,其中a.client.id=:whatEverIdYouWant
,或者,要将额外的查询保存到DB,请从约会a执行
,并从约会a获取a.client where a.client.id=:whatEverIdYouWant

如果您的设计不介意客户根据约定添加@sharakan映射

公共类约定{
public class Appoinment {

@Override
public List<Appointment > methodName(String search) {
    String hql =" from Appointment a join fetch a.client where a.client.id = 
                   :search";

    Query<Appointment > query=this.getSession().createQuery(hql,Appointment 
           .class);
    Long id=-1L;
    try {
        id=Long.parseLong(search);
    }catch (NumberFormatException ex) {
        ex.printStackTrace();
    }
    query.setParameter("id", id);
    query.setParameter("search", "%" +search+ "%");
    return query.getResultList();
}

}
@凌驾 公共列表方法名(字符串搜索){ String hql=“从约会a连接获取a.client,其中a.client.id= :搜索“; Query Query=this.getSession().createQuery(hql,约会 (类别),; 长id=-1L; 试一试{ id=Long.parseLong(搜索); }捕获(NumberFormatException ex){ 例如printStackTrace(); } query.setParameter(“id”,id); query.setParameter(“search”、“%”+search+“%”); 返回query.getResultList(); } }
谢谢你,沙拉肯。我想我会试试这个方法,看看会发生什么。沙拉肯,我试过你的方法,但我遇到了一个错误。描述就在这里——好吧,从你在那里的约会的定义(特别是你有一个ID的事实,我不知道),我认为你实际上想要一个实体。我会更新我的答案。“不过,我不能对未映射的情况发表评论,我不熟悉Glassfish是如何进行配置的。”Dave更新。我想您还想删除:clientapps.appt和Appointment.person\u id。我不知道为什么要删除第一个,第二个被示例代码中的“client”字段替换。
@Entity
public class Client {
  @Id
  @Column(name="clientId")
  private Long id;

  @Column
  private String longName;
}

@Entity
public class Appointment {
  @Id
  private Long id;

  @ManyToOne
  @Column(name="clientId")
  private Client client;
}
public class Appoinment {

@Override
public List<Appointment > methodName(String search) {
    String hql =" from Appointment a join fetch a.client where a.client.id = 
                   :search";

    Query<Appointment > query=this.getSession().createQuery(hql,Appointment 
           .class);
    Long id=-1L;
    try {
        id=Long.parseLong(search);
    }catch (NumberFormatException ex) {
        ex.printStackTrace();
    }
    query.setParameter("id", id);
    query.setParameter("search", "%" +search+ "%");
    return query.getResultList();
}

}