Tag-Based HQL Queries on CF9

I'm sure I wasn't the only one that was sorely disappointed when Adobe released CF9 without the ability to execute HQL queries via the CFQUERY tag.  Using a function (ormExecuteQuery) works, but it's really ungainly if you have complex – or even just long – HQL or need to build your statement conditionally, and you can't get syntax highlighting/code completion.  Being one to solve the Hibernate problem myself (I've been using Hibernate on CF8 for years via CFGroovy), I wrote a couple really simple custom tags to give me the functionality.  Pure CFML, 14 lines total.  Yes, 14 lines.

First, the query tag:

<cfif thisTag.executionMode EQ "start">
  <cfset params = [] />
<cfelse>
  <cfset caller[attributes.name] = ormExecuteQuery(
    thisTag.generatedContent,
    params,
    structKeyExists(attributes, "unique") AND attributes.unique
  ) />
  <cfset thisTag.generatedContent = "" />
</cfif>

And then the queryparam tag:

<cfif thisTag.executionMode EQ "start">
  <cfset arrayAppend(getBaseTagData("cf_query").params, attributes.value) />
  <cfoutput>?</cfoutput>
</cfif>

Wheee!  And here's how you might use them:

<cfimport prefix="h" taglib="/tags/hqlquery" />
<h:query name="policies">
  from FtoPolicy
  order by effectiveDate
</h:query>
<h:query name="emp" unique="true">
  from Employee
  where username = <h:queryparam value="#attributes.username#" />
</h:query>

Note, in particular, that I support a 'unique' attriute on query which behaves exactly like the 'unique' argument to ormExecuteQuery returning a single entity instead of an array of entities.

One response to “Tag-Based HQL Queries on CF9”

  1. Ben Nadel

    I happen to think tag-based approaches are very nice. This looks pretty sweet to me.