---
title: Making Freeform Queries
order: 7
layout: page
---

[[sqlcontainer.freeform]]
= Making Freeform Queries

In most cases, the provided [classname]#TableQuery# will be enough to allow a
developer to gain effortless access to an SQL data source. However there may
arise situations when a more complex query with, for example, join expressions
is needed. Or perhaps you need to redefine how the writing or filtering should
be done. The [classname]#FreeformQuery# query delegate is provided for this
exact purpose. Out of the box the [classname]#FreeformQuery# supports read-only
access to a database, but it can be extended to allow writing also.

[[sqlcontainer.freeform.getting-started]]
== Getting started

Getting started with the [classname]#FreeformQuery# may be done as shown in the
following. The connection pool initialization is similar to the
[classname]#TableQuery# example so it is omitted here. Note that the name(s) of
the primary key column(s) must be provided to the [classname]#FreeformQuery#
manually. This is required because depending on the query the result set may or
may not contain data about primary key columns. In this example, there is one
primary key column with a name 'ID'.


----
FreeformQuery query = new FreeformQuery(
        "SELECT * FROM SAMPLE", pool, "ID");
SQLContainer container = new SQLContainer(query);
----


[[sqlcontainer.freeform.limitations]]
== Limitations

While this looks just as easy as with the [classname]#TableQuery#, do note that
there are some important caveats here. Using [classname]#FreeformQuery# like
this (without providing [classname]#FreeformQueryDelegate# or
[classname]#FreeformStatementDelegate# implementation) it can only be used as a
read-only window to the resultset of the query. Additionally filtering, sorting
and lazy loading features will not be supported, and the row count will be
fetched in quite an inefficient manner. Bearing these limitations in mind, it
becomes quite obvious that the developer is in reality meant to implement the
[classname]#FreeformQueryDelegate# or [classname]#FreeformStatementDelegate#
interface.

The [classname]#FreeformStatementDelegate# interface is an extension of the
[classname]#FreeformQueryDelegate# interface, which returns
[classname]#StatementHelper# objects instead of pure query [classname]#String#s.
This enables the developer to use prepared statetemens instead of regular
statements. It is highly recommended to use the
[classname]#FreeformStatementDelegate# in all implementations. From this chapter
onwards, we will only refer to the [classname]#FreeformStatementDelegate# in
cases where [classname]#FreeformQueryDelegate# could also be applied.


[[sqlcontainer.freeform.custom-freeformstatementdelegate]]
== Creating your own [classname]#FreeformStatementDelegate#

To create your own delegate for [classname]#FreeformQuery# you must implement
some or all of the methods from the [classname]#FreeformStatementDelegate#
interface, depending on which ones your use case requires. The interface
contains eight methods which are shown below. For more detailed requirements,
see the JavaDoc documentation of the interface.


----
// Read-only queries
public StatementHelper getCountStatement()
public StatementHelper getQueryStatement(int offset, int limit)
public StatementHelper getContainsRowQueryStatement(Object... keys)

// Filtering and sorting
public void setFilters(List<Filter> filters)
public void setFilters(List<Filter> filters,
                       FilteringMode filteringMode)
public void setOrderBy(List<OrderBy> orderBys)

// Write support
public int storeRow(Connection conn, RowItem row)
public boolean removeRow(Connection conn, RowItem row)
----

A simple demo implementation of this interface can be found in the SQLContainer
package, more specifically in the class
[classname]#com.vaadin.addon.sqlcontainer.demo.DemoFreeformQueryDelegate#.




