Как преобразовать вложенный SQL в HQL
Я новичок в Hibernate и HQL. Я хочу написать запрос на обновление в HQL, эквивалент которого выглядит следующим образом:
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
является PK для doctor
и является FK и PK в patient
. Существует взаимно однозначное отображение.
Соответствующие классы Java - это Patient (с поля lastName, firstName, doctorId) и Doctor (с полями doctorId).
Может кто-нибудь рассказать, что будет эквивалентом HQL вышеупомянутого SQL-запроса?
Большое спасибо.
Ответы
Ответ 1
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')";
Вы можете решить, как выражать запросы hql, если вы проверяете спецификацию . Здесь вы можете найти раздел о subqueries.
Ответ 2
Я не думаю, что вам нужен HQL (я знаю, вы спрашиваете это явно, но, поскольку вы говорите, что вы новичок в Hibernate, позвольте мне предложить альтернативу типа Hibernate). Я не пользуюсь HQL, потому что вы по-прежнему имеете дело со строками, которые могут стать трудноподдерживаемыми, как и SQL, и вы потеряете безопасность типов.
Вместо этого используйте "Запросы и метод запроса на гибернацию" для запроса ваших данных. В зависимости от вашего сопоставления классов вы можете сделать что-то вроде этого:
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 затруднено. Это требует немного привыкания, правда, но у него есть преимущество в типе безопасности, и сложности могут быть легко скрыты за родовыми классами. Google для "Hibernate java GetByProperty", и вы понимаете, что я имею в виду.
Ответ 3
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)
Ответ 4
Существует значительная разница между выполнением обновления с помощью select и фактическим извлечением записей клиенту, их обновлением и отправкой обратно:
UPDATE x SET a=:a WHERE b in (SELECT ...)
работает в базе данных, данные не передаются клиенту.
list=CreateCriteria().add(Restriction).list();
выводит все клики, которые нужно обновить клиенту, обновляет их, а затем отправляет обратно в базу данных, возможно, с одним UPDATE на запись.
Использование UPDATE намного, намного быстрее, чем использование критериев (думайте тысячи раз).