最近在复习基础,今天在学习使用DBUtils的QueryRunner类时产生疑问,再次想起自己的博客太少了,所以又开始充数了。。哈哈
String sql = "select * from user";
try {
// 执行
/**
* 注意:这里传递第二个参数是new BeanHandler(User.class)
*/
User user = qr.query(sql, new BeanHandler<User>(User.class));
System.out.println(user.getUsername() + " " + user.getPassword());
/**
* 这里传递的第二个参数是new BeanListHandler(User.class)
*/
List<User> users = qr.query(sql, new BeanListHandler<User>(User.class));
for (User user : users) {
System.out.println(user.getUsername() + " " + user.getPassword());
}
} catch (SQLException e) {
e.printStackTrace();
}
这里的User类时JavaBean哈,就不粘代码了
嗯。。。我的疑问是为啥同一方法会有不同的返回值???乍一看很神奇有木有???
那我们来看一看这个QueryRunner类的query()
public <T> T query(String sql, ResultSetHandler<T> rsh) throws SQLException {
Connection conn = this.prepareConnection();
return this.query(conn, true, sql, rsh, (Object[]) null);
}
可以看到返回值使用了泛型,噢……原来是用了泛型,难怪能随意返回呢!!!
但是我们还是没有看到具体的返回值类型啊,这里有个return好像是调用了另一个query方法,好吧,那就继续看吧
private <T> T query(Connection conn, boolean closeConn, String sql, ResultSetHandler<T> rsh, Object... params)
throws SQLException {
// 这里由于怕大家看太多,就将一些null值判断删了
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,再看看result的赋值,result = rsh.handle(rs)
哎,rsh是啥?我们再往回看。。。。
卧槽,rsh不就是我们一开始在query()中传递的第二个参数吗?
嗯。。。看来最终的返回值还是取决于第二个参数啊(废话)
我们来看看第二个参数不同对象的handle方法
// BeanHandler
public T handle(ResultSet rs) throws SQLException {
return rs.next() ? this.convert.toBean(rs, this.type) : null;
}
// BeanListHandler
public List<T> handle(ResultSet rs) throws SQLException {
return this.convert.toBeanList(rs, type);
}
哇,原来在这!!!