我是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_id
是doctor
的PK,是patient
中的FK和PK。有一对一的映射。
相应的Java类是Patient(带有字段lastName,firstName,doctorId)和Doctor(带有字段doctorId)。
任何人都可以告诉HQL与上述SQL查询相同的内容吗?
非常感谢。
答案 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比使用标准更快,更快(想想成千上万次)。