Java和SQL:返回null还是抛出异常?
这是另一个有争议的话题,但这一次我只是在寻找简单且有记录的答案。情景: 让我们假设以下方法:Java和SQL:返回null还是抛出异常?,java,mysql,exception,layer,Java,Mysql,Exception,Layer,这是另一个有争议的话题,但这一次我只是在寻找简单且有记录的答案。情景: 让我们假设以下方法: public static Hashtable<Long, Dog> getSomeDogs(String colName, String colValue) { Hashtable<Long, Dog> result = new Hashtable<Long, Dog>(); StringBuffer sql = null; Dog dog = nul
public static Hashtable<Long, Dog> getSomeDogs(String colName, String colValue) {
Hashtable<Long, Dog> result = new Hashtable<Long, Dog>();
StringBuffer sql = null;
Dog dog = null;
ResultSet rs = null;
try {
sql = new StringBuffer();
sql.append("SELECT * FROM ").append("dogs_table");
sql.append(" WHERE ").append(colName).append("='");
sql.append(colValue).append("'");
rs = executeQuery(sql.toString());
while (rs.next()) {
dog= new Dog();
//...initialize the dog from the current resultSet row
result.put(new Long(dog.getId()), dog);
}
}
catch (Exception e) {
createErrorMsg(e);
result = null; //i wonder....
}
finally {
closeResultSet(rs); //this method tests for null rs and other stuff when closing the rs.
}
return result;
}
公共静态哈希表getSomeDogs(字符串colName、字符串colValue){
Hashtable result=新的Hashtable();
stringbuffersql=null;
Dog=null;
结果集rs=null;
试一试{
sql=新的StringBuffer();
sql.append(“SELECT*FROM”).append(“dogs_table”);
sql.append(“WHERE”).append(colName).append(“=”);
append(colValue).append(“”);
rs=executeQuery(sql.toString());
while(rs.next()){
狗=新狗();
//…从当前结果集行初始化狗
result.put(新的Long(dog.getId()),dog);
}
}
捕获(例外e){
createErrorMsg(e);
result=null;//我想知道。。。。
}
最后{
closeResultSet(rs);//此方法在关闭rs时测试空rs和其他内容。
}
返回结果;
}
问题:
一,。你建议用什么方法来改进这项技术,把一些狗带回来?
二,。rs.next()将为空结果集返回false,或生成异常,如下所示:
字符串str=null;
System.out.println(str.toString());
三,。如果在从ResultSet的当前行初始化dog对象时,发生了一些不好的情况,例如:连接失败,不兼容的值已传递给dog属性设置器,等等,该怎么办?到目前为止,哈希表中可能有10个元素,或者没有(第一行)。下一个操作是什么:a)返回空哈希表;b) 返回结果哈希表,与此阶段的方式相同;c) 抛出异常:这里的异常类型是什么?
四,。我想你们都会同意这一点:没有什么不好的事情发生,询问中没有行,返回空值。然而,@Thorbjørn Ravn Andersen说我应该返回一个null对象,而不是null值。我不知道那是什么。
五,。我注意到很多人和团体都在说,应该将应用程序划分为若干层,或某种级别。考虑到上面的例子,除了我能想到的这些层之外,这里还有哪些层:
Layer1::执行操作的数据库层:此方法
第二层::?:构建新狗对象的某个层:my Dog对象
第三层::?:我打算在某个层对狗的集合做些什么:主要是GUI层,或者是用户界面的子层
按照应用程序流程,如果在第一层中发生异常,最好的处理方法是什么?我的想法:捕获异常,记录异常,返回一些值。这是最好的做法吗
曼尼:谢谢你的回答,我期待着看到其他人对这些问题的看法。
我会避免以下情况
sql.append("SELECT * FROM ").append("dogs_table");
sql.append(" WHERE ").append(colName).append("='");
sql.append(colValue).append("'");
并与其关联的参数设置器方法(setString()
)等一起使用。这将防止带有引号的colValue
的值出现问题,以及SQL注入攻击(或者更一般地说,colValue
形成一些SQL语法)
如果集合只是空的,我永远不会返回null。这似乎非常违反直觉,从客户的角度来看完全出乎意料
我不建议在错误条件下返回null,因为您的客户机必须显式地检查这一点(并且可能会忘记)。如果需要,我会返回一个空集合(这可能类似于您的注释re.null对象),或者更可能引发异常(取决于具体情况和严重性)。异常非常有用,因为它将携带一些与遇到的错误相关的信息。空表示什么也不告诉您
如果在构建狗
对象时遇到问题,应该怎么做?我认为这取决于您希望应用程序的健壮性和弹性。返回Dog
s的子集是一个问题,还是完全是灾难性的,您需要对此进行报告?这是一个应用程序需求(在过去,我必须满足任何一种情况——尽最大努力或全部或全无)
一些观察结果。我宁愿使用而不是旧的哈希表
(对于所有访问都是同步的,更重要的是,不是一个适当的集合
——如果你有一个集合
,你可以将它传递给任何其他需要任何集合的方法,出于类似的原因,我会使用字符串缓冲区
)。这不是一个大问题,但值得了解。是一种设计模式,在这种模式中,您总是返回一个对象,以避免NPE:s和代码中的任何空检查。在您的情况下,这意味着不是返回null
,而是返回一个空的哈希表
原因是,由于它是一个集合,而您的其他代码也将访问它,因此如果您返回一个空集合,它不会崩溃;它不会被迭代,不会包含任何令人惊讶的内容,也不会导致NPE:s被抛出等等
准确地说,空对象是类/接口的特殊实现,它完全不做任何事情,因此没有任何副作用。由于其不为空的性质,使用它将使代码更干净,因为当您知道无论方法内部发生什么,您都可以从方法调用中获取对象时,您甚至不必检查空值,也不必让代码对其作出反应!因为Null对象不做任何事情,所以您甚至可以让它们只是躺在那里,这样做可以节省内存。如果发生错误,尽管发生异常。如果没有数据,则返回空集合,而不是空集合。(此外,通常应返回更通用的“映射”,而不是特定的im。)
public static Hashtable<Long, Dogs> getSomeDogs(String colName, String colValue) {
StringBuffer sql = new StringBuffer();
sql.append("SELECT * FROM ").append("dogs_table");
sql.append(" WHERE ").append(colName).append("='");
sql.append(colValue).append("'");
Hashtable<Long, Dogs> result = new Hashtable<Long, Dogs>();
RowMapper mapper = new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Dogs dog = new Dogs();
//...initialize the dog from the current resultSet row
result.put(new Long(dog.getId()), dog);
}
};
(Hashtable<Long, Dogs>) jdbcTemplate.queryForObject(sql, mapper);
}
String sql =
"SELECT * FROM dogs_table " +
"WHERE " + "colName" + " = '" + colValue + "'";
sql = new StringBuffer();
sql.append("SELECT * FROM ").append("dogs_table");
sql.append(" WHERE ").append(colName).append("='");
sql.append(colValue).append("'");
PreparedStatement ps = connection.prepareStatement("SELECT * FROM dogs_table WHERE MYCOL=?");
ps.setString(1, colValue);
rs = ps.executeQuery();