恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
JSP连接Access数据库全攻略:从JDBC-ODBC桥到UCanAccess驱动
首页
资讯中心
/
JSP连接Access数据库全攻略:从JDBC-ODBC桥到UCanAccess驱动
JSP连接Access数据库全攻略:从JDBC-ODBC桥到UCanAccess驱动
发布时间:2026/10/16 23:29:03
简介这是一份JSP连接ACCESS数据库的入门教程资源面向初学Web开发的读者重点演示如何通过JDBC-ODBC桥驱动实现JSP与Access数据库的连接及数据读取适用于小型项目、毕业设计或课程实训场景。资源共1个文件为doc格式文档压缩包大小约31KB内含完整示例代码、配置步骤与运行说明。当前已有240人学习。文档以创建test.mdb数据库、放置到Tomcat指定目录、编写JDBCAccess.jsp三个步骤为主线详细展开连接字符串、驱动加载、Statement创建、ResultSet结果集遍历以及资源释放等关键环节并给出可直接套用的JSP页面代码。通过这份文档读者可以快速搭建一个可运行的JSPAccess数据访问示例理解JDBC访问数据库的基本流程同时也能积累有关数据库路径映射、异常处理、字符集设置的实际经验为后续切换到MySQL、Oracle等主流数据库打下扎实基础。1. JSP连接ACCESS小项目里反复被翻出来的老手艺最近又在网上看到有人问“JSP怎么连ACCESS数据库”。这个组合放在今天确实有点过时但在课程设计、内部工具、个人博客这类数据量不大的场景里Access文件型数据库比MySQL省事得多——不用装服务不用管账号权限拷一个.mdb就能跑。可真正动手时光一个JDBC-ODBC桥驱动就能劝退不少人再加上中文乱码、路径不对、文件锁死这类问题折腾一下午不算稀奇。这篇笔记就把整套流程拆开讲清楚从建库放文件到写连接代码再到最常见的翻车点最后给出一条迁移到纯Java驱动的升级路线。新手照步骤做能跑通熟手也能复用这里面的排查思路。2. 建库与布署数据库文件放错位置是第一个翻车点2.1 建数据库和表字段类型先定清Access的数据库是一个文件整个库的所有表、查询、窗体都装在一个.mdb或.accdb文件里。按教程要求新建一个test.mdb在里面建立一个名为username的表表里有两个字段uid和pwd两者都选文本型。用Access的图形界面做很简单打开test.mdb然后选择“使用设计器创建表”在字段名列输入uid和pwd数据类型选“短文本”旧版本叫“文本”。字段长度默认是255实际用50就够密码一般也不会超过50个字符。如果你习惯用SQL语句可以在Access的查询视图里执行这一句CREATE TABLE username ( uid TEXT(50), pwd TEXT(50) );注意Access的SQL方言和MySQL不完全一样这里直接用TEXT指定短文本类型但有些版本对TEXT的默认长度有争议。更稳妥的方法还是走图形界面选“短文本”类型长度自己填50。表结构建好以后随意插入两三行测试数据比如INSERT INTO username (uid, pwd) VALUES (admin, 123456); INSERT INTO username (uid, pwd) VALUES (guest, guest123);这样后面查询时才有数据可展示。2.2 数据库文件放哪Tomcat目录下的隐含规则示例代码里有一行String spath data/test.mdb;然后通过application.getRealPath(spath)把相对路径转成物理路径。这个方法拿到的基准路径是当前Web应用的根目录也就是Tomcat下webapps\ROOT这个目录。所以数据库文件必须放在webapps\ROOT\data\下和WEB-INF目录平级。有人喜欢把数据库放到D盘某个自定义路径然后在代码里直接写jdbc:odbc:Driver{Microsoft Access Driver (*.mdb)};DBQD:/test.mdb。这种写法在当前机器上能跑但换一台电脑、换一个Tomcat目录就得改代码很不方便。更合理的做法是放到Web应用内部靠getRealPath动态解析。如果你把文件放在webapps\ROOT\data\test.mdb那么getRealPath返回的物理路径类似C:\Tomcat\webapps\ROOT\data\test.mdb。注意Windows下的路径反斜杠在连接字符串里需要处理吗实际上JDBC-ODBC桥能接受反斜杠路径但为了稳妥最好先转成正斜杠比如dbpath dbpath.replace(\\, /)。2.3 getRealPath的坑它在某些环境下返回nullapplication.getRealPath()是ServletContext的经典方法但在现在的Tomcat里如果你把项目打包成war包并且没有解压目录这个方法可能返回null。还有在下一次部署时如果应用以“exploded”方式运行路径也有可能和预期不一致。所以拿到dbpath后不要直接拼进URL先做一个存在性检查String dbpath application.getRealPath(spath); if (dbpath null) { throw new RuntimeException(getRealPath返回null无法定位数据库文件); } java.io.File dbFile new java.io.File(dbpath); if (!dbFile.exists()) { throw new RuntimeException(数据库文件不存在: dbpath); }这步检查看似多余但能省掉后面一大半的排查时间。常见错误是“data”目录建错位置——不是建在工程的根目录下而是建在了WEB-INF里面或者干脆忘记建目录。用这个检查就能立刻看到实际报错信息。2.4 文件权限与锁Windows下的隐形杀手Access数据库是文件型数据库Tomcat运行时使用的系统账户必须有对这个文件及其所在目录的读写权限。如果你把Tomcat注册成Windows服务默认运行账户是LocalSystem或某个服务账户对桌面目录、D盘根目录可能没有写权限。一旦连接成功但写入失败报错信息往往很难看懂。还有更常见的你刚用Access程序打开test.mdb看过数据没有关闭Tomcat里连接时就会报“文件正在使用”或“数据库独占锁定”。写代码之前确认Access桌面程序已经彻底退出。这些细节不算技术难点但十次连接失败里至少有三次是这种环境问题。3. 连接代码逐段拆解从Class.forName到ResultSet关闭3.1 驱动加载与连接URL为什么是JdbcOdbcDriver先看一份完整可运行的JSP代码按示例的结构整理如下% page contentTypetext/html; charsetgb2312 languagejava importjava.sql.* % % try { // 数据库相对路径 String spath data/test.mdb; // 转成物理路径 String dbpath application.getRealPath(spath); // 连接字符串直接通过ODBC驱动访问Access文件 String url jdbc:odbc:Driver{Microsoft Access Driver (*.mdb)};DBQ dbpath; // 加载JDBC-ODBC桥驱动 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()); } %这段代码的核心是Class.forName(sun.jdbc.odbc.JdbcOdbcDriver)。JDBC-ODBC桥是早期JDK自带的桥接驱动它的作用是把JDBC调用翻译成ODBC调用再由ODBC去访问Access。连接URL不是常见的jdbc:mysql://...而是jdbc:odbc:Driver{Microsoft Access Driver (*.mdb)};DBQ物理路径。花括号里是ODBC驱动名称必须是系统里已安装的驱动。需要说明的是这里的Driver{Microsoft Access Driver (*.mdb)}并不是在ODBC数据源管理器里配置一个DSN而是直接指定驱动名后面用DBQ参数告诉驱动数据库文件在哪里。这种写法省去了手动配置DSN的步骤方便部署。如果你的Access数据库设置了密码连接字符串还要加上;PWDxxxx。示例里用户名和密码都为空所以没有拼接。3.2 查询与遍历ResultSet的基本用法stmt.executeQuery(select * from username)返回一个ResultSet结果集。ResultSet内部像一个游标初始位置在第一行之前rs.next()把游标移到下一行如果还有数据就返回true否则返回false。所以while(rs.next())会逐行遍历结果。rs.getString(uid)表示取出当前行里字段名为uid的值返回类型是Java字符串。如果你的表字段名是混合大小写比如UidgetString是大小写不敏感的写成uid也能解析。访问完后注意关闭顺序先关ResultSet再关Statement最后关Connection。如果顺序颠倒驱动可能无法正常释放资源Access文件会被一直锁到连接超时。3.3 资源关闭的改进用try-with-resources替代手工关闭手工关闭的问题在于如果中间抛出异常后面的关闭代码不会执行。常见的改进是在finally里关闭但代码会显得啰嗦。Java 7之后可以用try-with-resourcesJSP里同样适用try (Connection conn DriverManager.getConnection(url); Statement stmt conn.createStatement(); ResultSet rs stmt.executeQuery(select * from username)) { while (rs.next()) { out.print(用户名: rs.getString(uid)); out.print( 密码: rs.getString(pwd) br); } } catch (Exception e) { out.print(连接出错 e.getMessage()); }这里把Connection、Statement、ResultSet都放在try的括号里无论正常结束还是抛异常它们都会自动关闭。这种写法在旧项目里不常见但完全兼容建议新写的代码直接采用。3.4 为什么用Statement而不是PreparedStatement示例里用的是Statement直接拼接SQL字符串。如果SQL语句是固定的不带任何外部参数用Statement就够了。但一旦查询条件来自用户提交比如String sql select * from username where uid request.getParameter(uid) 就存在SQL注入风险。这种情况下应该用PreparedStatementString sql select * from username where uid ?; PreparedStatement pstmt conn.prepareStatement(sql); pstmt.setString(1, request.getParameter(uid)); ResultSet rs pstmt.executeQuery();PreparedStatement的好处是先把SQL模板交给数据库预编译参数再通过setString绑定特殊字符不会被当作SQL语法执行。对于Access这种文件数据库注入同样危险不要因为项目小就忽略。4. 连接Access常见问题与排查五个实战踩坑记录4.1 故障一ClassNotFoundException: sun.jdbc.odbc.JdbcOdbcDriver现象JSP页面报错控制台或浏览器显示java.lang.ClassNotFoundException: sun.jdbc.odbc.JdbcOdbcDriver。原因JDK 8开始移除了JDBC-ODBC桥驱动这个类在标准运行时里已经不存在。如果电脑装的是JDK 8及以上版本或者Tomcat使用的高版本JREClass.forName自然加载不到。解决换用纯Java驱动UCanAccess下一章会详细说明。临时方案是降级到JDK 7但不建议在生产环境用一个过时的JDK。验证方式可以写一个最简单的Java类测试Class.forName(...)是否能通过如果抛同样的异常基本确认是JDK版本问题。4.2 故障二数据库路径不对文件找不到现象页面报错信息里能看到java.io.FileNotFoundException: data\test.mdb (系统找不到指定的路径)或者连接URL里DBQ部分是null。原因数据库文件没有放在webapps\ROOT\data下或者getRealPath返回了null或者路径是反斜杠导致驱动解析异常。解决在代码里打印dbpath并在连接前检查文件是否存在。我一般会在Class.forName之前加一段调试输出System.out.println(DB path: dbpath); System.out.println(File exists: new java.io.File(dbpath).exists());如果文件确实不存在就检查data目录是否真的建在Web应用根目录下。很多开发工具把工程根目录和实际部署目录混在一起在IDE里运行Tomcat时文件放在src同级目录部署后却不在webapps下需要手动把data目录拷贝到部署目录里。4.3 故障三数据库文件被独占锁定现象页面报错类似Cannot open database或者The database has been opened by another user。原因Access的.mdb文件被桌面版Access程序打开或者另一个连接没有正常关闭数据库文件被独占锁住。还有一种情况是Tomcat服务账户没有对文件的写权限。解决关闭所有Access窗口在任务管理器里检查是否有MSACCESS.EXE进程结束掉。然后确认Tomcat所在目录的文件权限给Tomcat服务账户至少读写权限。如果是在开发环境直接用控制台启动Tomcat通常不会遇到权限问题但注册成服务后就要格外注意。4.4 故障四中文乱码现象页面上显示的用户名变成了???或者写入数据库的中文变成乱码。原因JSP页面声明了charsetgb2312但容器在读取请求参数或输出时用的编码不一致也可能Access表字段本身存储的编码与页面不一致。解决统一页面编码在JSP头部同时声明contentType和pageEncoding% page contentTypetext/html; charsetgb2312 pageEncodinggb2312 %如果数据库里已经存入乱码文本就需要读取后重新转码比如rs.getString(uid).getBytes(ISO-8859-1), gb2312但这属于补救手段。最省心的做法是库和页面都按GBK或UTF-8统一。Access对UTF-8支持较差建议页面和数据库都用GBK体系减少转换中的坑。4.5 故障五64位系统下ODBC驱动不一致现象在64位Windows上运行报错提示[Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序。原因Tomcat以32位模式运行但系统里装的是64位ODBC驱动或者反过来。JDBC-ODBC桥访问的是系统ODBC管理器32位和64位是隔离的驱动不匹配就会报这个错。解决先确认Tomcat的位数下载与Tomcat相同位数的Microsoft Access Driver或者在ODBC数据源管理器区分32位和64位中选择合适的驱动。这个问题的根源是ODBC的架构限制与其折腾位数匹配不如直接换UCanAccess纯Java驱动从根上绕开ODBC。5. 升级到纯Java驱动UCanAccess替换JDBC-ODBC桥5.1 为什么UCanAccess是当前的最佳选择JDBC-ODBC桥从JDK 8开始被移除再用老驱动等于在新环境里强行踩一脚坑。UCanAccess是一个开源的纯Java驱动直接读取Access数据库文件不需要任何ODBC配置跨平台支持.mdb和.accdb格式。它内部依赖HSQLDB模拟SQL引擎对常见SQL语句的支持比ODBC桥更好也支持事务和预处理语句。UCanAccess由几个jar包组成核心是ucanaccess另外需要jackcess、hsqldb、commons-lang3、commons-logging等依赖。如果你用Maven管理项目引入依赖会自动拉齐。如果是手动部署要把这些jar包全部放到WEB-INF/lib目录下。没有Maven的情况下可以直接从UCanAccess的发布页下载压缩包里面包含了所有依赖。5.2 改造连接代码三步切换驱动第一步把jar包放到WEB-INF/lib下。第二步修改驱动类和URL。第三步调整连接参数。下面是一份改造后的JSP代码% page contentTypetext/html; charsetgb2312 languagejava importjava.sql.* % % try { String spath data/test.mdb; String dbpath application.getRealPath(spath); if (dbpath null || !new java.io.File(dbpath).exists()) { throw new RuntimeException(数据库文件不存在: dbpath); } // UCanAccess 驱动类 Class.forName(net.ucanaccess.jdbc.UcanaccessDriver); // UCanAccess 连接URL注意前缀是 jdbc:ucanaccess:// String url jdbc:ucanaccess:// dbpath; // 如果数据库设置了密码追加 user 和 password 参数 // String url jdbc:ucanaccess:// dbpath ;userxxx;passwordyyy; Connection conn DriverManager.getConnection(url); Statement stmt conn.createStatement(); ResultSet rs stmt.executeQuery(select * from username); 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(连接错误 e.getMessage()); } %对比一下驱动类从sun.jdbc.odbc.JdbcOdbcDriver变成了net.ucanaccess.jdbc.UcanaccessDriverURL前缀从jdbc:odbc:变成了jdbc:ucanaccess://后面直接跟数据库文件的绝对路径。不再有Driver{...}这种ODBC写法文件路径就是URL的一部分。5.3 新旧驱动参数对比对比项JDBC-ODBC桥UCanAccess驱动类sun.jdbc.odbc.JdbcOdbcDrivernet.ucanaccess.jdbc.UcanaccessDriverURL前缀jdbc:odbc:Driver{...};DBQ路径jdbc:ucanaccess://路径是否依赖ODBC依赖系统ODBC驱动不依赖纯Java实现JDK 8支持不兼容类已移除兼容跨平台能力Windows上受限跨平台数据源配置可在URL中临时指定驱动无需数据源对Access版本支持主要.mdb.mdb和.accdb并发性能一般文件锁明显一般但比桥接稳定从表里能看出来UCanAccess不是性能增强而是兼容性和可维护性的增强。它让你脱离ODBC这个黑匣子所有逻辑都在Java层可控。5.4 性能与并发注意事项UCanAccess适合单用户或低并发场景底层用HSQLDB缓存数据库内容写入时可能把整个数据库重写一遍。如果多个用户同时写入会出现锁冲突或数据不一致。真到了需要多人并发读写的业务Access这种文件格局限太大尽早迁移到MySQL或H2更稳妥。在技术选型时要清楚自己的边界。6. 调试技巧把连接过程变成可观测的日志6.1 在页面输出关键调试信息连接失败时最怕只有一句“数据库连接错误”完全不知道错在哪一步。建议在开发阶段把关键变量直接输出到页面上out.print(spath: spath br); out.print(dbpath: dbpath br); out.print(file exists: new java.io.File(dbpath).exists() br);这段输出能立刻告诉你路径是否正确、文件是否存在。如果是null或false问题就在布署环节而不是代码逻辑。确认无误后再注释掉这些输出或者放在一个开关后面。6.2 打印完整异常堆栈示例代码里只打印e.getMessage()很多关键信息被吞了。比如ClassNotFound的完整堆栈能看出到底缺哪个类。可以改成catch (Exception e) { out.print(连接错误); e.printStackTrace(new java.io.PrintWriter(out)); }或者直接把堆栈打到服务器控制台} catch (Exception e) { e.printStackTrace(); }这样Tomcat的logs目录里会留下完整堆栈。我在排查UCanAccess依赖缺失时就是靠堆栈第一行定位到缺少commons-logging比猜快得多。6.3 用try-with-resources再稳一层前面已经写过改进代码这里再强调一次连接代码必须保证Connection关闭否则再次访问时Access文件会被锁住。尤其是在并发或反复刷新页面时一个未关闭的连接就可能让整个应用瘫痪。我在实际项目里吃过亏——页面刷新三次后数据库直接锁死重启Tomcat才恢复。从那以后我每次写数据库相关代码都强制用try-with-resources或者至少在finally里关连接。这个习惯救了我很多次。6.4 写一个独立的Java测试类验证驱动JSP页面的调试环境太复杂我一般会先写一个最简Java控制台程序放到IDE里直接跑验证驱动、路径、SQL这三件事import java.sql.*; public class AccessTest { public static void main(String[] args) throws Exception { Class.forName(net.ucanaccess.jdbc.UcanaccessDriver); String url jdbc:ucanaccess://C:/webapps/ROOT/data/test.mdb; try (Connection conn DriverManager.getConnection(url); Statement stmt conn.createStatement(); ResultSet rs stmt.executeQuery(select uid, pwd from username)) { while (rs.next()) { System.out.println(rs.getString(uid) rs.getString(pwd)); } } } }注意这个测试类里的绝对路径必须和实际部署路径一致。如果这个程序能跑通而JSP里报错问题就在ServletContext路径解析或编码上如果这个程序本身报错那就先解决驱动依赖或文件路径再回到JSP。通过这种分层排查能把环境问题、代码问题、部署问题快速隔离。希望这篇笔记能帮你少走一点弯路也希望你下次再看到JSP连Access时心里清楚哪些坑是旧时代留下的哪些是值得花时间避开的。本文还有配套的精品资源点击获取