如何将嵌套SQL转换为HQL

时间:2011-03-04 20:01:45

标签: java hibernate hql

我是Hibernate和HQL的新手。我想在HQL中编写更新查询,其SQL等效项如下:

update patient set 
      `last_name` = "new_last", 
      `first_name` = "new_first" 
where id = (select doctor_id from doctor 
            where clinic_id = 22 and city = 'abc_city');

doctor_iddoctor的PK,是patient中的FK和PK。有一对一的映射。

相应的Java类是Patient(带有字段lastName,firstName,doctorId)和Doctor(带有字段doctorId)。

任何人都可以告诉HQL与上述SQL查询相同的内容吗?

非常感谢。

4 个答案:

答案 0 :(得分:13)

String update = "update Patient p set p.last_name = :new_last, p.first_name = :new_first where p.id = some (select doctor.id from Doctor doctor where doctor.clinic_id = 22 and city = 'abc_city')";

如果查看specification,可以了解如何对hql查询进行短语。您可以在那里找到有关subqueries的部分。

答案 1 :(得分:4)

我认为你不需要HQL(我知道,你明确地问过,但是因为你说你是Hibernate的新手,让我提供一个Hibernate风格的替代方案)。我不喜欢HQL,因为你仍然处理字符串,这可能变得难以维护,就像SQL一样,并且你失去了类型安全性。

相反,请使用Hibernate criteria queries and method来查询您的数据。根据您的类映射,您可以执行以下操作:

List patients = session.CreateCriteria(typeof(Patient.class))         
    .createAlias("doctor", "dr")
          .add(Restrictions.Eq("dr.clinic_id", 22))
          .add(Restrictions.Eq("dr.city", "abc_city"))
    .list();

// go through the patients and set the properties something like this:
for(Patient p : patients)
{
     p.lastName = "new lastname";
     p.firstName = "new firstname";
}

有些人认为使用CreateCriteria很困难。它需要一点点习惯,但是它具有类型安全的优点,并且复杂性可以很容易地隐藏在泛型类之后。谷歌的“Hibernate java GetByProperty”,你明白我的意思。

答案 2 :(得分:2)

update Patient set last_name = :new_last , first_name = :new_first where patient.id = some(select doctor_id from Doctor as doctor where clinic_id = 22 and city = abc_city)  

答案 3 :(得分:0)

使用select执行更新和实际将记录提取到客户端,更新它们并将它们发回来之间存在显着差异:

UPDATE x SET a=:a WHERE b in (SELECT ...) 

在数据库中工作,没有数据传输到客户端。

list=CreateCriteria().add(Restriction).list();

将所有记录更新到客户端,更新它们,然后将它们发回数据库,每个记录可能有一个UPDATE。

使用UPDATE比使用标准更快,更快(想想成千上万次)。