Java课程设计:图书管理系统
项目概述
本项目旨在设计并实现一个基于Java Swing或JavaFX的桌面应用程序——图书管理系统,该系统将模拟图书馆日常的图书管理操作,包括图书信息的增、删、改、查,以及用户(图书管理员)的登录、注销等功能,系统旨在提供一个简洁、直观、易用的图形用户界面,方便管理员进行图书管理工作,提高管理效率。

功能需求分析
系统主要分为两大模块:管理员模块和系统登录模块。
1. 系统登录模块
- 功能描述:提供管理员登录界面,验证用户身份。
- 具体需求:
- 用户名和密码输入框。
- 登录按钮和退出按钮。
- 点击“登录”按钮,验证输入的用户名和密码是否正确(可预设一个或多个管理员账户)。
- 验证成功,则跳转到主管理界面;验证失败,则给出错误提示。
- 点击“退出”按钮,关闭应用程序。
2. 管理员模块(主管理界面)
- 功能描述:提供图书管理的核心功能入口,通常以菜单栏或按钮组的形式呈现。
- 具体需求:
- 图书信息管理:
- 添加图书:弹出对话框,输入图书信息(如:图书ID、书名、作者、出版社、ISBN、库存数量等),并将信息保存到数据源中。
- 修改图书:在图书列表中选择一条记录,弹出修改对话框,修改其信息并保存。
- 删除图书:在图书列表中选择一条或多条记录,点击删除按钮,从数据源中移除。
- 查询图书:提供多种查询方式,如按书名、作者、ISBN等模糊查询或精确查询,并将查询结果显示在列表中。
- 图书列表展示:
- 以表格形式展示所有图书的信息,或查询结果。
- 表格应支持滚动,以便查看大量数据。
- 每一行记录前应有复选框,方便进行批量操作(如批量删除)。
- 图书信息管理:
技术选型
- 开发语言:Java 8 或更高版本。
- GUI框架:
- Java Swing (推荐):轻量级、跨平台,是Java课程设计的经典选择,易于学习和实现。
- JavaFX:更现代、功能更强大的GUI框架,但如果课程时间紧张或对JavaFX不熟悉,Swing是更稳妥的选择。
- 数据存储:
- 文件存储 (如 .txt, .csv):最简单的实现方式,适合初学者,通过
BufferedReader和BufferedWriter进行读写。 - 数据库存储 (如 MySQL, SQLite):更专业、更稳定的选择,推荐使用 SQLite,它是一个轻量级的、文件式的数据库,无需单独安装数据库服务器,非常适合桌面应用。
- 文件存储 (如 .txt, .csv):最简单的实现方式,适合初学者,通过
- 开发工具:IntelliJ IDEA 或 Eclipse。
系统设计
1. 功能模块图

