是否可以在相同的try-with-resources块中使用两个预准备语句

时间:2016-05-25 06:34:32

标签: java mysql database prepared-statement

这种方法很有效,只是因为它让我觉得我没有正确地做到这一点。我有2个表相关的地方

一个科目有许多学年。 (主题可以有很多或可以属于不同的学年)

一个学年有很多科目

主题

code PK
creator
dateCreated
description
name
units
yearLevel

SchoolYearSubjects

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;
    }

我有点犹豫要坚持在一种方法中准备两份准备好的陈述。

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

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

感谢。

1 个答案:

答案 0 :(得分:-1)

一个区块中的两个预备语句没有任何问题。

保证执行多个是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中访问它。 (无论如何,你通常会这样做,因为连接是一个“昂贵”的物体,通常寿命更长。)