A bit more HQL
November 06, 2009
Yesterday I blogged the basics of HQL, by replicating the functionality of EntityLoad(), so you're probably wondering why you'd bother. Using the same set up as I had in my previous post let's look at some things you can't do with EntityLoad.
We can do "like" searches. Imagine we wanted to get all artists whose surname starts with the letter 'B'
result = ORMExecuteQuery("from Artist as artist Where artist.Lastname like :prefix", {prefix='B%'});
WriteDump(result);
We will get an array of Artist objects returned. It is worth noting that the like search is case sensitive so if you searched with a lowercase 'b', then you'll get no matches. Fear not, we can use the lower function to solve that problem.
result = ORMExecuteQuery("from Artist as artist Where lower(artist.Lastname) like :prefix", {prefix='b%'});
WriteDump(result);
What if we wanted to find out how many Artists resided in a state?
result = ORMExecuteQuery("select Count(artist), artist.State from Artist as artist group by artist.State");
WriteDump(result);
Now the result from the HQL above is different to all the other statements we've tried before, because it returns an array of arrays, not an array of objects.
We can reference the values by doing something like:
<cfoutput>
<table>
<tr>
<th>State</th>
<th>Count</th>
</tr>
<cfloop array="#result#" index="row">
<tr>
<th>#row[2]#</th>
<th>#row[1]#</th>
</tr>
</cfloop>
</table>
</cfoutput>
Whilst that works it's not particularly nice to have to reference properties by the position in an array. Luckily hibernate has a map class which we can use in this situation.
result = ORMExecuteQuery("select new map(Count(artist) as count, artist.State as state) from Artist as artist group by artist.State");
WriteDump(result);
Our result now looks like:
This means that we can write much more descriptive code:
<cfoutput>
<table>
<tr>
<th>State</th>
<th>Count</th>
</tr>
<cfloop array="#result#" index="row">
<tr>
<th>#row["state"]#</th>
<th>#row["count"]#</th>
</tr>
</cfloop>
</table>
</cfoutput>
Much better! You might be wondering why I'm using row["state"] instead of row.state. Well, this is because hibernate is written in Java, a case-sensitive language and the struct is actually a java.util.HashMap. When you use row.state, under the hood ColdFusion automatically changes this to an uppercase STATE. By using the square brackets we are telling coldfusion that we want to preserve the case.
No comments
Leave a comment
If you found this post useful, interesting or just plain wrong, let me know - I like feedback :)
Please note: If you haven't commented before, then your comments will be moderated before they are displayed.