【问题标题】:Hibernate HQL - what to do if one property might be nullHibernate HQL - 如果一个属性可能为空怎么办
【发布时间】:2017-02-12 15:35:44
【问题描述】:

我需要通过这个查询从我的数据库中获取用户:

SELECT * FROM users
WHERE first_name = 'Aragorn'
AND last_name = 'SonOfAratorn'
AND city = 'Osgiliot'
AND country = 'Gondor'

问题是在我的应用程序中,我经常会丢失城市或国家/地区,或者两者都丢失。

我可以为此进行 3 或 4 个 HQL 查询,但这似乎不是一个非常有效的解决方案。

有没有一种方法可以只使用一个查询来适应这些属性(城市和国家)中的一个或两个为空的情况,以及如何将该查询转换为 HQL?

我的数据库在 MySql 服务器上。

PS:

我尝试过类似的方法,但没有成功:

SELECT * FROM users
WHERE first_name = 'Aragorn'
AND last_name = 'SonOfAratorn'
AND city like IFNULL('%', <my-city-param>)
AND country like IFNULL('%', <my-country-param>);

我正在寻找类似 HQL 格式的内容。

提前致谢。 :)

【问题讨论】:

  • 我更喜欢 Criteria 而不是 HQL。如果您愿意,我可以按标准提供解决方案))

标签: mysql hibernate hql


【解决方案1】:
SELECT * FROM users
WHERE first_name = 'Aragorn'
AND last_name = 'SonOfAratorn'
AND (city is null or @city is null or city like '%' + @city)
AND (country is null or @country is null or country like '%' + @country)

【讨论】:

  • AND 的优先级高于 OR,因此您的查询将返回与城市或国家匹配的所有用户,并且在这种情况下不关心 first_name 和 last_name。另外我认为OP想要检查参数是否为空,而不是条目的表字段。
【解决方案2】:

如果您有一个名为 Users 的实体,但您并不总是传递填写的城市和国家/地区参数并希望忽略它们,这是 JPQL/HQL 和 Java 代码:

StringBuilder jpql = new StringBuilder();

jpql.append("SELECT user FROM Users user ");
jpql.append("WHERE user.first_name = :firstname ");
jpql.append("AND user.last_name = :lastname ");

Map<String, Object> paramsQuery = new HashMap<String, Object>();

if (cityParam == null) {
    paramsQuery.put("city", "%" + cityParam+ "%");
    jpql.append("AND (city like :city) ");
}

if (countryParam == null){
    paramsQuery.put("country", "%" + countryParam+ "%");
    jpql.append("AND (country like :country) ");
}

Query q = em.createQuery(jpql.toString())
q.setParameter("firstname", firstnameParam);
q.setParameter("lastname",lastnameParam);
setQueryParameters(params, q);

在查询中设置可选参数的辅助方法:

public Query setQueryParameters(Map<String, Object> params, Query query) {
    Set<Entry<String, Object>> entrySet = params.entrySet();
    for (Entry<String, Object> entry : entrySet) {
        query.setParameter(entry.getKey(), entry.getValue());
    }

    return query;
}

【讨论】:

  • 我认为他的意思是传递给查询的参数为空,而不是数据库中的那个。
【解决方案3】:

勾选coalesce功能;

coalesce(:valueifnotnull,'valueifnull') 

应该做的伎俩

【讨论】:

    猜你喜欢
    • 2017-12-20
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    • 2010-11-19
    • 2012-07-06
    相关资源
    最近更新 更多