SQL语句可能运行,没有错误,但断言失败

时间:2014-04-28 11:04:33

标签: java sql jdbc

所以我遇到了这个问题,我必须尝试预订航班上的所有座位。

我使用静态方法创建了一个Helper类,用于单元测试。当我运行测试时,我的bookAll()方法运行“isAllBooked()”方法。但isAllBooked方法返回false。

经过调查,事实证明最初的bookAll()声明并没有触及数据库。但没有错误。可能是什么原因造成的?

HelperClass.java

public static void bookAll(String plane_no) {
    conn = getConnection("", "");
    try {
        conn.prepareStatement(""
                + "UPDATE SEAT"
                + "SET reserved='1337',booked='1337',booking_time='1337'"
                + "WHERE plane_no='" + plane_no + "';"
        );
        conn.commit();
    } catch (SQLException ex) {
        System.out.println("[HELPER CLASS] SQL ERROR: " + ex.getMessage());
    }
    closeConnection(conn);
}

public static boolean isAllBooked(String plane_no) {
    conn = getConnection("", "");
    try {
        ResultSet rs =
                conn.prepareStatement(
                        "SELECT booked FROM SEAT WHERE plane_no='"
                                + plane_no + "'")
                        .executeQuery();
        while(rs.next()) {
            int i = rs.getInt("BOOKED");
            if(rs.wasNull()) {
                closeConnection(conn);
                return false;
            }
        }
    } catch (SQLException ex) {
        System.out.println("[HELPER CLASS] SQL ERROR: " + ex.getMessage());
    }
    closeConnection(conn);
    return true;
}

HelperClassTest.java

@Test
public void testBookAll() {
    System.out.println("bookAll");
    String plane_no = "CR9";
    HelperClass.bookAll(plane_no);
    boolean expResult = true;
    boolean result = HelperClass.isAllBooked(plane_no);
    assertEquals(expResult,result);
}

1 个答案:

答案 0 :(得分:4)

你永远不会执行语句:

conn.prepareStatement(""
        + "UPDATE SEAT"
        + "SET reserved='1337',booked='1337',booking_time='1337'"
        + "WHERE plane_no='" + plane_no + "';"
);
conn.commit();

你忽略了prepareStatement的返回值,所以你实际上并没有针对数据库执行任何操作。

应该使用带参数的固定SQL创建PreparedStatement,根据PreparedStatement指定参数值,然后调用PreparedStatement.executeUpdate()

类似于:

public static void bookAll(String planeNo) {
    String sql = "UPDATE SEAT "
               + "SET (reserved, booked, booking_time) "
               + "VALUES ('1337', '1337', '1337') "
               + "WHERE plane_no=?";
    try (Connection conn = getConnection("", "");
         PreparedStatement st = conn.prepareStatement(sql)) {
        st.setString(1, planeNo);
        st.executeUpdate();
        conn.commit();
    } catch (SQLException ex) {
        System.out.println("[HELPER CLASS] SQL ERROR: " + ex.getMessage());
    }
}

请注意:

  • 使用 local 变量进行连接,而不是实例变量。您应该为每个操作使用单独的Connection,即使它实际上是合并的
  • 使用符合Java编码约定的变量名称
  • 使用try-with-resources语句确保即使出错也能关闭所有内容

我个人不会使用那种异常处理方式 - 我会让异常传播,可能会将其重新抛出为未经检查的异常 - 但这是另一回事。