如何使用具有多个连接的 SQL 查询并使用休眠计数

Posted

技术标签:

【中文标题】如何使用具有多个连接的 SQL 查询并使用休眠计数【英文标题】:How to use an SQL Query with multiple joins and count with hibernate 【发布时间】:2017-12-11 12:52:42 【问题描述】:

我有一个使用 hibernate 的 Java Spring MVC Web 应用程序。我正在尝试使用SQL join 从多个表中检索数据,并使用单个查询根据少数条件计算行数。我当前使用的 SQL 如下:

SELECT (s.school_id, u.first_name, u.last_name, u.username, u.email, p.plan_name, s.start_date, s.end_date,(SELECT COUNT(*) FROM c_school_user t WHERE t.user_type = 'TA' and t.school_id = s.school_id), (SELECT COUNT(*) FROM c_school_user t WHERE t.user_type = 'PA' and t.school_id = s.school_id), (SELECT COUNT(*) FROM c_school_user t WHERE t.user_type = 'ST' and t.school_id = s.school_id)) FROM c_school s inner join u_user u on s.user_created = u.user_id inner join c_plan p on s.current_plan = p.plan_Id where s.application_id = 1 and s.site_id = 1;

此查询为我返回所需的结果。我正在尝试在我的方法中使用与 SQL Query 相同的查询来使用 hibernat 获取结果,如下所示:

public List<Object[]> getBuyersInformation(int applicationId, int siteId) throws HibernateException 


    Session session = getCurrentSession();
    Query query = session.createSQLQuery("SELECT (s.school_id, u.first_name, u.last_name, u.username, u.email, p.plan_name, s.start_date, s.end_date, s.subscription_price, (SELECT COUNT(*) FROM c_school_user t WHERE t.user_type = 'TA' and t.school_id = s.school_id), (SELECT COUNT(*) FROM c_school_user t WHERE t.user_type = 'PA' and t.school_id = s.school_id), (SELECT COUNT(*) FROM c_school_user t WHERE t.user_type = 'ST' and t.school_id = s.school_id)) FROM c_school s inner join u_user u WHERE s.user_created = u.user_id inner join c_plan p WHERE s.current_plan = p.plan_Id where s.application_id = :applicationId and s.site_id = :siteId");
    query.setParameter("applicationId", applicationId);
    query.setParameter("siteId", siteId);
    List<Object[]> results = query.list();
    if(results != null && results.size() > 0)
    
    return results;
    
    return null;

如果我使用没有连接的 SQL 查询,我会得到正确的结果,但是当使用当前查询时,我会得到以下异常:

org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111

我使用 Postgres 数据库。有什么方法可以让我获得所需的结果作为对象列表或自定义类。我正在尝试使用这个单一的 SQL,因为我的数据库可能包含数千行信息,并且拆分此查询将导致如此多的数据库调用,最终会减慢系统速度。有没有什么方法可以使用 hibernate 执行具有多个连接和计数的 SQL 查询。

【问题讨论】:

【参考方案1】:

由于您的列列表周围有括号,您的查询仅返回一个单个列,该列是包含选定列作为字段的匿名记录。

在 Postgres 中 select (a,b)select a,b 不同。表达式(a,b)(也称为“行构造函数”)creates an anonymous record 有两个字段。

删除那些无用的括号,您的查询应该可以正常工作。给你的列表达式一个别名也是一个好主意:

类似:

SELECT s.school_id, u.first_name, u.last_name, u.username, u.email, p.plan_name, s.start_date, s.end_date,
       (SELECT COUNT(*) FROM c_school_user t WHERE t.user_type = 'TA' and t.school_id = s.school_id) as ta_count, 
       (SELECT COUNT(*) FROM c_school_user t WHERE t.user_type = 'PA' and t.school_id = s.school_id) as pa_count, 
       (SELECT COUNT(*) FROM c_school_user t WHERE t.user_type = 'ST' and t.school_id = s.school_id) as st_count
FROM c_school s 
  inner join u_user u on s.user_created = u.user_id 
  inner join c_plan p on s.current_plan = p.plan_Id 
where s.application_id = 1 and s.site_id = 1;

【讨论】:

以上是关于如何使用具有多个连接的 SQL 查询并使用休眠计数的主要内容,如果未能解决你的问题,请参考以下文章

使用计数和连接从休眠的实体中获取行

如何使用 Spring 管理具有不同 jdbc(或休眠?)的多个“运行时注意到”数据库连接?

SQL 查询:计数,按月-年分组,具有多个日期字段

我可以在不创建实体类的情况下对大型 sql 使用休眠命名查询吗?

在具有分页的单个模型查询代码点火器中获取具有多个条件的多个连接结果

休眠条件排序依据