如何在Java中使用预处理语句进行select查询?

17

我尝试使用准备好的语句好几次,但是它一直返回SQL异常。这是我的代码:

public ArrayList<String> name(String mobile, String password) {
    ArrayList<String> getdata = new ArrayList<String>();
    PreparedStatement stmt = null;
    try {
        String login = "select mobile, password from tbl_1 join tbl_2 on tbl_1.fk_id=2.Pk_ID where mobile=? and password=?";

        String data = "select * from tbl_2  where password='" + password + "'";

        PreparedStatement preparedStatement = conn.prepareStatement(login);

        preparedStatement.setString(1, mobile);
        preparedStatement.setString(1, password);

        ResultSet rs = preparedStatement.executeQuery(login);

        Statement stmts = (Statement) conn.createStatement();

        if (rs.next()) {
            System.out.println("Db inside RS");
            ResultSet data = stmts.executeQuery(data);

            while (data.next()) { /* looping through the resultset */

                getdata.add(data.getString("name"));
                getdata.add(data.getString("place"));
                getdata.add(data.getString("age"));
                getdata.add(data.getString("job"));
            }

        }

    } catch (Exception e) {
        System.out.println(e);
    }

    return getdata;
}

运行时,我遇到了以下 SQL 异常:

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 '? and password=?' at line 1.

有什么建议可以让这个工作起来吗?欢迎提供任何代码片段。


10
第一个问题 - 您两次设置了参数1,但从未设置参数2。第二个问题 - 您仅为一个查询使用了预准备语句。第三个问题:听起来您可能正在以明文形式存储密码...第四个问题:您没有告诉我们在哪里出现了异常。 - Jon Skeet
2.PK_ID是什么?看起来你忘记加上tbl_了。 - BigMike
3
Jon Skeet 的分析机器刚刚仔细审查了你的问题。可以说,你已经被 Skeet 处理过了。 - christopher
1
@Jon Skeet,我解决了第一个问题。我只需要为第一个查询准备语句,因为我使用的是准备语句,所以出现了异常。谢谢,它起作用了。 - jasim
可能是PreparedStatement does not work with mysql/JDBC的重复问题。 - Mark Rotteveel
2个回答

32

你需要使用:

preparedStatement.executeQuery();

而不是

preparedStatement.executeQuery(login);

当您将字符串传递给executeQuery()时,查询文字逐字执行,因此?被发送到数据库,从而创建错误。通过传递查询字符串,您没有执行传递值的“缓存”准备语句。


4

对于这两个参数,您都可以使用preparedStatement.setString(1, ..);,因此第一个参数设置了两次。但是您从未设置第二个参数的值。

所以请更改为:

preparedStatement.setString(1, mobile);
            preparedStatement.setString(1, password);

to

    preparedStatement.setString(1, mobile);
    preparedStatement.setString(2, password);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接