☰
JavaWeb医院药品管理系统:源码导入到Tomcat部署全攻略
2026/9/29 18:53:28 网站建设 项目流程

简介:这是一套基于JavaWeb的医院药品管理系统完整项目,面向计算机相关专业正在做毕业设计的学生,以及需要项目实战练习的Java学习者,同时适用于课程设计或期末大作业。系统采用Java开发语言,以MySQL作为后台数据库,覆盖药品信息管理、库存维护等常用功能模块。压缩包共包含195个文件,以Java源文件、JavaScript脚本、HTML页面、CSS样式等前后端代码为主,并配有SQL数据库脚本、GIF演示图片和项目说明文档,整体大小约869KB,目录结构清晰,便于导入IDE后直接运行。项目已获导师指导并通过,所有代码经过严格调试,确保下载即用、无需额外修改。目前已有652人学习下载,适合需要快速获得完整毕设方案或学习JavaWeb开发流程的读者参考,可直接作为毕业设计使用,也可基于源码进行二次功能扩展。

1. 拿到的医院药品管理系统:先搞清楚这包东西值不值得解压

先说实话,这类 javaweb 的医院药品管理系统源码+数据库,在课程设计和毕业设计里出现频率极高,也是我后台被问得最多的一类资源。这套东西本质是一个基于 Servlet + JSP + MySQL 的标准 JavaWeb 项目,覆盖了药品信息管理、供应商管理、入库出库、库存预警和用户权限几个核心模块,适合用来交 Java 课程设计、应付毕业设计答辩,也适合刚学完 JavaWeb 想找个完整案例练手的人。

这篇笔记我会按自己的拆包习惯来讲:先看技术栈和模块边界,再讲数据库脚本怎么用,然后是 IDEA 里跑起来的完整配置流程,最后把账号登录、增删改查这些必测点过一遍。中间会穿插我实际复现时踩过的坑——这套资源在 Tomcat 版本和 JDK 版本上非常敏感,不是下下来就能跑的。读完你能知道这包源码的底细,也能照着步骤把它在本地跑起来。

2. 技术栈与模块边界:为什么这个老组合到现在还是课设首选

2.1 技术选型拆解:JSP + Servlet + Javabean 的分层逻辑

这套系统没有用 Spring 系框架,核心是 JSP + Servlet + Javabean + JDBC 的经典组合。很多刚学完 JavaWeb 的人拿到这种项目会疑惑:现在企业里都是 SpringBoot,为什么课设和毕设还在用这套老组合?

原因很简单:课程设计考察的核心是「用 Java 语言操作数据库 + 理解 HTTP 请求处理链路」,而不是框架熟练度。Servlet 负责接收请求和转发,JSP 负责渲染页面,Javabean 封装实体数据,JDBC 负责和 MySQL 打交道。这个链路把 JavaWeb 最底层的逻辑跑了一遍,比直接上 SpringBoot 更能让答辩老师看到你对基础知识的掌握程度。

从这套资源的包结构也能看出来,它通常按 com.xxx.entity、com.xxx.dao、com.xxx.service、com.xxx.servlet 这样的层级划分。entity 放药品、供应商、用户等实体类;dao 层写 JDBC 的增删改查;service 层处理业务逻辑比如入库时扣减库存、出库时校验库存量;servlet 层接收前端请求并调用 service。这种分层虽然笨,但边界清晰,非常适合学习和二次改造。

2.2 功能模块盘点:药品、供应商、出入库和权限

拿到手第一件事,我会先把功能模块捋清楚。这套系统的模块一般包含下面这些:

模块核心功能涉及表
用户登录账号密码校验、角色区分user / admin
药品管理药品 CRUD、药品分类维护drug / category
供应商管理供应商信息维护supplier
入库管理采购入库、库存自动增加drug_in / drug_stock
出库管理销售出库、库存扣减与校验drug_out / drug_stock
库存预警低于安全库存时列表预警drug_stock
系统管理用户密码修改、权限控制user

这里要特别说一下权限控制。这套系统虽然简陋,但一般会区分管理员和普通操作员两种角色。管理员能做药品的增删改和供应商维护,操作员可能只能做出入库登记。这个设计在答辩里是加分项,因为涉及会话管理和权限拦截,面试官或答辩老师大概率会追问「你是怎么控制用户只能访问自己权限内的功能的」。

