Java数据库课设实战:医院病房管理系统从建表到跑通

发布时间:2026/10/12 18:02:48
Java数据库课设实战:医院病房管理系统从建表到跑通 简介本资源是一套基于Java开发的医院病房管理系统完整源码包面向计算机相关专业学生与Java初学者可直接用于数据库课程设计、期末大作业或毕业设计。系统涵盖患者管理、医生管理、科室管理、病房与床位管理、请假费用结算等核心模块界面美观、操作简单代码附有详细注释新手也能快速理解与二次开发。压缩包共145个文件约5.05MB包含37个java源文件、59个class编译文件、1个sql数据库脚本以及xml配置、project工程文件、jpg与png界面截图、doc文档说明和实验报告等部署后即可运行。目前已有250人学习下载项目经过严格调试个人手打98分导师认可度高。下载后可获得完整源码、数据库脚本、文档说明与实验报告便于快速搭建环境、理解系统架构并完成课程或毕设任务。1. 医院病房管理系统从建表到跑通一套能写进课设的 Java 方案做过数据库课设的人都懂那种感觉选题看着简单真动手才发现表关系理不清、外键到处报错、Java 那边连不上库。医院病房管理系统就是这类选题里最典型的一个——它不复杂但把「病人、病房、床位、医生、住院记录」这几张表的关系串起来足够覆盖数据库课设要求的实体关系设计、范式、事务和查询。这套方案用 Java 做后端逻辑、SQL 数据库做持久化配套源码、建表脚本和实验报告适合正在赶数据库课设、又想顺手把 Java 基础练一遍的同学。下面我按自己带课设的经验把从环境到跑通的路径讲清楚参数怎么设、坑在哪都落到具体命令上。2. 先想清楚表怎么建病房管理系统的实体关系与字段设计很多人一上来就写 Java结果写到一半发现表结构撑不住业务回头改表比重新写还痛苦。血泪经验是先把 ER 图和建表脚本定死再动代码。这一章把核心表、字段类型和约束讲透你照着建就能跑。2.1 五张核心表和它们的关系病房管理系统的业务其实就一条主线病人住院 → 分配床位 → 医生负责 → 产生住院记录 → 出院结算。对应到表patient病人病人基本信息主键patient_idward病房病房编号、类型、床位数主键ward_idbed床位属于哪个病房是否占用主键bed_id外键指向warddoctor医生医生信息、所属科室主键doctor_idadmission住院记录把病人、床位、医生串起来记录入院出院时间主键admission_id三个外键分别指向patient、bed、doctor关系上一个病房有多个床位一对多一个床位在某一时段只对应一条有效住院记录一个医生可以负责多个病人。这里最容易翻车的是把床位状态直接写死在bed表里结果出院时忘了改回来床位永远占用。常见做法是床位占用状态由admission表的discharge_time是否为空来推导bed表只存静态属性。2.2 建表脚本与字段类型选择下面这段是 MySQL 8 的建表脚本字段类型和约束都按课设常见要求来。注意status用TINYINT而不是字符串方便加索引和做统计。-- 病人表 CREATE TABLE patient ( patient_id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, gender TINYINT NOT NULL COMMENT 0女1男, id_card VARCHAR(18) UNIQUE NOT NULL, phone VARCHAR(20), create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 病房表 CREATE TABLE ward ( ward_id INT PRIMARY KEY AUTO_INCREMENT, ward_no VARCHAR(10) UNIQUE NOT NULL, ward_type VARCHAR(20) NOT NULL COMMENT 普通/重症/隔离, bed_count INT NOT NULL DEFAULT 0 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 床位表 CREATE TABLE bed ( bed_id INT PRIMARY KEY AUTO_INCREMENT, ward_id INT NOT NULL, bed_no VARCHAR(10) NOT NULL, status TINYINT NOT NULL DEFAULT 0 COMMENT 0空闲1占用, CONSTRAINT fk_bed_ward FOREIGN KEY (ward_id) REFERENCES ward(ward_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 医生表 CREATE TABLE doctor ( doctor_id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, department VARCHAR(50) NOT NULL, title VARCHAR(20) COMMENT 职称 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 住院记录表 CREATE TABLE admission ( admission_id INT PRIMARY KEY AUTO_INCREMENT, patient_id INT NOT NULL, bed_id INT NOT NULL, doctor_id INT NOT NULL, admit_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, discharge_time DATETIME DEFAULT NULL, CONSTRAINT fk_adm_patient FOREIGN KEY (patient_id) REFERENCES patient(patient_id), CONSTRAINT fk_adm_bed FOREIGN KEY (bed_id) REFERENCES bed(bed_id), CONSTRAINT fk_adm_doctor FOREIGN KEY (doctor_id) REFERENCES doctor(doctor_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;逻辑说明patient的id_card加唯一约束防止重复登记bed的status用TINYINT存 0/1比字符串省空间且能直接做条件查询admission的discharge_time允许为空空值就代表还在住院这是判断床位是否占用的关键。参数上字符集统一utf8mb4避免中文乱码存储引擎用InnoDB因为要外键和事务支持。提示如果课设要求用 SQL Server把AUTO_INCREMENT换成IDENTITY(1,1)DATETIME换成DATETIME2其余逻辑不变。2.3 三个必调的约束和索引建完表别急着写 Java先加索引和检查约束不然后面查询慢、脏数据多。第一给admission的patient_id和bed_id各加普通索引因为按病人查住院记录、按床位查占用是高频操作CREATE INDEX idx_adm_patient ON admission(patient_id); CREATE INDEX idx_adm_bed ON admission(bed_id);第二给bed的(ward_id, status)加联合索引查某病房空闲床位时能直接命中。第三如果数据库支持检查约束MySQL 8.0.16给gender加CHECK (gender IN (0,1))防止写入非法值。参数上索引不是越多越好admission表写多读少时索引会拖慢插入课设数据量小影响不大但要知道这个边界。3. Java 侧怎么连库和写业务JDBC 最小可跑通版本表建好了接下来是 Java 怎么把数据读写起来。课设不要求上框架用原生 JDBC 反而更能体现你对连接、事务的理解。这一章给一个能直接跑的最小版本再讲事务和连接池怎么加。3.1 JDBC 连接与增删改查最小代码先建一个DBUtil工具类把连接参数集中管理。注意密码别硬编码在代码里课设也建议放配置文件这里为演示方便先写常量。import java.sql.*; public class DBUtil { // 连接参数库名、时区、是否用SSL private static final String URL jdbc:mysql://localhost:3306/hospital?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse; private static final String USER root; private static final String PWD your_password; static { try { Class.forName(com.mysql.cj.jdbc.Driver); // MySQL 8 驱动类 } catch (ClassNotFoundException e) { throw new RuntimeException(驱动加载失败, e); } } public static Connection getConn() throws SQLException { return DriverManager.getConnection(URL, USER, PWD); } }逻辑说明serverTimezone必须设否则 MySQL 8 连接会报时区错误这是新手最常见的翻车点useSSLfalse在本地开发关掉避免证书警告。参数上characterEncodingutf8要和建表时的utf8mb4配合中文才不会乱码。下面是一个「给病人分配床位」的核心方法用事务保证床位状态和住院记录同时成功public boolean admitPatient(int patientId, int bedId, int doctorId) { String insertAdm INSERT INTO admission(patient_id, bed_id, doctor_id) VALUES(?,?,?); String updateBed UPDATE bed SET status1 WHERE bed_id? AND status0; Connection conn null; try { conn DBUtil.getConn(); conn.setAutoCommit(false); // 开启事务 try (PreparedStatement ps1 conn.prepareStatement(updateBed)) { ps1.setInt(1, bedId); if (ps1.executeUpdate() 0) { // 床位已被占用 conn.rollback(); return false; } } try (PreparedStatement ps2 conn.prepareStatement(insertAdm)) { ps2.setInt(1, patientId); ps2.setInt(2, bedId); ps2.setInt(3, doctorId); ps2.executeUpdate(); } conn.commit(); return true; } catch (SQLException e) { try { if (conn ! null) conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } e.printStackTrace(); return false; } finally { try { if (conn ! null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }逻辑说明UPDATE bed ... AND status0这个条件很关键它利用数据库的行锁保证并发下不会两个请求抢到同一张床返回影响行数为 0 就说明床位已被占直接回滚。参数上setAutoCommit(false)是事务起点commit和rollback必须成对出现finally里关连接防止泄漏。3.2 事务边界和连接池怎么选上面那段代码把「改床位状态」和「插住院记录」放在一个事务里这是对的。但很多人会把查询也塞进事务导致事务过长、锁等待。原则是只把写操作放进事务查询单独走连接。连接池方面课设数据量小用HikariCP就够配置也简单HikariConfig config new HikariConfig(); config.setJdbcUrl(DBUtil.URL); config.setUsername(root); config.setPassword(your_password); config.setMaximumPoolSize(10); // 最大连接数 config.setMinimumIdle(2); // 最小空闲连接 config.setConnectionTimeout(3000); // 获取连接超时3秒 HikariDataSource ds new HikariDataSource(config);参数说明maximumPoolSize按并发量设课设 10 足够connectionTimeout设 3 秒避免连接不上时线程一直卡住。如果不用连接池每次DriverManager.getConnection都新建物理连接几十次请求后数据库就扛不住了这是课设演示时卡顿的常见原因。3.3 出院结算的 SQL 怎么写出院操作要把admission的discharge_time填上同时把床位状态改回空闲同样用事务-- 出院更新住院记录 UPDATE admission SET discharge_time NOW() WHERE admission_id ? AND discharge_time IS NULL; -- 释放床位 UPDATE bed SET status 0 WHERE bed_id (SELECT bed_id FROM admission WHERE admission_id ?);逻辑说明discharge_time IS NULL这个条件防止重复出院第二条 SQL 用子查询拿到床位号再释放。注意 MySQL 不允许在UPDATE的子查询里直接查同一张表如果报错就拆成两条语句在 Java 里先查后改。参数上NOW()用数据库时间而不是 Java 时间避免客户端时区不一致。4. 避坑与排查课设演示前必须过的五道坎这一章是我带课设时学生问得最多的五类问题每条按「现象 → 原因 → 解决」写演示前照着过一遍能省下大量返工时间。4.1 中文乱码查出来全是问号现象Java 控制台或页面显示的病人姓名是???。原因建表字符集、连接串字符集、JDBC 驱动三者不一致。解决建表用utf8mb4连接串加characterEncodingutf8MySQL 8 驱动用com.mysql.cj.jdbc.Driver。三处对齐后重启应用即可。4.2 外键报错Cannot add or update a child row现象插入住院记录时报外键约束失败。原因patient_id、bed_id或doctor_id在主表里不存在或者插入顺序错了。解决先插主表数据再插admission检查 Java 传进来的 ID 是不是 0 或 null。演示前用SELECT确认三个 ID 都真实存在。4.3 时区错误The server time zone value is unrecognized现象连接数据库直接抛异常连不上。原因MySQL 8 默认时区和 JDBC 驱动不匹配。解决连接串加serverTimezoneAsia/Shanghai或者数据库执行SET GLOBAL time_zone 8:00。这是最高频的启动失败原因没有之一。4.4 床位重复分配两个病人住同一张床现象并发测试时同一床位出现两条未出院记录。原因只查了status没加锁或者事务隔离级别不够。解决用 3.1 里UPDATE ... AND status0的写法靠数据库行锁兜底或者给admission加唯一索引UNIQUE(bed_id, discharge_time)做最后防线。4.5 连接泄漏跑一会儿就卡死现象系统运行几分钟后所有请求超时。原因Connection、Statement、ResultSet没关连接池被占满。解决用 try-with-resources 自动关闭或者finally里显式close()。检查方法数据库执行SHOW PROCESSLIST看有没有大量Sleep状态的连接堆积。5. 让课设拿高分从能跑到能讲清楚设计取舍课设演示不只是「能跑」老师更想看你能不能讲清楚为什么这么设计。这一章给几个进阶技巧帮你在答辩时把方案讲出深度。第一个技巧是准备一份「设计取舍对照表」把关键决策和替代方案列出来。比如床位状态为什么用TINYINT而不是布尔为什么用外键而不是应用层校验为什么事务只包写操作。下面这张表可以直接放进实验报告设计点本方案选择替代方案取舍理由床位状态存储bed.status字段由admission推导字段查询快但需事务保证一致主键类型自增 INTUUID自增省空间、索引友好课设够用字符集utf8mb4utf8utf8mb4 支持 emoji 和生僻字事务范围只包写操作包所有操作缩短事务减少锁等待第二个技巧是加一个「床位占用率」统计查询答辩时现场跑体现你会用聚合和分组SELECT w.ward_no, COUNT(b.bed_id) AS total, SUM(CASE WHEN b.status 1 THEN 1 ELSE 0 END) AS used, ROUND(SUM(CASE WHEN b.status 1 THEN 1 ELSE 0 END) / COUNT(b.bed_id) * 100, 2) AS rate FROM ward w JOIN bed b ON w.ward_id b.ward_id GROUP BY w.ward_no;逻辑说明CASE WHEN把占用床位映射成 1 再求和除以总数得到占用率ROUND保留两位小数。参数上GROUP BY的字段必须出现在SELECT里除非用聚合函数这是 SQL 标准要求。第三个技巧是准备一个「异常演示」环节。故意让床位分配失败一次展示事务回滚后数据没脏。老师看到你能主动演示异常处理印象分直接拉满。我自己的习惯是演示前把数据库备份一份跑完异常演示立刻恢复保证后续流程干净。最后说个我踩过的坑别在答辩前一天才改表结构。改表意味着所有 Java 代码、实验报告里的 ER 图、截图全要重来。定稿后只加数据不改结构这是最稳的节奏。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询