Dynamic HQL query using hql expressions rather than Criteria?

僤鯓⒐⒋嵵緔 提交于 2019-12-03 17:04:45

If you absolutely must avoid dynamic queries, you can do so at the expense of two additional parameters:

SELECT customer 
  FROM Customer AS customer 
  JOIN customer.profile AS profile 
 WHERE (profile.status IN :statusCodes OR :statusCodeCount = 0)
   AND (profile.orgId IN :orgIds OR :orgIdCount = 0)

In your Java code you would then do something like:

session.getNamedQuery("your.query.name")
       .setParameterList("statusCodes", statusCodes)
       .setParameter("statusCodeCount", statusCodes.length)
       .setParameterList("orgIds", orgIds)
       .setParameter("orgIdCount", orgIds.length);

You'll need to ensure arrays are zero-length rather than null or supply additional if checks to handle null scenario.

All that said, HQL is really better suited for well-defined (e.g. static) queries. You can work around dynamic parameters, you won't be able to work around dynamic sorting.

My suggestion is to put all parameters in a map and build the query dynamic, after building before execution set all parameters required by the query taking values from the map:

Map<String, Object> pars = new HashMap<String,Object>();
pars.put("statusCodes", statusCodes);
pars.put("orgIds", orgIds);

StringBuilder b = "SELECT customer FROM Customer as customer INNER JOIN customer.profile as profile where 1 = 1";
if (statusCodes != null) {
  b.append(" and profile.status in :statusCodes");
}
if (orgIds != null) {
  b.append(" and profile.orgId in :statusCodes");
}

...

Query q = session.createQuery(b.toString());

...

for (String p : q.getNamedParameters()) {
  q.setParameter(p, pars.get(p));
}

Of course some improvements are needed for example throw exception when parameters is not set, use typed parameter if complexity is bigger than a few simple parameters and so on.

You'll have to generate your query dynamically:

StringBuilder hql = 
    new StringBuilder("SELECT customer FROM Customer as customer INNER JOIN customer.profile as profile where 1 = 1")
if (statusCodes != null) {
    hql.append(" and profile.status IN :statusCodes");
}
if (orgIds != null) {
    hql.append(" and profile.orgId IN :orgIds");
}

Of course, you will also have to set the parameters to the query only if they're not null.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!