This is the situation
In jOOQ, there is a lot of need for abstraction over JDBC. I want the jOOQ client code to be unaware of the fact, that some data is retrieved from a simple ResultSet, some data is retrieved from SQLInput (for UDTs), or from CallableStatements (for stored procedures/functions). Hence, I want to add abstraction over these JDBC types:
java.sql.ResultSet
java.sql.CallableStatement
java.sql.SQLInput
java.sql.SQLOutput
Now they all work pretty much the same way. They usually have a get
and set
method for every data type in java.sql.Types
. For example, they ship with methods like
BigDecimal getBigDecimal(int index);
int getInt(int index);
And they all have methods like
boolean wasNull();
The problem
Unfortunately, these JDBC interfaces don't extend a single common interface making lives easier for those who want to write generic JDBC code like this snippet here (just an example to support my question):
// As JDBC has no support for BigInteger types directly,
// read a BigDecimal and transform it to a BigInteger
BigDecimal result = null;
if (source instanceof ResultSet) {
result = ((ResultSet) source).getBigDecimal(index);
}
else if (source instanceof CallableStatement) {
result = ((CallableStatement) source).getBigDecimal(index);
}
else if (source instanceof SQLInput) {
result = ((SQLInput) source).readBigDecimal();
}
return result == null ? null : result.toBigInteger();
The above code needs to be written for all three of them, ResultSet
, CallableStatement
, SQLInput
. And there are lots of similar examples
My question is
- Does anyone know a JDBC extension library that solves this problem elegantly?
- Or should I write a simple wrapper class (or adapter) for all of these types myself?
- Or would you just accept that fact and keep duplicating internal library code?
Which solution do you prefer and why? Thanks for any feedback