ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

JSP连接ACCESS数据库实战:JDBC-ODBC桥配置与避坑指南

JSP连接ACCESS数据库实战:JDBC-ODBC桥配置与避坑指南

简介:这份文档面向JSP Web开发初学者与小型项目实践者,聚焦JSP与ACCESS数据库之间的基础数据交互,帮助读者理解JDBC-ODBC桥接方式下连接数据库、执行查询并输出结果的完整流程。资源包内共1个doc文件,约31KB,以图文与代码结合的形式呈现,核心示例围绕test.mdb数据库、username表及uid、pwd两个文本字段展开,并给出JDBCAccess.jsp的完整代码与逐段说明,涵盖驱动加载、连接字符串拼接、Statement与ResultSet的使用以及资源关闭等关键环节。已有241人学习,适合作为课堂实验或自学练手材料。读者可从中获得可直接参照的代码模板、数据库与Tomcat目录的放置约定,以及异常捕获与错误信息输出的排错思路,为后续迁移到MySQL等关系型数据库打下JDBC基础。

1. 老项目里翻出 JSP 连 ACCESS:这套 JDBC-ODBC 桥到底还能不能跑

整理旧机器时翻出一个教学用的 Web 目录,里面躺着一个JDBCAccess.jsp和一份test.mdb,页面打开就报“数据库连接错误”。这类 JSP 连接 ACCESS 数据库的写法,是很多年前小型项目、课程实践里最常见的组合:JSP 负责页面输出,ACCESS 当轻量存储,中间靠 JDBC-ODBC 桥把两者接起来。它解决的是“没有独立数据库服务、又要让网页读到表数据”的问题,适合还在维护老系统、或者想搞明白 JDBC 底层链路的人。但它的边界也很硬:驱动依赖操作系统里的 ODBC 数据源,JDK 版本一升就可能直接失效。这篇就按我实际复现的顺序,把建库、放文件、写页面、排错、验证一条线拆开,能抄的地方给代码,翻车的地方给现象。

2. 建库与部署:test.mdb 放哪、字段怎么定才不返工

2.1 先定表结构,再谈连接串

ACCESS 这一侧的准备工作看着简单,实际最容易在后面返工。按原始做法,建一个test.mdb,里面建username表,两个字段uid、pwd,都设成文本型。这里有个血泪经验:字段类型别图省事用“备注”或“数字”,JSP 里rs.getString("uid")取文本型最稳,一旦字段是数字型,取出来可能带格式差异,页面显示就对不上。表名和字段名建议全小写、不加空格,因为后面 SQL 是拼字符串进去的,带空格或中文的表名在 ODBC 层容易解析出岔子。

建表时把uid设为主键,插入两三条测试数据,比如admin / 123456、test / abc。这一步不是为了好看,是为了后面页面能立刻看出“连上了但没读到数据”和“压根没连上”的区别。数据库文件名保持test.mdb,如果你改成别的名字,记住代码里spath那一行必须同步改,这是新手第一个翻车点。

2.2 文件落位与物理路径的换算逻辑

原始做法是把test.mdb放到 Tomcat 的webapps/ROOT/data目录下。这个位置不是随便定的,因为代码里用的是application.getRealPath("data/test.mdb"),它把 Web 应用内的相对路径换算成服务器上的绝对物理路径。也就是说,文件必须落在当前 Web 应用的根目录下的data文件夹里,getRealPath才找得到。

部署时按这个顺序走:

  1. 确认 Tomcat 的webapps/ROOT目录存在,在里面新建data文件夹。
  2. 把test.mdb复制进data,注意不要复制成test.mdb.mdb(Windows 隐藏扩展名时的高频事故)。
  3. 把JDBCAccess.jsp放到webapps/ROOT下,和data同级。
  4. 启动 Tomcat,浏览器访问http://localhost:8080/JDBCAccess.jsp。

这里要提醒一句:getRealPath返回的路径里如果带空格(比如Program Files),拼进 ODBC 连接串时可能出问题。常见做法是部署时把 Tomcat 装在无空格路径下,或者确认连接串对空格做了处理。我一般会先在 JSP 里把dbpath打印出来看一眼,确认路径真实存在再往下走,这比盲猜省时间。