提示:源码里的 role 或 type 字段就是判断权限的开关,你在 Servlet 里能看到if(role == 1)这种硬编码判断,这是一种最简单可行的权限方案,但二次开发时建议改成过滤器统一拦截。

2.3 数据库表设计:这份 SQL 脚本里隐藏的依赖链

数据库是这套资源的核心交付物之一,通常是一个 .sql 文件或一个 db 文件夹。里面除了建库建表语句,还会预置几条测试数据。我的习惯是先看表结构,再捋表之间的外键关系。

药品表一般是整张库的核心,字段包括 drug_id、drug_name、category_id、specification、unit、purchase_price、sale_price、stock_quantity、safe_stock。其中 category_id 关联分类表,stock_quantity 在入库、出库操作时会实时变动。供应商表通过 supplier_id 和入库记录关联,属于典型的从表引用主表。

这里有个常见坑:这套老项目的 SQL 脚本很多是从 MySQL 5.x 时代导出的,默认存储引擎是 MyISAM,没有真正的外键约束,只有逻辑上的关联关系。这意味着你在代码里删除一个分类时,如果该分类下还有药品,不会触发数据库级报错,而是会在你的 service 层逻辑里漏掉校验,导致药品表里出现孤立数据。这个后续在避坑章节我会单独展开。

3. 数据库初始化与配置:跑起来之前先让 MySQL 这边稳住

3.1 建库建表与初始数据导入的完整操作

拿到这份资源后,数据库导入是第一关。一般源码包里会带一个 hospital_drug.sql 或类似命名的脚本,你需要在本地 MySQL 里执行它。先在命令行登录 MySQL,然后建库并导入:

mysql -u root -p # 输入密码后进入 MySQL 命令行,执行以下命令 CREATE DATABASE IF NOT EXISTS hospital_drug DEFAULT CHARACTER SET utf8mb4; USE hospital_drug; SOURCE /your/path/hospital_drug.sql;

SOURCE命令直接导入整个 SQL 文件,如果文件里自带建库语句,那你前面手动建的库会被覆盖。所以稳妥的做法是先用文本编辑器打开 SQL 文件看一眼开头——如果开头已经有CREATE DATABASE,那就不需要手动建库,直接执行SOURCE就行。

导入完成后验证一下数据,跑这几条命令:

USE hospital_drug; SHOW TABLES; SELECT COUNT(*) FROM drug; SELECT * FROM user;

如果SHOW TABLES能列出所有表且 drug 表有数据、user 表里有预设的管理员账号,说明脚本执行完整。常见情况是脚本中途报错,比如Unknown collation或Duplicate column,多半是 MySQL 版本差异或重复执行导致的。

3.2 JDBC 连接参数与 MySQL 版本匹配:驱动和 URL 是两回事

数据库弄完,接下来要看代码里的 JDBC 配置。打开项目的 jdbc.properties 或者 DBUtil 工具类,核心就三行内容:

jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/hospital_drug?useUnicode=true&characterEncoding=utf8 jdbc.username=root jdbc.password=123456

这里的第 1 行和第 2 行是最容易翻车的地方。如果你用的是 MySQL 5.x,驱动类名com.mysql.jdbc.Driver没问题;但如果你本机装的是 MySQL 8.x,驱动类名必须改成com.mysql.cj.jdbc.Driver,且 URL 里要带上时区参数:

jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/hospital_drug?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai jdbc.username=root jdbc.password=你的密码

提示:改动驱动类名时,记得把项目的 lib 目录或 Maven 依赖里的 mysql-connector-java 版本也换到位,8.x 驱动对应 8.x 的 jar,5.1.x 对应 5.x 的 jar,版本对不上照样报ClassNotFoundException。

这一步是新手重灾区。我见过太多人上来就改密码,改完运行报Establishing SSL connection without server's identity verification或Unknown database,最后发现是 URL 里库名拼错或者时区参数缺了。数据库的连接字符串是个细心活,建议一行一行对着我的示例核对。

3.3 数据库连接池:为什么课设项目一般不用

