Java数据库课程设计实战:从JDBC到事务处理完整指南
发布时间:2026/10/1 3:54:22来源:尧图网络
简介数据库课程设计完整版文档以学生成绩管理系统为实战主题面向需要完成数据库课程设计、巩固Java编程与数据库理论的高校学生。文档从课程设计目的与需求分析切入系统梳理数据流图与数据字典随后展开数据库概念结构设计E-R图和逻辑结构设计表结构与功能结构图并给出系统实施运行结果与总结末附完整源代码清晰还原大学学籍管理系统的构建全过程。系统涵盖学生、教师、管理员三类角色支持登录、密码修改、个人信息查看、成绩录入与查询、用户增删改查等模块同时提供用户表、学生学籍表、成绩表、教师表等核心数据表定义可作为课程设计报告撰写、数据库建模以及Java连接数据库操作的直接参考。资源为单个doc文档压缩包大小269KB已有330人浏览学习适合正在准备数据库课程设计或复习相关知识点的读者。1. 数据库与Java的课程设计拿到这份.doc你到底要交什么很多同学在交作业前搜“数据库-Java课程设计完整版.doc”以为改名提交就完事。其实这份doc只是别人把“数据库设计Java源码操作说明”打包后的一个索引真正重要的是里面那套可复现的流程从建库建表到增删改查每一步都要能讲清楚。文章里我会从一线工程师的角度把这个方向拆成一串标准动作做什么题目、怎么建表、怎么写DAO、哪些坑必须避开最后怎么让答辩老师愿意给高分。适合正准备数据库/Java课程设计、或者想快速补上项目经验的新手也适合想把自己代码整理成文档的老手。2. 拆需求与技术选型课程设计不是“写代码”是“答得上问”2.1 先用最小闭环的增删改查定住业务范围课程设计评分看的是完整度不是复杂度。一个图书管理系统、学生信息管理、超市商品进销存都是经久不衰的选题。原因很简单它们都能用一张主表加一张关联表完成最核心的增删改查又能引出外键、事务这类必考知识点。我一般拿到题目先写一句话系统管什么数据、谁在用、操作后产生什么变化。然后把这句话拆成功能清单。以“图书借阅管理”为例清单就三行图书新增、修改、删除、按书名/作者查询。读者新增、修改、删除、查借阅历史。借书/还书关联读者和图书记录借出日期、应还日期。这三行就是整个课程设计的“需求边界”。再往多加权限、分类、统计报表都可以做但必须先把最小闭环跑通。你给答辩老师演示的时候先走一遍“新增读者→新增图书→借书→还书→再查一下借阅记录”老师心里已经有底了。注意做需求拆解时不要把自己绕进大而全的功能里。我见过一个小组选了“高校教务系统”光角色就搞了四种最后一个月连登录都做得半吊子。课程设计的时间只够做一条清晰的主线主线之外的都算加分项不是必选项。把“核心CRUD”写进开题报告比写十个含糊的功能点更有说服力。2.2 技术栈选型JDBC DAO 保底ORM 当亮点别一上来就全家桶现在Java做数据库操作的常见路线有三条纯JDBC、JDBCDAO封装、MyBatis/JPA这类ORM。课程设计阶段我强烈建议用“JDBC 手写DAO”当保底方案。理由很实际纯JDBC能让你把Connection、Statement、ResultSet、事务的提交回滚都讲明白这些是面试里反复问的“数据库基础”而直接上MyBatis虽然代码少一半但很多同学连SqlSessionFactory怎么创建都说不清答辩时反而被问穿。技术对比说穿了就一句话JDBC是Java访问数据库的基本能力ORM是外包了SQL生成的脚手架。课程设计如果想要“亮点”又不丢基础可以在保底方案上加一个Druid连接池再用DBUtils简化ResultSet的转换。不过前提是你心里清楚JDBC自己做要经历哪几步否则亮点会变成翻车点。下面是一个最小的Maven依赖片段我一般会把JDBC驱动、连接池和JUnit一起放进pom.xml避免后面测试时到处找jardependencies dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version scoperuntime/scope /dependency dependency groupIdcom.alibaba/groupId artifactIddruid/artifactId version1.2.22/version /dependency dependency groupIdjunit/groupId artifactIdjunit/artifactId version4.13.2/version scopetest/scope /dependency /dependencies这段依赖的三个作用mysql-connector-java 是驱动负责把Java的JDBC调用转成MySQL协议Druid提供连接池避免每次操作都新建物理连接JUnit让你在写DAO之前先测通“连库-查一条数据”这个最简单的动作。注意版本不是越新越好。mysql-connector-java 8.x对应MySQL 5.7/8.0都能用但com.mysql.jdbc.Driver这个旧驱动类名在8.x里已经变成com.mysql.cj.jdbc.Driver。很多同学的连接失败不是密码错是驱动类名写成了老版本。这里要按你本地MySQL版本选驱动别随手复制网上的连接串。连接URL里有个关键参数第一次写的时候要注意jdbc:mysql://localhost:3306/library?useUnicodetruecharacterEncodingUTF-8useSSLfalseserverTimezoneAsia/Shanghai这个字符串里useUnicode和characterEncoding解决中文字符乱码useSSLfalse关闭本地开发时的SSL握手干扰serverTimezone指定时区否则Java 8以后的驱动会报时间类型错误。每个参数都能在答辩时被问到哪怕只记住中文乱码和时区这两条也比照着抄有底。如果还是纠结选型可以看这个对比表我把常见方案按答辩风险和工作量排了序方案工作量答辩风险适合场景纯JDBC大中容易暴露连接管理细节想展示基础原理JDBCDAO中低每层职责清楚课程设计保底MyBatisSpring小高必须能解释框架原理憋大招或毕设课程设计不是公司项目评分的权重里“你说的清楚”远大于“功能多”。选保底方案把精力留给数据库设计和事务才是性价比最高的做法。2.3 把功能清单纯化成验收清单让老师十分钟看到全貌需求拆解之后我习惯再画一张“验收清单”表格放进报告的开头。表格的作用不是给代码加注释而是让老师快速知道你做了什么、没做什么。比如编号功能点涉及表是否必做验证方式1图书新增book必做插入后列表出现2图书删除book, borrow必做无借阅记录时可删3借书book, borrow必做库存减一生成借阅记录4还书borrow必做更新return_date5未还列表borrow, reader加分按return_date is null过滤这个清单还能防止你自己做歪了。很多人写着写着就在查询里加了各种花活回头一看核心增删改查反而没走通。有验收清单在每完成一项就勾一项心里有数。3. 数据库设计落地从ER图到一份能交差的建表SQL3.1 以图书管理系统为例三张表把关系说清楚数据库设计是课程设计的重头。评分标准里概念设计ER图、逻辑设计表结构和数据字典通常占30%以上。别把建表SQL当成最后一步应该先把表关系画出来。图书借阅管理最简模型是“读者借图书”的多对多关系需要用一张借阅记录表破开。book存图书信息主键book_id还有书名、作者、价格、库存。reader存读者信息主键reader_id包括姓名、学号/工号、电话。borrow借阅记录主键borrow_id外键book_id、reader_id加上借书日期和还书日期。这三张表的关系一句话一本书可以被多个读者借一个读者可以借多本书一对多和多对一中间靠borrow表承接。设计时要注意借阅记录里不该存冗余的图书价格和读者姓名只存外键ID需要显示时用JOIN查出来。这是数据库设计的基本原则老师一眼就能看出你有没有概念。3.2 建表SQL主键、外键、索引和默认值一次配齐下面这段SQL是我常用的一版在MySQL 8.0下可以直接跑CREATE DATABASE IF NOT EXISTS library DEFAULT CHARSET utf8mb4; USE library; CREATE TABLE book ( book_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 图书ID, book_name VARCHAR(100) NOT NULL COMMENT 书名, author VARCHAR(50) NOT NULL COMMENT 作者, price DECIMAL(10,2) NOT NULL DEFAULT 0 COMMENT 价格, stock INT NOT NULL DEFAULT 1 COMMENT 当前库存, created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 入库时间 ) ENGINEInnoDB COMMENT图书表; CREATE TABLE reader ( reader_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 读者ID, reader_no VARCHAR(20) NOT NULL UNIQUE COMMENT 学号/工号, reader_name VARCHAR(30) NOT NULL COMMENT 姓名, phone VARCHAR(11) COMMENT 手机号 ) ENGINEInnoDB COMMENT读者表; CREATE TABLE borrow ( borrow_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 借阅ID, book_id INT NOT NULL COMMENT 图书ID, reader_id INT NOT NULL COMMENT 读者ID, borrow_date DATE NOT NULL COMMENT 借书日期, return_date DATE DEFAULT NULL COMMENT 还书日期, CONSTRAINT fk_borrow_book FOREIGN KEY (book_id) REFERENCES book(book_id), CONSTRAINT fk_borrow_reader FOREIGN KEY (reader_id) REFERENCES reader(reader_id), INDEX idx_borrow_reader (reader_id), INDEX idx_borrow_book (book_id) ) ENGINEInnoDB COMMENT借阅表;这里的几个设计选择值得解释。VARCHAR用100而不是255是告诉老师你了解字段长度对索引的影响DECIMAL而不是FLOAT存金额是为了避免浮点误差TIMESTAMP默认值可以让插入时少写一个字段FOREIGN KEY保证借阅记录不会指向不存在的书或读者。INDEX on外键是因为外键列常用于JOIN查询和WHERE过滤不加索引在这个数据量下也能跑但加了在答辩时能答出“为了级联查找性能”。关于字符集我用utf8mb4而不是utf8因为utf8mb4是MySQL对完整Unicode支持的字符集能存emoji和生僻字。课程设计虽然不一定用到但如果你用Navicat之类的工具导数据时遇到中文乱码多半是这里不一致。建库时最好统一字符集后续所有表都继承避免一张表一个编码的尴尬。3.3 测试数据一份干净的insert胜过临场瞎点很多同学写完建表后直接开写Java这是反的。应该先插入几条代表性数据把查询逻辑在SQL工具Navicat/DataGrip/DBeaver里验证一遍再回到Java里写代码。这样出问题时能确定是SQL的问题还是Java的问题。INSERT INTO book(book_name, author, price, stock) VALUES (Java核心技术, Cay S. Horstmann, 149.00, 10), (数据库系统概论, 王珊, 49.50, 5), (重构, Martin Fowler, 92.00, 3); INSERT INTO reader(reader_no, reader_name, phone) VALUES (2024001, 张伟, 13800000001), (2024002, 李娜, 13800000002), (2024003, 王芳, 13800000003); INSERT INTO borrow(book_id, reader_id, borrow_date, return_date) VALUES (1, 1, 2024-11-01, NULL), (1, 2, 2024-11-02, 2024-11-10), (2, 3, 2024-11-03, NULL);这份数据里特意设置了几个边界情况有一条读者1未还书return_date为NULL有一条读者2已还还有读者3借的是第二本。将来在Java里写“查询当前未归还的借阅记录”时就能用WHERE return_date IS NULL来覆盖这是课程设计最常见的查询类型。测试数据还有个讲究自增主键不要显式指定让MySQL自动生成外键值一定要在父表里存在否则InnoDB会报外键约束错误。如果你在图形工具里手工插数据遇到“cannot add or update a child row”先查父表里有没有对应ID别怀疑工具。3.4 视图和存储过程要不要加给报告找个可答的加分项很多课程设计范例会在数据库设计里加入视图或存储过程。我的建议是不加则已加就要能几句话讲清用途。视图适合用来展示“当前未归还的借阅明细”因为它把三表JOIN的复杂查询封装成一个虚拟表存储过程适合演示“还书时更新库存”的一串操作。这些知识点在数据库课程里讲过写在报告里能加分。但要注意别贪多。如果老师问“存储过程和Java里的Service层事务有什么区别”答不上来反而扣分。我的习惯是视图可以加一个存储过程如果时间紧张就放弃。把“借书-扣库存”的事务用Java代码讲明白效果不差于存储过程。4. Java代码实现连接池、DAO与CRUD跑通一条完整链路4.1 从驱动加载到连接池别再每个方法里new Connection课程设计最常见的幼稚写法是在每个方法里Class.forName、DriverManager.getConnection、最后conn.close。代码跑得通但有一个致命问题每次数据库操作都建立和销毁物理连接在高并发下会拖垮数据库面试时也过不了关。常见的工程做法是用连接池Druid/HikariCP都可以课程设计用Druid更多因为配置直观、自带监控页面。下面是一个最简单的JdbcUtil用Druid连接池代替手动获取连接package com.example.library.util; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.InputStream; import java.util.Properties; public class JdbcUtil { private static DataSource dataSource; static { try (InputStream in JdbcUtil.class.getClassLoader() .getResourceAsStream(druid.properties)) { Properties props new Properties(); props.load(in); dataSource DruidDataSourceFactory.createDataSource(props); } catch (Exception e) { throw new ExceptionInInitializerError(连接池初始化失败: e.getMessage()); } } public static DataSource getDataSource() { return dataSource; } }然后在resource目录放一个druid.propertiesdriverClassNamecom.mysql.cj.jdbc.Driver urljdbc:mysql://localhost:3306/library?useUnicodetruecharacterEncodingUTF-8useSSLfalseserverTimezoneAsia/Shanghai usernameroot password123456 initialSize3 maxActive10 maxWait3000这段配置里initialSize是池子启动时创建的连接数maxActive是最大连接数maxWait是拿不到连接时的等待毫秒数。课程设计规模很小initialSize3、maxActive10就够不要写成100否则本地MySQL会报too many connections。注意druid.properties里的driverClassName也是8.x驱动要写com.mysql.cj.jdbc.Driver别和旧版混。password是你本机MySQL的实际密码不要原样抄。如果改用HikariCP配置项名字会略有不同但思路一样。4.2 DAO层与PreparedStatement为什么你的SQL会报错或被注入有了连接下一步是写DAO。以BookDAO为例最核心的方法是insert、update、delete、selectAll和selectById。这里必须使用PreparedStatement而不是Statement原因有两点一是预编译能减少SQL解析开销虽然单条插入不明显二是参数用占位符绑定不会出现拼接字符串导致的单引号问题也就是防SQL注入。答辩老师如果问“为什么不用Statement”你能回答PreparedStatement防止注入这就是基础分。先看一个完整的BookDAOpackage com.example.library.dao; import com.example.library.entity.Book; import com.example.library.util.JdbcUtil; import java.sql.*; import java.util.ArrayList; import java.util.List; public class BookDAO { public int insert(Book book) { String sql INSERT INTO book(book_name, author, price, stock) VALUES(?,?,?,?); try (Connection conn JdbcUtil.getDataSource().getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, book.getBookName()); ps.setString(2, book.getAuthor()); ps.setBigDecimal(3, book.getPrice()); ps.setInt(4, book.getStock()); return ps.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(新增图书失败, e); } } public ListBook selectList(String keyword) { String sql SELECT book_id, book_name, author, price, stock FROM book WHERE book_name LIKE ? OR author LIKE ?; ListBook list new ArrayList(); try (Connection conn JdbcUtil.getDataSource().getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { String pattern % keyword %; ps.setString(1, pattern); ps.setString(2, pattern); try (ResultSet rs ps.executeQuery()) { while (rs.next()) { Book b new Book(); b.setBookId(rs.getInt(book_id)); b.setBookName(rs.getString(book_name)); b.setAuthor(rs.getString(author)); b.setPrice(rs.getBigDecimal(price)); b.setStock(rs.getInt(stock)); list.add(b); } } } catch (SQLException e) { throw new RuntimeException(查询图书失败, e); } return list; } public int deleteById(int id) { String sql DELETE FROM book WHERE book_id ?; try (Connection conn JdbcUtil.getDataSource().getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, id); return ps.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(删除图书失败, e); } } }这个DAO有三个值得抄作业的点。第一try-with-resources让connection和statement自动关闭即使SQL执行出错也不会泄漏连接。第二PreparedStatement的setXxx方法根据字段类型选择setString/setBigDecimal/setInt类型不匹配会在执行前报错比等数据库报错更早。第三selectList里的LIKE查询参数直接传“%” keyword “%”不要在SQL里写%?%那样?会被当成字符串字面量查不出任何数据。参数大小写方法名insert、selectList、deleteById是常见命名。注意Book实体的字段类型要与表字段一一对应比如价格用BigDecimal日期用LocalDate或java.util.Date不要所有数字都填int。实体的代码很简单因篇幅就不贴了但建议在设计报告里把实体字段和数据字典对应起来方便老师比对。4.3 业务层与事务借书不是一条insert而是一串必须同时成功的操作课程设计里最能体现数据库知识的地方就在业务层。以“借书”为例光在borrow表里插一条记录不算完整还要做一件事把book表里的stock减1。这两步必须同时成功或同时失败否则会出现库存没减但借阅记录存在的数据脏乱。这就是事务。下面是一个简单的事务控制方法不借助Spring用手动commit/rollback演示原理public boolean borrowBook(int bookId, int readerId, LocalDate borrowDate) { String updateStock UPDATE book SET stock stock - 1 WHERE book_id ? AND stock 0; String insertBorrow INSERT INTO borrow(book_id, reader_id, borrow_date, return_date) VALUES(?,?,?,?); Connection conn null; try { conn JdbcUtil.getDataSource().getConnection(); conn.setAutoCommit(false); try (PreparedStatement ps1 conn.prepareStatement(updateStock)) { ps1.setInt(1, bookId); if (ps1.executeUpdate() 0) { conn.rollback(); return false; } } try (PreparedStatement ps2 conn.prepareStatement(insertBorrow)) { ps2.setInt(1, bookId); ps2.setInt(2, readerId); ps2.setDate(3, Date.valueOf(borrowDate)); ps2.executeUpdate(); } conn.commit(); return true; } catch (SQLException e) { if (conn ! null) { try { conn.rollback(); } catch (SQLException ignored) { } } throw new RuntimeException(借书失败事务已回滚, e); } finally { if (conn ! null) { try { conn.setAutoCommit(true); conn.close(); } catch (SQLException ignored) { } } } }这段代码的关键是conn.setAutoCommit(false)之后所有SQL都处于同一个事务里直到commit或rollback才结束。update语句里加了AND stock 0意思是如果库存已经为0执行影响行数为0这时候借书操作在该方法内返回false不会继续插入借书记录。finally里把自动提交恢复为true再关闭连接是为了确保连接回到连接池时是干净状态避免下次使用还带着一个未提交事务。这个“两步操作事务”的模式就是课程设计报告里“业务逻辑设计”一节的素材。写报告时你可以画一个简单的判断图检查库存-扣减库存-插入记录-提交任何一步失败则回滚。老师看到这个就知道你理解了事务的ACID。4.4 用一个JUnit测试把CRUD串起来界面还没写的时候怎么验证DAO层没问题我习惯在写完DAO后写一个JUnit测试直接打真实数据库跑一遍。测试类长这样public class BookDAOTest { Test public void testInsertAndQuery() { Book book new Book(); book.setBookName(测试书); book.setAuthor(作者); book.setPrice(new BigDecimal(30)); book.setStock(2); BookDAO dao new BookDAO(); int rows dao.insert(book); Assert.assertEquals(1, rows); ListBook list dao.selectList(测试); Assert.assertFalse(list.isEmpty()); Assert.assertEquals(测试书, list.get(0).getBookName()); } }注意这个测试依赖真实数据库跑之前必须先把init.sql执行过而且连接池配置里的数据库名和账号密码正确。如果你用的是JUnit 4测试方法要加Test如果你被老师要求用JUnit 5import要从org.junit.jupiter.api包引入断言类也略有不同。这个小测试最大的价值是验证“环境通没通”如果测试通过说明驱动、连接池、建表、DAO全链路都没问题后面写界面就只剩UI的事。5. 课程设计避坑指南5个让答辩翻车的细节5.1 驱动类找不到这种翻车八成是依赖没进classpath现象运行main方法直接报ClassNotFoundException: com.mysql.cj.jdbc.Driver或者No suitable driver found。原因如果用了Maven依赖作用域是runtime却在编译时没有把驱动加到运行时classpath如果用了普通工程mysql-connector-java.jar根本没有放到lib目录。另外驱动类名写错也会报这个错比如8.x驱动用com.mysql.jdbc.Driver可能不报编译错但运行时找不到。解决先把pom.xml清理干净确保mysql-connector-java没写成provided普通工程把jar放进WEB-INF/lib或项目lib目录并右键Add as Library。再检查类名MySQL 5.x用com.mysql.jdbc.Driver8.x用com.mysql.cj.jdbc.Driver。最稳的办法是在JdbcUtil静态块里先Class.forName(driverClassName)加载一次失败时能看到是jar缺失还是类名错误。5.2 中文乱码从Excel复制进库就变问号原因不在Java而在链路上现象在Java插入中文后查询出来是??或者表里能显示但控制台打印乱码。原因中文乱码是“客户端字符集→JDBC URL→数据库表字符集”整条链路的任一环节不一致造成的。常见的组合是URL里少了characterEncodingUTF-8数据库默认字符集是latin1或者插入数据时用了直接拼SQL而不是PreparedStatement。解决统一三个地方。建库时用DEFAULT CHARSET utf8mb4JDBC URL加useUnicodetruecharacterEncodingUTF-8如果从外部文件导入先检查文件编码是不是UTF-8。另外MySQL 8.0默认字符集虽然是utf8mb4但连接层还是可能被驱动参数影响所以URL里的参数别删。这个坑我至少填了三回每次都是新建表时没注意继承父数据库的字符集。5.3 明明没报错数据却没插入自动提交被关了现象执行executeUpdate返回1但去Navicat里看表没有新记录。再执行一次当主键自增跳了几号说明insert其实执行过只是被回滚了。原因连接池的Connection可能被上一段代码设置过autoCommit(false)并且没有在finally里恢复。虽然手动事务代码里用try-with-resources关闭了Statement但Conn返回连接池时把autoCommit状态保留了下一个人拿到这条连接执行insert后不commit数据就不会落库。解决在事务方法的finally里除了close还要conn.setAutoCommit(true)更保险的方法是每次拿连接时检查连接状态或用Druid连接池的配置项配置。也可以写一个简单过滤器拦截所有查询但课程设计用不着记住“谁改自动提交谁负责恢复”就好。5.4 删除父表记录失败外键约束成了“绊脚石”现象想删除一本书结果报Cannot delete or update a parent row: a foreign key constraint fails。有的同学直接把外键删掉来“解决”。原因borrow表通过外键引用了book表只要存在借阅记录直接删父表记录就会被InnoDB拦截。这是外键的默认行为它保护数据完整性。直接删外键等于放弃了数据库设计里最重要的知识点答辩时是送分变送命。解决有两种合理做法。第一种先删除子表里对应的borrow记录再删除book第二种给外键加ON DELETE CASCADE让删除父表记录时自动清掉子表引用。但要注意CASCADE在课程设计系统里可能太危险比如删一本被借出去的书会连历史借阅记录一起删。我一般推荐“先删子表再删父表”或者在DAO里用逻辑删除给book加deleted字段并把选择逻辑在报告里写清楚。5.5 时间类型映射混乱Date和LocalDate的转换踩坑现象从ResultSet里getDate(borrow_date)后赋给LocalDate编译报错或者在Java里setObject传LocalDateTime数据库报类型转换错误。原因java.sql.Date是java.util.Date的子类用于SQL层LocalDate是Java 8时间类型两者不能直接互转。JDBC 4.2之后setObject(4, localDate)理论上可以支持LocalDate但不同数据库驱动实现有差异MySQL 8.x驱动支持5.x驱动不一定支持。解决最稳的方式是显式转换读出来用rs.getDate(borrow_date).toLocalDate()插入用Date.valueOf(borrowDate)。如果字段带时间用Timestamp.valueOf(LocalDateTime.atStartOfDay())。另外实体里的日期字段一律用LocalDate/LocalDateTime不要为了省事用String否则排序和范围查询都会出问题。6. 从“能跑”到“高分”三个交付技巧和我的文档习惯6.1 用一份README把复现路径写清楚不管老师要不要我都建议在项目根目录放一个README.md记录环境版本、建库步骤、启动命令、测试账号。这不是给老师看的是给自己留的后悔药——两周后再打开代码不用从头推。可以用一个小代码块- 环境JDK 17、MySQL 8.0、Maven 3.8 - 建库执行 sql/init.sql - 运行mvn clean package 后启动 Main - 账号admin / 1234566.2 答辩前把演示脚本背熟别让老师看翻车老师问你项目有什么功能不要打开代码现找。准备一条演示路线登录→添加一本测试书→查询→借书→还书→查库存。每个操作旁边准备一句“这里我用了PreparedStatement防注入”“这里我用了事务保证库存一致”。这是加分的核心。我见过太多项目代码没问题结果现场输入中文乱码、删除时报外键错误这种翻车完全可以靠提前走一遍脚本避免。6.3 数据库设计文档里加一张数据字典表我的习惯是给每张表做一张字段说明表列出字段名、类型、长度、是否主键、是否外键、注释。这件事花不了半小时但能让老师第一眼觉得你专业。可以用一个简表字段名类型说明约束book_idINT图书ID主键自增book_nameVARCHAR(100)书名非空stockINT库存非空默认1最后说个我个人踩过无数次、现在变成习惯的规则一切以“能复现”为准。报告里的SQL要自己跑过代码里的连接池参数要按实际环境写README里别写别人机器上没有的路径。这样哪怕功能朴素老师也能看到你训练过工程交付的痕迹。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网