实战项目:基于控制台与数据库的图书管理系统开发指南

一、项目概述与设计思路

1.1 为什么选择图书管理系统

图书管理系统是学习编程的经典项目,它涵盖了:

  • 控制台交互:学习用户输入输出处理

  • 数据库操作:掌握CRUD核心功能

  • 业务逻辑:理解实际应用场景

  • 系统架构:实践分层设计思想

1.2 系统功能设计

核心功能模块

1. 图书管理- 添加新书- 删除图书- 修改图书信息- 查询图书(按ID/书名/作者)2. 借阅管理- 图书借出- 图书归还- 借阅记录查询3. 用户管理- 读者注册- 读者信息修改- 读者注销4. 统计报表- 图书库存统计- 借阅排行榜- 逾期未还清单

1.3 技术选型

技术组件选择方案备注
开发语言Java 8+兼顾教学与实用
数据库MySQL 8.0免费开源,应用广泛
数据库连接JDBC学习原生数据库操作
控制台框架-纯Java实现
单元测试JUnit 5保证代码质量
日志系统SLF4J + Logback记录系统运行状态

二、数据库设计与实现

2.1 数据库表结构设计

ER图关键实体

图书(Book) ---< 借阅记录(BorrowRecord) >--- 读者(Reader)

建表SQL

