Dashboard > iBATIS DataMapper > Home > Frequently Asked Questions > How do I gain access to underlying JDBC Objects?
How do I gain access to underlying JDBC Objects?
Added by Jeff Butler, last edited by Jeff Butler on Jan 25, 2008  (view change)
Labels: 
(None)


There are many cases where it is useful to gain access to the actual JDBC objects when using iBATIS. For example, type handlers sometimes need access to the ResultSet object, other times applications need access to the Connection object. Gaining access to these objects is made complex by the iBATIS logging infrastructure - things behave differently depending on whether logging is enabled or not. This article shows how to gain access to the underlying objects in all circumstances.

Note: this code requires iBATIS 2.3 or later

java.sql.Connection

Unwinding connections is further complicated if you are using iBATIS' simple data source. This method will unwind the connection from any of the iBATIS Connection proxies (note - SimplePooledConnection is a private inner class in iBATIS 2.3 and earlier. You will either have to patch the iBATIS source to make it public, build iBATIS from the SVN trunk, or use a later release).

import java.sql.Connection;
    import java.lang.reflect.Proxy;
    import java.lang.reflect.InvocationHandler;
    import com.ibatis.common.jdbc.SimpleDataSource.SimplePooledConnection;
    import com.ibatis.common.jdbc.logging.ConnectionLogProxy;
    
    public Connection unwindConnection(Connection connection) {
    if (connection == null) {
    return null;
    }
    
    Connection localConnection = connection;
    
    while (Proxy.isProxyClass(localConnection.getClass())) {
    InvocationHandler ih = Proxy.getInvocationHandler(localConnection);
    if (ih instanceof ConnectionLogProxy) {
    localConnection = ((ConnectionLogProxy) ih).getConnection();
    } else if (ih instanceof SimplePooledConnection) {
    localConnection = ((SimplePooledConnection) ih).getRealConnection();
    } else {
    // some other non iBATIS proxy - jump out
          break;
    }
    }
    
    return localConnection;
    }

To use this method, do the following...

Connection connection = unwindConnection(sqlMapClient.getCurrentConnection());
    
    // now do something interesting with the connection...
    if (connection instanceof DB2Connection) {
    ...
    }

java.sql.ResultSet

Unwinding ResultSet objects is easier becuase there is only one possible iBATIS proxy. In a type handler, you might write code like this:

java.sql.ResultSet rs = getter.getResultSet();
    if (Proxy.isProxyClass(rs.getClass())) {
    InvocationHandler ih = Proxy.getInvocationHandler(rs);
    if (ih instanceof ResultSetLogProxy) {
    rs = ((ResultSetLogProxy) ih).getRs();
    }
    }
    
    // now do something interesting with the ResultSet...
    if (rs instanceof OracleResultSet) {
    ...
    }

There are similar proxy objects for java.sql.PreparedStatement (PreparedStatementLogProxy) and java.sql.Statement (StatementLogProxy).


Site running on a free Atlassian Confluence Open Source Project License granted to OSS. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.5 Build:#811 Jul 25, 2007) - Bug/feature request - Contact Administrators