//Get a prepared statement to use PreparedStatement stmnt =
null;
try {
//Get an actual prepared statement stmnt =
conn.prepareStatement(sql);
//Attempt to stuff this statement with
the given values. If //no values were given, then we can skip this
step. if(pStmntValues != null)
{ PreparedStatementFactory.buildStatement(stmnt,
pStmntValues); }
//Attempt to execute the statement ResultSet
rs = stmnt.executeQuery();
//Get the results from this
query Object[] results = processor.process(rs);
//Close out the
statement only. The connection will be closed by
the //caller. closeStmnt(stmnt);
//Return the
results return results;
//Any SQL exceptions that occur should
be recast to our runtime query //exception and thrown from here }
catch(SQLException e) { String message = "Could not perform the query
for " + sql;
//Close out all resources on an
exception closeConn(conn); closeStmnt(stmnt);
//And rethrow
as our runtime exception throw new
DatabaseQueryException(message); } } } ... }
//Loop through all objects of the values array, and set the
value //of the prepared statement using the value array
index for(int i = 0; i < values.length; i++) {
//If the
object is our representation of a null value, then handle it
separately if(value instanceof NullSQLType) { stmnt.setNull(i + 1,
((NullSQLType) value).getFieldType()); } else { stmnt.setObject(i +
1, value); } } 由于stmnt.setObject(int index,
Object
value)方法不可以接受一个null对象值,因此我们必须使用自己特殊的构造:NullSQLType类。NullSQLType表示一个null语句的占位符,并且包含有该字段的JDBC类型。当一个NullSQLType对象实例化时,它获得它将要代替的字段的SQL类型。如上所示,当预处理语句通过一个NullSQLType组合时,你可以使用NullSQLType的字段类型来告诉预处理语句该字段的JDBC类型。这就是说,你使用NullSQLType来表明正在使用一个null值来组合一个预处理语句,并且通过它存放该字段的JDBC类型。
private static final String SQL_GET_USER = "SELECT * FROM USERS WHERE
ID =
?"; 接着,我们形成ResultProcessor,我们将使用它来接受结果集并且形成一个User对象:
public class UserResultProcessor implements ResultProcessor
{
//Column definitions here (i.e., COLUMN_USERNAME,
etc...) ..
public Object[] process(ResultSet rs) throws
SQLException {
//Where we will collect all returned
users List users = new ArrayList(); User user =
null;
//If there were results returned, then process
them while(rs.next()) {
user = new User(rs.getInt(COLUMN_ID),
rs.getString(COLUMN_USERNAME), rs.getString(COLUMN_FIRST_NAME),
rs.getString(COLUMN_LAST_NAME), rs.getString(COLUMN_EMAIL));
//Get a SQL processor and
execute the query SQLProcessor processor = new
SQLProcessor(); Object[] users =
processor.executeQuery(SQL_GET_USER_BY_ID, new Object[] {new
Integer(userId)}, new UserResultProcessor());
//And just return
the first User object return (User)
users[0]; } 这就是全部。我们只需要一个处理类和一个简单的方法,我们就可以无需进行直接的连接维护、语句和异常处理。此外,如果我们拥有另外一个查询由用户表中得到一行,例如通过用户名或者密码,我们可以重新使用UserResultProcessor。我们只需要插入一个不同的SQL语句,并且可以重新使用以前方法的用户处理器。由于返回行的元数据并不依赖查询,所以我们可以重新使用结果处理器。
//Get a prepared statement to
use PreparedStatement stmnt = null;
try {
//Get an actual
prepared statement stmnt = conn.prepareStatement(sql);
//Attempt
to stuff this statement with the given values. If //no values were
given, then we can skip this step. if(pStmntValues != null)
{ PreparedStatementFactory.buildStatement(stmnt,
pStmntValues); }
//Attempt to execute the statement int rows
= stmnt.executeUpdate();
//Now hand off the number of rows updated
to the processor processor.process(rows);
//Close out the
statement only. The connection will be closed by
the //caller. closeStmnt(stmnt);
//Any SQL exceptions that
occur should be recast to our runtime query //exception and thrown from
here } catch(SQLException e) { String message = "Could not perform
the update for " + sql;
//Close out all resources on an
exception closeConn(conn); closeStmnt(stmnt);
//And rethrow
as our exception throw new
DatabaseUpdateException(message); } }