我有一个带有列的课程表,
id
,teacher_id
和name
。
这是我用来获取id的课程的方法。
public static Course getById(int id) throws SQLException {
String query = "SELECT * FROM courses WHERE id = ?" ;
Course course = new Course();
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try{
DriverManager.registerDriver(new com.mysql.jdbc.Driver ());
connection = (Connection) DriverManager.getConnection(ConnectDb.CONN_STRING, ConnectDb.USERNAME, ConnectDb.PASSWORD);
statement = (PreparedStatement) connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
statement.setInt(1, id);
resultSet = statement.executeQuery(query);
while (resultSet.next()) {
course.setId(resultSet.getInt("id"));
course.setName(resultSet.getString("name"));
course.setTeacherId(resultSet.getInt("teacher_id"));
}
}catch (SQLException e) {
System.err.println(e);
}finally{
if (resultSet != null) resultSet.close();;
if (statement != null) statement.close();
if(connection != null) connection.close();
}
return course;
}// end of method
当我运行此方法时,我得到一个输出id:0,teacher_id:0
服务器日志说我有一个SQLException
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1
答案 0 :(得分:4)
错误在这里:
resultSet = statement.executeQuery(query);
您没有致电PreparedStatement#executeQuery
,而是致电Statement#executeQuery
(Statement
是PreparedStatement
的超级接口)。因此,参数替换不会发生,而您实际上是将?
发送到服务器。
将其更改为:
resultSet = statement.executeQuery();
// No argument here ---------------^
(是的,这是一个API设计缺陷;不,你不是第一个陷入它的人。)
该代码还有一些其他可以改进的地方:
即使发生异常,您也总是返回Course
。最佳做法是允许异常传播给调用者;第二好的做法是将某种标志返回给调用者发生错误,例如null
。
try-with-resources语句可以使代码更短更清晰
您不必转换getConnection
或prepareStatement
的返回值。
您正在使用while
,但您只希望获得一个结果。 if
会更有意义。
关于该主题,您可以使用setMaxRows
向驱动程序提供相关提示。
您的方法声明它可以抛出SQLException
,因为它调用了close
,所以它实际上是真的,但实际上只有有用的 SQLException
被代码捕获,记录和抑制,使得在方法上声明它有点误导。
我被告知现代JDBC驱动程序不再需要registerDriver
调用了。 (我个人暂时没有使用过JDBC,所以......)
这是一个包含上述内容的例子。它允许传播异常,因此在正常的代码流中不处理错误(异常条件);如果没有匹配的课程,它会返回null
:
public static Course getById(int id) throws SQLException {
String query = "SELECT * FROM courses WHERE id = ?";
try (
Connection connection = DriverManager.getConnection(ConnectDb.CONN_STRING, ConnectDb.USERNAME, ConnectDb.PASSWORD);
PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
) {
statement.setInt(1, id);
statement.setMaxRows(1);
try (
ResultSet resultSet = statement.executeQuery();
) {
if (resultSet.next()) {
Course course = new Course();
course.setId(resultSet.getInt("id"));
course.setName(resultSet.getString("name"));
course.setTeacherId(resultSet.getInt("teacher_id"));
return course;
}
// No matching course
return null;
}
}
} // end of method
这可能会进一步改善,但你明白了。