如何在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
相关产品推荐
相关产品推荐

