You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Tomcat中通过Java代码(而非XML)配置JDBC连接池并在Servlet中使用?

用Java代码配置Tomcat JDBC连接池并在Servlet中获取连接

1. 准备依赖

首先确保项目包含Tomcat JDBC连接池及对应数据库驱动的依赖,以Maven为例,在pom.xml中添加:

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-jdbc</artifactId>
    <version>9.0.80</version> <!-- 匹配你的Tomcat版本 -->
</dependency>
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-dbcp</artifactId>
    <version>9.0.80</version>
</dependency>
<!-- MySQL驱动示例,其他数据库替换为对应依赖 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>

2. 修改启动类,配置连接池并绑定JNDI

在原TestStarter代码中添加连接池配置,将数据源绑定到JNDI上下文,让Servlet可以通过JNDI获取连接池:

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
import javax.naming.NamingException;
import java.io.File;

public class TestStarter {

    public static void main(String[] args) throws LifecycleException, NamingException {
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(8080);
        tomcat.getConnector();

        String contextPath = "";
        String docBase = new File(".").getAbsolutePath();

        Context context = tomcat.addContext(contextPath, docBase);

        // 配置JDBC连接池
        BasicDataSource dataSource = new BasicDataSource();
        // MySQL 8+用这个驱动,5.x版本替换为com.mysql.jdbc.Driver
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/your_db?useSSL=false&serverTimezone=UTC");
        dataSource.setUsername("db_username");
        dataSource.setPassword("db_password");
        // 连接池参数按需调整
        dataSource.setInitialSize(5);
        dataSource.setMaxTotal(20);
        dataSource.setMaxIdle(10);
        dataSource.setMinIdle(2);

        // 将数据源绑定到JNDI,自定义名称为jdbc/TestDB
        context.getNamingResources().addResource(
            "jdbc/TestDB",
            "javax.sql.DataSource",
            dataSource
        );

        // 注册Servlet
        String servletName = "HelloServlet";
        tomcat.addServlet(contextPath, servletName, new HelloServlet());
        context.addServletMappingDecoded("/test", servletName);

        tomcat.start();
        tomcat.getServer().await();
    }
}

3. 修改Servlet,从连接池获取连接

在Servlet中通过JNDI查找数据源,进而获取连接执行数据库操作:

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        PrintWriter out = resp.getWriter();

        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        try {
            // 通过JNDI查找数据源,注意前缀java:comp/env/是Web应用JNDI命名空间的固定写法
            InitialContext ctx = new InitialContext();
            DataSource dataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/TestDB");
            
            // 从连接池获取连接
            conn = dataSource.getConnection();
            
            // 数据库操作示例:查询MySQL版本
            stmt = conn.prepareStatement("SELECT version()");
            rs = stmt.executeQuery();
            
            if (rs.next()) {
                out.println("<h1>数据库版本:" + rs.getString(1) + "</h1>");
            }
            out.println("<h1>成功从连接池获取连接!</h1>");

        } catch (NamingException | SQLException e) {
            e.printStackTrace();
            out.println("<h1>获取连接失败:" + e.getMessage() + "</h1>");
        } finally {
            // 关闭资源,连接会自动归还到连接池
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

注意事项

  • 数据库驱动类、URL需根据实际使用的数据库调整(如Oracle、PostgreSQL的参数均不同)。
  • 连接池的初始化参数、最大连接数等需根据应用并发需求调整,避免资源浪费或连接不足。
  • JNDI查找名称必须和启动类中绑定的名称一致,前缀java:comp/env/不可省略。

内容的提问来源于stack exchange,提问作者ipolevoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 02:15:54