如何通过连接到 JSP 的 servlet 插入带有 auto_increment 外键的 MySQL 表

How to insert into MySQL tables with auto_increment foreign key via servlet connected to JSP

我正在尝试让 servlet 做与此 SQL 语句相同的事情:

INSERT INTO event(title, description, start, end, guest_no) VALUES('someTitle', 'someDescription', '2018-02-02 20:00:00', '2018-02-02 21:00:00', 6);

INSERT INTO shift(event_id, start, end, positions) VALUES(LAST_INSERT_ID(), '2018-02-02 20:00:00', '2018-02-02 21:00:00', 2);

我现在的表单从 html 获取输入,然后使用每个 table 的单独 servlet 将信息插入 SQL table。但是我似乎无法像使用上述语句那样同时将它添加到两个 table 中?我已经尝试过批处理并考虑过进行交易,但我只需要知道如何使 LAST_INSERT_ID() 在 java post 方法中工作。

<section>
      <form name="create" action="${pageContext.request.contextPath}/createEventShift" method="post">
     
        <hr>
        <label for="title"><b>Event Name</b></label>
        <input type="text" placeholder="Enter title of the event" name="title" required>
        <hr>
        <label for="description"><b>Description</b></label>
        <input type="text" placeholder="Describe your event" name="description" required>

        <label for="guest_no"><b>Number of Guests</b></label>
        <input type="number" placeholder="Write how many guests" name="guest_no" required>

        <label for="start"><b>Start Date & Time (yyyy-MM-dd HH:mm:ss)</b></label>
        <input type="datetime-local" placeholder="Start" name="start" step="2">

        <label for="end"><b>End Date & Time (yyyy-MM-dd HH:mm:ss)</b></label>
        <input type="datetime-local" placeholder="End" name="end" step="2">
      
    <div class="expansive-button v2">
      <div><i></i></div>
    </div>

      <h3>Add Shift</h3>
      
      <label for="event_id"><b>Event ID</b></label>
      <input type="" name="event_id" value="LAST_INSERT_ID()">
            
          <label for="startshift"><b>Shift Start (yyyy-MM-dd HH:mm:ss)</b></label>
   <input type="datetime-local" placeholder="Start date and time of shift" name="startshift" step="2">
          
   <label for="endshift"><b>Shift End (yyyy-MM-dd HH:mm:ss)</b></label>
   <input type="datetime-local" placeholder="End date and time of shift" name="endshift" step="2">
          
   <label for="positions"><b>Number of Staff Needed</b></label>
   <input type="number" placeholder="How many staff do you need for this shift" name="positions">
    </div>
    
    <br/><br />
    
    <button>Submit</button>
     </form>

Servlet 看起来像这样:

@WebServlet("/createEventShift")

public class createEventShift extends HttpServlet {
private static final String URL = "jdbc:mysql://localhost:3306/e_manager";
private static final String USER = "root";
private static final String PASSWORD = "2timeLearning!";

private static Connection conn = null;

static {
    try {
        Class.forName("com.mysql.jdbc.Driver");
        conn = DriverManager.getConnection(URL, USER, PASSWORD);
    } catch (ClassNotFoundException | SQLException e) {
    }

}

public static Connection getConnection() {
    return conn;
}

@Override
protected void doPost(HttpServletRequest request, 
        HttpServletResponse response) throws ServletException, IOException {

    String insertSQL = "INSERT INTO event(title, description, start, end, "
            + "guest_no) VALUES(?, ?, ?, ?, ?)";
    String insertSQL2 = "INSERT INTO shift(event_id, start, end, positions)"
            + " VALUES(LAST_INSERT_ID(), ?, ?, ?)";

    String title = request.getParameter("title");
    String description = request.getParameter("description");
    String start = request.getParameter("start");
    String end = request.getParameter("end");
    String guest_no = request.getParameter("guest_no");       
    String ss = request.getParameter("startshift");
    String es = request.getParameter("endshift");
    String pos = request.getParameter("positions");

    try {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(createEventShift.class.getName()).log
    (Level.SEVERE, null, ex);
        }

        Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
        PreparedStatement ce = conn.prepareStatement(insertSQL); 
        PreparedStatement cs = conn.prepareStatement(insertSQL2);

        ce.setString(1, title);
        ce.setString(2, description);
        ce.setString(3, start); 
        ce.setString(4, end);
        ce.setInt(5, Integer.parseInt(guest_no));
        ce.executeUpdate(insertSQL);
        ce.close();

        cs.setString(2, ss);
        cs.setString(3, es);
        cs.setInt(4, Integer.parseInt(pos));
        cs.executeUpdate(insertSQL2);
        cs.close();

         response.sendRedirect("/viewEvents.jsp");     

        conn.close();

    } catch (SQLException ex) {

    }
}}

