【问题标题】:Is it okay to use two prepared statements within same try-with-resources block可以在同一个 try-with-resources 块中使用两个准备好的语句吗
【发布时间】:2016-05-25 06:34:32
【问题描述】:

这个方法很有效,只是它让我觉得我做得不对。我有 2 个与 where 相关的表

一个学科有许多学年。 (一个学科可以有多个学年,也可以属于不同的学年)

一个学年有许多科目

主题

code PK
creator
dateCreated
description
name
units
yearLevel

学年科目

id PK
code FK
dateAdded
schoolyear

方法如下。

public Boolean add(){
        Boolean success ;
        String SQLa = "INSERT INTO subject(name,code,units,description,yearlevel,creator) "
                + "VALUES (?,?,?,?,?,?)";
        String SQLb = "INSERT INTO schoolyearsubjects(code,schoolyear,addedBy) values(?,?,?)";
        try(Connection con = DBUtil.getConnection(DBType.MYSQL);
                PreparedStatement ps1 = con.prepareStatement(SQLa);
                PreparedStatement ps2= con.prepareStatement(SQLb);){
          //a.)Prepare ps1
            ps1.setString(1,subjectName );
            ps1.setString(2,subjectCode );
            ps1.setInt(3, subjectUnits);
            ps1.setString(4, subjectDescription);
            ps1.setString(5, subjectYearLevel);
            ps1.setString(6, Login.getUsername());

          //b.)Prepare ps2
            ps2.setString(1,subjectCode);
            ps2.setString(2, schoolYearStart+"-"+schoolYearEnd);
            ps2.setString(3, Login.getUsername());

          //c.) execute both statements
            ps1.executeUpdate();
            ps2.executeUpdate();

            success = true;

        } catch (SQLException e) {
            success = false;
            JOptionPane.showMessageDialog(null,e.getClass()+" "+e.getMessage());
        }
        return success;
    }

我有点犹豫是否坚持在一个方法中包含 2 个准备好的语句。

考虑到code 列是Foreign Key 并且两者都必须在同一个函数中执行,我如何确保成功执行两个语句? 另外,要补充一点,add() 方法只绑定到一个按钮。

如果我做错了什么,请给我建议并纠正我。

谢谢。

【问题讨论】:

  • 如果没有其他原因,您应该考虑将 INSERT 语句分开,因为它允许在您的调用代码中单独处理故障。目前,您必须使用错误代码来区分一个故障和另一个故障,因为单个布尔值无法传达这一点。
  • 执行两个preparedStatement没有错,但是请不要忘记关闭创建的PreparedStatementConnection对象。否则会导致 sqlError。

标签: java mysql database prepared-statement


【解决方案1】:

两个prepared statements在一个块中没有错。

多次保证执行是您在 SQL 中所说的“事务”,而在 Java 中,您可以通过以下方式执行(从您的 try 块开始):

     con.setAutoCommit(false);  // switch to transactional mode
     ...
     ps1.executeUpdate();
     ps2.executeUpdate();

     con.commit();              // commit the transaction
 }
 catch(...) {
     con.rollback();            // undo everything that happened
 }

请注意,您必须将连接对象移动到 try-with-resources 的外部,以便您可以在 catch-block 中访问它。 (无论如何你通常都会这样做,因为连接是一个“昂贵”的对象,通常具有更长的寿命。)

【讨论】:

    猜你喜欢
    • 2014-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    相关资源
    最近更新 更多