首页 / 资讯中心 / 文章详情

JSP+Access网上购物系统开发实战:从JDBC连接到订单事务

JSP+Access网上购物系统开发实战:从JDBC连接到订单事务 ★ FEATURED ARTICLE
简介基于JSP与Access的网上购物系统设计与实现资源面向需要完成课程设计、毕业设计或BS架构项目练手的计算机相关专业学生。资源围绕前端页面、后端业务逻辑与Access数据库交互展开提供完整可运行的项目源码以及配套的设计文档可帮助读者快速理解网上商城从用户注册、商品浏览、购物车到订单处理的典型流程并可直接用于项目参考或二次开发。压缩包采用zip格式总体积约1.9MB内容以JSP页面、Java类文件、配置文件及项目文档为主便于按模块对照学习。该资源已有290人学习下载适合具备一定Java Web基础、希望获取完整项目范例的开发者。通过源码注释与文档说明读者能掌握系统架构、数据库表设计及关键功能实现思路节省从零搭建的时间。1. 为什么 2025 年还有人用 JSPAccess 做购物系统这题到底值不值得做你打开那个「基于JSPaccess的网上购物系统设计与实现源码文档.zip」的时候大概率不是因为它时髦而是因为课程设计、毕业设计或者一个老系统的维护单子落在了你头上。这个技术栈里 JSP 是十年前的服务器页面方案Access 是微软早就不怎么推的桌面数据库两个老家伙凑在一起却能稳稳撑起一个带用户登录、商品展示、购物车、订单管理的完整购物流程。它最大的价值不是性能而是结构简单、源码可读、文档好写特别适合拿来理解 Web 应用的数据流转和会话管理。如果你正在做 Java Web 课设或者要快速接手一个小型内网商城这一套仍然是最容易跑通、最容易答辩的方案。2. 把购物系统拆成四个模块从登录到结算的 JSP 页面流转一个 JSPAccess 的网上购物系统不管压缩包里文件名怎么起核心逃不开四块用户模块、商品模块、购物车模块、订单模块。页面流转一般是 index.jsp 做入口登录后跳到商品列表点击商品进详情加购物车后去结算最后生成订单写入 Access 库。后台管理通常是独立的 admin 文件夹包含商品增删改和订单状态更新。2.1 用户与商品模块JSP 页面里如何绑定 Access 数据库用户模块要做的事就是注册、登录、个人信息展示。注册页把表单提交给一个 register.jsp它通过 JDBC 连接 Access 数据库的 user 表先查重再插入。这里有两条路一是用 JDBC-ODBC 桥接配置系统 DSN二是用 UCanAccess 纯 Java 驱动。我一般建议课设项目用 JDBC-ODBC因为答辩时老师常问你用的什么连接方式JDBC-ODBC 是教材标配。下面是最小可用的连接代码// dbconn.jsp —— 公共数据库连接片段所有页面通过 include 引入 % page importjava.sql.* % %! Connection conn; Statement stmt; ResultSet rs; public Connection getConn() throws Exception { String dsn jdbc:odbc:shopDB; // shopDB 是配置好的 Access DSN 名称 Class.forName(sun.jdbc.odbc.JdbcOdbcDriver); conn DriverManager.getConnection(dsn, , ); return conn; } %这段代码里的Class.forName加载驱动JDK 8 里sun.jdbc.odbc.JdbcOdbcDriver还能用但 JDK 11 以后就移除了这也是很多人拿到源码后一运行就报ClassNotFoundException的原因。后面的getConnection的三个参数分别是连接串、用户名、密码Access 默认没有用户名密码所以留空。如果你用的是 UCanAccess连接串要换成jdbc:ucanaccess://C:/shop.accdb驱动也换成net.ucanaccess.jdbc.UcanaccessDriver。两种方案的区别在于 DSN 依赖 Windows 系统配置换机器要重新设置UCanAccess 直接把 .mdb 文件路径写死在代码里跨平台更省事。用户登录校验是从 access 的 user 表里查用户名和密码-- login_check.jsp 中执行的查询 SELECT user_id, username, password, email FROM users WHERE username ? AND password ?用?占位符是为了防止 Access 注入很多课设源码图省事直接用SELECT * FROM users WHERE username name 字符串拼接这是最典型的漏洞。安全写法是用 PreparedStatement下面这段完整展示了登录校验jsp:useBean iduser classbeans.UserBean scopesession/ % request.setCharacterEncoding(GBK); // 处理中文提交Access 默认中文编码坑 String username request.getParameter(username); String password request.getParameter(password); String sql SELECT user_id, email FROM users WHERE username? AND password?; Connection conn getConn(); PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, username); ps.setString(2, password); ResultSet rs ps.executeQuery(); if (rs.next()) { session.setAttribute(loginUser, username); session.setAttribute(userId, rs.getInt(user_id)); response.sendRedirect(index.jsp); } else { out.println(scriptalert(用户名或密码错误);history.back();/script); } %这里有个容易忽略的参数request.setCharacterEncoding(GBK)或UTF-8必须放在取参数之前否则中文用户名会乱码。Access 数据库默认的文本编码经常和 JSP 页面编码不一致最稳的做法是页头统一% page contentTypetext/html; charsetGBK %因为很多老 Access 文件是 GBK 保存的你强行用 UTF-8 反而会看到问号。商品模块通常就是 goods 表字段包括商品编号、名称、价格、图片路径、库存、分类。商品列表页需要显示图片图片在 JSP 里其实是个img标签src 属性指向项目里的 upload 目录。老项目里图片路径经常用相对路径但部署到 Tomcat 的 webapps 下时路径一错图片就裂了。我一般会把图片路径存在数据库里存成upload/goods01.jpg这种相对于项目根的路径JSP 页面直接${goods.pic}就能渲染。注意 Access 的文本字段长度默认 255如果存了长路径加文件名可能不够要把字段类型改成备注。2.2 购物车与订单模块Session 与数据库的取舍购物车这个模块在各家源码里实现方式差异最大。常见的做法是用 Session 域对象直接存一个 Mapkey 是商品 IDvalue 是购买数量。这样做的好处是不用操作数据库加购、删购都在内存里完成页面跳转不丢失数据。坏处是用户关浏览器购物车就没了。另一种做法是设计一个 cart 表每次加购都写 Access代码量翻倍但数据能持久化。课设项目为了答辩好讲Session 方式足够下面是一个典型加购逻辑// cart.jsp 中把商品加入 Session % Integer pid Integer.parseInt(request.getParameter(pid)); MapInteger, Integer cart (MapInteger, Integer) session.getAttribute(cart); if (cart null) { cart new HashMapInteger, Integer(); } if (cart.containsKey(pid)) { cart.put(pid, cart.get(pid) 1); // 已存在则数量加 1 } else { cart.put(pid, 1); } session.setAttribute(cart, cart); response.sendRedirect(cart_view.jsp); %购物车页面读取 Session 里的 Map再根据每个商品 ID 去 Access 查名称、单价。这一步要注意不要在 cart_view.jsp 里做循环查询数据库因为每查一条就开一次连接Access 对并发很敏感连接一多就报文件正在使用。正确做法是先把所有 ID 拼成一个IN (...)条件一次查回来。比如WHERE goods_id IN (1,2,3)Access 对IN列表支持没问题但列表长度有限制一般购物车也就十来个商品完全够用。订单模块则必须写数据库因为订单要长久保存。下单逻辑涉及两张表orders 主表和 order_detail 明细表。主表存订单号、用户 ID、下单时间、总金额、收货地址明细表存订单号、商品 ID、数量、单价。下单时先插入主表拿到自动生成的订单号然后遍历购物车插入明细最后清空 Session。这里有个事务问题Access 支持事务但需要conn.setAutoCommit(false)操作成功后conn.commit()失败则rollback()。很多课设源码为了少写代码插入主表和明细表之间没有任何事务保护一旦明细插入到一半报错就会留下一个没有明细的总订单这种翻车现象在答辩演示时特别尴尬。所以订单提交的 JSP 里事务三件套一定要写全。3. 用 Access 当数据库JDBC-ODBC 桥接配置与连接池参数Access 数据库不像 MySQL 需要独立安装服务它就是一个 .mdb 或 .accdb 文件。JSP 连它有两个方案JDBC-ODBC 桥和 UCanAccess 驱动。对老项目来说JDBC-ODBC 是经典路线但配置过程最容易出问题。你先得在 Windows 的控制面板里建一个系统 DSN这一步对新手极不友好很多人卡在找不到 ODBC 数据源管理器上。其实 Win10/Win11 里直接在开始菜单搜ODBC就能打开32 位和 64 位要分清——Tomcat 如果是 32 位的 JVM就得用C:\Windows\SysWOW64\odbcad32.exe打开 32 位 ODBC 管理器否则配置的 DSN 在 Java 里根本看不见。3.1 配置 Access 数据源 DSN 的完整步骤配 DSN 的核心是把 Access 文件路径绑定到一个名称上。打开 ODBC 数据源管理器后选择系统 DSN页签点添加驱动列表里选 Microsoft Access Driver (*.mdb, *.accdb)。然后数据源名填shopDB描述随便写数据库按钮选择你的 shop.mdb 文件。如果 Access 文件带密码还要在高级里设置登录名称和密码。注意 DSN 的名称必须和 Java 代码里jdbc:odbc:shopDB冒号后面的名字完全一致大小写不敏感但别带空格带空格容易出Data source name not found。配置完成后可以在 ODBC 管理器直接点测试显示连接成功再开 Tomcat。有一点特别玄学JDBC-ODBC 桥是线程不安全的多用户同时访问时会随机出现[Microsoft][ODBC 驱动程序管理器] 驱动不支持或连接被重置。这就是为什么网上购物系统课设通常只做演示级并发。如果你想在答辩时展示多用户登录建议把 Tomcat 的 JSP 执行方式改成单线程或者干脆用 UCanAccess。UCanAccess 不需要 DSN连接串用jdbc:ucanaccess://C:/shop.accdb它底层把 Access 文件当嵌入式数据库支持并发读写窗口比 ODBC 稳定得多。但 UCanAccess 要求你的 Java 版本带 JDK 8而且需要引入三个依赖 jar 包ucanaccess、jackcess、hsqldb、commons-lang3。源码包里如果只有 lib 目录通常会有这几个包如果没有就得去 Maven 仓库手动下载。3.2 JDBC 连接串与连接代码的三种写法老源码里最常见的连接代码是直接在 JSP 里写Class.forName(sun.jdbc.odbc.JdbcOdbcDriver)这种方式在小项目里没问题但每一次 JSP 请求都创建一个新连接Access 文件会被频繁打开关闭性能很差。建议加一层简单的连接管理至少在应用启动时只初始化一次驱动然后用一个公共类封装getConnection()。下面是三种连接串按适用场景区分// 方式一JDBC-ODBC 桥适用于 JDK 8 Windows 课设 String url jdbc:odbc:shopDB; Class.forName(sun.jdbc.odbc.JdbcOdbcDriver); // 方式二UCanAccess适用于 JDK 8/11 跨平台 可提交的课程设计 String url jdbc:ucanaccess://D:/project/shopdb.accdb; Connection conn DriverManager.getConnection(url, , ); // 方式三Access 带密码UCanAccess 连接串参数带上用户密码 String url jdbc:ucanaccess://D:/project/shopdb.accdb;password123; Connection conn DriverManager.getConnection(url, admin, 123);方式三里的密码参数有两种写法一种是拼在 URL 里一种是放在getConnection的第二个参数位置。我踩过坑Access 2007 以后生成的 .accdb 文件默认加密方式不同密码如果超过 14 位UCanAccess 会报错说密码无效实际上它只支持传统加密的 Access 数据库。遇到这种情况最好用 Access 本身的工具把数据库转换为 2002-2003 格式并重新设置密码。连接池方面JSP 原生没有连接池但你可以在src下放一个context.xml配置 Tomcat 的 JNDI 数据源把 Access 包一层。配置里driverClassName填net.ucanaccess.jdbc.UcanaccessDriverurl填上面方式二的串maxActive设成 10maxWait设 5000。这样 JSP 里通过InitialContext.lookup(java:comp/env/jdbc/shopDS)拿到DataSource再取连接能显著减少文件正在使用报错。不过 Access 不管怎么包本质还是单文件数据库并发上限就在那里别指望它扛住真实网购流量。答辩时老师问你并发你就老实说这是课设演示不是生产系统这才是正确的定位。4. 源码里最该看懂的 5 个 JSP 文件个人信息展示、商品列表、购物车、订单提交、后台管理压缩包里的 JSP 文件可能有好几十个但你不需要全看。抓住五个关键文件整个系统的逻辑就串起来了。其余的无非是 include 的页头页脚、样式引用、错误页。我根据自己的经验把每个文件的核心代码段抽出来讲清楚这样你拿到任何一份类似源码都能按图索骥。4.1 个人信息展示页面JSP 图片坐标定位与信息绑定个人信息页一般在userinfo.jsp打开后要显示当前用户的用户名、邮箱、注册时间、头像。头像是个难点很多源码用img src% user.getPic() %但图片保存的是绝对路径如D:\upload\avatar.jpg浏览器访问不到本地盘符。正确做法是图片复制到 webapps 项目目录下数据库只存相对路径。如果你的页面设计要求在图片上做坐标定位比如点击头像某个区域触发事件那是典型的usemap用法。热词里jsp图片如何对坐标定位指的就是这个。JSP 里输出坐标要结合后台数据比如用户信息里有头像上的标记点 x、y 坐标你可以动态生成map标签!-- userinfo.jsp 中动态生成可点击区域 -- % int pointX user.getPointX(); // 从数据库取坐标0-100 之间 int pointY user.getPointY(); % img src% user.getAvatar() % usemap#avatarMap styleborder:0 alt用户头像 map nameavatarMap area shapecircle coords% pointX %,% pointY %,10 hrefprofile.jsp?actdetail title个人信息 /map坐标定位的关键是 coords 里的数值要和图片实际显示尺寸一致如果 CSS 里把图片缩放了坐标会错位。所以要么固定图片显示尺寸要么在后台存坐标时就用百分比换算。我一般建议存 0-100 的百分比坐标前台用图片实际宽度乘以百分比输出不过那样就需要一点 JavaScript 配合。在老 JSP 项目里没必要搞这么复杂直接定死图片宽度最简单。个人信息展示页面还经常涉及 Access 的备注字段。比如用户签名、自我介绍字段类型是备注在 JSP 里输出时换行符会丢。你需要在显示前把\n替换成br但注意防 XSS最好先escapeHtml再替换换行。不少源码直接out.println(profile)用户如果在文本里输入一段script页面就崩了。这一点在答辩时可以主动提算是你对自己的代码做了安全改造。4.2 商品列表的分页查询Access 的 TOP 和子查询商品列表页goods_list.jsp是商城最常被问到的页面。因为它要分页Access 不像 MySQL 有LIMIT它得用TOP关键字配合子查询。拓扑逻辑是先查出当前页的最大 ID再取 TOP N。网上流传的标准写法如下-- 假设每页显示 8 条当前第 pageNo 页每页偏移 offset SELECT TOP 8 goods_id, goods_name, price, pic FROM goods WHERE goods_id NOT IN ( SELECT TOP 8 * (pageNo - 1) goods_id FROM goods ORDER BY goods_id ) ORDER BY goods_id;这个写法在 Access 里可以跑但NOT IN子查询里如果有 NULL 值会出问题。更好的写法是用主键大于当前游标的方式int pageSize 8; int currentPage Integer.parseInt(request.getParameter(page) null ? 1 : request.getParameter(page)); int cursor (currentPage - 1) * pageSize; String sql SELECT TOP pageSize * FROM goods WHERE goods_id cursor ORDER BY goods_id;用goods_id cursor而不是NOT IN性能好且代码简单。注意 Access 的TOP后面必须跟常数不能跟参数占位符所以只能用字符串拼接数字。这个数字是从前台传来的一定要做整数校验否则被人传一个负数或单词就会SQL 语法错误这就是 Access 注入的常见入口。商品图片在列表页要统一大小。数据库里存图片路径后直接用img src...不一定能正常显示因为有些图片格式是 BMP 或 PNGAccess 的 OLE 对象字段也能存图片但 JSP 读出来是二进制需要写一个showImage.jsp?id1的 servlet 去getBinaryStream输出。如果源码里把商品图片直接放在项目images文件夹那就不存在这个问题。我见过的课设源码 80% 是路径方式20% 是 OLE 方式。后者一旦你换数据库文件就会显示空白因为 OLE 对象封装了 Access 特有的包装头。遇到这种情况建议把图片字段导出成文件再改代码为路径方式。4.3 购物车页面里的 Session 输出与数量修改购物车查看页cart_view.jsp要遍历 Session 中的 Map同时查询商品信息。一个容易忽略的点是如果用户直接访问购物车页Session 里没有 cart需要先判断if (session.getAttribute(cart) null)再 new 一个空 Map否则getAttribute返回 null 后强转会报空指针。正确写法% MapInteger, Integer cart (MapInteger, Integer) session.getAttribute(cart); if (cart null) { cart new HashMapInteger, Integer(); session.setAttribute(cart, cart); } if (cart.size() 0) { out.println(div classempty购物车是空的/div); } else { // 拼 ID 列表 StringBuilder ids new StringBuilder(); for (Integer id : cart.keySet()) { if (ids.length() 0) ids.append(,); ids.append(id); } String sql SELECT goods_id, goods_name, price, pic FROM goods WHERE goods_id IN ( ids ); // 执行查询并循环输出行 } %注意IN后面的 ID 列表如果来自 SessionSession 是服务器端的数据不会被用户直接篡改但为了保险还是把每个 id 转成Integer.parseInt处理一次。购物车数量的增减一般用cart.jsp?pid3opadd或opminus操作完跳回window.history.back()。这个操作不涉及数据库所以不用考虑事务但要注意 Session 并发读写的线程安全Tomcat 默认 Session 是线程隔离的问题不大。4.4 订单提交页面生成订单号与事务提交订单提交order_submit.jsp是整套系统里最核心的事务逻辑。订单号生成常见方案是时间戳加随机数System.currentTimeMillis()拼上三位随机数保证同一秒内不重复。然后先插入 orders 表获取getGeneratedKeys()得到自增 ID再循环插入 order_detail。这一步代码最容易踩 Access 的坑因为 Access 的自动编号字段在 JDBC 下返回getGeneratedKeys不一定有效。如果拿不到自增 ID可以改查SELECT IDENTITY FROM orders但 Access 的IDENTITY支持有限。我推荐最简单可靠的方案自己用SELECT MAX(order_id)1 FROM orders计算下一个订单号虽然并发下可能冲突但课设场景够用。关键代码如下// order_submit.jsp Connection conn getConn(); conn.setAutoCommit(false); try { int orderId 0; Statement stmt conn.createStatement(); ResultSet rs stmt.executeQuery(SELECT MAX(order_id) FROM orders); if (rs.next()) { orderId rs.getInt(1) 1; } // 插入主表 String insertOrder INSERT INTO orders(order_id, user_id, total, address, create_time) VALUES(?,?,?,?,NOW()); PreparedStatement ps conn.prepareStatement(insertOrder); ps.setInt(1, orderId); ps.setInt(2, userId); ps.setBigDecimal(3, totalPrice); ps.setString(4, address); ps.executeUpdate(); // 循环插入明细 for (Map.EntryInteger, Integer entry : cart.entrySet()) { String sql INSERT INTO order_detail(order_id, goods_id, quantity, price) VALUES(?,?,?,?); PreparedStatement ps2 conn.prepareStatement(sql); ps2.setInt(1, orderId); ps2.setInt(2, entry.getKey()); ps2.setInt(3, entry.getValue()); ps2.setBigDecimal(4, getPrice(entry.getKey())); ps2.executeUpdate(); ps2.close(); } conn.commit(); session.removeAttribute(cart); response.sendRedirect(order_success.jsp?orderId orderId); } catch (Exception e) { conn.rollback(); out.println(scriptalert(下单失败 e.getMessage().replace(, ) );history.back();/script); } finally { conn.setAutoCommit(true); conn.close(); }NOW()在 Access 里是NOW()函数但如果用PreparedStatement建议用new Timestamp(System.currentTimeMillis())设置避免不同数据库的 SQL 方言问题。还要注意在事务里conn.setAutoCommit(false)之前连接必须已经成功取得否则后面的 commit 会报连接未打开。血泪经验Access 在事务未提交时会锁定整个表其他用户读同一张表会一直阻塞所以事务里的循环查询不要太慢。4.5 后台管理页面JSP 与 Access 的权限控制后台管理通常是一个admin/目录包含商品添加、修改、删除和订单处理。这块的技术含量不高但要想清楚权限校验放在哪。很多源码只在管理页顶部检查session.getAttribute(admin)是否等于admin但商品删除操作是delete_goods.jsp?id1直接访问这个 URL 也能执行删除没有权限拦截。应该在每个管理操作前都做一次校验或者把管理页面放到WEB-INF/admin/下Web 容器会拒绝直接访问。修改商品时图片上传是另一个坑老项目用commons-fileupload包表单enctypemultipart/form-data下不能用request.getParameter取普通字段要先解析 FileItemStream。这些代码细节比较繁琐但源码里通常会带上你需要关注的是文件保存路径Tomcat 重启后upload临时目录可能被清空我一般保存到项目外的固定目录再在 Tomcat 配置虚拟目录映射。5. 避坑指南Access 注入、中文乱码、文件路径、并发写入的 4 个实战踩坑这一部分是这个项目最值得记录的血泪经验。JSPAccess 的老旧程度决定了你运行时会遇到一堆玄学问题下面四条是我在帮人调试这类系统时反复见到的每一条都按现象 - 原因 - 解决的顺序来梳理。5.1 Access 注入文本框输入单引号直接报错现象在登录用户名或搜索框里输入admin or 11页面报Microsoft Office Access 数据库引擎找不到表达式或直接 500。原因源码用字符串拼接 SQL单引号破坏了语法这就是传说中的 Access 注入。很多 JSP 老课设源码里全是这种写法因为 Access 没有像 MySQL 那样的预处理习惯学生容易忽略。解决统一改成PreparedStatement的setString传参。如果是从request.getParameter拿到的参数即使做不了预编译比如TOP子句也要用白名单校验。对于数字参数用Integer.parseInt包装失败就返回错误页。我可以给你一段防御校验工具public static int parseIntSafe(String str, int defaultVal) { if (str null || str.trim().isEmpty()) return defaultVal; try { return Integer.parseInt(str.trim()); } catch (NumberFormatException e) { return defaultVal; } }这一步能在根上堵住 Access 注入因为数字型注入的根源就是参数进入 SQL 前没有类型校验。字符串参数全部走PreparedStatement这样 OR 11只会被当成普通字符不会闭合 SQL。5.2 中文乱码页面、数据库、Tomcat 三个地方编码不一致现象插入的中文在列表页显示为???或者从 Access 里读出来是乱码。原因JSP 页面默认编码是ISO-8859-1Access 文本列默认编码受 Windows 系统区域影响通常为 GBK。前后多级编码不一致任何一个环节断了都会乱码。解决统一全链路为 GBK 或 UTF-8。如果 Access 是中文版且用旧表建议用 GBK。在 JSP 第一行写% page contentTypetext/html; charsetGBK pageEncodingGBK%表单提交时在request.setCharacterEncoding(GBK)JDBC 连接串补上;charsetGBKUCanAccess 支持。Tomcat 的server.xml里 connector 加URIEncodingGBK。改了这些之后重启 Tomcat再测一遍插入和查询。如果 Access 表结构是某次改编码前建的旧数据已经是乱码那就只能删掉重建没有后悔药。5.3 文件路径问题JSP 在 Tomcat 中获取不到真实路径现象上传图片提示成功但页面上图片裂了查看元素发现src是upload/20230601.jpg但目录里没有文件。原因JSP 里直接写相对路径upload/xx.jpg浏览器解析时相对于当前 URL如果当前页面在admin/goods_add.jsp浏览器会请求admin/upload/xx.jpg服务器返回 404。或者图片被保存到了 Tomcat 的temp目录重启后被清理。解决在项目里建一个固定上传目录并使用application.getRealPath(/)得到项目的物理根路径。例如保存时用application.getRealPath(/upload)输出图片时用${pageContext.request.contextPath}/upload/xxx.jpg。注意getRealPath返回的是部署后的路径如果项目被 Tomcat 以 exploded 方式部署路径是实打实的目录如果以 war 包部署路径可能在临时目录重启会丢。所以生产环境通常不用getRealPath而用绝对路径保存并在 TomcatContext里配置docBase指向外部目录。5.4 Access 并发写入一个用户下单时另一个用户卡死现象两个浏览器窗口同时提交订单其中一个等很久最后报Microsoft Office Access 数据库引擎已停止进程或提示文件共享锁定数溢出。原因Access 是文件型数据库写入时会锁定整个文件或页并发一高就冲突。JSP 的长连接加上事务没及时关闭锁就积压了。解决减少连接持有时间每次操作完立刻close()。事务范围尽量小不要在一个事务里查询多个表。把conn.setAutoCommit(true)的默认行为保留只有下单和订单明细插入这种强一致操作才开事务。另外检查是否有Statement或ResultSet没有关闭在代码的finally块里统一关闭资源。只要你每轮页面操作控制在 1 秒内关闭连接5 个并发以内 Access 基本能扛住。如果还是一直卡就换成 UCanAccess 驱动它对并发锁的处理比 ODBC 好一些但仍不建议超过十个用户。5.5 开发工具认不出 JSP 项目IDEA 提示limited functionality现象用 IntelliJ IDEA 打开解压后的源码右下角提示 limited functionality. Trust the project to access full IDE functionality点 Trust Project 后仍提示不支持某些功能或者直接无法运行。原因IDEA 需要把项目识别为 Web Application 类型否则不会开启 JSP/JSF 支持。而课设源码往往没有.idea目录导入时被当成普通 Java 项目。解决导入时选择从现有源创建项目然后在 Project Structure 的 Modules 里添加 Web 模块指定web目录或WebRoot作为 Web 资源目录。在 Web 模块创建后IDEA 才会把 JSP 文件识别为模板语言语法高亮和运行配置才出现。如果不是运行问题只是提示功能受限点 Trust Project 就够了。这个提示不会影响最终编译部署Tomcat 运行的是 class 文件和 JSP 的编译结果和 IDEA 的辅助功能无关。6. 把项目跑通的最小操作顺序从解压到浏览器看到首页你现在手上是一个 zip 包解压后先不要急着配 Idea。按我的习惯先把运行环境凑齐JDK 1.8千万不能 JDK 17JSP 老项目跑不了、Tomcat 8.5 或 9.0、Access 数据库文件。然后按这个顺序来每一步只做必要的验证解压源码到D:/shop确认里面有src、web或WebRoot、lib、shop.mdb文件和readme.txt。用 Access 打开shop.mdb确认users、goods、orders、order_detail表存在。如果打不开注意 Access 版本与文件格式不匹配可以用systools access password recovery这类工具检查是否有密码但更常见的是直接用 Access 2007 以上版本打开。配置系统 DSN名称为shopDB指向你的shop.mdb。在src下找到db.properties或dbconn.jsp把连接串改成jdbc:odbc:shopDB。编译并部署到 Tomcat如果你用 IDEA直接配置 Tomcat 运行如果用命令行把src编译的class放到WEB-INF/classeslib里的 jar 放到WEB-INF/lib启动 Tomcat 后访问http://localhost:8080/shop。如果首页空白或 500看 Tomcat 日志的localhost.log最常见的错误是ClassNotFoundException: sun.jdbc.odbc.JdbcOdbcDriver说明你用了 JDK 11需要换成 JDK 8 或用 UCanAccess 方案。做完整套流程你就能体会到这个老技术栈最舒服的地方Access 让数据库和代码放在一起拷走 zip 就能在另一台机器上还原整个环境。但记住一个教训生产环境别用 Access。我自己接手过一个小公司内网商城后来并发一多整个系统就死最后迁到 MySQL代码反而比换数据库更费劲——因为 JSP 里满屏的out.println和 JSP 脚本逻辑混在一起改造时头皮发麻。如果你只是做课设或者学原理JSPAccess 值得投入它能让你把 Servlet、Session、JDBC、事务这些概念在一套完整项目里串成一条线。如果以后真要上线趁早换技术栈。希望这个老项目能把你的基础打扎实至少在答辩时你能把 Access 的局限和 JSP 的职责说清楚这就值回解压它花的时间了。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站