当前位置: 首页 > ds >正文

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

一、项目概述与设计思路

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.xdnf.cn/news/3836.html

相关文章:

  • C语言中memmove和memcpy
  • 智慧校园整体解决方案-5PPT(65页)
  • python中的异常处理
  • 【CF】Day50——Codeforces Round 960 (Div. 2) BCD
  • 数学实验Matlab
  • 多把锁以及线程死锁问题
  • Linux-GRUB全面指南
  • CUDA输出“hello world”
  • 多数据源动态切换
  • 算法每日一题 | 入门-顺序结构-数字反转
  • (38)VTK C++开发示例 ---纹理裁剪
  • C++负载均衡远程调用学习之异步消息任务功能与连接属性
  • CVPR2021 | 重新思考视觉Transformer中的自注意力机制
  • Java学习手册:Spring 生态其他组件介绍
  • 单细胞测序试验设计赏析(一)
  • AWS在跨境电商中的全场景实践与未来生态构建
  • D. 例题3.2.2 整数划分问题
  • 二种MVCC对比分析
  • 学习黑客风险Risk
  • iOS启动优化:从原理到实践
  • 2025年渗透测试面试题总结-拷打题库35(题目+回答)
  • 【C++】:C++17新特性
  • Vivado FPGA 开发 | 创建工程 / 仿真 / 烧录
  • 2845. 统计趣味子数组的数目
  • 【LLaMA-Factory实战】Web UI快速上手:可视化大模型微调全流程
  • The Sims 4 模拟人生 4 [DLC 解锁] [Steam Epic EA] [Windows SteamOS]
  • 《操作系统真象还原》第十二章(2)——进一步完善内核
  • 影刀RPA中新增自己的自定义指令
  • UDP网络编程
  • Xilinx FPGA | 管脚约束 / 时序约束 / 问题解析