这套源码大概率不用连接池,直接在 DAO 层DriverManager.getConnection(),每次请求都新建连接,用完再关。这在并发量极低的课设场景下完全够用,但如果你想让它更接近企业级,可以手动接一个 Druid 连接池。

换成 Druid 只需在工具类里改成:

Properties props = new Properties(); props.load(new FileInputStream("src/main/resources/druid.properties")); DataSource ds = DruidDataSourceFactory.createDataSource(props); Connection conn = ds.getConnection();

druid.properties里配置driverClassName、url、username、password、initialSize=5、maxActive=20。这样做的好处是避免每次请求都新建连接,插入效率会明显提升。不过如果你是交作业,不建议改这一步——结构变了容易引入新问题,答辩重点如果不在性能优化,反而可能把自己绕进去。

4. 在 IDEA 里完整跑起来:配置路径与踩坑清单

4.1 导入项目:要选对导入方式,别被 IDEA 的提示带偏

用 IDEA 打开这份源码,不要直接点 Open 然后选文件夹,正确的做法是通过File -> New -> Project from Existing Sources导入,然后在弹窗里选Import project from external model并选Eclipse或直接Create project from existing sources。

注意:这套老项目很多不带 Maven 或 Gradle 配置,直接 Open 会让 IDEA 把它当成普通文件夹,不识别源码根目录,To Do 面板里一堆报错还不知道去哪修。

导入完成后,先检查 Project Structure 里的 SDK 和语言级别。点击File -> Project Structure -> Project,把 SDK 选成你本机装的 JDK 1.8 或以上,Language Level 选 8。然后在Modules里把src目录标记为 Sources,把web或WebContent目录标记为 Web 资源目录。

这套老项目通常是在 Eclipse 里开发的,目录结构是src+WebContent。IDEA 导入后需要手动添加 Web Facet:右键项目 ->Add Framework Support-> 勾选Web Application,然后把 Web 资源目录从 IDEA 默认的web改为实际的WebContent。这一步不设对,JSP 页面全部无法访问。

4.2 配置 Tomcat:Artifact 与 Deployment 是运行的关键

项目编译环境和 Web 目录都设置好之后,就是配置 Tomcat 运行。先在Run/Debug Configurations里新增一个 Tomcat Server -> Local,然后在 Deployment 页签里添加 Artifact。

这里最容易出问题的是 Artifact 类型。第一次添加时 IDEA 可能会弹出No artifacts marked as deployed的提示,你需要点Fix或者手动在Project Structure -> Artifacts里新增一个 Web Application Exploded 类型的 Artifact,并指定对应的 WebContent 目录作为输出根目录。

Tomcat 版本我建议用 Tomcat 8.5 或 Tomcat 9,这两个版本兼容 JDK 8,也是这套老代码比较稳定的运行环境。Tomcat 10 及以上把javax.servlet换成了jakarta.servlet,这套老源码的引包全部是javax.servlet.*,直接跑会报 NoClassDefFoundError,所以千万别用新版本,这不是配置问题而是兼容性问题。

配置完 Server 后,在 Application context 一栏填入/hospital_drug或者在浏览器里用http://localhost:8080/访问。建议填一个上下文路径,这样 IDEA 自动打开的地址就是http://localhost:8080/hospital_drug/,方便和数据库配置里的路径对上一对。

4.3 配置步骤总览:照这个顺序操作最稳妥

我按自己的复现经验,把整套启动流程压缩成下面几步,照做基本能跑起来:

  1. MySQL 中建库导入hospital_drug.sql,确认 user 表有初始账号
  2. 修改 JDBC 配置,核对驱动类名、URL、用户名、密码四样全对
  3. IDEA 导入项目,确认 src 为 Sources 根目录、JSP 目录被识别为 Web 资源目录
  4. 添加 Web Application Exploded Artifact,绑定 WEB-INF 的 web.xml
  5. 配置 Tomcat 8.5/9,Deployment 里添加刚建好的 Artifact
  6. 修改 Application context 为/hospital_drug
  7. 启动项目,观察 IDEA Console 日志无异常,再打开浏览器访问登录页

启动成功后,浏览器访问登录页能正常显示,输入初始账号密码能跳转到主界面,基本就确认这套源码是可运行的。如果你的首页静态资源垮了,比如 CSS 和 JS 全部加载不出来,那多半是 Artifact 配置里漏了WEB-INF/lib下面的 jar 包,IDEA 没有把依赖打包进 Artifact。这个检查方法是在 Project Structure -> Artifact 的 Output Layout 里确认所有 jar 都在,如果没有就手动加。

5. 避坑与常见问题:这套源码最容易翻车的五个地方

5.1 Artifact 是空的,启动直接报 404

现象:Tomcat 正常启动,日志也没报错,但浏览器访问任何路径都是 404,IDEA 里看 Artifact 是空的。

原因:项目在 Eclipse 里开发,依赖的 jar 放在WebContent/WEB-INF/lib目录下。IDEA 导入时没有识别 Web 资源目录,导致 Artifact 没有打包任何依赖。

解决:手动Add Framework Support勾选 Web Application,然后到 Project Structure -> Artifacts 里新建 Web Application Exploded,把 Web 资源目录指定为WebContent。最后把WEB-INF/lib下的 jar 全部加入 Output Layout。

这个问题我复现时至少遇到三次,每次都是因为没有先检查 Output Layout,建议启动前先看一眼这个列表,至少要有十几个 mysql 和 servlet 相关 jar。

5.2 数据库连接能 Ping 通但程序报Access denied for user

现象:Navicat 里用 root/123456 可以登录,但程序运行时报 Access denied。

原因:MySQL 8.x 默认使用 caching_sha2_password 认证插件,旧版 mysql-connector-java 5.x 驱动不支持这个插件。

解决:要么把驱动换成 8.x 并改驱动类名为com.mysql.cj.jdbc.Driver,要么在 MySQL 里把 root 的认证方式改回 mysql_native_password:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456'; FLUSH PRIVILEGES;

两条路选一条走。我个人的建议是换驱动,因为改认证方式到后面用 Navicat 也可能遇到其他兼容问题,不如一步到位。

5.3 页面中文全部乱码,药品名称显示成问号

现象:页面数据全是???或乱码,刚导入的测试数据中文显示异常。

原因:数据库连接 URL 里没有设置 characterEncoding,或数据库本身默认字符集不是 utf8mb4。这套资源的 SQL 文件如果是 GBK 编码导出的,导入 MySQL 时也会直接乱掉。

解决:先确认 SQL 文件本身的编码格式,用记事本或 Sublime 打开看是否正常。然后在 jdbc.url 里加上characterEncoding=utf8,并确认数据库建表语句里有DEFAULT CHARSET=utf8mb4。如果现有表不是 utf8mb4,可以执行:

ALTER TABLE drug CONVERT TO CHARACTER SET utf8mb4;

乱码问题对课设答辩影响很大,因为老师打开页面第一眼看到的就是数据展示。检查顺序一定是先看数据库客户端里直接查询是否正常,再看页面是否正常,逐步缩小问题范围。

5.4 Tomcat 启动报ClassNotFoundException: javax.servlet.ServletException

现象:Tomcat 一启动就报类找不到,或者程序里 import 的 servlet 包全部标红。

原因:JDK 版本太新,或者项目里引用了 servlet-api.jar 和 Tomcat 自带的冲突。JDK 9+ 模块化后,javax.servlet不再自动出现在 classpath 里。

解决:确认 Project Structure 里 Project SDK 是 JDK 8,然后检查WEB-INF/lib是否有 servlet-api.jar。如果有,建议移除,因为 Tomcat 自带了 servlet-api,重复引用会导致版本冲突。同时把 Tomcat 的 library 添加到项目依赖中:Project Structure -> Modules -> Dependencies -> Add -> Library -> Tomcat。

5.5 登录成功后跳转路径不对,页面 404

现象:登录校验成功,浏览器地址栏是/hospital_drug/login,但是跳转后 404,而直接在浏览器访问 index.jsp 是正常的。

原因:Servlet 里用了相对路径跳转,比如request.getRequestDispatcher("index.jsp"),而在 Servlet 的映射路径下相对路径解析的基准目录不是你期望的根目录。

解决:把所有跳转路径改成带上下文根的绝对路径,常见写法是在 Servlet 里:

