繁体   English   中英

如何将嵌套 SQL 转换为 HQL

[英]How to convert nested SQL to 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)。

谁能告诉上述 SQL 查询的 HQL 等价物是什么?

非常感谢。

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 查询。 您可以在那里找到有关子查询的部分。

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

相反,使用Hibernate 条件查询和方法来查询您的数据。 根据您的类映射,您可以执行以下操作:

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”,你明白我的意思。

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)  

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

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

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

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

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

使用 UPDATE 比使用标准要快得多(想想数千次)。

由于问题标题通常可以解释为“如何在休眠中使用嵌套选择”,并且 HQL 语法将嵌套选择限制为仅在 select- 和 where 子句中,我想在这里添加使用 native 的可能性SQL 也是如此。 例如,在 Oracle 中,您还可以在 from 子句中使用嵌套选择。

具有两个嵌套内部选择的以下查询不能由 HQL 表示:

select ext, count(ext)
from (
    select substr(s,   nullif( instr(s,'.', -1) +1, 1) ) as ext
    from ( 
         select b.FILE_NAME as s from ATTACHMENT_B b 
         union select att.FILE_NAME as s from ATTACHEMENT_FOR_MAIL att
         )
 )
GROUP BY ext
order by ext;    

(顺便说一句,每个不同的文件扩展名在两个不同的表中出现)。

您可以使用这样的 sql 字符串作为本机 sql,如下所示:

@Autowired
private SessionFactory sessionFactory;

    String sql = ...
    SQLQuery qry = sessionFactory.getCurrentSession().createSQLQuery(sql);
    // provide an appropriate ResultTransformer
    return qry.list();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM