简介这是一份面向Java Web初学者的JSP与Access数据库连接教程适用于小型项目开发或课程实践。文档以创建test.mdb数据库并读取username表数据为例详细讲解了从设计数据表包含uid与pwd两个文本字段、将数据库文件部署到Tomcat服务器指定目录到编写JSP页面实现连接查询的完整流程。重点展示了使用JDBC-ODBC桥驱动建立连接、通过应用路径转换获取数据库物理路径、执行SQL语句、遍历结果集以及正确关闭资源的关键代码并给出了异常处理的排错思路。资源为单个doc文档共31KB内容紧凑附带可直接运行的JDBCAccess.jsp示例注释清晰便于读者对照练习。已有238人学习下载适合正在学习JSP数据库编程或需要快速实现Access数据交互的开发者参考。1. JSP连接ACCESS数据库这个“老古董”组合为什么还值得会最近带一个课设小组题目是“JSP个人信息展示页面”后台数据库被指定成Access。他们兴冲冲写了Class.forName(sun.jdbc.odbc.JdbcOdbcDriver)结果页面一开就报错机房老师看了一眼说“JDK8以上已经没有这个驱动了”。这就是JSP连接ACCESS数据库的现状技术很老但课设、毕设、老单位内部小系统里还在用。它解决的问题很直接让Java Web页面读写一个小型文件型数据库完成增删改查。适合刚学JavaWeb的初学者、需要快速交付的课设项目以及维护传统JSP项目打包war的老程序员。核心结论先行别再碰ODBC桥换用UCanAccess这类纯JDBC驱动这条路能少踩八成坑。2. 选对连接方案JDBC-ODBC桥退役后UCanAccess成了最省心的路2.1 三种连接Access的方式与选型对比在JSP里连接ACCESS数据库按我的经验只有三条路JDBC-ODBC桥、UCanAccess、微软官方Access数据库驱动。如果你在网上搜到2005年左右的教程大多是第一种。原理是Java先通过ODBC读取Access文件页面代码里常见的写法是Class.forName(sun.jdbc.odbc.JdbcOdbcDriver); String url jdbc:odbc:test;这段代码在Oracle JDK 8里还能勉强跑到JDK 11就彻底没了。更麻烦的是你在Windows上还要先建一个“ODBC数据源”一旦系统是64位而机器里装了32位驱动就会看到“64位引擎不支持DBC数据”之类的报错。所以ODBC桥这条老路我把它定义为“只适合考古”。UCanAccess则不一样。它是一个纯Java实现的JDBC驱动底层用Jackcess库直接解析.mdb/.accdb文件不依赖Windows ODBC所以你在Windows、Linux、macOS上都能用。对JSP来说只需要把几个jar包丢进项目的WEB-INF/lib然后用标准JDBC接口操作即可。方案原理依赖Windows维护状态适合场景JDBC-ODBC桥通过ODBC访问Access是JDK8后移除考古、老教程UCanAccess纯Java解析Access否活跃JSP课设、小站点、数据迁移微软Access数据库驱动通过ODBC访问Access是维护但受限仅限Windows下专用程序选型结论很清楚UCanAccess。Access本身有一些“玄学”特性比如不支持存储过程、不支持复杂事务但做课设和个人信息展示绰绰有余。如果你已经在用Access数据库64位系统驱动程序也不要紧张它和JDBC桥是两回事后续统一用UCanAccess替换即可。2.2 在IDEA新建JSP项目并引入UCanAccess依赖假设你用的是IDEA。新建项目时选“Java Enterprise”项目模板选“Web Application”服务器勾上Tomcat。如果选的是Maven就在pom.xml里加依赖。我一般固定用UCanAccess 5.0.1这是一个成熟版本网上的报错案例也最多搜起来方便。dependency groupIdnet.sf.ucanaccess/groupId artifactIducanaccess/artifactId version5.0.1/version /dependency逻辑说明Maven会把UCanAccess及其依赖全部下载进来包括jackcess、commons-lang3、hsqldb。如果你们公司不许用Maven需要手动下载jar包并一个个放进WEB-INF/lib。“传统jsp项目打包war”的场景里经常有人只放一个ucanaccess.jar运行时就报ClassNotFoundException: com.healthmarketscience.jackcess.Database这就是缺依赖了。还需要提醒一点Access数据库文件是文件型数据库不像MySQL、Oracle那样有个服务端。你要保证运行环境里有这个文件并且连接串里的路径能读到它。常见陋习是先把Access文件放到桌面或者网盘里再写死绝对路径结果一换机器就翻车。我在本地习惯建一个db目录把数据库文件放进去后面部署时再外置路径。2.3 用UCanAccess写第一个连接代码模板与参数说明依赖进好后先写一个工具类。这几年维护这类老项目我的习惯是第一件事就是把连接逻辑从JSP页面里抽出来否则每个页面都写一遍Class.forName乱得没法看。package com.example.db; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class DBUtil { static { try { // 加载UCanAccess纯Java驱动 Class.forName(net.ucanaccess.jdbc.UcanaccessDriver); } catch (ClassNotFoundException e) { throw new ExceptionInInitializerError(e); } } public static Connection getConnection() throws SQLException { // Windows下也建议用正斜杠避免反斜杠转义问题 String dbPath D:/data/users.accdb; String url jdbc:ucanaccess:// dbPath ;showSchematrue;charSetUTF-8; return DriverManager.getConnection(url, admin, ); } }逻辑说明静态块负责加载驱动。URL格式是jdbc:ucanaccess://后跟文件绝对路径注意路径里的分隔符用/而不是\\JDBC URL里的反斜杠是转义字符写错会连不上。showSchematrue表示把Access内部系统表也暴露出来平时查询可以不加。charSetUTF-8在连接串里指定字符集配合页面UTF-8可以避免中文乱码。Access文件如果没设密码用户填admin、密码留空即可如果设了密码需要额外拼接;pwd密码参数。这里再补一个格式差异Access 2003之前的.mdb是旧格式2007之后的.accdb是新格式UCanAccess两者都支持。如果数据库是老师给的.mdb直接用如果是自己新建建议另存为.accdb新格式的锁文件处理更稳。别混着用“Access数据库64位系统驱动程序”来理解UCanAccessUCanAccess不需要你在系统层面装任何东西。测试连接时可以在main方法里写两行Connection conn DBUtil.getConnection(); System.out.println(conn null ? fail : ok);看到“ok”说明JSP连接ACCESS数据库的通道已经建立。接下来可以进入真正的页面开发。3. 在JSP页面里完成增删改查一个可抄作业的用户信息管理模块3.1 数据库准备建表与插入测试数据先建库。打开Access新建空数据库保存为users.accdb。Access不会像MySQL那样给你命令行你需要用“创建→查询设计→SQL视图”执行SQL。这里有个反直觉的点Access的SQL语句不完全兼容MySQL、Oracle。我们建一张用户表CREATE TABLE users ( id COUNTER PRIMARY KEY, name TEXT(20) NOT NULL, age INTEGER, remark TEXT(100) );逻辑说明COUNTER是Access里的自增字段等价于MySQL的AUTO_INCREMENT。表名用users而不是user因为user在Access里也是保留字容易让SQL语句报错。TEXT在Access里默认有长度限制写20够用。执行后再插入三条测试数据INSERT INTO users (name, age, remark) VALUES (张三, 22, 测试数据); INSERT INTO users (name, age, remark) VALUES (李四, 25, 来自Access); INSERT INTO users (name, age, remark) VALUES (王五, 30, JSP连接);注意如果你打算把Access文件放到项目目录下保存后的users.accdb要复制到web/db/目录下并在连接串里改成对应路径。相对路径方案我会在部署那一章展开现在先继续写代码。3.2 查询列表页连接、遍历ResultSet与关闭资源JSP页面直接用Java代码块连数据库看起来丑但这是课设和传统JSP项目最常见的形态。不要用Statement拼SQL直接用PreparedStatement一是防access注入二是参数绑定更省心。创建一个user_list.jsp% page languagejava contentTypetext/html; charsetUTF-8 pageEncodingUTF-8 % % page importjava.sql.*, com.example.db.DBUtil % html headtitle用户列表/title/head body table border1 trthID/thth姓名/thth年龄/thth备注/th/tr % Connection conn null; PreparedStatement ps null; ResultSet rs null; try { conn DBUtil.getConnection(); ps conn.prepareStatement(SELECT id, name, age, remark FROM users); rs ps.executeQuery(); while (rs.next()) { % tr td% rs.getInt(id) %/td td% rs.getString(name) %/td td% rs.getInt(age) %/td td% rs.getString(remark) %/td /tr % } } finally { if (rs ! null) rs.close(); if (ps ! null) ps.close(); if (conn ! null) conn.close(); } % /table /body /html逻辑说明% page import %把DBUtil引入页面。DBUtil.getConnection()每次请求新建连接这是合理的因为Access是文件型数据库并发不高临时连接比长期占用更安全。finally里的资源关闭是必须的尤其是UCanAccess连接不关闭会导致Access锁文件一直存在后续写操作报错。页面编码三件套别漏contentTypetext/html; charsetUTF-8、pageEncodingUTF-8、数据库连接串里的charSetUTF-8。漏任何一个中文就变成乱码。这是我在课设里翻车最多的点。如果不需要对表结构做反射可以不设置showSchematrueResultSet里就不会出现系统表查询更干净。3.3 新增和删除PreparedStatement的写法与防注入列表页解决后做新增。新增通常从一个表单页提交到自己或专门的Servlet。这里写一个混合JSP的例子重点展示PreparedStatement的写法。创建user_add.jsp% page languagejava contentTypetext/html; charsetUTF-8 pageEncodingUTF-8 % % page importjava.sql.*, com.example.db.DBUtil % % request.setCharacterEncoding(UTF-8); String name request.getParameter(name); String ageStr request.getParameter(age); String remark request.getParameter(remark); if (name ! null !name.trim().isEmpty()) { Connection conn null; PreparedStatement ps null; try { conn DBUtil.getConnection(); String sql INSERT INTO users(name, age, remark) VALUES(?, ?, ?); ps conn.prepareStatement(sql); ps.setString(1, name); ps.setInt(2, Integer.parseInt(ageStr)); ps.setString(3, remark); ps.executeUpdate(); } finally { if (ps ! null) ps.close(); if (conn ! null) conn.close(); } response.sendRedirect(user_list.jsp); } % html headtitle新增用户/title/head body form methodpost 姓名input typetext namenamebr 年龄input typetext nameagebr 备注input typetext nameremarkbr button typesubmit保存/button /form /body /html逻辑说明request.setCharacterEncoding(UTF-8)必须放在任何读取request参数之前否则POST中文必乱。PreparedStatement的三个占位符用?占位然后通过setString和setInt绑定。这样即使参数里有单引号或SQL关键字也不会拼进SQL语句Access注入的老套路就失效了。这个写法同样适用于删除和修改删除就是DELETE FROM users WHERE id ?修改就是UPDATE users SET name ?, age ? WHERE id ?参数绑定方式一致。Integer.parseInt(ageStr)在年龄为空或不是数字时会抛NumberFormatException课设可以先不管生产环境建议加上校验否则页面直接500。我建议至少用try包一层并给用户返回一个可读的提示。3.4 把连接逻辑收进DBUtil工具类页面代码多了之后会发现两个问题一是每个JSP都写Connection conn null这些重复代码二是连接串改个路径得翻遍所有页面。解决办法是扩展DBUtil把关闭连接的方法也放进去。我在正式动手前习惯把这一层做好后面写增删改查会快很多。补上close方法public static void close(Connection conn, Statement stmt, ResultSet rs) { if (rs ! null) { try { rs.close(); } catch (SQLException ignored) {} } if (stmt ! null) { try { stmt.close(); } catch (SQLException ignored) {} } if (conn ! null) { try { conn.close(); } catch (SQLException ignored) {} } }逻辑说明Statement是PreparedStatement的父类所以close方法参数声明成Statement新增、删除、查询都能用。忽略关闭异常是为了避免资源关闭失败盖过业务异常。关闭顺序必须是ResultSet、Statement、Connection虽然现代JDBC驱动大多会自动处理但按标准顺序关最稳。有了DBUtil之后JSP里的finally块可以简化成一行DBUtil.close(conn, ps, rs);。这样至少不会因为漏关连接导致Access文件被锁。到这里一个支持查询、新增、删除的JSPACCESS小模块已经能跑了。下一章集中讲那些让人头皮发麻的坑。4. JSP连接ACCESS的避坑指南从驱动缺失到中文乱码的5个高频问题4.1 64位系统报“未找到Microsoft Access驱动程序”或“无法加载ODBC”现象新手照着老教程写Class.forName(sun.jdbc.odbc.JdbcOdbcDriver)Tomcat直接抛ClassNotFoundException或者用ODBC数据源时提示“指定的DSN包含驱动程序和应用程序之间的体系结构不匹配”。原因JDK 8之后JDBC-ODBC桥被移除而且你大概率是64位系统却装了32位Access驱动于是系统一直提示“64位引擎不支持DBC数据”。机房电脑最常见这个组合。解决放弃ODBC方案换成UCanAccess。驱动类名写成net.ucanaccess.jdbc.UcanaccessDriver连接串写成jdbc:ucanaccess://...一步到位。不要混用“Access数据库64位系统驱动程序”和JDBC桥那只是ODBC引擎的一部分和纯Java的UCanAccess不是一回事。4.2 Access文件被Lock文件占用写操作报错现象第一次插入成功第二次执行executeUpdate()报错大概意思是“Could not lock file”或者“Unable to open database”。原因UCanAccess以文件方式打开Access如果上次连接没有正常关闭会在数据库目录下生成一个users.laccdb锁文件或者你调试时用Access程序手动打开了同一个文件。解决先关掉Access程序删除users.laccdb然后检查代码里finally是否关闭了Connection。我自己的经验是数据库文件放到网络共享目录会频繁锁放在本地磁盘最稳定。如果你只是做只读展示可以把连接参数改成只读模式但课设一般用不上只要每次用DBUtil.close及时释放锁就够了。4.3 数据库路径是中文或带空格导致连接失败现象本地开发一切正常把项目拷到用户名是中文的机器上启动后报Database file not found。原因UCanAccess对URL编码的处理在某些JDK版本上遇到中文路径容易出问题Windows路径里的反斜杠也被当成转义吃掉。解决数据库文件放到纯英文、无空格的路径比如D:/data/users.accdb。如果非要放中文目录在Java代码里用URLEncoder.encode处理路径或者通过new File(...).toURI().toASCIIString()拼URL。我一般不会为了一台机器给自己加戏直接改路径最简单。这个坑也解释了为什么生产部署时一定要把路径外置而不是写死在页面里。4.4 UCanAccess与JDK版本不匹配报UnsupportedClassVersionError现象Tomcat启动正常一旦访问JSP页面就抛UnsupportedClassVersionError: net/ucanaccess/jdbc/UcanaccessDriver has been compiled by a newer version...。原因UCanAccess的编译版本高于当前JDK运行版本。比如JDK 8环境用了为JDK 11编译的UCanAccess包。解决先确认Tomcat用的JDK版本再选匹配的UCanAccess版本。JDK 8环境装UCanAccess 5.0.1JDK 11以上用更新的版本反之亦然。注意IDEA里虽然设置了某个JDK但Tomcat运行时用的可能是另一个去Tomcat的bin目录执行java -version确认。这个报错是JDK自带的安全机制不要试图绕过换jar包最靠谱。4.5 JSP页面中文乱码页面编码与数据库编码步调一致现象页面上的中文变成???或者从数据库读出的中文全是乱码。原因三种编码不一致——JSP文件本身的保存编码、HTTP响应的字符集、数据库连接串里的字符集。Access内部按Unicode存储但连接时没有指定字符集UCanAccess可能会按系统默认编码读。解决JSP头写成% page contentTypetext/html; charsetUTF-8 pageEncodingUTF-8 %表单接收前执行request.setCharacterEncoding(UTF-8)连接串里的charSetUTF-8不能省。这三个地方对齐后中文就是透明的。如果你的项目里有Tomcat配置了请求编码过滤器那就不用每个页面都写但老项目很少配还是手动设置比较稳。5. 从课设到部署把JSPACCESS项目打包WAR并发布到Tomcat5.1 数据库路径外置用配置文件与相对路径定位Access文件很多人在IDEA里把Access文件放在web/db/下面然后用相对路径拿不到因为JSP的工作目录不一定在项目根目录。部署后更麻烦路径一变就找不到文件。常见的做法是把Access路径外置到一个配置里。我给你一个我经常用的方案用环境变量。代码放在DBUtil里public static String getDbPath() { String dbPath System.getenv(ACCESS_DB_PATH); if (dbPath null || dbPath.trim().isEmpty()) { throw new RuntimeException(请设置环境变量 ACCESS_DB_PATH); } return dbPath; }逻辑说明System.getenv读取的是JVM所在进程的环境变量。在IDEA里运行给Tomcat的运行配置加一个ACCESS_DB_PATH环境变量在服务器上写进Tomcat的bin/setenv.sh或者Windows的系统环境变量。这样代码和数据库文件地址彻底解耦换机器不用改代码。如果你不喜欢环境变量也可以用配置文件把jdbc.properties放在WEB-INF/classes下用ClassLoader.getResourceAsStream(jdbc.properties)读取。注意部署后war包里的WEB-INF/classes可能是只读的后期改配置不方便所以环境变量方案更省事。5.2 用IDEA打包WAR并部署到Tomcat传统JSP项目打包warIDEA里的操作路径是File→Project Structure→Artifacts→ 点→Web Application: Archive→ 命名后确认。然后Build→Build Artifacts→ 选择war。这个动作会生成一个*.war文件通常在项目的out/artifacts目录下。War其实是标准ZIP格式你可以用压缩工具打开看看里面应该有WEB-INF/lib、WEB-INF/classes和JSP页面。部署步骤一句话把war文件复制到Tomcat的webapps目录启动Tomcat它会自动解压并部署。注意Tomcat版本要和JDK匹配Tomcat 9配JDK 8或11。如果是用Maven可以在pom.xml里配置maven-war-plugin但课设直接用IDEA打包更快。部署后访问地址是http://localhost:8080/项目名/user_list.jsp。如果Tomcat的webapps下已经有了同名目录先删除旧目录再放新war避免Tomcat解压时把旧文件混进来。5.3 部署后路径与权限排查部署后最常见的报错是“Database file not found”或者“Unable to open database file”。首先检查ACCESS_DB_PATH是否真的指向数据库文件路径里不要带前后空格。其次检查权限Windows下要给数据库文件所在目录加“Users”可读写权限Linux下用chmod 666 users.accdb和chmod 777 /var/data。为什么要给目录权限因为Access文件型数据库写操作不仅写数据文件还会在同目录创建锁文件目录不可写锁文件创建失败事务就挂了。另一个容易忽略的点如果Access文件被放进war包里也就是WEB-INF内部运行时可能读不到或写入失败。Tomcat解压war后放在临时目录重启后路径可能变而且应用内部资源不应该承受外部写入。所以生产环境务必把Access文件放到应用外部比如/data或者D:/data。这一步是很多人把课设改成“可部署项目”时踩得最狠的坑。我一般会在DBUtil里加一个启动自检让日志打印真实路径System.out.println([DBUtil] dbPath dbPath);看到日志里的路径和你预期一致再继续往下查。6. 连接性能与数据迁移Access做后台时的三个务实技巧6.1 不要照搬MySQL连接池UCanAccess是文件型数据库连接池并不总是帮手。我踩过坑把Tomcat DBCP连接池配给UCanAccess平时查询没问题一旦多个连接同时写Access产生文件级锁页面卡死。课设和小型系统并发很低每次请求新建连接再关闭完全够用。如果确实想复用连接可以用单例Connection但写操作时要做好同步或者干脆保持“请求-关闭”的模式。6.2 迁移到MySQL的快捷路径Access不适合做正式生产数据库数据量大了会明显拖慢。如果想迁移用Java逐行读Access然后写入MySQL代码逻辑很简单从Access查出ResultSet再往MySQL的PreparedStatement里绑定。也可以用Access自带的“外部数据→ODBC数据库”导出功能但需要先在目标库建好表。迁移前记得备份.accdb文件复制一份到安全目录即可完成备份。6.3 用main方法自检连通性最后推荐一个务实技巧在项目里保留一个main方法专门测试连接状态。部署后先执行它能确认驱动、路径、编码、权限都正常再打开页面。代码很短public class CheckAccess { public static void main(String[] args) throws Exception { Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(SELECT COUNT(*) AS total FROM users); ResultSet rs ps.executeQuery(); if (rs.next()) { System.out.println(ok, users count rs.getInt(total)); } rs.close(); ps.close(); conn.close(); } }逻辑说明直接运行这个类如果打印出ok, users count3说明连接没问题如果报错根据异常类型就能定位是路径、驱动还是权限问题。比打开浏览器看200错误页高效得多。我接手老项目的第一天就是先干这件事。这个方法也适合做完课设验收前自检省得答辩时当着老师的面翻车。希望帮到你。本文还有配套的精品资源点击获取