java - 在 ServletContextListener 与 Filter 中创建和关闭数据库连接

标签 java tomcat servlets jdbc connection-pooling

我正在使用 Java 在 Web 项目中创建数据库连接。然而,有一件事让我感到困惑;

  1. 创建数据库连接和关闭连接的最佳方式是什么?使用 FilterServletContextListener
  2. 一旦我在 servlet 中执行数据库操作,JDBC 连接将如何关闭?我需要手动关闭连接吗?我应该在哪里关闭连接?我确实添加了 contextDestroyed关闭连接的方法,但我认为它只有在 Tomcat 服务器停止时才有效。
  3. 或者,我需要打开和关闭 Filter 中的连接吗? ?

这是我工作的步骤

  1. 创建 DataSource在 Tomcat 服务器的 Context.xml使用 <resource> 文件标签
  2. 引用 web.xml 中的资源通过使用 <resource-ref>标签
  3. contextInitialized 中创建连接的 ServletContextListener
  4. 在servlet的doPost中进行数据库操作或 doGet方法

contextInitialized方法:

    @Override
public void contextInitialized(ServletContextEvent event) {
    System.out.println("START CONNECTION");
    try {
        Context contextEnvironment = (Context) new InitialContext().lookup("java:comp/env/");
        DataSource ds = (DataSource) contextEnvironment.lookup("jdbc/lunaruniversity");
        try {
            Connection con = ds.getConnection();
            ServletContext context = event.getServletContext();
            context.setAttribute("dbConnection", con);
        } catch (SQLException e) {
            e.printStackTrace();
        }

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

servlet 的 doGet方法:

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    Connection con = (Connection) getServletContext().getAttribute("dbConnection");

    String saveStudent = request.getParameter("saveStudent");
    String insertSQL = "INSERT INTO STUDENT (FNAME, LNAME, EMAIL, PHONE, STATE, ZIPCODE) VALUES(?,?,?,?,?,?)";

        String fName = request.getParameter("fName");
        String lName = request.getParameter("lName");
        String email = request.getParameter("email");
        String phone = request.getParameter("phone");
        String state = request.getParameter("state");
        String zipCode = request.getParameter("zipCode");
        try {
            java.sql.PreparedStatement ps = con.prepareStatement(insertSQL);
            ps.setString(1, fName);
            ps.setString(2, lName);
            ps.setString(3, email);
            ps.setString(4, phone);
            ps.setString(5, state);
            ps.setString(6, zipCode);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

contextDestroyed方法:

    @Override
public void contextDestroyed(ServletContextEvent event) {
    System.out.println("CLOSE CONNECTION");
    DataSource ds = (DataSource) event.getServletContext().getAttribute("dbConnection");
    try {
        if (!ds.getConnection().isClosed()) {
            System.out.println("CONNECTION IS CLOSED");
            ds.getConnection().close();
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

最佳答案

1、2、3:以上都不是。

当您需要开始交易时,您会从 DataSource 获得一个连接。您在参与该事务的所有方法调用中传递该连接。然后提交并关闭连接。使用 try-with-resources 确保它始终关闭,即使在出现异常的情况下也是如此:

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    try (Connection connnection = dataSource.getConnection()) {
        // use the connection

        connection.commit();
    }
}

关于java - 在 ServletContextListener 与 Filter 中创建和关闭数据库连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46226903/

相关文章:

java - android-哪个线程在SensorChanged上运行?

java - 不处理就抛出同样的Exception,还是构造一个新的Exception?

java - API反射困惑

java - 使用 Eclipse 调试时从 ServletRequest 获取 HTTP Post 数据

java - 显示日期列中的数据 - 解析到日期

java - 如何为弹性 beanstalk tomcat 提供配置

tomcat - Facelets:页面未呈现

java - 在部署到 tomcat 服务器的 Spring Web 应用程序中,catalina.properties 文件由 spring 自动加载和检测。如何?

java - servlet容器和spring容器有什么区别?

java - 使用 XML 的 Servlet