猿问

使用列表参数将 HQL 查询转换为可执行的 SQL 查询

我正在编写一个 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)));



猛跑小猪
浏览 278回答 2
2回答

交互式爱情

可以直接用sql&nbsp; &nbsp; &nbsp;String sql="your query"&nbsp; &nbsp; &nbsp;Query query = sessionFactory.getCurrentSession().createSQLQuery(sql);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query.setParameter("paramterName", parameterValue);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List<Object[]> resultSet = query.list();&nbsp; &nbsp; &nbsp;List<YouClass > data= new ArrayList<>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (Object[] row : resultSet) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; YouClass yourObject=new YouClass ();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; yourObject.setDate((Date) row[0]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; yourObject.setAmount((BigDecimal) row[1]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data.add(yourObject);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }假设 Yourclass 有两个元素 date 和 amount

喵喵时光机

在 HQL 中,您可以使用查询参数并使用 setParameterList 方法设置集合。Query q = session.createQuery("SELECT entity FROM Entity entity WHERE name IN (:names)");q.setParameterList("names", names);
随时随地看视频慕课网APP

相关分类

Java
我要回答