This version of the manual is outdated. For the latest version, follow this link: http://www.jooq.org/doc/3.0/manual.
| The jOOQ User Manual. Multiple Pages : Advanced topics : Execute listeners and the jOOQ Console | previous : next |
# ExecuteListener
The jOOQ Factory Settings let you specify a list of org.jooq.ExecuteListener classes. The ExecuteListener is essentially an event listener for Query, Routine, or ResultSet render, prepare, bind, execute, fetch steps. It is a base type for loggers, debuggers, profilers, data collectors. Advanced ExecuteListeners can also provide custom implementations of Connection, PreparedStatement and ResultSet to jOOQ in apropriate methods. For convenience, consider extending org.jooq.impl.DefaultExecuteListener instead of implementing this interface.
Here is a sample implementation of an ExecuteListener, that is simply counting the number of queries per type that are being executed using jOOQ:
package com.example;
public class StatisticsListener extends DefaultExecuteListener {
public static Map<ExecuteType, Integer> STATISTICS = new HashMap<ExecuteType, Integer>();
// Count "start" events for every type of query executed by jOOQ
@Override
public void start(ExecuteContext ctx) {
Integer count = STATISTICS.get(ctx.type());
if (count == null) {
count = 0;
}
STATISTICS.put(ctx.type(), count + 1);
}
}
Now, configure jOOQ's runtime to load your listener
<settings>
<executeListeners>
<executeListener>com.example.StatisticsListener</executeListener>
</executeListeners>
</settings>
And log results any time with a snippet like this:
log.info("STATISTICS");
log.info("----------");
for (ExecuteType type : ExecuteType.values()) {
log.info(type.name(), StatisticsListener.STATISTICS.get(type) + " executions");
}
This may result in the following log output:
15:16:52,982 INFO - TEST STATISTICS 15:16:52,982 INFO - --------------- 15:16:52,983 INFO - READ : 919 executions 15:16:52,983 INFO - WRITE : 117 executions 15:16:52,983 INFO - DDL : 2 executions 15:16:52,983 INFO - BATCH : 4 executions 15:16:52,983 INFO - ROUTINE : 21 executions 15:16:52,983 INFO - OTHER : 30 executions
Please read the ExecuteListener Javadoc for more details
# jOOQ Console
The ExecuteListener API was driven by a feature request by Christopher Deckers, who has had the courtesy to contribute the jOOQ Console, a sample application interfacing with jOOQ's ExecuteListeners. The jOOQ Console logs all queries executed by jOOQ and displays them nicely in a Swing application. With the jOOQ Console's logger, you can:
- Activate the console's DebugListener anytime (in-process or if the remote server is active).
- View simple and batch queries and their parameters.
- Reformat queries along with syntax highlighting for better readability.
- View stack trace of originator of the call.
- Dump the stack to stdout when in an IDE, to directly navigate to relevant classes.
- Track execution time, binding time, parsing time, rows read, fields read.
- Show/hide queries depending on their type (SELECT, UPDATE, etc.).
- Sort any column (timing columns, queries, types, etc.)
- Easy copy paste of rows/columns to Spreadsheet editors.
A short overview of such a debugging session can be seen here:
Please note that the jOOQ Console is still experimental. Any feedback is very welcome on the jooq-user group
# jOOQ Console operation modes
The jOOQ Console can be run in two different modes:
- In-process mode: running in the same process as the queries you're analysing
- "headless" mode: running remotely
Both modes will require that you set the org.jooq.debug.DebugListener in the Factory's settings. When using XML settings:
<settings>
<executeListeners>
<executeListener>org.jooq.debug.DebugListener</executeListener>
</executeListeners>
</settings>
Or when using programmatic settings:
Settings settings = new Settings()
.getExecuteListeners().add("org.jooq.debug.DebugListener");
Factory factory = new Factory(connection, dialect, settings);
# In-process mode
The in-process mode is useful for Swing applications or other, locally run Java programs accessing the database via jOOQ. In order to launch the jOOQ Console "in-process", specify the previously documented settings and launch the Console as follows:
// Define a DatabaseDescriptor for the "in-process" mode
// It is needed for the "Editor" tab
DatabaseDescriptor descriptor = new DatabaseDescriptor() {
// Return your generated schema. This is used by the console
// to introspect your schema data
@Override
public Schema getSchema() {
return com.example.MySchema.MY_SCHEMA;
}
// Return the SQL dialect that you're using
@Override
public SQLDialect getSQLDialect() {
return SQLDialect.ORACLE;
}
// Return a connection
@Override
public Connection createConnection() {
try {
return DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "test", "test");
}
catch (Exception ignore) {}
}
};
// Now pass this database descriptor to the Console and make it visible
try {
// Use this for a nicer look-and-feel
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
// Create a new Console
Console console = new Console(descriptor, true);
console.setLoggingActive(true);
console.setVisible(true);
}
catch (Exception ignore) {}
Only in the in-process mode, you can execute ad-hoc queries directly from the console, if you provide it with proper DatabaseDescriptor. These queries are executed from the Editor pane which features:
- SQL editing within the console.
- Incremental search on tables.
- Simple code completion with tables/columns/SQL keywords.
- Syntax highlighting and formatting capabilities.
- Results shown in one or several tabs.
- Easy analysis of Logger output by copy/pasting/running queries in the Editor.
# "Headless" mode
In J2EE or other server/client environments, you may not be able to run the console in the same process as your application. You can then run the jOOQ Console in "headless" mode. In addition to the previously documented settings, you'll have to start a debugger server in your application process, that the console can connect to:
// Create a new RemoteDebuggerServer in your application that listens to // incoming connections on a given port SERVER = new RemoteDebuggerServer(DEBUGGER_PORT);
Now start your application along with the debugger server and launch the console with this command:
java -jar jooq-console-2.1.0.jar [host] [port]
Depending on your distribution, you may have to manually add rsyntaxtextarea-1.5.0.jar and jOOQ artefacts on your classpath.
| The jOOQ User Manual. Multiple Pages : Advanced topics : Execute listeners and the jOOQ Console | previous : next |