2.3 连接串拆开看:每一段在干什么

原始代码里的连接串是jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=加物理路径。拆开理解:jdbc:odbc:表示走 JDBC-ODBC 桥;Driver={...}指定操作系统里注册的 ACCESS ODBC 驱动名;DBQ=后面跟数据库文件的绝对路径。用户名和密码对无密码的 ACCESS 库留空即可。

String spath = "data/test.mdb"; // Web 应用内相对路径 String dbpath = application.getRealPath(spath); // 换算成服务器物理路径 String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=" + dbpath; Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // 加载桥驱动 Connection conn = DriverManager.getConnection(url); // 无用户名密码

参数说明:spath必须和实际存放的相对路径一致;dbpath由容器计算,不要手写死绝对路径,否则换机器就废;驱动名要和本机 ODBC 里注册的名称完全一致,差一个字符都连不上。这段代码的价值在于把“路径”和“驱动”两个变量分离,排错时可以分别验证。

3. JSP 页面实现:从加载驱动到结果集遍历的完整链路

3.1 页面头部与编码设置

原始 JSP 用的是gb2312,页面指令和 meta 都声明了。这一步在老环境里不能省,因为 ACCESS 里的中文数据经 ODBC 取出后,如果页面编码和数据库存储编码不一致,中文会变乱码。现在新环境更常见的是UTF-8,但要注意:改页面编码的同时,ACCESS 里已有数据的编码不会自动变,贸然改可能让原本正常的中文变乱。稳妥做法是保持和原始数据一致的编码,先跑通再谈迁移。

<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*"%> <meta http-equiv="Content-Type" content="text/html; charset=gb2312">

import="java.sql.*"是必须的,否则Connection、Statement、ResultSet全部找不到。language="java"在老容器里是默认值,写上无妨。

3.2 连接、查询、遍历、关闭的完整代码

把原始代码整理成可读版本,逻辑顺序是:加载驱动 → 建连接 → 建语句对象 → 执行查询 → 遍历输出 → 逐层关闭。语句对象用了TYPE_SCROLL_SENSITIVE和CONCUR_UPDATABLE,意思是结果集可滚动、可更新。对只读展示来说这两个参数不是必需,但保留它们不影响功能,只是多占一点资源。

