首先介绍该方法的功能,就是实现数据库查询功能,并返回某个封装的对象,参数conn是数据库的连接对象,参数sql是查询的sql语句,参数rsh是用来约束返回的对象。
这是query(Connection conn, String sql, ResultSetHandler<T> rsh)方法的源代码:
public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh) throws SQLException {
return this.<T>query(conn, false, sql, rsh, (Object[]) null);
}
通过源码我们可以发现他调用的是另一个重载的query方法:
该方法的源代码如下:
private <T> T query(Connection conn, boolean closeConn, String sql, ResultSetHandler<T> rsh, Object... params)
throws SQLException {
if (conn == null) {
throw new SQLException("Null connection");
}
if (sql == null) {
if (closeConn) {
close(conn);
}
throw new SQLException("Null SQL statement");
}
if (rsh == null) {
if (closeConn) {
close(conn);
}
throw new SQLException("Null ResultSetHandler");
}
PreparedStatement stmt = null;
ResultSet rs = null;
T result = null;
try {
stmt = this.prepareStatement(conn, sql);
this.fillStatement(stmt, params);
rs = this.wrap(stmt.executeQuery());
result = rsh.handle(rs);
} catch (SQLException e) {
this.rethrow(e, sql, params);
} finally {
try {
close(rs);
} finally {
close(stmt);
if (closeConn) {
close(conn);
}
}
}
return result;
}
在源代码中我标记为橙色就是代码的关键部分,该方法返回一个泛型的result对象,而该对象通过调用ResultSetHandler对象的hadle()方法获得,
我们来了解ResultSetHandler<T>,以下是ResultSetHandler<T>的源码:
public interface ResultSetHandler<T> {
/**
* Turn the <code>ResultSet</code> into an Object.
*
* @param rs The <code>ResultSet</code> to handle. It has not been touched
* before being passed to this method.
*
* @return An Object initialized with <code>ResultSet</code> data. It is
* legal for implementations to return <code>null</code> if the
* <code>ResultSet</code> contained 0 rows.
*
* @throws SQLException if a database access error occurs
*/
T handle(ResultSet rs) throws SQLException;
}
他是一个接口;所以我们要实现query(Connection conn, String sql, ResultSetHandler<T> rsh)方法的功能,就必须实现ResultSetHandler<T>中的hadle()f方法。
可以通过匿名内部类来实现该功能:如下所示,Student为一个实体类