Java tutorial
import java.io.InputStream; import java.io.Reader; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.math.BigDecimal; import java.net.URL; import java.sql.Blob; import java.sql.Clob; import java.sql.Date; import java.sql.Ref; import java.sql.ResultSet; import java.sql.Time; import java.sql.Timestamp; import java.util.HashMap; import java.util.Map; /** * Decorates a <code>ResultSet</code> with checks for a SQL NULL value on each * <code>getXXX</code> method. If a column value obtained by a * <code>getXXX</code> method is not SQL NULL, the column value is returned. * If the column value is SQL null, an alternate value is returned. The * alternate value defaults to the Java <code>null</code> value, which can be * overridden for instances of the class. * * <p> * Usage example: <blockquote> * * <pre> * Connection conn = // somehow get a connection * Statement stmt = conn.createStatement(); * ResultSet rs = stmt.executeQuery("SELECT col1, col2 FROM table1"); * * // Wrap the result set for SQL NULL checking * SqlNullCheckedResultSet wrapper = new SqlNullCheckedResultSet(rs); * wrapper.setNullString("---N/A---"); // Set null string * wrapper.setNullInt(-999); // Set null integer * rs = ProxyFactory.instance().createResultSet(wrapper); * * while (rs.next()) { * // If col1 is SQL NULL, value returned will be "---N/A---" * String col1 = rs.getString("col1"); * // If col2 is SQL NULL, value returned will be -999 * int col2 = rs.getInt("col2"); * } * rs.close(); * </pre> * * </blockquote> * </p> * <p> * Unlike some other classes in DbUtils, this class is NOT thread-safe. * </p> */ public class SqlNullCheckedResultSet implements InvocationHandler { /** * Maps normal method names (ie. "getBigDecimal") to the corresponding null * Method object (ie. getNullBigDecimal). */ private static final Map nullMethods = new HashMap(); static { Method[] methods = SqlNullCheckedResultSet.class.getMethods(); for (int i = 0; i < methods.length; i++) { String methodName = methods[i].getName(); if (methodName.startsWith("getNull")) { String normalName = "get" + methodName.substring(7); nullMethods.put(normalName, methods[i]); } } } private InputStream nullAsciiStream = null; private BigDecimal nullBigDecimal = null; private InputStream nullBinaryStream = null; private Blob nullBlob = null; private boolean nullBoolean = false; private byte nullByte = 0; private byte[] nullBytes = null; private Reader nullCharacterStream = null; private Clob nullClob = null; private Date nullDate = null; private double nullDouble = 0.0; private float nullFloat = 0.0f; private int nullInt = 0; private long nullLong = 0; private Object nullObject = null; private Ref nullRef = null; private short nullShort = 0; private String nullString = null; private Time nullTime = null; private Timestamp nullTimestamp = null; private URL nullURL = null; /** * The wrapped result. */ private final ResultSet rs; /** * Constructs a new instance of <code>SqlNullCheckedResultSet</code> to wrap * the specified <code>ResultSet</code>. * * @param rs * ResultSet to wrap */ public SqlNullCheckedResultSet(ResultSet rs) { super(); this.rs = rs; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getAsciiStream</code> method. * * @return the value */ public InputStream getNullAsciiStream() { return this.nullAsciiStream; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getBigDecimal</code> method. * * @return the value */ public BigDecimal getNullBigDecimal() { return this.nullBigDecimal; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getBinaryStream</code> method. * * @return the value */ public InputStream getNullBinaryStream() { return this.nullBinaryStream; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getBlob</code> method. * * @return the value */ public Blob getNullBlob() { return this.nullBlob; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getBoolean</code> method. * * @return the value */ public boolean getNullBoolean() { return this.nullBoolean; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getByte</code> method. * * @return the value */ public byte getNullByte() { return this.nullByte; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getBytes</code> method. * * @return the value */ public byte[] getNullBytes() { return this.nullBytes; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getCharacterStream</code> method. * * @return the value */ public Reader getNullCharacterStream() { return this.nullCharacterStream; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getClob</code> method. * * @return the value */ public Clob getNullClob() { return this.nullClob; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getDate</code> method. * * @return the value */ public Date getNullDate() { return this.nullDate; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getDouble</code> method. * * @return the value */ public double getNullDouble() { return this.nullDouble; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getFloat</code> method. * * @return the value */ public float getNullFloat() { return this.nullFloat; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getInt</code> method. * * @return the value */ public int getNullInt() { return this.nullInt; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getLong</code> method. * * @return the value */ public long getNullLong() { return this.nullLong; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getObject</code> method. * * @return the value */ public Object getNullObject() { return this.nullObject; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getRef</code> method. * * @return the value */ public Ref getNullRef() { return this.nullRef; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getShort</code> method. * * @return the value */ public short getNullShort() { return this.nullShort; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getString</code> method. * * @return the value */ public String getNullString() { return this.nullString; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getTime</code> method. * * @return the value */ public Time getNullTime() { return this.nullTime; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getTimestamp</code> method. * * @return the value */ public Timestamp getNullTimestamp() { return this.nullTimestamp; } /** * Returns the value when a SQL null is encountered as the result of invoking * a <code>getURL</code> method. * * @return the value */ public URL getNullURL() { return this.nullURL; } /** * Intercepts calls to <code>get*</code> methods and calls the appropriate * <code>getNull*</code> method if the <code>ResultSet</code> returned * <code>null</code>. * * @throws Throwable * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, * java.lang.reflect.Method, java.lang.Object[]) */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(this.rs, args); Method nullMethod = (Method) nullMethods.get(method.getName()); // Check nullMethod != null first so that we don't call wasNull() // before a true getter method was invoked on the ResultSet. return (nullMethod != null && this.rs.wasNull()) ? nullMethod.invoke(this, (Object[]) null) : result; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getAsciiStream</code> method. * * @param nullAsciiStream * the value */ public void setNullAsciiStream(InputStream nullAsciiStream) { this.nullAsciiStream = nullAsciiStream; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getBigDecimal</code> method. * * @param nullBigDecimal * the value */ public void setNullBigDecimal(BigDecimal nullBigDecimal) { this.nullBigDecimal = nullBigDecimal; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getBinaryStream</code> method. * * @param nullBinaryStream * the value */ public void setNullBinaryStream(InputStream nullBinaryStream) { this.nullBinaryStream = nullBinaryStream; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getBlob</code> method. * * @param nullBlob * the value */ public void setNullBlob(Blob nullBlob) { this.nullBlob = nullBlob; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getBoolean</code> method. * * @param nullBoolean * the value */ public void setNullBoolean(boolean nullBoolean) { this.nullBoolean = nullBoolean; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getByte</code> method. * * @param nullByte * the value */ public void setNullByte(byte nullByte) { this.nullByte = nullByte; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getBytes</code> method. * * @param nullBytes * the value */ public void setNullBytes(byte[] nullBytes) { this.nullBytes = nullBytes; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getCharacterStream</code> method. * * @param nullCharacterStream * the value */ public void setNullCharacterStream(Reader nullCharacterStream) { this.nullCharacterStream = nullCharacterStream; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getClob</code> method. * * @param nullClob * the value */ public void setNullClob(Clob nullClob) { this.nullClob = nullClob; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getDate</code> method. * * @param nullDate * the value */ public void setNullDate(Date nullDate) { this.nullDate = nullDate; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getDouble</code> method. * * @param nullDouble * the value */ public void setNullDouble(double nullDouble) { this.nullDouble = nullDouble; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getFloat</code> method. * * @param nullFloat * the value */ public void setNullFloat(float nullFloat) { this.nullFloat = nullFloat; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getInt</code> method. * * @param nullInt * the value */ public void setNullInt(int nullInt) { this.nullInt = nullInt; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getLong</code> method. * * @param nullLong * the value */ public void setNullLong(long nullLong) { this.nullLong = nullLong; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getObject</code> method. * * @param nullObject * the value */ public void setNullObject(Object nullObject) { this.nullObject = nullObject; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getRef</code> method. * * @param nullRef * the value */ public void setNullRef(Ref nullRef) { this.nullRef = nullRef; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getShort</code> method. * * @param nullShort * the value */ public void setNullShort(short nullShort) { this.nullShort = nullShort; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getString</code> method. * * @param nullString * the value */ public void setNullString(String nullString) { this.nullString = nullString; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getTime</code> method. * * @param nullTime * the value */ public void setNullTime(Time nullTime) { this.nullTime = nullTime; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getTimestamp</code> method. * * @param nullTimestamp * the value */ public void setNullTimestamp(Timestamp nullTimestamp) { this.nullTimestamp = nullTimestamp; } /** * Sets the value to return when a SQL null is encountered as the result of * invoking a <code>getURL</code> method. * * @param nullURL * the value */ public void setNullURL(URL nullURL) { this.nullURL = nullURL; } }