<% try { String spath = "data/test.mdb"; String dbpath = application.getRealPath(spath); String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=" + dbpath; Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection conn = DriverManager.getConnection(url); Statement stmt = conn.createStatement( ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); String sql = "select * from username"; ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { out.print("用户名:" + rs.getString("uid")); out.print(" 密码:" + rs.getString("pwd") + "<br>"); } out.print("<br>恭喜你!数据库连接成功!"); rs.close(); // 先关结果集 stmt.close(); // 再关语句 conn.close(); // 最后关连接 } catch (Exception e) { out.print("数据库连接错误!,错误信息如下:<br>"); out.print(e.getMessage()); } %>

关闭顺序不能乱:结果集 → 语句 → 连接,反过来关连接会让前面的对象失效。catch里直接打印e.getMessage()是排错的关键,别把它吞掉,很多“连不上”的真相就藏在这行消息里。查询用select *在演示里没问题,真实项目里建议写明字段,避免表结构变动导致取列错位。

3.3 用表格把结果输出得更像回事

原始代码用<br>拼接输出,能看但不直观。稍微改一下,用表格展示,顺便把字段名当表头,读数据时一眼能对上。

<table border="1"> <tr><th>uid</th><th>pwd</th></tr> <% while (rs.next()) { %> <tr> <td><%= rs.getString("uid") %></td> <td><%= rs.getString("pwd") %></td> </tr> <% } %> </table>

这种写法把 Java 代码和 HTML 混排,可读性比out.print好,但要注意<%和%>的配对,少一个就整页编译失败。参数上rs.getString对文本型字段最安全,如果字段可能为 NULL,取出来是null字符串,页面会显示“null”,需要的话加个判空。

4. 避坑与排查:驱动、路径、编码三类高频翻车

4.1 现象:报“找不到驱动”或ClassNotFoundException

原因:sun.jdbc.odbc.JdbcOdbcDriver这个桥驱动在较新的 JDK 里已经被移除,JDK 8 之后基本不再自带。老教程能跑,是因为当年用的是 JDK 6/7。解决:确认当前 JDK 版本,如果必须用这套写法,就换回带桥驱动的 JDK;如果环境不允许降级,就得改用 UCanAccess 这类纯 Java 的 ACCESS 驱动,连接串和驱动类名都要换,不能照抄本文代码。

4.2 现象:报[Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序

原因:连接串里的驱动名和操作系统 ODBC 里注册的名称不一致,或者系统根本没装 ACCESS 的 ODBC 驱动(64 位系统上尤其常见,32 位驱动和 64 位进程不匹配)。解决:到系统的 ODBC 管理器里核对驱动名称,确认 Tomcat 运行的位数和驱动位数一致;连接串里的{Microsoft Access Driver (*.mdb)}必须和注册名逐字一致。

4.3 现象:页面提示连接成功,但一条数据都没有

原因:getRealPath算出的路径指向的文件不存在,或者文件存在但表名、字段名对不上。ODBC 对“库能打开但表不存在”有时不报错,直接返回空结果集。解决:在 JSP 里临时打印dbpath,去服务器上确认该路径下确有test.mdb;再确认表名是username、字段是uid和pwd,大小写虽不敏感,但拼写不能错。

4.4 现象:中文显示成乱码

原因:页面编码、ACCESS 存储编码、ODBC 取数编码三者不一致。解决:先保持页面gb2312不动,确认数据在 ACCESS 里本身正常;如果必须改UTF-8,要同步处理取数后的转码,不能只改页面头。这一步没有万能参数,只能对着实际数据试。

4.5 现象:第一次能连,刷新几次后报连接耗尽

原因:异常路径下rs、stmt、conn没有关闭,连接泄漏。解决:把关闭动作放进finally块,保证无论查询是否成功都执行关闭;演示代码里为了简短放在 try 末尾,真实使用要补finally。

5. 进阶验证:换一种驱动思路,把老写法跑成可维护的样子

老代码能跑通只是第一步,真正要落地得考虑它还能撑多久。我的习惯是:先用原始 JDBC-ODBC 写法确认数据和页面没问题,再评估是否换成纯 Java 驱动。UCanAccess 是常见替代方案,它不依赖操作系统的 ODBC 数据源,连接串形如jdbc:ucanaccess://加物理路径,驱动类名也不同。换的时候注意两点:一是原 SQL 基本不用改,但结果集的一些可滚动特性支持程度不同,TYPE_SCROLL_SENSITIVE可能要降级;二是 ACCESS 文件被占用时,纯 Java 驱动和 ODBC 驱动的锁行为不一样,部署时要确认没有别的进程占着.mdb。

验证是否真的连对库,我一般做三步:第一步,在页面打印dbpath,人工确认文件存在;第二步,把 SQL 换成select count(*) from username,看数字是否和 ACCESS 里一致;第三步,故意改错表名,确认页面能报出可读的错误而不是白屏。这三步走完,连接链路基本就透明了。

验证项操作期望结果
路径页面输出dbpath指向真实存在的 test.mdb
数据量执行 count 查询与 ACCESS 内记录数一致
错误可读故意写错表名页面显示具体错误信息

还有一个容易被忽略的点:application.getRealPath在打包成 war 部署时,返回的是解压后的临时目录,数据库文件如果放在 war 内部,重启可能被覆盖。稳妥做法是把.mdb放在 Web 应用外部,用配置项传绝对路径,而不是依赖getRealPath。这一点在演示里看不出来,一上生产就暴露。

从那以后我每次碰这类老 JSP 连 ACCESS 的活,都强制先打印物理路径、再跑 count 查询、最后才看页面展示,三步不过不往下写。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表