response.sendRedirect(request.getContextPath() + "/index.jsp");

或者

request.getRequestDispatcher("/index.jsp").forward(request, response);

注意getRequestDispatcher里路径以斜杠开头就是相对于 Web 根目录,不以斜杠开头就是相对于当前 Servlet 路径,这个细节坑过很多人。建议拿到这套源码后全局搜一遍getRequestDispatcher(,统一改成绝对路径,能省掉一批跳转问题。

6. 验证链路与二次开发入口:从登录到改造成自己项目的正确姿势

6.1 必测流程:登录、增删改查、库存联动一条线走完

项目跑起来后,建议按完整业务链做一遍回归测试。先打开登录页,输入初始管理员账号,验证登录成功并进入主页面。然后创建一个新药品、再修改它的价格、删除一个库存为 0 的药品,最后做一次入库操作看库存量是否自动增加,再做一次出库操作看库存是否扣减。

// 出库时检查库存是否充足,避免负数库存,这是这套项目里最常被忽略的校验 public boolean outStock(String drugId, int quantity) { String checkSql = "SELECT stock_quantity FROM drug_stock WHERE drug_id=?"; // 先查出当前库存 int stock = getJdbcTemplate().queryForObject(checkSql, Integer.class, drugId); if (stock < quantity) { return false; // 库存不足,提示用户 } String updateSql = "UPDATE drug_stock SET stock_quantity = stock_quantity - ? WHERE drug_id=?"; int rows = jdbcTemplate.update(updateSql, quantity, drugId); return rows > 0; }

这段代码代表这套项目里最核心的一条业务逻辑:出库前先查库存、再扣库存。很多课程设计在这个环节直接只做 UPDATE,不做 SELECT 预检查,结果库存能扣成负数,答辩被老师问住。看一下你的源码里是不是也有同样问题,如果确实验证了库存再更新,这个项目的完成度是合格的。

6.2 二次开发切入点:给项目加上 Filter 权限控制

如果你想让这个课设项目在答辩时显得更完整,最值得做的小改造是加一个 Filter 做登录拦截。原来的代码里每个 Servlet 都写一遍if(session.getAttribute("user") == null)太重复了,抽成一个过滤器,权限控制会清晰很多:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; HttpSession session = request.getSession(); if (session.getAttribute("loginUser") == null) { response.sendRedirect(request.getContextPath() + "/login.jsp"); return; } chain.doFilter(request, response); }

然后在 web.xml 里配置 Filter 映射,排除 login.jsp、登录 Servlet 和静态资源路径:

<filter> <filter-name>LoginFilter</filter-name> <filter-class>com.hospital.filter.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>LoginFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping>

这样所有 JSP 页面都必须登录后才能访问,不需要登录的页面用dispatcher映射单独放行。这个改动大约 30 行代码,但答辩时讲权限控制的思路就完全不一样了,从「我在每个页面复制粘贴判断」变成「我用过滤器统一拦截」,观感差距很大。

6.3 换数据库表的技巧:如果不想用预设的表结构

有人会想把它改成别的管理系统,比如换成仓库管理系统或图书管理系统。最快的方式是只改实体类字段和 JSP 页面标签,保留整套 Servlet 流转骨架。具体做法是先在数据库里新建你的业务表,再照着原表的 CRUD SQL 业务线逐层改:改 entity 属性、改 dao 层 SQL 语句、改 service 传参逻辑。表面看起来改动很大,但三层之间调用的结构完全不用动,Servlet 的请求分发也不用动。

这个项目是我拆过的课设资源里结构比较规矩的一类,分层清楚、SQL 完整、权限有区分,属于能直接跑、也能作为脚手架往上加东西的类型。我第一次拿到手时也踩了 Tomcat 版本和驱动不一致的坑,前前后后折腾了一个小时才把环境对齐。从那以后我每接手这一类老 JavaWeb 项目,都会强制先做三件事:看 SQL 脚本开头的建库语句、确认驱动 jar 版本与 MySQL 版本对应、检查 Tomcat 是 9 还是 10。这三个点只要稳了,项目基本就活了一半。希望这篇笔记能帮你少走一段弯路,顺利把这套系统跑起来、交上去。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询