Java 图书管理系统实战:MySQL 与 JDBC 开发详解
本文基于 MySQL 和 Java 实现一个具备多角色权限(管理员与普通用户)的简易图书管理系统。核心内容包括使用 JdbcTemplate 或原生 JDBC 操作数据库、ORM 实体映射、DAO 层业务逻辑封装,以及利用抽象类和接口实现不同用户的菜单切换。
一、梳理功能需求
在设计系统前,需明确书籍数据模型、用户体系及各自的操作权限:
- 书籍信息实体:包含序号、书名、作者、价格、分类状态等字段。
- 用户角色:分为普通用户和管理员,两者拥有的操作菜单不同。
- 功能划分:
- 普通用户:支持查看书籍列表、查找指定书籍、借书、还书。
- 管理员:除了常规查询外,新增删除书籍的管理权限。
二、准备 MySQL 数据库
首先创建名为 java100_bookmanager 的数据库,分别定义书籍表 (book) 和用户表 (user)。初始化部分测试数据以便于调试。
create database if not exists java100_bookmanager;
use java100_bookmanager;
drop table if exists book;
-- 设置id为自增主键
create table book(id int primary key auto_increment,name varchar(20),author varchar(20),price int,type varchar(20),isBorrowed int);
drop table if exists user;
-- userId为自增主键,用户名唯一约束
create table user(
userId int primary key auto_increment,
username varchar(20) unique,
password varchar(20),
isAdmin int
);
-- 插入测试书籍
insert into book values(null,'西游记','吴承恩',10000,'古典小说',0);
insert into book values(null,'三国演义','罗贯中',10000,'古典小说',0);
insert into book values(null,'水浒传','施耐庵',10000,'古典小说',0);
insert into book values(null,'金瓶梅','兰陵笑笑生',10000,'古典小说',0);
-- 插入测试用户 (admin为管理员,普通用户为0)
insert into user values(null,'admin','123',1);
insert into user values(null,'zhangsan','123',0);
三、构造与数据库相关的实体类
书籍实体 (Books)
将数据库中的列映射为 Java 对象属性,并提供 Getter/Setter 方法。
public class Books {
private int bookId;
private String name;
private String author;
private int price;
private String type;
private boolean isBorrowed; //是否被借阅
// Setters & Getters ...
}
用户体系设计
利用多态特性设计用户基类。AbstractUser 持有操作数组 (IOperation[] operations) 并定义执行操作的模板方法。管理员与普通用户继承该类并重写不同的菜单输出。
abstract public class AbstractUser {
private int userId;
private String userName;
private String passWord;
IOperation[] operations;
abstract int menu(); // 抽象方法:各子类返回自己的菜单逻辑
public void doOperation(int choice){
operations[choice].work();
}
// ... Getter and Setter ...
}
普通用户类 (NormalUser)
实例化操作集合,限定其只能调用查看、搜索、借阅、归还等功能。
public class NormalUser extends AbstractUser {
public NormalUser(){
this.operations=new IOperation[]{
new ExitOperation(), new DisplayOperation(),
new FindOperation(), new BorrowOperation(), new ReturnOperation()
};
}
@Override
public int menu() {
System.out.println("欢迎您,"+this.getUserName()+"!");
System.out.println("1.查看书籍列表\n2.查找指定书籍\n3.借阅书籍\n4.归还书籍\n0.退出系统");
Scanner sc=new Scanner(System.in);
return sc.nextInt();
}
}
管理员类 (Admin)
相比普通用户,额外赋予了书籍的新增与删除操作。
public class Admin extends AbstractUser {
public Admin(){
this.operations=new IOperation[]{
new ExitOperation(), new DisplayOperation(),
new FindOperation(), new AddOperation(), new DelOperation()
};
}
@Override
public int menu() {
System.out.println("欢迎您,"+this.getUserName()+"!您是管理员");
System.out.println("1.查看书籍列表\n2.查找指定书籍\n3.新增书籍\n4.删除书籍\n0.退出系统");
Scanner sc=new Scanner(System.in);
return sc.nextInt();
}
}
四、封装数据库相关操作
采用 DAO (Data Access Object) 模式隔离数据库操作细节。
数据库连接管理 (DBUtil)
封装 DataSource 的懒汉式初始化。注意:实际生产环境中密码不应硬编码,建议从配置文件读取。
public class DBUtil {
private static final String URL="jdbc:mysql://127.0.0.1:3306/java100_bookmanager?characterEncoding=utf8&&useSSL=false";
private static final String USERNAME="root";
private static final String PASSWORD="your_password";
private static DataSource dataSource = null;
public static DataSource getDataSource(){
if(dataSource==null){
try {
dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl(URL);
((MysqlDataSource)dataSource).setUser(USERNAME);
((MysqlDataSource)dataSource).setPassword(PASSWORD);
} catch (SQLException e) {
e.printStackTrace();
}
}
return dataSource;
}
public static Connection getConnection() throws SQLException {
return getDataSource().getConnection();
}
// 统一资源释放方法
public static void close(ResultSet resultSet, PreparedStatement statement, Connection connection){
try {
if(resultSet!=null) resultSet.close();
if(statement!=null) statement.close();
if(connection!=null) connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
书籍表操作 (BookDAO)
封装对 book 表的 CRUD 逻辑。以“添加”和“借阅”为例:
public class BookDAO {
// 1. 新增书籍
public boolean add(Books book){
Connection conn = null;
PreparedStatement ps = null;
try {
conn = DBUtil.getConnection();
String sql="insert into book values(null, ?, ?, ?, ?, ?)";
ps=conn.prepareStatement(sql);
ps.setString(1,book.getName());
ps.setString(2,book.getAuthor());
ps.setInt(3,book.getPrice());
ps.setString(4,book.getType());
ps.setInt(5,book.isBorrowed()?1:0);
return ps.executeUpdate() == 1;
} catch (SQLException e) { e.printStackTrace(); return false; }
finally { DBUtil.close(null,ps,conn); }
}
// 5. 借阅书籍
public boolean borrowBook(int bookId){
Connection conn = null;
PreparedStatement selectPs = null;
PreparedStatement updatePs = null;
ResultSet rs = null;
try {
conn = DBUtil.getConnection();
// 检查该书是否存在且未被借出
String checkSql = "select isBorrowed from book where id=?";
selectPs=conn.prepareStatement(checkSql);
selectPs.setInt(1, bookId);
rs = selectPs.executeQuery();
if(!rs.next()) {
System.out.println("该书籍不存在");
return false;
}
if(rs.getInt("isBorrowed") == 1) {
System.out.println("此书已被借出");
return false;
}
// 更新状态
String updateSql = "update book set isBorrowed=1 where id=?";
updatePs=conn.prepareStatement(updateSql);
updatePs.setInt(1, bookId);
return updatePs.executeUpdate() == 1;
} catch (SQLException e) { e.printStackTrace(); return false; }
finally { DBUtil.close(rs,selectPs,conn); }
}
}
用户表操作 (UserDao)
根据传入的用户名查询用户信息,并根据管理员标识 (isAdmin) 动态实例化对应类型的 User 对象。
public class UserDao {
public AbstractUser selectByName(String name){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn=DBUtil.getConnection();
String sql="select * from user where username=?";
ps = conn.prepareStatement(sql);
ps.setString(1, name);
rs = ps.executeQuery();
if(rs.next()){
boolean isAdmin=(rs.getInt("isAdmin")==1);
AbstractUser user = isAdmin ? new Admin() : new NormalUser();
user.setPassWord(rs.getString("password"));
user.setUserId(rs.getInt("userId"));
user.setUserName(rs.getString("username"));
return user;
}
} catch (SQLException e) { e.printStackTrace(); }
finally { DBUtil.close(rs,ps,conn); }
return null;
}
}
五、编写主程序入口与业务逻辑
登录模块与循环调度
在 Main 类中实现启动流程:先验证登录凭证,获取对应的 AbstractUser 实例后,进入死循环等待用户输入选择。
public class Main {
public static void main(String[] args) {
AbstractUser currentUser = login();
while(true){
int choice = currentUser.menu();
currentUser.doOperation(choice);
}
}
private static AbstractUser login(){
Scanner sc = new Scanner(System.in);
System.out.print("请输入用户名: ");
String name = sc.next();
System.out.print("请输入密码: ");
String password = sc.next();
UserDao userDao = new UserDao();
AbstractUser user = userDao.selectByName(name);
if(user == null){
System.out.println("用户不存在,程序退出");
System.exit(0);
}
if(!user.getPassWord().equals(password)){
System.out.println("密码错误,程序退出");
System.exit(0);
}
return user;
}
}
业务操作类实现 (Operations)
所有具体业务动作均实现统一的 IOperation 接口。
// 通用接口定义
public interface IOperation {
void work();
}
// 示例:显示所有书籍
public class DisplayOperation implements IOperation {
@Override
public void work() {
System.out.println("展示所有书籍:");
BookDAO bookdao = new BookDAO();
List<Books> list = bookdao.selectAll();
for(Books b : list) {
System.out.println(b);
}
}
}
// 示例:退出系统
public class ExitOperation implements IOperation {
@Override
public void work() {
System.out.println("感谢使用,退出程序");
System.exit(0);
}
}
六、总结
本案例通过构建命令行版的图书管理系统,串讲了 Java 面向对象的设计思想以及后端开发的基石——JDBC。通过 DAO 层的解耦以及多态机制的应用,代码结构清晰,易于后续扩展。以上就是 Java 图书管理系统结合 MySQL 与 JDBC 的详细内容,更多关于 Java 实战项目开发的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









