Java和SQL:返回null或抛出异常?

hyp*_*ube 3 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 = 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;
 }
Run Code Online (Sandbox Code Playgroud)

问题:

1.你有什么方法可以改善这种归还某些狗的技术?

2. rs.next()将为null ResultSet返回false,或者将生成一个异常,如下所示:

String str = null; 的System.out.println(str.toString());

3.如果在从ResultSet的当前行初始化dog对象时发生了一些不好的事情,例如:连接失败,不兼容的值已经传递给dog属性设置器等等,该怎么办?我现在可能在哈希表中有10个元素,或者没有(第一行).下一步操作是什么:a)返回空哈希表; b)返回结果哈希表,它在这个阶段的方式; c)抛出异常:这里的异常类型是什么?

4.我想你们都会同意这一点:没有什么不好的事情发生,审讯中没有行,将返回空值.但是,@ThorbjørnRavnAndersen 在这里说我应该返回一个NullObject而不是null值.我不知道那是什么.

5.我注意到人们和一群人说应该将应用程序分成几层或某种层次.考虑到上面的例子,这里有哪些层,除了我能想到的这些层:

Layer1 :: Database层,执行操作:此方法.

Layer2 :: ??? :构建新Dog对象的一些层:我的Dog对象.

Layer3 ::?:我打算用狗的集合做一些事情的层:主要是GUI层,或用户界面的子层.

在应用程序流程之后,如果第一层出现异常,最好的想法是什么?我的想法:捕获异常,记录异常,返回一些值.这是最好的做法吗?

Manny感谢您的回答,我期待看到其他人对这些问题的看法.

Bri*_*new 8

我会避免以下情况

   sql.append("SELECT * FROM ").append("dogs_table");
   sql.append(" WHERE ").append(colName).append("='");
                        sql.append(colValue).append("'");
Run Code Online (Sandbox Code Playgroud)

而是使用PreparedStatement及其相关的参数setter方法(setString())等.这将防止colValue有引号和SQL注入攻击(或更一般地,colValue形成一些SQL语法)的值的问题.

如果集合只是空的,我永远不会返回null.这看起来非常违反直觉,从客户的角度来看完全出乎意料.

我不建议在错误条件下返回null,因为您的客户端必须明确检查这个(并且可能会忘记).如果需要,我会返回一个空集合(这可能类似于你的注释re.一个空对象),或者更可能抛出异常(取决于环境和严重性).该例外是有用的,因为它将携带与遇到的错误有关的一些信息.Null告诉你什么.

如果在构建Dog对象时遇到问题,您应该怎么做?我认为这取决于您希望应用程序的强大和弹性.返回Dogs 的子集是一个问题,还是完全是灾难性的,你需要报告这个?这是一个应用程序要求(我必须满足过去的任何一种情况 - 尽力而为全有或全无).

几点意见.我会使用HashMap中,而不是旧的Hashtable(所有访问不同步,更重要的是,不正确的Collection-如果你有一个Collection,你可以将它传递给任何其他方法期待任何 Collection),和StringBuilder的StringBuffer类似的原因.不是一个大问题,但值得了解.


CPe*_*ins 6

你问五个问题

1.你有什么方法可以改善这种归还某些狗的技术?

实际上有几个.

  • 你的方法是静态的 - 这并不可怕,但会导致你使用另一个静态的"executeQuery",这对我来说有点像辛格尔顿...
  • "Dogs"这个类违反了OO的命名习惯 - 复数名词不能成为好的类名,除非该类的一个实例拥有一系列东西 - 而且似乎Dogs实际上是"Dog".
  • HashTable几乎全部弃用.HashMap或ConcurrentHashMap提供更好的性能.
  • 我看不出有理由用多个追加创建查询的第一部分 - 它不错,但它的可读性低于它可能的,所以sql.append("SELECT*FROM dogs_table WHERE"); 如果您只是要对所选列(*)和表名(dogs_table)进行硬编码,那么这将是一个更明智的开端.

2. rs.next()将为null ResultSet返回false,否则将生成异常

这似乎不是一个问题,但是,只要没有任何行要处理,rs.next()就会返回false.

3.如果在从ResultSet的当前行初始化dog对象时发生了一些不好的事情

如果"发生了一些不好的事情",你接下来要做的就取决于你和你的设计.有宽容的方法(返回你可以的所有行)和不宽容(抛出异常).我倾向于倾向于"无情"的方法,因为使用"宽容"的方法,用户不会知道你没有返回所有存在的行 - 只是你在错误之前得到的所有行.但可能存在宽容方法的情况.

4.我想你们都会同意这一点:没有什么不好的事情发生,审讯中没有行,将返回空值.

这不是一个明显正确答案的东西.首先,它不是所写方法中发生的事情.它将返回一个空的HashTable(这是"null对象"的意思).其次,在"未找到结果"的情况下,null并不总是答案.

我见过null,但我也看到了一个空结果变量.我声称它们都是正确的方法,但我更喜欢空的结果变量.但是,最好保持一致,所以选择一种返回"无结果"并坚持下去的方法.

5.我注意到人们和一群人说应该将应用程序分成几层或某种层次.

这比其他人更难回答,而没有看到你的应用程序的其余部分.