我正在编写一个util函数,以基于传递的任何HQL来获取总记录计数,而无需加载所有数据。 HQL中传递的条件可能很复杂,其中包含许多选择,联接,条件,分组和排序。为此,我想用SELECT COUNT(*) FROM (<ORIGINAL_QUERY>) x
包装查询。我发现,这对于HQL是不可能的,因为Hibernate不允许FROM元素中的子查询。
现在,我尝试将可能具有某些命名参数(其中一些可能是简单参数,某些可能是列表)的此随机HQL查询转换为可执行SQL语句,而无需内联参数值。这似乎适用于简单的参数,但不适用于列表参数。
hqlString和namedParameterMap来自外部:
final String hqlString = "...";
final Map<String, Object> namedParametersMap = ...;
将HQL转换为SQL的代码(以及ParameterTranslations:
final QueryTranslatorFactory translatorFactory = new ASTQueryTranslatorFactory();
final SessionFactoryImplementor factory = getSessionFactory();
final QueryTranslator translator = translatorFactory.createQueryTranslator(hqlString, hqlString, Collections.EMPTY_MAP, factory, null);
translator.compile(Collections.EMPTY_MAP, false);
final String sqlString = translator.getSQLString();
final ParameterTranslations parameterTranslations = translator.getParameterTranslations());
用于创建SQLQuery,设置参数并执行查询的代码:
SQLQuery sqlQuery = getCurrentSession().createSQLQuery(sqlString);
((Set<?>) parameterTranslations.getNamedParameterNames()).forEach(parameterName -> {
for (int position : parameterTranslations.getNamedParameterSqlLocations(parameterName)) {
sqlQuery.setParameter(position, namedParametersMap.get(parameterName));
}
});
final Long rowCount = ((BigInteger) query.uniqueResult()).longValueExact();
此查询可以正常工作:
final String hqlString = "SELECT p.firstname, p.surname FROM Person p WHERE p.id = :param1";
final Map<String, Object> namedParametersMap = Maps.newHashMap(ImmutableMap.<String, Object>of("param1", Integer.valueOf(1));
此查询无效:
String hqlString = "SELECT p.firstname, p.surname FROM Person p WHERE p.id IN (:param1)";
final Map<String, Object> namedParametersMap = Maps.newHashMap(ImmutableMap.<String, Object>of("param1", Lists.newArrayList(Integer.valueOf(1)));
例外:
org.hibernate.exception.SQLGrammarException:无法在org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java)的org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106)处提取ResultSet :42)在org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)在org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)在org.hibernate。 org.hibernate.loader.Loader.getResultSet(Loader.java:2313)位于org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2096)处的engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79)位于org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2072)位于org.hibernate.loader.Loader.doQuery(Loader.java:941)位于org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:352) )在org.hibernate.loader.Loader.doList(Loader.java:2813)在org.hibernate.loader.Loader.doList(Loader.java:2796)在org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2625)在org.hibernate.loader.Loader.list(Loader.java:2620) )于org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1996)于org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1996)于org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl。 org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:125)处的org.hibernate.internal.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:966)处的HQLQueryUtils.getCount(HQLQueryUtils.java:350)< / p>
由以下原因引起:org.postgresql.util.PSQLException:错误:运算符不存在:整数= bytea提示:没有运算符匹配给定的名称和参数类型。 您可能需要添加显式类型转换。位置:301,在org.postgresql.core.v3的org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2178)的org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2433)上。在org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441)在org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365)上的QueryExecutorImpl.execute(QueryExecutorImpl.java:306)在org.postgresql.jdbc上org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:118)的org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:155) .. 49更多
环境:
- Java 8
- 休眠5.1.8
- Postgres-JDBC 42.2.2
- PostgreSQL服务器10.5
答案 0 :(得分:0)
在HQL中,您可以使用查询参数,并使用setParameterList方法设置Collection。
Query q = session.createQuery("SELECT entity FROM Entity entity WHERE name IN (:names)");
q.setParameterList("names", names);
答案 1 :(得分:0)
您可以使用直接sql
String sql="your query"
Query query = sessionFactory.getCurrentSession().createSQLQuery(sql);
query.setParameter("paramterName", parameterValue);
List<Object[]> resultSet = query.list();
List<YouClass > data= new ArrayList<>();
for (Object[] row : resultSet) {
YouClass yourObject=new YouClass ();
yourObject.setDate((Date) row[0]);
yourObject.setAmount((BigDecimal) row[1]);
data.add(yourObject);
}
假设Yourclass有两个元素日期和金额