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

标签 java mysql servlets prepared-statement forms http-post

我试图让一个 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 获取输入,然后使用每个表的单独 servlet 将信息插入到 SQL 表中。但是我似乎无法像使用上述语句那样将它同时添加到两个表中?我已经尝试过批处理并考虑过进行交易,但我只需要知道如何使 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 一遍又一遍地编写数据库连接)。从安全的角度来看,也不建议这样做。除其他原因外...

您可以采取以下措施使事情变得更轻松。创建另一个你将只用于你的数据库连接的类,每当你想对你的数据库做一些事情时,你可以调用这个类(我将在下面告诉你如何做):

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)。 ... 这是一种将软件分为三个相互关联的部分的方法,同样,原因之一是使其更易于管理。在您的设置中,您可以将 View 视为您的 jsps/html 页面, Controller 是您的 Servlet,您的模型是您用来连接两者的工具。

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

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

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

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

关于java - 如何通过连接到 JSP 的 servlet 插入带有 auto_increment 外键的 MySQL 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50437135/

相关文章:

java - 检查默认响应时避免代码重复

java - Hibernate 加入两个不相关的表,当两个表都有复合主键时

php - MySQL 存储过程中的数学公式返回不正确的值

tomcat - 如何制作 Tomcat 6 服务器 JSON 内容

Java clone() 和 equals() 检查

java - IntelliJ 格式化许可证头

php - 如何执行具有多个 WHERE 子句的 MySQL 查询?

php - Web 应用程序中的数据库前缀是什么?

java - Spring jsp页面未评估

java - 从 jscript 获取字符串值到 servlet