Java JSP:多个查询和生成的键的问题

Java JSP:多个查询和生成的键的问题,java,mysql,jsp,tomcat,netbeans,Java,Mysql,Jsp,Tomcat,Netbeans,我有一个java方法: public boolean insertAuthor(String userid, String password){ try{ String query1 = "INSERT INTO user (id, firstName, lastName, belonging, country) VALUES(?,?,?,?,?)"; PreparedStatement stmt = this.dbConn.prepareStatemen

我有一个java方法:

public boolean insertAuthor(String userid, String password){
    try{
        String query1 = "INSERT INTO user (id, firstName, lastName, belonging, country) VALUES(?,?,?,?,?)";
        PreparedStatement stmt = this.dbConn.prepareStatement(query1);
        stmt.setInt(1,0);
        stmt.setString(2,"default"); //Yes, it's correct with "default"
        stmt.setString(3,"default");
        stmt.setString(4,"default");
        stmt.setString(5,"default");
        //stmt.executeUpdate();
        stmt.executeUpdate(query1, PreparedStatement.RETURN_GENERATED_KEYS);
        ResultSet rs = stmt.getGeneratedKeys();
        int key=0;
        if ( rs.next() ) {
            key = rs.getInt(1);
        }
        String query2 = "INSERT INTO authentication (id, address, password, user_id, login_id) VALUES(?,?,?,?,?)";
        stmt = this.dbConn.prepareStatement(query2);
        stmt.setInt(1,0);
        stmt.setString(2,"default");
        stmt.setString(2,password);
        stmt.setInt(2,key);
        stmt.setString(2,userid);
        stmt.executeUpdate();
        return true;
    }catch(Exception e){
        System.err.println(e.getMessage());
    }
    return false;
}
让我解释一下:我想执行两个查询,第二个查询需要在第一个查询中生成的密钥(我需要表“user”的主键,因为用户身份验证是1:1关系)

因此:

  • 这是执行多个查询的正确方法吗
  • 我的钥匙还缺什么吗?因为如果我只运行executeUpdate(),并且对下面的每一行都进行注释,那么该方法工作得很好,但是当我运行示例中的代码时(第一个executeUpdate()被注释),我得到false(只有false,没有异常)。我必须检查数据库中的某些内容吗
  • 提前谢谢

    编辑:
    我找到了解决办法。这是列中的错误,而不是获取生成的键本身的方法中的错误。我会选择约普·艾根的答案来回答他给我的改进。谢谢

    我建议您在
    用户
    表中有一个
    用户名
    字段,这样插入后,您只需从用户名所在的用户中选择一个
    id…
    就可以了,需要做一些改进

    String query1 = "INSERT INTO user (firstName, lastName, belonging, country)"
            + " VALUES(?,?,?,?)";
    String query2 = "INSERT INTO authentication (address, password, user_id, login_id)"
            + " VALUES(?,?,?,?)";
    try (PreparedStatement stmt1 = this.dbConn.prepareStatement(query1,
                    PreparedStatement.RETURN_GENERATED_KEYS);
            stmt2 = this.dbConn.prepareStatement(query2)) {
        stmt1.setString(1, "default");
        stmt1.setString(2, "default");
        stmt1.setString(3, "default");
        stmt1.setString(4, "default");
        stmt1.executeUpdate();
        try (ResultSet rs = stmt1.getGeneratedKeys())  {
            if (rs.next()) {
                int userid = rs.getInt(1);
                stmt2.setString(1, "default");
                stmt2.setString(2, password);
                stmt2.setInt(3, key);
                stmt2.setString(4, userid);
                stmt2.executeUpdate();
                return true;
            }
        }
    } catch (SQLException e) {
        System.err.println(e.getMessage());
    }
    return false;
    
  • 尝试自动关闭资源,也可以在异常和返回时关闭资源
  • 您有两个准备好的声明要结束
  • SQL的executeUpdate用于parents类语句,不尊重参数设置。您为generated keys参数选择了该参数,但它进入Connection.prepareStatement
  • (SQL)不应列出/插入生成的密钥
  • 在这里是否应该捕获SQLException是有争议的<代码>抛出SQLException对我来说是有效的

  • 我不明白你真正的问题是什么。我想说的是,如果从逻辑的角度来看这两个插入是密切相关的,那么您可能希望在事务中同时运行这两个插入。这样,如果其中一个失败,您就可以回滚整个事务,而不会在数据库中出现奇怪的结果。@TimBiegeleisen问题是我无法获取生成的密钥。如果我使用
    PreparedStatement执行查询。返回生成的\u键
    代码将以false而不是true退出,但查询是正确的。但是,如果不是更有效的话,为什么不能获得生成的键呢?因为
    username
    是唯一的,并且它被传递到方法中,所以它永远不会出错。如果您同时有大量请求,那么获取生成的密钥“可能”是有问题的。在我看来,使用主键或用户名似乎是一样的,实际上获取生成的密钥甚至可能比对用户名进行正式查询更快。感谢改进,这样看起来更干净。无论如何,问题出在列中,而不是方法本身。