谁能告诉我如何完成这项工作? (是的,我是新手)

通常我们将数据库逻辑与 servlet 分开。因为如果您有很多 servlet,您的代码将更难维护(您必须为每个 servlet 一遍又一遍地编写数据库连接)。从安全的角度来看,也不建议这样做。除其他原因外...

您可以采取以下措施使事情变得更轻松。创建另一个仅用于数据库连接的 class,每当您想对数据库执行某些操作时,您都可以调用此 class(我将在下面向您展示如何操作):

public class DBConnection {
    private static String url = null;
    private static Connection conn = null;
     public static Connection getConnection(){
     try{

       Class.forName("com.mysql.jdbc.Driver");
       url = "jdbc:mysql://localhost:3306/e_manager";

     conn = DriverManager.getConnection(url,"root","2timeLearning!");
     }   catch (Exception e) {
            System.out.println(e);
        } 
     return conn;
     }
}

还有一个有用的东西叫做 Model-View-Controller (MVC)...这是一种将软件分成三个相互关联的部分的方法,同样,原因之一是使其更易于管理。在您的设置中,您可以将视图视为 jsps/html 页面,控制器是您的 Servlet,您的模型是您用来在两者之间进行交互的工具。

让我们创建一个模型来处理您的事件和轮班(但实际上像这样的事情应该分开)

那么让我们创建另一个 class,在这里我将其命名为 EventsAndShifts。在这个 class 中,我们将处理各种数据库操作。通常我们会为 EventsAndShifts 数据库连接创建另一个 class(称为 Data Access Object Pattern,简称 DAO),但在本例中我们将在同一个 class 中创建它。

public class EventsAndShifts{    

  //i noticed you wanted to insert the event id for a shift, you can't do it the way you wanted to, you have to do it like this (this method will return an int)
public int setEventInfo(String title, String description, String start, String end, String guestNo){
     int eventID = 0; //initialize
    //get connection from our DBConneciton class we created earlier
    try(Connection conn= DBConnection.getConnection()){
//returning the generated keys lets us get the row id of what we insert
   PreparedStatement pst = conn.prepareStatement("INSERT INTO event(title, description, start, end, guest_no) VALUES(?, ?, ?, ?, ?);", Statement.RETURN_GENERATED_KEYS); 

         pst.setString(1, title);
         pst.setString(2, description);
         pst.setString(3, start); 
         pst.setString(4, end);
         pst.setInt(5, Integer.parseInt(guestNo));

         pst.executeUpdate();   
       //now get the eventID
    ResultSet rs = pst.getGeneratedKeys();
    while (rs.next()) {
    eventID = rs.getInt(1); //get the id of the inserted event
      }

        } catch (SQLException e) {
            e.printStackTrace();
        }
     //we don't need to close our db connection because the try statement does it for us   
return eventID; //return the eventID
}   




public void setShiftInfo(int eventID, String ss, String es, String pos){
    //get connection from our DBConneciton class we created earlier
    try(Connection conn= DBConnection.getConnection()){
   PreparedStatement pst = conn.prepareStatement("INSERT INTO shift(event_id, start, end, positions)VALUES(?, ?, ?, ?);"); 

         pst.setInt(1, eventID);    
         pst.setString(2, ss);
         pst.setString(3, es);
         pst.setInt(4, Integer.parseInt(pos));

         pst.executeUpdate();   

        } catch (SQLException e) {
            e.printStackTrace();
        }
}  



}

现在我们已经完成了所有这些设置,让我们来创造奇迹吧:

@Override
protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {

    //get our parameters
    String title = request.getParameter("title");
    String description = request.getParameter("description");
    String start = request.getParameter("start");
    String end = request.getParameter("end");
    String guest_no = request.getParameter("guest_no");       
    String ss = request.getParameter("startshift");
    String es = request.getParameter("endshift");
    String pos = request.getParameter("positions");

    EventsAndShifts eas = new EventsAndShifts(); //instantiate our EventsAndShifts class

    //insert into event table and return eventID
    int eventID = eas.setEventInfo(title,description,start,end,guest_no);

    //use eventID and insert into event table shift table
    eas.setShiftInfo(eventID,ss,es,pos);

    //all done
  response.sendRedirect("/viewEvents.jsp");     
}

希望这可以帮助您更多地了解如何将它们组合在一起,如果有什么不对或您有任何疑问,请告诉我。