更正尝试/最终

时间:2019-06-17 08:11:49

标签: java try-catch finally

我试图通过try / finally关闭我的结果集,连接和语句,但是Sonar似乎不喜欢它。我在做什么错?为什么不解决?谢谢。

public static List<String> findByName(String firstName, String lastName) throws SQLException {

    /*Connects  to  table and contexts a statement to this connection. Creates the appropriate statement (query)
    according to the first name and last name nulls, builds an array from the ResultSet that is created.*/
    List<String> nameList = new ArrayList();
    String query;

    Connection conn = null;
    Statement preparedStatement = null;
    ResultSet allNames = null;

    try {
        conn = DriverManager.getConnection(getHost(), getuName(), getuPass());
        preparedStatement = conn.createStatement();
        if (firstName == null && lastName == null) {
            query = "SELECT * FROM person_c";
        } else if (firstName == null) {
            query = "SELECT * FROM person_c WHERE LAST_NAME= '" + lastName + "'";
        } else if (lastName == null) {
            query = "SELECT * FROM person_c where FIRST_NAME= '" + firstName + "'";
        } else {
            query = "SELECT * FROM person_c where FIRST_NAME =  '" + firstName + "'" + "AND LAST_NAME= '" + lastName + "'";
        }
        allNames = preparedStatement.executeQuery(query);
        while (allNames.next()) {
            nameList.add(allNames.getString("FIRST_NAME") + "  " + allNames.getString("LAST_NAME"));
        }
    } finally {
        if (allNames != null) allNames.close();
        if (preparedStatement!=null)  preparedStatement.close();
        if (conn!=null) conn.close();
    }
    return nameList;
}

1 个答案:

答案 0 :(得分:3)

该代码中存在三个不相关的问题:

  1. 理论上,close可以抛出。如果您之前的close调用中有任何抛出,则以后的调用将不会完成。另外,如果已经在发生异常,则来自那些close调用的异常将覆盖它,从而隐藏了真正的问题。解决方案是使用try-with-resources

  2. 您正在PreparedStatement上呼叫executeQuery(String)。永远不要那样做,它像对待PreparedStatement一样对待Statement。 (这是API设计错误。)而是将查询传递到prepareStatement

  3. 不要使用字符串串联将值放入查询中。这就是PreparedStatement的重点:安全地对查询进行参数化。 (让我向您介绍my friend Bobby ...)

因此要处理所有这三个问题:

public static List<String> findByName(String firstName, String lastName) throws SQLException {

    /*Connects  to  table and contexts a statement to this connection. Creates the appropriate statement (query)
    according to the first name and last name nulls, builds an array from the ResultSet that is created.*/
    List<String> nameList = new ArrayList();
    String query;

    try (
        Connection conn = DriverManager.getConnection(getHost(), getuName(), getuPass());
    ) {
        if (firstName == null && lastName == null) {
            query = "SELECT * FROM person_c";
        } else if (firstName == null) {
            query = "SELECT * FROM person_c WHERE LAST_NAME = ?";
        } else if (lastName == null) {
            query = "SELECT * FROM person_c where FIRST_NAME = ?";
        } else {
            query = "SELECT * FROM person_c where FIRST_NAME = ? AND LAST_NAME = ?";
        }
        try (
            Statement preparedStatement = conn.createStatement(query);
        ) {
            int n = 1;
            if (firstName != null) {
                preparedStatement.setString(n++, firstName);
            }
            if (lastName != null) {
                preparedStatement.setString(n++, lastName);
            }
            try (
                ResultSet allNames = preparedStatement.executeQuery();
            ) {
                while (allNames.next()) {
                    nameList.add(allNames.getString("FIRST_NAME") + "  " + allNames.getString("LAST_NAME"));
                }
            }
        }
    }
    return nameList;
}