Apache MetaModel offers three different ways of defining a query for a DataContext to retrieve data. Each approach offers a set of features, making them appropriate for different situations.
1 - The
At the core of all query execution in MetaModel is the
Query is a regular Java class containing the structural elements that make up a query. The main elements of a query is a set of clauses (
FromClause and so on) which in turn each contain a set of items (
The object structure is depicted in the below class diagram. Each item will typically refer to some structure in the
DataContext's schema model (a
Column or such), or even an embedded sub-query. A query must have at least 1
SelectItem and 1
FromItem for it to be executable.
As such, you can instantiate
Query and populate the object yourself:
- Building your query this way gives you a lot of control. It allows you to effectively separate the static and dynamic parts of a query and grow awareness of any assumptions/hardcoded values etc.
- One of the main advantages of having the query as an object is that the building of the query lends itself to advanced construction logic, potentially spanning multiple components to aid in the building of a particular query. Therefore, using the Query object type is the most powerful of the three approaches to querying in MetaModel.
- Having the query available as an object also allows you to unittest / assert the structure of the queries you are creating.
- Creating the query this way is a bit verbose, and as we shall see below, it can be made simpler in most cases.
2 - The Query-builder API
To make query definition easier and more developer-guided, Apache MetaModel also has the so-called Query-builder API. This term is used for the set of methods extending from a call to
DataContext.query(), ending with either
.execute(). Using the same simple example as before, we can define and execute the query like this:
- The API is easier to read than using the
- The API helps select which methods are meaningful in the given context, eliminating choices to what makes sense.
- The API does not require you to hold a
Queryobject if you wish to immediately just execute it.
- Some features are not available via this API, for instance sub-querying.
3 - Query parsing
Finally, Apache MetaModel allows you to simply parse a query from a string form. You can use this feature in a two-step parse-then-execute mode or in a single step to parse-and-execute.
The parseQuery method allows you to interrogate or even manipulate the parsed query, potentially leveraging the control and power of the
Query object approach in combination with parsing.
Note that unlike the query builder API, the sequence of query clauses in a string query is like that of SQL (select before from):
SELECT ... FROM ... [ WHERE ...] [ GROUP BY ...] [ HAVING ...] [ ORDER BY ...]
- This approach is often the most readable way of defining a query.
- This approach allows for easy externalization of queries as strings, or of having the users type their own queries.
- Using string literals for queries is un-safe and may introduce bugs in your code due to the non-typed and non-checked nature of the query.
- The fact that string SQL-like queries are supported may be misleading some users to think that the query is passed un-interpreted to the backing datastore. This is NOT the case.