【问题标题】:How to inner join two tables using Hibernate HQL or Criteria?如何使用 Hibernate HQL 或 Criteria 内部连接两个表?
【发布时间】:2012-08-20 06:22:07
【问题描述】:
@Entity
public class doctor {
   @Id
   private int id;
   private String username;
   private String password;
   private String phone;
   private String email;

   @OneToMany(targetEntity = patient.class, cascade = CascadeType.ALL, mappedBy = "doctor")
   @Cascade(value = org.hibernate.annotations.CascadeType.ALL)
   private Collection<patient> patients = new ArrayList<patient>();
}

@Entity
public class patient {
   @Id
   private int id;
   private String name;
   private String surname;
   private String phone;
   private int systolic;
   private int diastolic;

   @ManyToOne
   private doctor doctor;
}

目前我只能按此标准检索医生信息:

Criteria query = session.createCriteria(doctor.class);
query.createCriteria("patients", "p");
query.add(Restrictions.eq("p.phone", phone));
List<doctor> doctorList = (ArrayList<doctor>) query.list();

我如何使用休眠标准通过提供患者电话、他的医生信息和一些患者信息来检索?

类似:phone=3423423424,那么答案是:

----------医生信息-------------------------------- --患者信息(收缩压,舒张压)-----------

  1 "Dr dre" sdfssd 243242 drdre@gmail.com  160 170

160 170 是患者的信息

如果不使用标准,使用 HQL?

【问题讨论】:

    标签: java hibernate hql hibernate-criteria


    【解决方案1】:

    你想要的是以下内容。

    使用休眠标准 API:

    Criteria query = sessionFactory.getCurrentSession().
    createCriteria(Patient.class, "patient");
    query.setProjection(Projections.projectionList().
    add(Projections.property("patient.doctor")).
    add(Projections.property("patient.systolic")).
    add(Projections.property("patient.diastolic")));
    query.add(Restrictions.eq("patient.phone", phone));
    return query.list();
    

    使用 HQL(实际上只是 JPQL):

    select p.doctor, p.systolic, p.diastolic from Patient p where p.phone = ?1
    

    您在结果中得到的是类型List&lt;Object[]&gt; 的值。 还要将@Cascade(value=CascadeType.SAVE_UPDATE) 添加到Patient 类的doctor 字段中。

    【讨论】:

      【解决方案2】:

      您有双向映射,因此您可以从每位医生那里获取他的患者,并从每位患者那里获取他的医生信息。如果您需要一个包含患者的列表而不是医生列表,只需为患者创建类似的标准。 session.createCriteria(patient.class),有必要的限制。你不必急于求成。在大多数情况下,我们不需要急切的获取。如果您需要休眠会话之外的对象,最好初始化(Hibernate.initialize)集合或代理。

      顺便说一句,当您命名 java 类时使用驼峰式大小写。这是一种广泛使用的约定。

      【讨论】:

      • 每个病人都有一个医生。所以我想要医生信息,他的病人电话是“45353534”+病人信息。可以这样做吗? [Doctor.phone Doctor.email Patient.diastolic Patient.Systolic]
      • 当然可以。正如我上面写的那样,为患者类别创建标准,并限制特定电话号码。然后您将获得具有此特定电话号码的患者列表。然后您可以遍历此列表并为每个患者找到他的医生。如果您想在休眠会话中使用它,则不必初始化代理。当您通过 Patient.getDoctor() 从患者那里获得医生时,您当然拥有医生的所有属性。它是java,这些是对象!这里唯一的技巧是记住初始化代理。
      • 阅读一点关于 java 和对象的知识,并查看 hibernate 文档。这些是对象,如果您想要字符串中的此类信息,您可以遍历对象模型并在 java 代码中自己从对象属性创建一个字符串。
      • 因此,使用上面使用的条件查询,我可以检索医生信息。要检索他的特定患者,我会这样做: for (doctor d : doctorList) {answear = answear.concat(d.getPhone( )+ " " + d.getEmail()+" "+d.getPatient().diastolic+" ?"+d.getPatient().systolic);}
      • 如果您可以假设每个医生只有一个具有选定电话号码的患者,那么您可以执行 d.getPhone +...+d.getEmail+...+d.getPatients().get( 0).diastolic 等(请记住,一位医生有一份患者名单,因此可能会有一位具有相同电话号码的医生
      【解决方案3】:

      之所以你的查询只返回医生信息(而不是病人信息)是因为for a OneToMany relation, FetchType by default is set to LAZY,如果你指定fetch type为EAGER,hibernate也会返回病人。

      @OneToMany(targetEntity = patient.class, cascade = CascadeType.ALL, mappedBy = "doctor", fetch = FetchType.EAGER)
      

      【讨论】:

      • 这是怎么做到的?我有医生列表。如何检索患者和医生信息。我想将它们传递给一个字符串。“医生电话是” +doctor.phone + ... + “患者舒张压是”patient.diastolic +...
      【解决方案4】:

      如果您使用的是 HibernateTemplate

      String hql = "from Boo where id in (:listParam)";
      String[] params = { "listParam" };
      Object[] values = { list};
      List boos = getHibernateTemplate().findByNamedParam(hql, params, values);
      

      引自Spring Forum

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-27
        • 1970-01-01
        • 2011-08-30
        • 1970-01-01
        • 2011-02-25
        • 1970-01-01
        相关资源
        最近更新 更多