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();