-- 图书表
CREATE TABLE books (book_id INT AUTO_INCREMENT PRIMARY KEY,isbn VARCHAR(20) NOT NULL UNIQUE,title VARCHAR(100) NOT NULL,author VARCHAR(50) NOT NULL,publisher VARCHAR(50),publish_date DATE,price DECIMAL(10,2),stock INT DEFAULT 1 COMMENT '库存数量',create_time DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;-- 读者表
CREATE TABLE readers (reader_id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50) NOT NULL,gender CHAR(1) CHECK (gender IN ('M', 'F')),phone VARCHAR(20),email VARCHAR(100),register_date DATE DEFAULT (CURRENT_DATE),membership_level INT DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;-- 借阅记录表
CREATE TABLE borrow_records (record_id INT AUTO_INCREMENT PRIMARY KEY,book_id INT NOT NULL,reader_id INT NOT NULL,borrow_date DATETIME DEFAULT CURRENT_TIMESTAMP,due_date DATETIME GENERATED ALWAYS AS (borrow_date + INTERVAL 30 DAY) STORED,return_date DATETIME,status TINYINT DEFAULT 1 COMMENT '1-借出 2-已还 3-逾期',FOREIGN KEY (book_id) REFERENCES books(book_id),FOREIGN KEY (reader_id) REFERENCES readers(reader_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2.2 索引优化设计

-- 提高查询性能的索引
CREATE INDEX idx_books_title ON books(title);
CREATE INDEX idx_books_author ON books(author);
CREATE INDEX idx_borrow_records_status ON borrow_records(status);
CREATE INDEX idx_borrow_records_due_date ON borrow_records(due_date);

2.3 初始化测试数据

-- 插入示例图书
INSERT INTO books (isbn, title, author, publisher, price, stock)
VALUES 
('9787111636667', 'Java核心技术 卷I', 'Cay S. Horstmann', '机械工业出版社', 119.00, 5),
('9787115523660', 'Effective Java', 'Joshua Bloch', '机械工业出版社', 129.00, 3),
('9787302515421', 'Python编程:从入门到实践', 'Eric Matthes', '人民邮电出版社', 89.00, 7);-- 插入示例读者
INSERT INTO readers (name, gender, phone, email)
VALUES 
('张三', 'M', '13800138001', 'zhangsan@example.com'),
('李四', 'F', '13900139001', 'lisi@example.com');

三、Java核心代码实现

3.1 数据库连接层

DBUtil.java - 数据库工具类:

public class DBUtil {private static final String URL = "jdbc:mysql://localhost:3306/library_db?useSSL=false&serverTimezone=UTC";private static final String USER = "root";private static final String PASSWORD = "123456";static {try {Class.forName("com.mysql.cj.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}}public static Connection getConnection() throws SQLException {return DriverManager.getConnection(URL, USER, PASSWORD);}public static void close(Connection conn, Statement stmt, ResultSet rs) {try {if (rs != null) rs.close();if (stmt != null) stmt.close();if (conn != null) conn.close();} catch (SQLException e) {e.printStackTrace();}}
}

3.2 实体类设计

Book.java - 图书实体:

public class Book {private Integer bookId;private String isbn;private String title;private String author;private String publisher;private Date publishDate;private BigDecimal price;private Integer stock;// 构造方法、getter和setter省略// 建议使用Lombok @Data注解简化代码
}

3.3 数据访问层(DAO)

BookDAO.java - 图书数据访问:

public class BookDAO {// 添加新书public boolean addBook(Book book) {String sql = "INSERT INTO books (isbn, title, author, publisher, publish_date, price, stock) " +"VALUES (?, ?, ?, ?, ?, ?, ?)";try (Connection conn = DBUtil.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setString(1, book.getIsbn());pstmt.setString(2, book.getTitle());pstmt.setString(3, book.getAuthor());pstmt.setString(4, book.getPublisher());pstmt.setDate(5, new java.sql.Date(book.getPublishDate().getTime()));pstmt.setBigDecimal(6, book.getPrice());pstmt.setInt(7, book.getStock());return pstmt.executeUpdate() > 0;} catch (SQLException e) {e.printStackTrace();return false;}}// 按ID查询图书public Book getBookById(int bookId) {String sql = "SELECT * FROM books WHERE book_id = ?";Book book = null;try (Connection conn = DBUtil.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setInt(1, bookId);try (ResultSet rs = pstmt.executeQuery()) {if (rs.next()) {book = new Book();book.setBookId(rs.getInt("book_id"));book.setIsbn(rs.getString("isbn"));// 设置其他属性...}}} catch (SQLException e) {e.printStackTrace();}return book;}// 其他CRUD方法...
}

3.4 业务逻辑层(Service)

LibraryService.java - 核心业务逻辑:

public class LibraryService {private BookDAO bookDAO = new BookDAO();private ReaderDAO readerDAO = new ReaderDAO();private BorrowRecordDAO recordDAO = new BorrowRecordDAO();// 借书业务方法public boolean borrowBook(int bookId, int readerId) {// 检查图书库存Book book = bookDAO.getBookById(bookId);if (book == null || book.getStock() <= 0) {System.out.println("图书不存在或库存不足");return false;}// 检查读者是否存在Reader reader = readerDAO.getReaderById(readerId);if (reader == null) {System.out.println("读者不存在");return false;}// 检查是否已借过同一本书未还if (recordDAO.hasUnreturnedRecord(bookId, readerId)) {System.out.println("您已借阅该书且未归还");return false;}// 开启事务Connection conn = null;try {conn = DBUtil.getConnection();conn.setAutoCommit(false);// 1. 减少库存bookDAO.updateStock(conn, bookId, -1);// 2. 创建借阅记录BorrowRecord record = new BorrowRecord();record.setBookId(bookId);record.setReaderId(readerId);recordDAO.addRecord(conn, record);conn.commit();return true;} catch (SQLException e) {if (conn != null) {try {conn.rollback();} catch (SQLException ex) {ex.printStackTrace();}}e.printStackTrace();return false;} finally {if (conn != null) {try {conn.setAutoCommit(true);conn.close();} catch (SQLException e) {e.printStackTrace();}}}}// 其他业务方法...
}

3.5 控制台界面实现

ConsoleUI.java - 用户交互界面:

public class ConsoleUI {private Scanner scanner = new Scanner(System.in);private LibraryService libraryService = new LibraryService();public void start() {while (true) {showMainMenu();int choice = getIntInput("请选择操作:");switch (choice) {case 1:manageBooks();break;case 2:manageReaders();break;case 3:manageBorrowing();break;case 4:generateReports();break;case 0:System.out.println("感谢使用图书管理系统,再见!");return;default:System.out.println("无效选择,请重新输入");}}}private void showMainMenu() {System.out.println("\n===== 图书管理系统 =====");System.out.println("1. 图书管理");System.out.println("2. 读者管理");System.out.println("3. 借阅管理");System.out.println("4. 统计报表");System.out.println("0. 退出系统");}private void manageBooks() {while (true) {System.out.println("\n===== 图书管理 =====");System.out.println("1. 添加新书");System.out.println("2. 查询图书");System.out.println("3. 修改图书信息");System.out.println("4. 删除图书");System.out.println("0. 返回上级菜单");int choice = getIntInput("请选择操作:");switch (choice) {case 1:addNewBook();break;case 2:searchBooks();break;// 其他case...case 0:return;default:System.out.println("无效选择");}}}private void addNewBook() {System.out.println("\n--- 添加新书 ---");String isbn = getStringInput("ISBN:");String title = getStringInput("书名:");String author = getStringInput("作者:");Book book = new Book();book.setIsbn(isbn);book.setTitle(title);book.setAuthor(author);// 设置其他属性...if (libraryService.addBook(book)) {System.out.println("添加图书成功!");} else {System.out.println("添加图书失败");}}// 其他方法...private int getIntInput(String prompt) {while (true) {try {System.out.print(prompt);return Integer.parseInt(scanner.nextLine());} catch (NumberFormatException e) {System.out.println("请输入有效数字!");}}}private String getStringInput(String prompt) {System.out.print(prompt);return scanner.nextLine();}
}

四、项目扩展与优化

4.1 功能扩展建议

  1. 预约功能

    • 允许读者预约已被借出的图书

    • 图书归还时通知预约读者

  2. 逾期罚款

    • 计算逾期天数

    • 按规则自动计算罚款金额

  3. 图书推荐

    • 基于借阅历史的简单推荐

    • 热门图书推荐

4.2 代码优化方向

引入连接池

// 使用HikariCP替代原生JDBC连接
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/library_db");
config.setUsername("root");
config.setPassword("123456");
HikariDataSource dataSource = new HikariDataSource(config);

使用DAO接口

public interface BookDAO {boolean addBook(Book book);Book getBookById(int bookId);// 其他方法...
}public class BookDAOImpl implements BookDAO {// 实现方法...
}

日志记录

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class BookDAOImpl implements BookDAO {private static final Logger logger = LoggerFactory.getLogger(BookDAOImpl.class);public boolean addBook(Book book) {logger.debug("尝试添加图书:{}", book.getTitle());// 实现代码...}
}

4.3 异常处理改进

自定义异常类

public class LibraryException extends Exception {public LibraryException(String message) {super(message);}public LibraryException(String message, Throwable cause) {super(message, cause);}
}// 使用示例
public void borrowBook(int bookId, int readerId) throws LibraryException {try {// 业务逻辑...} catch (SQLException e) {throw new LibraryException("借书操作失败", e);}
}

五、项目部署与测试

5.1 单元测试示例

BookDAOTest.java

public class BookDAOTest {private BookDAO bookDAO = new BookDAOImpl();@Testpublic void testAddAndGetBook() {Book book = new Book();book.setIsbn("978-3-16-148410-0");book.setTitle("测试图书");book.setAuthor("测试作者");boolean added = bookDAO.addBook(book);assertTrue(added);Book retrieved = bookDAO.getBookByIsbn("978-3-16-148410-0");assertNotNull(retrieved);assertEquals("测试图书", retrieved.getTitle());}// 其他测试方法...
}

5.2 系统测试流程

  1. 图书管理测试

    • 添加不同种类的图书

    • 测试各种查询条件组合

    • 验证库存更新逻辑

  2. 借还书测试

    • 正常借书/还书流程

    • 测试库存不足情况

    • 验证逾期计算正确性

  3. 并发测试

    • 模拟多个用户同时借阅同一本书

    • 验证库存扣减的原子性

结语

通过这个图书管理系统项目,我们完整实践了:

  1. 控制台程序的交互设计

  2. 数据库表结构设计与优化

  3. JDBC的实战应用

  4. 分层架构的实现

  5. 基础业务逻辑开发

进一步学习建议

  1. 尝试使用MyBatis重构数据访问层

  2. 添加Web界面转型为B/S架构

  3. 学习使用Spring框架改造项目

  4. 研究数据库事务隔离级别的实际影响

如果您在实现过程中遇到任何问题,欢迎在评论区留言讨论。觉得本文有帮助的话,请点赞收藏支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/903982.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人工智能——层次聚类算法

目录 摘要 18 层次聚类 18.1 本章工作任务 18.2 本章技能目标 18.3 本章简介 18.4 编程实战 18.5 本章总结 18.6 本章作业 本章已完结&#xff01;&#xff01;&#xff01; 摘要 本章实现的工作是&#xff1a;首先导入20名学生的3科成绩&#xff0c;然后根据优先聚…

Linux中安装mysql8,转载及注意事项

一、先前往官网下载mysql8 下载地址&#xff1a; https://dev.mysql.com/downloads/选择Linux 二、删除Linux中的mysql&#xff08;如果有的话&#xff09;&#xff0c;上传安装包 1、先查看mysql是否存在&#xff0c;命令如下&#xff1a; rpm -qa|grep -i mysql如果使用这…

《算法导论(第4版)》阅读笔记:p4-p5

《算法导论(第4版)》学习第 3 天&#xff0c;p4-p5 总结&#xff0c;总计 2 页。 一、技术总结 1.instance Thus, given the input sequence h31; 41; 59; 26; 41; 58i, a correct sorting algorithm returns as output the sequence h26; 31; 41; 41; 58; 59i. Such an inp…

第十四篇:系统分析师第三遍——15章

目录 一、目标二、计划三、完成情况四、意外之喜(最少2点)1.计划内的明确认知和思想的提升标志2.计划外的具体事情提升内容和标志 五、总结六、后面准备怎么做&#xff1f; 一、目标 通过参加考试&#xff0c;训练学习能力&#xff0c;而非单纯以拿证为目的。 1.在复习过程中&…

Easy云盘总结篇-登录注册

**说在前面&#xff1a;该项目是跟着B站一位大佬写的&#xff0c;不分享源码&#xff0c;支持项目付费 ** 获取图形验证码 可以看到这里有2两种图形验证码&#xff0c;分为&#xff1a; type0&#xff1a;如上图下面那个&#xff0c;是完成操作后要进行注册的验证码 type1: 如…

【前端知识】Vue3状态组件Pinia详细介绍

Vue3状态组件Pinia详细介绍 关联知识 Pinia 组件介绍、核心原理及使用方式 Pinia 组件介绍 Pinia 是 Vue.js 的官方状态管理库&#xff0c;专为 Vue 3 设计&#xff0c;提供简洁的 API 和强大的 TypeScript 支持。其核心组件包括&#xff1a; • Store&#xff1a;状态存储容器…

mysql 云服务远程linux创建数据库

1. 本地使用已创建好的用户创建数据库出现问题 提示access deniey finalshell远程创建新用户 :~# mysql -u root -pR***34 > CREATE DATABASE r***e; > CREATE USER r**ue% IDENTIFIED BY Ry****34; > GRANT ALL PRIVILEGES ON ry_vue.* TO r***e%; > FLUSH PRI…

【“星瑞” O6 评测】 — CPU llama.cpp不同优化速度对比

前言 随着大模型应用场景的不断拓展&#xff0c;arm cpu 凭借其独特优势在大模型推理领域的重要性日益凸显。它在性能、功耗、架构适配等多方面发挥关键作用&#xff0c;推动大模型在不同场景落地 1. Kleidi AI 简介 Arm Kleidi 成为解决这些挑战的理想方案&#xff0c;它能…

wireshark抓包也能被篡改?

wireshark本身并不能修改数据包&#xff0c;但是tcprewrite 可以修改数据包&#xff0c;然后通过tcpreplay 进行重放&#xff0c;这个时候wireshark抓的包&#xff0c;就是被篡改后的pcap包了。 ailx10 网络安全优秀回答者 互联网行业 安全攻防员 去咨询 步骤一&#xff1a…

使用PyTorch进行热狗图像分类模型微调

本教程将演示如何使用PyTorch框架对预训练模型进行微调&#xff0c;实现热狗与非热狗图像的分类任务。我们将从数据准备开始&#xff0c;逐步完成数据加载、可视化等关键步骤。 1. 环境配置与库导入 %matplotlib inline import os import torch from torch import nn from d2l…

内容中台与企业内容管理核心差异剖析

功能定位与架构设计差异 在企业数字化进程中&#xff0c;内容中台与企业内容管理&#xff08;ECM&#xff09;的核心差异首先体现在功能定位层面。传统ECM系统以文档存储、版本控制及权限管理为核心&#xff0c;主要服务于企业内部知识库的静态管理需求&#xff0c;例如通过Ba…

使用PyMongo连接MongoDB的基本操作

MongoDB是由C语言编写的非关系型数据库&#xff0c;是一个基于分布式文件存储的开源数据库系统&#xff0c;其内容存储形式类似JSON对象&#xff0c;它的字段值可以包含其他文档、数组及文档数组。在这一节中&#xff0c;我们就来回顾Python 3下MongoDB的存储操作。 常用命令:…

第 12 届蓝桥杯 C++ 青少组中 / 高级组省赛 2021 年真题

一、选择题 第 1 题 题目&#xff1a;下列符号中哪个在 C 中表示行注释 ( )。 A. ! B. # C. ] D. // 正确答案&#xff1a;D 答案解析&#xff1a; 在 C 中&#xff0c;//用于单行注释&#xff08;行注释&#xff09;&#xff0c;从//开始到行末的内容会被编译器忽略。选项 A…

【python】【UV】一篇文章学完新一代 Python 环境与包管理器使用指南

&#x1f40d; UV&#xff1a;新一代 Python 环境与包管理器使用指南 一、UV 是什么&#xff1f; UV 是由 Astral 团队开发的高性能 Python 环境管理器&#xff0c;旨在统一替代 pyenv、pip、venv、pip-tools、pipenv 等工具。 1.1 UV 的主要功能 &#x1f680; 极速包安装&…

前端性能优化2:结合HTTPS与最佳实践,全面优化你的网站性能

点亮极速体验&#xff1a;结合HTTPS与最佳实践&#xff0c;为你详解网站性能优化的道与术 在如今这个信息爆炸、用户耐心极其有限的数字时代&#xff0c;网站的性能早已不是一个可选项&#xff0c;而是关乎生存和发展的核心竞争力。一个迟缓的网站&#xff0c;无异于在数字世界…

JavaWeb:vueaxios

一、简介 什么是vue? 快速入门 <!-- 3.准备视图元素 --><div id"app"><!-- 6.数据渲染 --><h1>{{ msg }}</h1></div><script type"module">// 1.引入vueimport { createApp, ref } from https://unpkg.com/vu…

Tauri联合Vue开发中Vuex与Pinia关系及前景分析

在 TauriVue 的开发场景中&#xff0c;Vuex 和 Pinia 是两种不同的状态管理工具&#xff0c;它们的关系和前景可以从以下角度分析&#xff1a; 一、Vuex 与 Pinia 的关系 继承与发展 Pinia 最初是作为 Vuex 5 的提案设计的&#xff0c;其目标是简化 Vuex 的复杂性并更好地适配 …

Linux中的时间同步

一、时间同步服务扩展总结 1. 时间同步的重要性 多主机协作需求&#xff1a;在分布式系统、集群、微服务架构中&#xff0c;时间一致性是日志排序、事务顺序、数据一致性的基础。 安全协议依赖&#xff1a;TLS/SSL证书、Kerberos认证等依赖时间有效性&#xff0c;时间偏差可能…

【算法基础】三指针排序算法 - JAVA

一、基础概念 1.1 什么是三指针排序 三指针排序是一种特殊的分区排序算法&#xff0c;通过使用三个指针同时操作数组&#xff0c;将元素按照特定规则进行分类和排序。这种算法在处理包含有限种类值的数组时表现出色&#xff0c;最经典的应用是荷兰国旗问题&#xff08;Dutch …

《操作系统真象还原》第十二章(2)——进一步完善内核

文章目录 前言可变参数的原理实现系统调用write更新syscall.h更新syscall.c更新syscall-init.c 实现printf编写stdio.h编写stdio.c 第一次测试main.cmakefile结果截图 完善printf修改main.c 结语 前言 上部分链接&#xff1a;《操作系统真象还原》第十二章&#xff08;1&#…