简介:这是一份基于Java与SQL Server的简易图书馆管理系统课程设计资源,专门面向计算机相关专业正在准备数据库课程设计的学生,也适合入门级Java开发人员用于学习项目整合。系统围绕图书馆日常业务,完整实现了图书信息录入与修改、读者信息管理、借书还书流程、登录验证以及选座管理等功能模块,并附带可直接执行的编译版本,大幅降低环境搭建门槛。资源包共127个文件,核心为java源文件和class编译文件,同时包含jar依赖库、SQL建库脚本、png与jpg界面截图、xlsx及xls表格数据,压缩后仅1.43MB,目录层次清晰,方便按需查看和迁移部署。已有2386人学习下载,对于需要快速搭建数据库课设、理解Swing界面与SQL Server联动、或在此基础上扩展功能的同学来说,是一份很实用的参考模板。
1. 这题目年年有人选,翻车也年年一样
每次到数据库课设季节,“图书馆管理系统”一定是最热门的题目。表面看它只是图书增删改查加个借还书,实际上一半人挂在同一个地方:Java连不上SQL Server。不是代码写错,而是驱动、实例名、认证方式、TCP/IP协议这几个环节里某个黑匣子没打开,最后整组人默默换回MySQL或Access交差。本文将基于Java和SQL Server数据库,把一个简易图书馆管理系统怎么做讲透。适合正在做课设、想从JDBC层面理解数据库连接的同学,也适合想快速搭一套能答辩的最小系统的读者。你会拿到建表SQL、连接代码、借还书事务和五条踩坑记录,照着搭,一天能跑通。
2. 数据库设计先行:五张表怎么撑起借还书闭环
2.1 简易不等于随便建表,业务线要先分清楚
很多课设拿到题目第一反应是建一张“图书表”再说,结果做到借书功能时发现缺读者表,做到统计时发现缺分类表,来回改结构。我一般先画三条业务线:谁在借(读者)、借什么(图书)、什么时候借还(借阅记录),再加一个管理员账号做登录入口,分类表用于图书筛选和统计。简易系统最少五张表:admin、readers、books、categories、borrow。别小看这五张表,它能支撑登录、图书管理、读者管理、借书还书、逾期统计这几个课设必问的功能。
表与表的关系也直接决定后面代码难度。readers和books之间是多对多,借阅记录表borrow就是它们的关联表,每本书当前是否在馆、被谁借走、什么时候该还,都在borrow里查。管理员和读者分开建表是安全习惯,我见过把管理员塞进读者表再用role字段区分的,答辩时评委一句“权限如何控制”就答得支支吾吾。分开表之后,登录逻辑只需要查一张表,职责清楚。
2.2 建表SQL:把约束写在数据库里,别只靠Java判断
下面是建库建表的SQL,SQL Server 2019 Express即可运行。课程设计不需要企业版,Express完全够用,注意Express默认实例名是SQLEXPRESS,连接串里会用到,这是后话。
-- 创建数据库 CREATE DATABASE LibraryDB; GO USE LibraryDB; GO -- 管理员表 CREATE TABLE admin ( admin_id INT IDENTITY(1,1) PRIMARY KEY, username VARCHAR(30) NOT NULL UNIQUE, password VARCHAR(64) NOT NULL ); GO -- 读者表 CREATE TABLE readers ( reader_id INT IDENTITY(10001,1) PRIMARY KEY, name VARCHAR(30) NOT NULL, phone VARCHAR(20), max_borrow INT DEFAULT 5 ); GO -- 分类表 CREATE TABLE categories ( category_id INT IDENTITY(1,1) PRIMARY KEY, category_name VARCHAR(50) NOT NULL ); GO -- 图书表 CREATE TABLE books ( book_id INT IDENTITY(1,1) PRIMARY KEY, title VARCHAR(100) NOT NULL, author VARCHAR(50), category_id INT, total INT DEFAULT 1, available INT DEFAULT 1, FOREIGN KEY (category_id) REFERENCES categories(category_id) ); GO -- 借阅记录表 CREATE TABLE borrow ( borrow_id INT IDENTITY(1,1) PRIMARY KEY, reader_id INT NOT NULL, book_id INT NOT NULL, borrow_date DATE DEFAULT CAST(GETDATE() AS DATE), due_date DATE, return_date DATE NULL, FOREIGN KEY (reader_id) REFERENCES readers(reader_id), FOREIGN KEY (book_id) REFERENCES books(book_id) ); GO建表的关键点有三个:第一,IDENTITY自增主键让Java端不用维护主键值,少一类并发冲突;第二,available字段代表可借数量,它是借书时判断能否借出的依据,比每次现算已借数量高效得多;第三,due_date不是随便算出来的,一般用DATEADD(DAY, 30, borrow_date)生成,下面会写。
2.3 借书还书的事务逻辑:先查后扣,任何一步失败都要回滚
借书看起来是往borrow表插一条记录,实际要动两张表:borrow增加记录,books的available减一。让Java代码用两条SQL循环完成不是不行,但并发一高就会超借。最稳妥的做法是把事务写进存储过程,数据库保证原子性。以下存储过程是课设答辩的加分项:
-- 借书存储过程 CREATE PROCEDURE usp_borrow_book @reader_id INT, @book_id INT AS BEGIN BEGIN TRANSACTION; BEGIN TRY DECLARE @avail INT; SELECT @avail = available FROM books WHERE book_id = @book_id; IF @avail <= 0 BEGIN RAISERROR('本书暂无可借数量', 16, 1); ROLLBACK TRANSACTION; RETURN; END; UPDATE books SET available = available - 1 WHERE book_id = @book_id; INSERT INTO borrow (reader_id, book_id, borrow_date, due_date) VALUES (@reader_id, @book_id, CAST(GETDATE() AS DATE), DATEADD(DAY, 30, CAST(GETDATE() AS DATE))); COMMIT TRANSACTION; END TRY BEGIN CATCH ROLLBACK TRANSACTION; THROW; END CATCH END GO这段存储过程的逻辑值得反复看。SELECT @avail = available是检查库存,小于等于零直接抛错回滚。更新库存和插入借阅记录放在同一事务里,任何一步失败都能退回原状。RAISERROR和THROW的区别要记一下:前者兼容旧版本,后者是SQL Server 2012以后推荐的异常抛出写法,错误信息能带中文直接显示在Java异常里,答辩时演示“借已借完的书报错”很能说明问题。
还书存储过程是逆操作,把return_date写当前日期,available加一。注意还书时不能盲目加一,太简单的写法可能导致一本书还两次、库存虚高,所以还书过程要校验return_date是否为空。这个细节写进存储过程,比Java端判断更可靠。
3. Java与SQL Server的连接:驱动、连接串、最小可跑通的代码
3.1 驱动选型:mssql-jdbc版本和JDK的匹配关系
Java连SQL Server,官方驱动有两条路线。一条是Microsoft的mssql-jdbc,从8.2到12.x版本还在更新;另一条是jTDS老古董,只支持到SQL Server 2008。课设用前者,最稳的版本是12.2.0.jre8或11.2.0.jre8,为什么强调jre8?因为很多课设电脑装的是JDK 8,用新版本驱动可能要求JDK 11以上,你代码没写错,启动却直接NoClassDefFoundError。捡麻烦最少的路走:JDK 8配mssql-jdbc-12.2.0.jre8.jar。Maven项目在pom里加微软仓库依赖,普通Eclipse课设直接下载jar丢进项目的lib目录,Build Path添加进去即可,代码完全一致。
驱动加载的经典代码只有一行,但面试和答辩常问:Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver")是在干嘛?简化说就是让驱动把自己注册到DriverManager里,JDBC 4之后这行其实可以省略,但写上能让老版本兼容性更好,也方便评眼看懂。我习惯保留它,代价可以忽略。
3.2 连接串参数的三个坑:实例名、TCP/IP协议、端口
连接串是课设翻车重灾区,常见写法:
String url = "jdbc:sqlserver://localhost:1433;databaseName=LibraryDB;encrypt=false;trustServerCertificate=true;"; String user = "sa"; String password = "你的密码"; Connection conn = DriverManager.getConnection(url, user, password);逐段说。localhost:1433是默认实例的地址端口;如果你安装时选了命名实例,比如SQLEXPRESS,则要写成localhost\\SQLEXPRESS:1433,反斜杠在Java字符串里要写成双反斜杠。这是SQL Server和MySQL最大的不同,MySQL一个端口一台机,SQL Server一台机可以跑多个实例,每个实例独立端口。很多人没装默认实例,装的是Express,然后照着网上的localhost:1433改都不用改,直接连接失败。
encrypt=false;trustServerCertificate=true这一段是最近几个驱动版本的必须项。SQL Server从2019开始驱动默认加密连接,而课设机器自签名证书未必受信任,不关加密就会报证书校验失败的SSL异常。这两个参数加上的顺序要放在databaseName后面,用分号隔开。另外sa密码如果提示“已过期”,多数是SQL Server密码策略强制90天更新,右键实例改密码或执行ALTER LOGIN sa WITH PASSWORD='新密码'即可。
还有个隐蔽问题:SQL Server 2019安装时默认可能没开启TCP/IP协议,连接串再对都白搭。检查方式是打开“SQL Server 配置管理器”,找到实例的“客户端协议”和“网络配置”,确保Named Pipes和TCP/IP都启用,然后重启SQL Server服务。这一步不做,网上的连接串抄一遍全报超时。这个配置不用改注册表,图形界面三分钟收工。
3.3 最小连通测试代码:跑通再往后写功能
写功能之前先写一个最简main方法做连通测试,避免把连接错误和业务代码混在一起排查。以下代码是每个课设的第一道关卡:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; public class DBConnection { public static Connection getConnection() throws SQLException { String url = "jdbc:sqlserver://localhost\\SQLEXPRESS:1433;databaseName=LibraryDB;encrypt=false;trustServerCertificate=true;"; Properties props = new Properties(); props.setProperty("user", "sa"); props.setProperty("password", "123456"); props.setProperty("loginTimeout", "10"); return DriverManager.getConnection(url, props); } public static void main(String[] args) { try (Connection conn = getConnection()) { System.out.println("数据库连接成功: " + conn.getCatalog()); } catch (SQLException e) { e.printStackTrace(); } } }这个测试类的三个要点:第一,loginTimeout=10写在Properties里,连接超时最多等10秒,而不是默认几十秒干瞪眼;第二,用try-with-resources把连接放在括号里,语法结束后自动关闭,课设代码不至于到处都是conn.close()还不一定执行得到;第三,打印conn.getCatalog()能直接验证当前连的是不是LibraryDB,很多人的连接串没写错,但手滑连到了master库,后续SQL全报对象名无效。测试通过后,其他类只需要调用DBConnection.getConnection()拿连接,整个项目的高层代码不感知驱动和URL细节,这是个好分层。
Properties传用户名密码还有一种替代写法是把user/password直接拼进URL,两种都对。我选Properties是因为密码里有特殊字符时URL容易写歧义,比如密码带&会被解析成分隔符。课设密码通常是123456这种简单密码,两种写法都行,但养成用Properties的习惯不亏。
4. 核心功能落地:登录、图书管理、借还书
4.1 登录模块:PreparedStatement是底线,Statement的注入问题必须知道
登录功能的SQL很多人这样写:SELECT * FROM admin WHERE username='admin' AND password='123',用Statement拼接字符串。课设系统演示没人攻击你,但答辩被问一句“SQL注入怎么防”答不上来很扣分。PreparedStatement在防注入和SQL缓存两方面都有优势,写起来也没多几行。以下是登录验证的标准写法:
public boolean login(String username, String password) { String sql = "SELECT password FROM admin WHERE username = ?"; try (Connection conn = DBConnection.getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) { ps.setString(1, username); try (ResultSet rs = ps.executeQuery()) { if (rs.next()) { return rs.getString("password").equals(password); } return false; } } catch (SQLException e) { e.printStackTrace(); return false; } }注意这里的细节:SQL里只查password这一列,不要SELECT *;用户参数用?占位,通过ps.setString()传入。PreparedStatement会把参数当普通字符串处理,用户名里再带引号、分号都不会被拼接成新SQL。还有一点值得留意,Java端应该比对的是哈希值而不是明文密码,但课设一般没做到那一步。如果想让代码有记忆点,可以在admin表存SHA-256哈希,登录时先把输入的密码哈希再比对。这个升级成本低,答辩却能多讲一分钟安全设计。
4.2 借书还书:Java调用存储过程,事务放在数据库里
上一章的存储过程在这里派上用场。Java端用CallableStatement调用它,比在Java里手动管理事务更清晰。以下是借书方法的完整代码:
public String borrowBook(int readerId, int bookId) { String sql = "{CALL usp_borrow_book(?, ?)}"; try (Connection conn = DBConnection.getConnection(); CallableStatement cs = conn.prepareCall(sql)) { cs.setInt(1, readerId); cs.setInt(2, bookId); cs.execute(); return "借书成功"; } catch (SQLException e) { // 存储过程抛出的中文错误信息会进到异常消息里 return "借书失败: " + e.getMessage(); } }这段代码很短,却把风险全堵住了。CALL语法是存储过程的标准调用格式,两个?对应存储过程的两个入参,出参和返回值在这里用不到就不声明。异常捕获为什么能拿到中文提示?因为SQL Server的RAISERROR消息经驱动传到Java后,会变成SQLException的message文本。我见过有的程序员收到异常后直接打印堆栈,用户看到一堆at开头的东西;这里返回用户可读的中文提示,才像个能用的系统。
还书方法与这个对称,区别是SQL变成{CALL usp_return_book(?, ?)},存储过程里判断记录是否存在且未归还。Java端不必再写UPDATE books SET available = available + 1这种SQL,数据库已经把细节管好了。存储过程中还要处理一个边界:同一个人借同一本书两本,可用数量不够时要报错。许多新手把“是否已借过”的判断放在Java里,先查记录再执行,这是典型的竞态窗口,并发时两次查询都在更新前执行,结果都认为可以借。放进存储过程后,SELECT ... WITH (UPDLOCK)或直接靠事务锁能挡住这种情况,课设不要求高并发,但设计意识要有。
4.3 图书查询和借阅列表:分页与联表查询
图书管理界面最常见的操作是书名搜索配分页列表。SQL Server分页有三种写法:OFFSET...FETCH、ROW_NUMBER()窗口函数、TOP加子查询。SQL Server 2012以后OFFSET...FETCH是标准写法,性能和可读性都好。以下代码是按书名模糊查询加分页:
public List<Book> searchBooks(String keyword, int page, int size) { String sql = "SELECT b.book_id, b.title, b.author, c.category_name, b.available, b.total " + "FROM books b JOIN categories c ON b.category_id = c.category_id " + "WHERE b.title LIKE ? " + "ORDER BY b.book_id " + "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; List<Book> books = new ArrayList<>(); try (Connection conn = DBConnection.getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) { ps.setString(1, "%" + keyword + "%"); ps.setInt(2, (page - 1) * size); ps.setInt(3, size); try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { books.add(new Book( rs.getInt("book_id"), rs.getString("title"), rs.getString("author"), rs.getString("category_name"), rs.getInt("available"), rs.getInt("total") )); } } } catch (SQLException e) { e.printStackTrace(); } return books; }这段代码值得拆开看两处。一是LIKE ?的占位符,参数在Java端拼好%关键词%传入,而不是SQL里写LIKE '%?%'——后者根本不会生效,因为?是参数占位符,不能嵌在引号里;二是我把category_id通过JOIN换成了category_name,这样前端直接显示分类名,不用二次查询。分页的OFFSET计算有个边界问题:page从1开始,(page-1)*size才是跳过的行数。如果你直接把前端传的page数字传给OFFSET,第一页数据会莫名其妙少几行。这个小问题我调试过一下午,后来养成了前端传page,后端减1的习惯。
借阅列表是一张联表视图更合适,避免每次查询都写三表JOIN:
CREATE VIEW v_borrow_info AS SELECT b.borrow_id, r.name AS reader_name, b.book_id, bk.title, b.borrow_date, b.due_date, b.return_date FROM borrow b JOIN readers r ON b.reader_id = r.reader_id JOIN books bk ON b.book_id = bk.book_id; GO视图在课设里是加分项,它让Java端查询变得像查单表一样简单:SELECT * FROM v_borrow_info WHERE return_date IS NULL。视图不占存储空间,只是一个虚拟表定义,答辩时被问“什么是视图”也好解释。如果你的课设要求里还有“热门图书统计”,基于视图再写一个GROUP BY查询就能出数据。
5. 避坑:课设里最常翻车的五个连接与数据问题
5.1 现象:连接超时或Access denied,原因不在密码而在TCP/IP协议未启用
我帮人排查的课设里,十台有六台卡在这一步。控制台报错是The TCP/IP connection to the host has failed,Java代码看起来和教程一模一样,sa密码也对,但就是连不上。打开SQL Server配置管理器一看,TCP/IP协议状态是禁用状态,而且协议列表里的“已启用”默认是“否”,很多人安装时一路Next没改。
解决步骤很固定:SQL Server配置管理器 → SQL Server网络配置 → 实例名协议 → 右键TCP/IP → 启用 → SQL Server服务右键重启。重启后可以用telnet测试,命令是telnet localhost 1433,看到光标不消失基本就是通了。另外Windows防火墙也可能拦1433端口,开发机能关防火墙就关,关不了就加一条入站规则放行1433。这个坑和代码无关,但一百篇博客里九十九篇没写,让你误以为是自己Java写错了。
5.2 现象:报SSL证书错误,原因在于驱动默认加密而证书不可信
新版本jdbc驱动连接SQL Server时会自动加密连接,默认验服务器证书。本机开发环境没有正确配置证书时,报错常见关键词是SQLServerException: The driver could not establish a secure connection或PKIX path building failed。用旧教程抄来的连接串在旧版本驱动上能跑,换了新驱动就打不开项目。
解决方式就是连接串加两个参数:encrypt=false;trustServerCertificate=true。第一个关掉加密,第二个即使启用了加密也信任自签名证书。课设环境两者加上即可。如果驱动版本太旧根本不认识这两个参数,别硬调,把驱动升级到11.x或12.x再跑。这是更新驱动带来的连锁问题,不是SQL Server配置错了。
5.3 现象:sa密码登录总提示过期或登录失败,原因在密码策略
SQL Server有强制密码过期策略,装完后sa密码默认有效期最多90天,到期后所有应用都连不上,日志里报“Login failed for user 'sa'。原因:必须更改密码”。另一个情况是安装时选了Windows身份验证模式,sa账户根本没启用,Java自然登不上。
解决方法是先用Windows身份验证进SSMS,执行以下SQL:
ALTER LOGIN sa ENABLE; GO ALTER LOGIN sa WITH PASSWORD = '123456'; GO ALTER LOGIN sa WITH CHECK_POLICY = OFF; GOCHECK_POLICY = OFF是关掉密码复杂性策略和过期策略,开发环境必要,生产环境别学。如果嫌这条麻烦,安装SQL Server时选“混合模式”并在下一步指定sa密码,能省一次折腾。在很多网上的安装教程里默认推荐“Windows身份验证”,Java连不上就卡在这了。
5.4 现象:事务日志暴涨,原因在简单模式没开,或删除操作太多
课设项目开发期会反复建表、清数据、恢复数据库,SQL Server默认的FULL恢复模式会不断累积事务日志,现象是sql server writelog相关日志多、数据库日志文件膨胀到几个GB甚至把C盘塞满。开发环境永远不需要恢复数据库到分钟级,改用简单模式即可:
ALTER DATABASE LibraryDB SET RECOVERY SIMPLE; GO DBCC SHRINKFILE (LibraryDB_log, 1);第一条把日志模式改为简单,已经不自动截断的旧日志靠第二条DBCC SHRINKFILE收回空间。shrinkfile后面的1是目标文件大小1MB,这个数字看你实际的日志文件大小来调整。另一层原因是循环测试借还书导致大量日志,无论怎样,简单模式一开,writelog相关的磁盘空间问题基本消失。答辩时提一句“开发环境用简单恢复模式减少日志开销”,评委知道这是懂行的。
5.5 现象:中文乱码或问号,原因在JDBC连接未设置字符编码
SQL Server的排序规则默认支持中文,但Java读取时涉及驱动和数据库之间的字符转码。如果控制台打印中文显示成???,或者写进数据库的中文变成乱码,多半是连接串缺编码参数。JDBC连接串里加characterEncoding=UTF-8不一定对SQL Server驱动生效,SQL Server驱动默认按数据库排序规则处理,常规做法是确保数据库排序规则是Chinese_PRC_CI_AS,并且代码中使用setString正常传入。
建库时可以在SQL里指定排序规则,防患于未然:
CREATE DATABASE LibraryDB COLLATE Chinese_PRC_CI_AS; GO这条路比改连接串可靠。CI表示大小写不敏感,AS表示区分重音。注意如果库已经建好再改排序规则比较麻烦,直接删掉重建或迁移数据更省事。这个坑很多教程不提,但中文系统下迟早碰到,早设参数早安心。
6. 验收前还能做的三件小事:批处理、验证脚本与面试价值
6.1 批量插入测试数据:用一条Java方法让图书表有底气
课设演示时图书表只有三五条数据,评委问“能测一下分页吗”会出现第二页空白。我习惯在系统里埋一个“生成演示数据”的隐藏功能,或者直接在main方法里跑批量插入。JDBC批处理有两种写法,一种是用addBatch()和executeBatch(),另一种简单粗暴是循环执行。批处理在大量数据时快很多,因为减少了往返数据库的次数。生成500条图书数据的核心代码:
public void batchInsertBooks() { String sql = "INSERT INTO books (title, author, category_id, total, available) VALUES (?, ?, ?, ?, ?)"; try (Connection conn = DBConnection.getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) { for (int i = 1; i <= 500; i++) { ps.setString(1, "测试图书" + i); ps.setString(2, "作者" + (i % 20)); ps.setInt(3, (i % 5) + 1); ps.setInt(4, 3); ps.setInt(5, 3); ps.addBatch(); if (i % 100 == 0) { ps.executeBatch(); } } ps.executeBatch(); } catch (SQLException e) { e.printStackTrace(); } }这段代码验证了批量操作和事务的配合关系。addBatch()把SQL暂存到驱动侧,每100条调一次executeBatch()实际发送,不至于500条挤在内存等最后一次性执行。批处理默认是非事务的,其中一条失败前面成功的不会回滚,不过课程设计数据是测试用,失败也不影响。如果想让老师眼前一亮,可以在前后加手动事务让500条要么全成、要么全不成,这是“批处理和事务结合”的典型面试知识点。
6.2 并发借书的验证脚本:证明你的系统不会超借
课设验收现场最怕被问“两个人同时借最后同一本书怎么办”。很多人答不上来,但你的系统用存储过程做扣减,理论上能防超借。验证方法也很直白:写两个并发线程,同时调用borrowBook(10001, 1),其中一本书total和available都是1。如果只有一次成功,说明库存扣减被事务控制住了。可以用Java代码实现:
public static void main(String[] args) throws Exception { Runnable task = () -> { BorrowService svc = new BorrowService(); System.out.println("借书结果: " + svc.borrowBook(10001, 1)); }; Thread t1 = new Thread(task); Thread t2 = new Thread(task); t1.start(); t2.start(); t1.join(); t2.join(); }注意这个测试结果不会每次都完美,因为存储过程里用的是SELECT后判断再更新,默认隔离级别下并发可能读到同一个旧库存值。要把这个测试跑稳,存储过程里的查询要加锁提示:SELECT @avail = available FROM books WITH (UPDLOCK) WHERE book_id = @book_id。UPDLOCK的作用是查询时就拿更新锁,避免另一个事务读到相同快照。把这一行加进存储过程,并发测试就能稳定输出“一个成功、一个失败”。这个细节是事务隔离级别和锁的一个典型应用,课设里能讲明白就已经超出平均水平了。
6.3 我把这个课设当成了面试敲门砖
别小看一个简易图书馆管理系统。你把它做完之后会涉及JDBC连接管理、事务边界、批处理、分页查询、存储过程、数据库约束设计,这些是Java后端面试的高频词。用spring boot + mybatis重写一遍,把JDBC这层换成框架,剩下的表结构、存储过程和业务逻辑完全可以复用。如果简历上的项目是“基于Spring Boot和SQL Server的图书借阅系统”,面试官至少会问:SQL Server和MySQL的差异、Spring事务和数据库事务的关系、存储过程的优缺点、OFFSET分页在深页码时为什么慢。这些问题在你的课设里都有真实答案,不是背来的。
还有一个建议:把存储过程脚本、建表SQL、Java代码按模块放好,答辩时演示完功能,现场跑一遍并发测试脚本。评委看到两个线程只有一个借书成功时,通常不会再追问“你的系统有什么亮点”,因为他们已经看到了。这个技巧是我从一个学长那学来的,后来每次给学弟学妹看代码都让他们加这段测试代码,效果比背PPT强十倍。
如果你真打算靠这个项目在面试里说事,建议把数据库从SQL Server换成MySQL再写一遍——很多公司内部用MySQL,但SQL Server的事务、存储过程经验同样有价值。把两套数据库都摸一遍,你对数据库连接、驱动、SQL语法的理解会比只用一个数据库的同学深一层。希望这些经验能帮你少走几步弯路,让这套简易图书馆管理系统真正成为你的作品而不是负担。
本文还有配套的精品资源,点击获取