SQL restrictions will allow you to add ad-hoc SQL to the criteria you are building. Simple enough, but we have made great strides to make this look easy for a developer but behind the scenes we take each sql you pass and compile it so we can abstract all the native Java types for you. This means that you can use it in a similar manner to executeQuery()
in CFML.
The method you will use for this restriction is sql()
The method takes in two arguments:
sql
- The ad-hoc query to execute. You can use positional parameters via the ?
placeholder.
params
- An array of parameters to bind the SQL with, can be simple values or a struct of a values and a supported type or a combination of both.
The parameters you bind the SQL with can be of two types
Plain values.
Typed values
If you use plain values, then we will INFER the type from it, which is not as accurate as using a typed value. A typed value is a struct with the value and a valid type.
Below you can see the TYPES
struct available in the criteria builder object which map the CFML types to the native Hibernate Types.
The inferred types we infer are the following and in the following order.
Binary
Boolean
Time
Date
uuid
float
numeric
url
string
text
We have created several methods available to you in the criteria builders to help you with casting ColdFusion values to Java values so you can use them in Criteria Queries. Most of the time the engines can do this for us but not always, so we would recommend to just use these convenience methods when needed.
Please note that the base services also include these methods with a few differences in arguments. Just check the API Docs for their usage.
BaseBuilder
Casting MethodsnullValue()
Produce a null value that can be used anywhere you like!
autoCast( propertyName, value )
This method allows you to cast any value to the appropriate type in Java for the property passed in.
idCast( id )
This method allows you to cast the identifier value to the appropriate type in Java.
So instead of casting it manually you can just let us do the work by calling these methods from any of the services.
The ColdBox restrictions class allows you to create criterions upon certain properties, associations and even SQL for your ORM entities. This is the meat and potatoes of criteria queries, where you build a set of criteria to match against or in SQL terms, your WHERE
statements.
The ColdBox criteria class offers most of the criterion methods found in the native hibernate Restrictions class:
If one isn't defined in the CFML equivalent, just call it as it appears in the Javadocs and we will proxy the call to the native Hibernate class for you.
You can get a direct reference to the Restrictions class via the Base/Virtual ORM services (getRestrictions())
, or the Criteria object itself has a public property called restrictions
which you can use rather easily. We prefer the latter approach. Now, please understand that the ColdBox Criteria Builder masks all this complexity and in very rare cases will you be going to our restrictions class directly. Most of the time you will just be happily concatenating methods on the Criteria Builder.
Ok, now that the formalities have been explained let's build some criterias.
To build our criteria queries we can use the methods in the criteria object or go directly to the restrictions object for very explicit criterions as explained above. We will also go to the restrictions object when we do conjunctions and disjunctions, which are fancy words for AND's, OR's and NOT's. To build criterias we will be calling these criterion methods and concatenate them in order to form a nice DSL language that describes what we will retrieve. Once we have added all the criteria then we can use several other concatenated methods to set executions options and then finally retrieve our results or do projections on our results.
Where the property value is between two distinct values
Group expressions together in a single conjunction (A and B and C...) and return the conjunction
Group expressions together in a single disjunction (A or B or C...)
Where a property equals a particular value, you can also use eq()
Where a property is greater than a particular value, you can also use gt()
Where a one property must be greater than another
Where a property is greater than or equal to a particular value, you can also use ge()
Where one property must be greater than or equal to another
Where an object's id equals the specified value
A case-insensitive 'like' expression
Where a property is contained within the specified list of values, the property value can be a collection (struct) or array or list, you can also use in()
Where a collection property is empty
Where a collection property is not empty
Where a collection property is false
Where a property is null
Where a property is NOT null
Where a property is less than a particular value, you can also use lt()
Where a one property must be less than another
Where a property is less than or equal a particular value, you can also use le()
Where a one property must be less than or equal to another
Equivalent to SQL like expression
Where a property does not equal a particular value
Where one property does not equal another
Where a collection property's size equals a particular value
Where a collection property's size is greater than a particular value
Where a collection property's size is greater than or equal to a particular value
Where a collection property's size is less than a particular value
Where a collection property's size is less than or equal a particular value
Where a collection property's size is not equal to a particular value
Use arbitrary SQL to modify the resultset
Return the conjuction of N expressions as arguments
Return the disjunction of N expressions as arguments
Return the negation of an expression. You can also use not()
Returns if the property is true
In some cases (isEq(), isIn(),
etc), you may receive data type mismatch errors. These can be resolved by using JavaCast on your criteria value or use our auto caster methods: idCast(), autoCast()
You can also use the add()
method to add a manual restriction or array of restrictions to the criteria you are building.
But as you can see from the code, the facade methods are much nicer.
Every restriction method you see above or in the docs can also be negated very easily by just prefixing the method with a not
.
There are times where you need if statements in order to add criterias based on incoming input. That's ok, but we can do better by adding a when( test, target )
function that will evaluate the test
argument or expression. If it evaluates to true then the target closure is called for you with the criteria object so you can do your criterias:
Adobe ColdFusion may throw an "Invalid CFML construct" error for certain CBORM methods that match , such as .and()
, .or()
, and .eq()
. You can use .$and()
, .$or()
, and .isEq()
to avoid these errors and build cross-engine compatible code.