public class StudentDAO extends ConnectorDAO {
private List<StudentBean> studentList = new LinkedList<>();
private StudentBean studentBean;
public List<StudentBean> retrieveStudents() {
Connection connection;
try {
String myQuery = "SELECT ?, ?, ? FROM Students";
connection = getConnection() // getConnection() comes from superclass
PreparedStatement preparedstatement = connection.prepareStatement(myQuery);
preparedStatement.setString(1, "firstname");
preparedStatement.setString(2, "lastname");
preparedStatement.setString(3, "studentID");
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
studentBean = new StudentBean();
studentBean.setFirstName(resultSet.getString("firstname"));
studentBean.setLastName(resultSet.getString("lastname"));
studentBean.setID(resultSet.getInt("studentID"));
studentList.add(studentBean);
}
} catch (Exception e) {
// Error handling stuff
} finally {
// close connection, resultset and preparedstatement
}
}
}
我的日食中出现错误。在我设置studentBean的ID的行上。我的数据库中studentID的数据类型是Int。我不知道如何检索它。谁能帮我?当我使用预准备语句中使用的参数进行查询时,它使用Statement对象时可以正常工作。
答案 0 :(得分:2)
构建查询的代码不正确:
String myQuery = "SELECT ?, ?, ? FROM Students";
connection = getConnection() // getConnection() comes from superclass
PreparedStatement preparedstatement = connection.prepareStatement(myQuery);
preparedStatement.setString(1, "firstname");
preparedStatement.setString(2, "lastname");
preparedStatement.setString(3, "studentID");
不可能: 查询字符串的格式如下(示例):
String myQuery = "SELECT firstname, lastname, studentID FROM Students WHERE studentID=?";
参数仅用于不在列名,表名等上的变量。
因此,一旦您拥有类似的代码,就可以查询studentID
(不是您的目标,只是为了示例):
preparedStatement.setInt(1, someStudentID);
将preparedStatement
发送给DBMS,然后DBMS将?
替换为someStudentID
的值。
答案 1 :(得分:0)
setString
(或setInt
中的setXXX
或任何其他PreparedStatement
)的含义是&#34;用适当的值替换相应的问号键入&#34 ;.所以这段代码:
String myQuery = "SELECT ?, ?, ? FROM Students";
connection = getConnection() // getConnection() comes from superclass
PreparedStatement preparedstatement = connection.prepareStatement(myQuery);
preparedStatement.setString(1, "firstname");
preparedStatement.setString(2, "lastname");
preparedStatement.setString(3, "studentID");
有效地创建以下查询:
SELECT 'firstname', 'lastname', 'studentID' FROM Students
现在,这告诉它从表中选择三个文字字符串。如果您在SQL命令行实用程序或类似的东西中运行此查询,您会发现结果是
firstname | lastname | studentID
firstname | lastname | studentID
firstname | lastname | studentID
firstname | lastname | studentID
...
而不是你的期望。由setString
设置的任何内容都被解释为文字字符串 - 就好像它包含单引号一样。
因此,问号用于在语句中设置值,如果您在命令行实用程序中键入语句,则该值将是文字值。
因此,结果集的行是包含三个字符串firstname
,lastname
和studentID
的行。
现在,在下一段代码中:
while (resultSet.next()) {
studentBean = new StudentBean();
studentBean.setFirstName(resultSet.getString("firstname"));
studentBean.setLastName(resultSet.getString("lastname"));
studentBean.setID(resultSet.getInt("studentID"));
studentList.add(studentBean);
}
在许多数据库系统中,您甚至无法使用getString("firstname")
,因为来自文字查询的返回列名是任意的。但我想你的数据库系统实际上给返回列提供了与文字值相同的名称。因此,您可以检索firstname
和lastname
(但他们的内容不是学生姓名!它是文字字符串"firstname"
和"lastname"
),因为您正在使用getString
。
但是当你尝试使用getInt
时,你运气不佳。由于您查询了文字字符串,因此您将获得三个字符串。第三列不是整数,而是文字字符串"studentID"
。这是你遇到错误的地方。
所以你应该将你的查询改为
"SELECT firstname, lastname, studentID FROM Students"
这意味着在这种情况下你不一定需要准备好的陈述,但它也不会受到伤害。
那么你在哪里可以使用问号?
您在查询中需要文字值的任何地方。例如,如果您想知道一个人的出生年份与给定年份之间的差异,您可以写下:
SELECT year_of_birth - ? FROM people
然后使用setInt(1,1969)
或setInt(1,2001)
使查询成为:
SELECT year_of_birth - 1969 FROM people
和
SELECT year_of_birth - 2001 FROM people
分别在预准备语句中,不能用问号替换数据库对象(如列和表)的实际名称(不是文字)。它们是查询计划本身的一部分。