JSP本身不能直接加载服务器上的数据文件,它必须通过JDBC驱动建立与数据库的连接,或者通过JNDI数据源让Tomcat等容器统一管理连接。下面把两条标准路径的全过程拆开讲,包括配置步骤、代码写法、以及不同数据库的坑,照着做就能跑通。
先理清:JSP连接数据库的两种主流方式
JSP页面本质是一个Servlet,它运行在Web容器里,和数据库打交道时绕不开两个选择:一是直接在代码中用JDBC连接,二是通过容器的数据源(JNDI)间接获取连接,两者没有绝对优劣,取决于项目规模。
直接JDBC连接适合小项目、测试环境或学习阶段,代码简单直观,但每一次请求都新建连接,高并发下数据库很快撑不住。JNDI数据源由Tomcat统一管理连接池,应用启动时初始化连接,请求时从池中借出,用完归还,性能和稳定性更好,是生产环境的标配。
业内专家指出,企业级JavaWeb项目里,超过九成采用数据源方式,而直接JDBC多出现在快速原型或低并发场景,如果你的项目部署在Tomcat、Jetty等容器中,建议一步到位使用数据源。
jsp连接mysql数据库:JDBC方式完整实操
我们以最常用的MySQL为例,从零开始走通一条完整链路,前提是你的服务器上已经装好MySQL并建好数据库,比如库名叫shop,用户名root,密码123456。
第一步:下载并放置JDBC驱动包
JSP代码要识别MySQL的协议,必须依赖驱动包,无论你用的是Tomcat7还是Tomcat9,都需要将mysql-connector-java.jar复制到项目的WEB-INF/lib目录下。
- MySQL5.x对应驱动类com.mysql.jdbc.Driver,连接URL以jdbc:mysql://开头。
- MySQL8.x及以上驱动类改为com.mysql.cj.jdbc.Driver,URL还需要带上时区参数serverTimezone=Asia/Shanghai,否则会报时区错误。
如果你的服务器上跑的是MySQL8.0,多数情况下,只需要把驱动包二进制的bin目录也一并配置到classpath中,再确认没有第二份旧驱动冲突即可。
第二步:在JSP页面中编写连接代码
在JSP文件的Java片段中,按以下顺序写:
<%@ page import="java.sql." %>
<%
String driver = "com.mysql.cj.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/shop?serverTimezone=Asia/Shanghai&useSSL=false";
String user = "root";
String password = "123456";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select from users where age > 20");
while(rs.next()){
out.println(rs.getString("name"));
}
rs.close();
stmt.close();
conn.close();
%>
这段代码的逻辑需要你完全理解,因为它涉及资源释放顺序,先开连接,再开语句,最后开结果集,关闭时完全反序:先关结果集,再关语句,最后关连接,很多新手把连接关早了,或者忘关了,最终导致数据库连接数耗尽。
避免重复加载驱动:一次注册,处处使用
上面的代码每次访问JSP都会执行Class.forName(driver),这其实是不必要的开销,驱动类在JVM中只会被加载一次,当第二次执行Class.forName时,JVM不会再重复注册。
行业共识认为,更好的做法是把驱动注册放到一个专门的Servlet中,让它随应用启动时执行一次,你可以在web.xml中配置一个load-on-startup的Servlet,把Class.forName放在它的init方法里,这样既能提前发现驱动缺失的问题,又不影响每次请求的性能。
如果是MySQL8以上,跳过高版本驱动转移的细节,还有一个更简单的点驱动类名本身已经说明了你的驱动版本适配情况,旧项目从MySQL5迁移到8,多数情况下只需要换jar包并改驱动类名,连接代码结构不变。
jsp数据库连接池配置:JNDI数据源方案
直接JDBC方式最大的问题在于连接生命周期,每次数据库会话都要经历网络握手、认证、资源分配,高并发时数据库会拒绝新的连接请求,数据源解决方案应运而生。
在Tomcat中配置context.xml
打开Tomcat安装目录下的conf/context.xml,或者项目META-INF/context.xml,添加如下资源定义:
<Context>
<Resource
name="jdbc/shopDB"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/shop?serverTimezone=Asia/Shanghai&useSSL=false"
username="root"
password="123456"
maxTotal="20"
maxIdle="10"
maxWaitMillis="10000"/>
</Context>
参数含义需要你记住:maxTotal是池中最大连接数,maxIdle是空闲连接上限,maxWaitMillis是获取连接的超时毫秒数,这几个值直接决定了你的应用在峰值时是平滑还是报错。
在JSP中通过名称查找数据源
配置完成后,JSP页面里的代码简洁得多:
<%@ page import="java.sql., javax.naming., javax.sql." %> <%Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/shopDB"); Connection conn = ds.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("select from products"); while(rs.next()){ out.println(rs.getProductName()); } rs.close(); stmt.close(); conn.close(); %>
注意代码最后一行:conn.close()在这里不是真的要关闭连接,而是把连接归还给连接池,这是数据源方式最大的心法,也是很多新手混淆的地方,拿到连接、用完归还,连接由池中的线程反复使用,而不是频繁创建销毁。
连接池参数怎么定
没有统一的黄金值,但有一个基本判断标准:maxTotal×单连接可用资源应该小于数据库服务器的总资源,如果服务器只有2GB内存,maxTotal设成200,每次查询都产生临时表,内存瞬间就会被打满,据统计,中小型业务系统maxTotal在20到50之间比较常见,大型系统会搭配读写分离或分库分表。
连接池的正确性需要你用压力测试工具验证,而不是靠猜,压测时观察数据库的Threads_connected指标,如果连接数长期超过maxIdle,说明池的容量偏小,反过来,如果连接数一直很低,maxIdle设得过大反而是浪费。
jsp连接sql server以及不同数据库的差异点
如果你部署的不是MySQL,代码结构依然一样,但有三处要改:驱动类名、URL前缀、方言SQL,比如jsp连接sql server时,需要下载mssql-jdbc.jar,驱动类是com.microsoft.sqlserver.jdbc.SQLServerDriver,URL格式为jdbc:sqlserver://localhost:1433;DatabaseName=shop,Oracle则是oracle.jdbc.OracleDriver和jdbc:oracle:thin:@localhost:1521:shop。
连接逻辑完全一样,但分页SQL写法差异明显,MySQL用limit关键字,SQL Server用OFFSET…FETCH,Oracle用ROWNUM,如果你在JSP中拼接SQL做分页,切换数据库时就必须重写查询语句,这是很多项目在数据库迁移时最头痛的部分。
更好的做法是把SQL语句抽离到数据访问层,JSP页面只负责展示,你用JDBC也好,用JNDI也好,都应该将数据库操作封装在JavaBean或DAO类中,JSP页面尽量少出现JDBC代码,这样做不仅便于维护,还能让你换数据库时只改DAO接口实现,页面完全不动。
常见故障排查:连不上的原因顺序
不管使用哪种方式,连接失败时按照以下顺序排查,多数情况下能快速定位:
- 确认数据库服务进程是否在运行,端口是否被防火墙拦截。
- 确认为驱动jar包在WEB-INF/lib下,而不是只放在Tomcat的lib目录中。
- 检查URL中的主机名、端口、库名是否和实际环境匹配。
- 检查用户名和密码是否有权限访问目标库。
- 查看Tomcat日志,驱动类找不到时会有ClassNotFoundException,连接超时时会有Connection refused。
五步覆盖了90%以上的连接异常,如果你用的是简米云或酷番云的数据库,还要额外检查安全组入站规则是否放开了对应端口,本地测试通过但云上连不上,多数情况下是安全组没有放行。
连接串密码与敏感信息的安全处理
JSP页面里直接写明文密码是极其危险的,一旦源代码泄露或被其他开发者看到,数据库就等于裸奔,更安全的做法是把数据源配置放在容器层,由运维管理,开发人员只拿到JNDI名称。
如果一定要在代码中配置,至少加密密码字段,你可以在Tomcat的context.xml中使用SecureRandom和加密算法处理密码,然后通过自定义的DataSourceFactory解密,或者简单一些,将配置文件放在WEB-INF目录之外,并通过环境变量注入。
切勿在JSP页面中打印连接串或密码到前端,曾经有不少站点因为调试代码忘了删,把数据库地址和账号直接暴露在网页源码里,后果相当严重。
Q&A:jsp加载服务器数据库的常见疑问
问:JSP页面连接数据库不成功,常见原因有哪些?
驱动包缺失、连接URL格式错误、数据库账号权限不足是三大主因,驱动包没放到WEB-INF/lib下会导致ClassNotFoundException,URL中的主机名不能解析会导致UnknownHostException,账号没有远程访问权限会报Access denied,先确认这三项,再往下排查网络和防火墙。
问:使用数据源比直接JDBC连接优秀在哪?
核心差异是连接复用,直接JDBC每次请求创建新连接,成本高,压力大;数据源由容器维护连接池,请求从池中获取连接,用完归还,性能上数据源在并发场景下有数量级的领先,管理上也更规范,学习阶段可以用直接JDBC理解原理,生产环境建议优先考虑数据源方案,除非项目过于简单且并发极低。
回到原点,JSP加载服务器数据库连接的核心无非三点:驱动类正确加载、连接信息准确无误、资源释放绝不遗漏,无论你用JDBC还是数据源,只要遵循这个框架,再遇到连接问题时,你就有完整的排查路径可走,而不是每次靠猜。
jsp怎么加载服务器上的数据库连接这个问题,从驱动下载到连接池配置,全流程的关键操作都在上面,你照着每一步执行,配合不同数据库的差异修改对应参数,就能在服务器上稳定跑通数据查询功能。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/757911.html