+---------------------+
| 图书管理系统 |
+----------+----------+
|
+------+------+
| |
+---v---+ +----v----+
| 登录模块 | | 管理员模块 |
+-------+ +----------+
| | +--------+ |
| | | 图书管理 | |
| | +--------+ |
| | | - 添加 |
| | | - 修改 |
| | | - 删除 |
| | | - 查询 |
| | +--------+ |
+---+------------+
2. 数据库设计 (如果使用SQLite)
创建一个名为 books 的表,包含以下字段:
CREATE TABLE books (
id INTEGER PRIMARY KEY AUTOINCREMENT, -- 图书ID,主键,自增 VARCHAR(100) NOT NULL, -- 书名
author VARCHAR(100) NOT NULL, -- 作者
publisher VARCHAR(100), -- 出版社
isbn VARCHAR(20) UNIQUE, -- ISBN,唯一
stock INTEGER DEFAULT 0 -- 库存
);
3. 类设计 (UML类图简化)
-
Book(实体类/Model)- 属性:
id,title,author,publisher,isbn,stock - 方法:
getter()和setter()方法。
- 属性:
-
BookDao(数据访问对象/DAO)
(图片来源网络,侵删)- 职责:封装所有与数据库(或文件)交互的逻辑。
- 方法:
addBook(Book book): 添加图书。updateBook(Book book): 更新图书信息。deleteBook(int id): 根据ID删除图书。queryBook(String keyword): 根据关键字查询图书。getAllBooks(): 获取所有图书。
-
LoginView(视图)- 职责:显示登录界面。
- 组件:
JFrame,JLabel(用户名, 密码),JTextField,JPasswordField,JButton(登录, 退出)。
-
MainView(主视图)- 职责:显示主管理界面。
- 组件:
JFrame,JMenuBar(菜单栏),JTable(图书列表),JButton(添加, 修改, 删除, 查询)。
-
AddBookDialog/UpdateBookDialog(对话框视图)- 职责:弹出用于添加或修改图书信息的对话框。
- 组件:
JDialog,JLabel,JTextField,JButton(确定, 取消)。
-
Controller(控制器 - 可选,但推荐)- 职责:连接视图和模型,处理用户事件(如按钮点击)。
MainView的“添加”按钮被点击时,会调用Controller的handleAddBook()方法,该方法再调用BookDao的addBook()方法,并更新MainView的表格。
核心代码实现 (Java Swing + SQLite 示例)
1. 数据库连接工具类 DBUtil.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBUtil {
private static final String URL = "jdbc:sqlite:library.db"; // 数据库文件
public static Connection getConnection() {
Connection conn = null;
try {
// 加载SQLite驱动
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection(URL);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return conn;
}
}
注意:你需要将 SQLite JDBC Driver 的 .jar 文件添加到你的项目库中。
2. 实体类 Book.java
public class Book {
private int id;
private String title;
private String author;
private String publisher;
private String isbn;
private int stock;
// 构造方法、getter和setter
public Book() {}
public Book(String title, String author, String publisher, String isbn, int stock) {
this.title = title;
this.author = author;
this.publisher = publisher;
this.isbn = isbn;
this.stock = stock;
}
// 省略 getter 和 setter...
@Override
public String toString() {
return "Book{" +
"id=" + id +
", title='" + title + '\'' +
", author='" + author + '\'' +
", publisher='" + publisher + '\'' +
", isbn='" + isbn + '\'' +
", stock=" + stock +
'}';
}
}
3. 数据访问对象 BookDao.java
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class BookDao {
// 添加图书
public void addBook(Book book) {
String sql = "INSERT INTO books(title, author, publisher, isbn, stock) VALUES(?, ?, ?, ?, ?)";
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, book.getTitle());
pstmt.setString(2, book.getAuthor());
pstmt.setString(3, book.getPublisher());
pstmt.setString(4, book.getIsbn());
pstmt.setInt(5, book.getStock());
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 更新图书
public void updateBook(Book book) {
String sql = "UPDATE books SET title=?, author=?, publisher=?, isbn=?, stock=? WHERE id=?";
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, book.getTitle());
pstmt.setString(2, book.getAuthor());
pstmt.setString(3, book.getPublisher());
pstmt.setString(4, book.getIsbn());
pstmt.setInt(5, book.getStock());
pstmt.setInt(6, book.getId());
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 删除图书
public void deleteBook(int id) {
String sql = "DELETE FROM books WHERE id=?";
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 查询所有图书
public List<Book> getAllBooks() {
List<Book> books = new ArrayList<>();
String sql = "SELECT * FROM books";
try (Connection conn = DBUtil.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
Book book = new Book();
book.setId(rs.getInt("id"));
book.setTitle(rs.getString("title"));
book.setAuthor(rs.getString("author"));
book.setPublisher(rs.getString("publisher"));
book.setIsbn(rs.getString("isbn"));
book.setStock(rs.getInt("stock"));
books.add(book);
}
} catch (SQLException e) {
e.printStackTrace();
}
return books;
}
// 根据ID查询图书 (用于修改前加载数据)
public Book getBookById(int id) {
String sql = "SELECT * FROM books WHERE id=?";
Book book = null;
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
book = new Book();
book.setId(rs.getInt("id"));
book.setTitle(rs.getString("title"));
book.setAuthor(rs.getString("author"));
book.setPublisher(rs.getString("publisher"));
book.setIsbn(rs.getString("isbn"));
book.setStock(rs.getInt("stock"));
}
} catch (SQLException e) {
e.printStackTrace();
}
return book;
}
}
4. 主界面 MainView.java (简化版)
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
public class MainView extends JFrame {
private JTable bookTable;
private DefaultTableModel tableModel;
private BookDao bookDao = new BookDao();
public MainView() {
setTitle("图书管理系统 - 主界面");
setSize(800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
// 初始化表格模型
String[] columnNames = {"ID", "书名", "作者", "出版社", "ISBN", "库存"};
tableModel = new DefaultTableModel(columnNames, 0) {
@Override
public Class<?> getColumnClass(int columnIndex) {
return columnIndex == 0 ? Integer.class : String.class;
}
};
bookTable = new JTable(tableModel);
loadBookData();
// 创建按钮面板
JPanel buttonPanel = new JPanel();
JButton addButton = new JButton("添加");
JButton updateButton = new JButton("修改");
JButton deleteButton = new JButton("删除");
JButton queryButton = new JButton("查询");
buttonPanel.add(addButton);
buttonPanel.add(updateButton);
buttonPanel.add(deleteButton);
buttonPanel.add(queryButton);
// 添加事件监听器
addButton.addActionListener(e -> showAddBookDialog());
updateButton.addActionListener(e -> showUpdateBookDialog());
deleteButton.addActionListener(e -> deleteSelectedBooks());
queryButton.addActionListener(e -> showQueryDialog());
// 布局
setLayout(new BorderLayout());
add(new JScrollPane(bookTable), BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
}
private void loadBookData() {
tableModel.setRowCount(0); // 清空表格
List<Book> books = bookDao.getAllBooks();
for (Book book : books) {
Object[] row = {
book.getId(),
book.getTitle(),
book.getAuthor(),
book.getPublisher(),
book.getIsbn(),
book.getStock()
};
tableModel.addRow(row);
}
}
private void showAddBookDialog() {
AddBookDialog dialog = new AddBookDialog(this, "添加图书");
dialog.setVisible(true);
if (dialog.isConfirmed()) {
Book newBook = dialog.getBook();
bookDao.addBook(newBook);
loadBookData(); // 刷新表格
}
}
// 其他方法如 showUpdateBookDialog, deleteSelectedBooks, showQueryDialog 等类似实现
// ...
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
// 在实际应用中,这里应该先显示登录界面
// LoginView loginView = new LoginView();
// if (loginView.loginSuccessful()) {
MainView mainView = new MainView();
mainView.setVisible(true);
// }
});
}
}
AddBookDialog.java, UpdateBookDialog.java 等视图类将使用 JDialog 和 JTextField 等组件构建,并将数据封装后返回给 MainView。
测试与部署
1. 测试
- 单元测试:对
BookDao中的每个方法进行测试,确保数据库操作的正确性。 - 集成测试:测试各个模块(如视图和DAO)之间的交互是否正常。
- 功能测试:模拟用户操作,测试所有功能是否符合需求,
- 使用正确的用户名密码能否成功登录。
- 添加一本新书后,列表中是否显示。
- 修改图书信息后,列表中的信息是否更新。
- 删除图书后,列表中是否消失。
- 查询功能是否能正确筛选出结果。
2. 部署
- 打包为可执行JAR:在IDE中,使用构建工具(如Maven或Gradle)或IDE自带的打包功能,将项目打包成一个
.jar文件。 - 制作安装包(可选):可以使用工具如 Launch4j 或 Inno Setup 将JAR文件打包成Windows下的
.exe安装程序,方便用户使用。 - 分发:将生成的
.jar文件或安装程序分发给用户,用户只需安装并运行即可,无需安装Java环境(如果打包为exe)。
课程设计答辩要点
- 项目概述:用1-2分钟清晰介绍你的项目是什么,解决了什么问题。
- 技术栈与架构:说明你使用了哪些技术(Java, Swing, SQLite),并解释你的系统架构(如MVC思想,即使没严格实现,也要说清楚视图、模型、控制器的分工)。
- 核心功能演示:这是最重要的部分,现场演示登录、添加、修改、删除、查询等核心功能,确保无误。
- 难点与解决方案:
- 难点1:如何实现数据的持久化?
- 解决方案:我选择了SQLite数据库,因为它轻量级且无需额外配置,我创建了
DBUtil类来管理数据库连接,并实现了BookDao来封装所有CRUD操作,实现了数据访问与业务逻辑的分离。
- 解决方案:我选择了SQLite数据库,因为它轻量级且无需额外配置,我创建了
- 难点2:如何实现
JTable与数据的动态绑定?- 解决方案:我使用了
DefaultTableModel作为JTable的数据模型,每次数据发生增删改后,我都会调用tableModel.setRowCount(0)清空表格,然后重新从数据库加载最新数据并添加到模型中,从而实现了界面的实时刷新。
- 解决方案:我使用了
- 难点1:如何实现数据的持久化?
- 项目总结与展望:
- 总结你在本次课程设计中学到了什么(如Java编程、GUI设计、数据库操作、软件工程思想等)。
- 展望:项目还有哪些可以改进的地方?(增加用户权限管理、图书借阅功能、数据导入导出功能、使用更高级的框架如Spring Boot重构后端等),这能体现你的思考深度和学习的积极性。
希望这份详细的指南能帮助你顺利完成你的Java课程设计!祝你成功!
