这是另一个有争议的主题,但这一次我只搜索简单和有文档记录的答案。场景:
让我们假设下面的方法:
 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;
 }问题:
对于空ResultSet,
String str = null;System.out.println(str.toString());
,
Layer1 ::执行操作的数据库层:此方法。
Layer2 ::?:构造新Dog对象的某个层: my Dog对象。
Layer3 ::?:我打算对狗的集合做一些事情的某一层: GUI层,主要是用户界面的子层。
根据应用程序流程,如果在第一层发生异常,最好的处理方法是什么?我的想法是:捕捉异常,记录异常,返回一些值。这是最佳实践吗?
曼尼,谢谢你的回答,我期待着看看其他人对这些事情的看法。
发布于 2009-10-09 16:59:55
我会避免以下几点
   sql.append("SELECT * FROM ").append("dogs_table");
   sql.append(" WHERE ").append(colName).append("='");
                        sql.append(colValue).append("'");取而代之的是使用PreparedStatement及其相关的参数设置方法(setString())等。这将防止colValue的值具有引号的问题,以及SQL注入攻击(或者更一般地,形成一些SQL语法的colValue )。
如果集合仅仅是空的,我永远不会返回null。这似乎非常违反直觉,从客户的角度来看是完全出乎意料的。
我不建议在错误条件中返回null,因为您的客户端必须显式地检查这一点(并且可能会忘记)。如果需要,我会返回一个空集合(这可能类似于你的评论re。空对象),或者更有可能抛出异常(取决于环境和严重性)。异常很有用,因为它将携带一些与所遇到的错误相关的信息。Null什么也不会告诉你。
如果在构建Dog对象时遇到问题,该怎么办?我认为这取决于您希望您的应用程序具有多强的健壮性和弹性。返回Dog的子集是一个问题,还是完全灾难性的,你需要报告这个问题?这是一个应用程序需求(在过去,我不得不迎合任何一种场景--尽力而为或全有或全无)。
我有几个观察。我会使用HashMap而不是旧的Hashtable (对所有访问都是同步的,更重要的是,不是一个正确的Collection -如果你有一个Collection,你可以把它传递给任何其他需要任何Collection的方法),出于类似的原因,在StringBuffer上使用StringBuilder。这不是一个大问题,但值得了解。
发布于 2009-10-09 17:10:02
Null Object Pattern是一种设计模式,在这种设计模式中,您总是返回一个对象,以避免在代码中执行NPE:s和任何检查。在您的例子中,这意味着返回一个空的Hashtable<Long, Dogs>而不是返回null。
原因是因为它是一个集合,你的其他代码会像这样访问它,如果你返回一个空的集合,它不会崩溃;它不会被迭代,它不会包含任何令人惊讶的东西,它不会导致NPE:s被抛出或诸如此类。
准确地说,Null对象是类/接口的特殊实现,它完全不做任何事情,因此没有任何副作用。因为它的本质不是空值( null ),所以使用它会使你的代码更干净,因为当你知道无论方法内部发生什么,你都会从你的方法调用中得到一个对象,你甚至不需要检查空值,也不需要让代码对它们做出反应!由于空对象不做任何事情,您甚至可以将它们作为singletons随意放置,从而通过这样做来节省内存。
发布于 2009-10-09 19:53:16
不要通过连接字符串来构建SQL查询,就像您正在做的那样:
sql = new StringBuffer();
sql.append("SELECT * FROM ").append("dogs_table");
sql.append(" WHERE ").append(colName).append("='");
sql.append(colValue).append("'");这使得您的代码容易受到一种众所周知的安全攻击,即SQL injection。而不是这样做,而是使用PreparedStatement,并通过在其上调用适当的set...()方法来设置参数。注意,您只能使用它来设置列值,而不能像您正在做的那样,使用它来动态构造列名。示例:
PreparedStatement ps = connection.prepareStatement("SELECT * FROM dogs_table WHERE MYCOL=?");
ps.setString(1, colValue);
rs = ps.executeQuery();如果使用PreparedStatement,JDBC驱动程序将自动处理colValue中可能存在的某些字符的转义,因此SQL注入攻击不再有效。
https://stackoverflow.com/questions/1544952
复制相似问题