-
Couldn't load subscription status.
- Fork 3
WebQuery API
ResultSetConstraintBuilder can be used to build up queries from a Map of Name-Value Pairs (such as from an HTTP Query String or HTTP Form POST). This functionality is designed to allow simple querying of the underlying database whilst also providing a high-level field constraint interface that is independent of hibernate (i.e. no HQL passed in from the web).
The Map of parameters is parsed as follows:
The query string is parsed for the following parameters:
- _offset: this form parameter is used to specify the start result in the result set
- _limit: this form parameter is used to specify the maximum result set size
- _order: this form parameter is used to order the result set. It can be repeated to order by a number of fields.
A typical example might be:
_offset=100
_limit=100
_order=id ASC
This returns result 100 to result 200, ordered by the “id” field ascending.
The remaining parameters are parsed as constraints. They take the form of simple field-name=value constraints. Constraints are combined logically into database constraints using a simple logic, where constraints on the same field are ORred together and constraints on different fields are ANDed together, for example:
field1=a
field1=b
field2=x
field2=y
Is converted to a database constraint of (field1 = a OR field1 = b) AND (field 2 = x OR field2 = y)
There are 2 special values for a field:
- _null: if used, translates to an IS NULL database constraint
- _notnull: if used, translates to an IS NOT NULL database constraint
Advanced operators are supported to simplify field constraints by providing a prefix to the value:
-
equals: prefix
_f_eq_, also by specifying no prefix, since it is the default function (e.g.visibility=_f_eq_PUBLIC) -
not equals: prefix
_f_neq_(e.g.visibility=_f_neq_PRIVATE) -
starts with: prefix
_f_starts_(only possible on string fields) (e.g.text=_f_starts_four score and seven years ago) -
contains: prefix
_f_contains_(only possible on string fields, uses SQL LIKE so this is a very slow operation) (e.g.text=_f_contains_java) -
range: prefix
_f_range_, with the value expressed as MIN..MAX (e.g.quantity=_f_range_1..100,id=_f_range_alpha..omega) -
greater than: prefix
_f_gt_ -
greater than or equal to: prefix
_f_ge_ -
less than: prefix
_f_lt_ -
less than or equal to: prefix
_f_le_
The data type is picked up based on the Hibernate field type. The supported types are:
- string
- number: encoded in decimal
- boolean: encoded as case insensitive true/false, yes/no, on/off (canonical representation being true/false)
-
date: encoded as an ISO date-with-optional-time, parsed by Joda Time (e.g.
2001-01-01or2001-01-01T09:00:00.25+0100). Special values are provided,now(for the current instant in time),today(for the first instant of today),tomorrow(for the first instant of tomorrow) andyesterday(for the first instant of yesterday) -
uuid: encoded as text (e.g.
3F2504E0-4F89-41D3-9A0C-0305E82C3301) - enum: encoded as case-sensitive enum value
-
timecode: encoded as SMPTE timecode with @timebase at the end
hh:mm:ss:ff@nom[:denom](e.g.01:00:00:04@25for 1 hour and 24 frames at 25 FPS) -
sample count: encoded as
samples@timebase(e.g.1920@48000for 1920 samples at 48kHz)
Consider an entity model describing blog posts for the following example query:
_offset=0
_limit=250
_order=datePosted DESC
_order=id ASC
author.first_name=_f_neq_Alice
datePosted=_f_range_2014-01-01..2014-02-01
deleted=false
postType=PUBLIC
text=_f_contains_java
text=_f_contains_python
The above query will search for the first 250 posts (in descending date posted order, then id order for posts with identical post dates) that match the following query (described in pseudo-SQL/HQL):
postType = PostType.PUBLIC
AND deleted = false
AND datePosted BETWEEN 2014-01-01T00:00:00Z AND 2014-02-01T00:00:00Z
AND author.first_name != 'Alice'
AND (text CONTAINS java OR text CONTAINS python)
The generated Hibernate Criteria will automatically join to the author entity.
The following code sample shows the use of a JAX-RS implementation that passes the query parameters from a GET call as a WebQuery and then calls a marshaller to translate the results to the appropriate representation.
public class PostRestServiceImpl implements PostRestService
{
@Inject
SearchResultMarshaller marshaller;
@Inject
PostDao dao;
@Inject
ResultSetConstraintBuilderFactory constraintBuilder;
@Override
@Transactional(readOnly = true)
public SearchResults getAll(UriInfo info)
{
// Build the query
ResultSetConstraint constraint = constraintBuilder.build(info.getQueryParameters());
// Execute the query and retrieve the resulting rows as objects
ConstrainedResultSet<PostEntity> results = dao.findByUriQuery(constraint);
// Convert the results to the appropriate wire data-type
return marshaller.marshalPosts(results);
}
}