Getting a connection

Tornado Query expects that you give it a java.sql.Connection, and doesn't really help you in obtaining one. Here we'll introduce some ways to do that, and show you how you would typically use Tornado Query in your applications. Please feel free to skip this chapter for now, and revisit it once you start actually using Tornado Query. Read about mappers and usage to wet your appetite, then come back for the details!

Explicit

The Query class has a static ThreadLocal where you can set a connection before performing queries. Tornado Query expects this connection to be ready to use, and will not commit, rollback or close this connection in any way. In it's simplest form, it means that you can use Tornado Query like this:

// Create a connection and set it
Query.connection.set(DriverManager.getConnection("jdbc:postgresql:/host/database"));

// Perform your queries here
...

// Close the connection
Query.connection.get().close();

Instead of using the static ThreadLocal, you can also supply each Query object with a specific connection. Remember that you are still responsible for closing, committing and rolling it back:

// Create a connection and set it
Connection conn = DriverManager.getConnection("jdbc:postgresql:/host/database");

// Set the connection on each query
Query.create(...).connection(conn);

// Close the connection
conn.close();

WebApp

In a web application it might make more sense to let a Filter make sure you have a connection, and even take care of the transaction demarcation for you. If you want to make sure that you always have a connection handy in every request, and that it gets commited if everything is OK, and rolled back if something goes wrong, you can register a Filter in your web application. We will also create a Commons DBCP connection pool to give each thread a connection efficiently.

@WebFilter("/*")
public class QueryFilter implements Filter {
    private BasicDataSource ds;

    public void init(FilterConfig filterConfig) throws ServletException {
        ds = new BasicDataSource();
        ds.setDriverClassName("org.postgresql.Driver");
        ds.setUrl("jdbc:postgresql:/host/dbname");
        ds.setDefaultAutoCommit(false);
        ds.setUsername("myuser");
        ds.setPassword("mypassword");
    }

    public void doFilter(ServletRequest request, ServletResponse response,
                    FilterChain chain) throws IOException, ServletException {
        try (Connection c = ds.getConnection()) {
            Query.connection.set(c);

            chain.doFilter(request, response);

            c.commit();
        } catch (Exception ex) {
            if (Query.connection.get() != null)
                try { Query.connection.get().rollback(); }
                    catch (SQLException ignored) { }
            throw new ServletException(ex);
        } finally {
            Query.connection.remove();
        }
    }

    public void destroy() {
        try {
            ds.close();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
}

In the init method, we create a DataSource which is basically a pool of opened connections. We make sure that the connections returned from the pool does not auto commit each transaction. This way, we wrap the entire HTTP request in one SQL Transaction, and commit only if everything is OK. We roll back if an Exception occurs. Finally, the destroy method will close the datasource and release all the connections.

You might want to exclude certain patterns, like files etc from the filter, or use a more sofisticated algoritm to determine if a connection should be provided.

All examples in this tutorial will assume that you have already given the current thread a connection using a strategy like the ones described here.