前言
✨Java Swing开发~✨
🎯项目介绍:
这是一款基于Java Swing开发的图书管理系统,极其适合作为Java课设设计以及学习技术使用,其中使用MySQL 8.x作为数据库。
👀功能特色:
1️⃣基础功能(管理员权限)
(1)系统登录功能:用户可以通过用户名和密码登录系统。
(2)图书分类管理功能:增、删、改、查操作不在话下!
(3)图书信息管理功能:增、删、改图书,修改图书名称、类别、价格等信息,畅所欲言。
(4)图书借阅管理功能:借、还,妥妥的轻松搞定!考虑到逾期情况的判别和处理,早就事无巨细了!
2️⃣可选加分功能(用户权限)
(1)借阅记录查询功能:学生只需查看自己在某时间段内的借阅记录,管理员可按照学号查询学生的借阅记录。
一、项目展示
二、部分代码
1.Book
package entity; /** * BookManagementSystem * 图书 * * @author PlutoCtx * @version 2024/5/26 1:07 * @email ctx195467@163.com * @since JDK17 */ public class Book { /** * 图书id */ private int id; /** * 书名 */ private String bookName; /** * 作者 */ private String author; /** * 图书数量 */ private int number; /** * 价格 */ private Float price; /** * 图书类别 */ private Integer bookTypeId; /** * 图书类别 */ private String bookTypeName; /** * 描述 */ private String bookDesc; public Book(String bookName, String author, Integer number, Float price, Integer bookTypeId, String bookDesc) { super(); this.bookName = bookName; this.author = author; this.number = number; this.price = price; this.bookTypeId = bookTypeId; this.bookDesc = bookDesc; } public Book(int id, String bookName, String author, Integer number, Float price, Integer bookTypeId, String bookDesc) { super(); this.id = id; this.bookName = bookName; this.author = author; this.number = number; this.price = price; this.bookTypeId = bookTypeId; this.bookDesc = bookDesc; } public Book(String bookName, String author, Integer bookTypeId) { super(); this.bookName = bookName; this.author = author; this.bookTypeId = bookTypeId; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public Float getPrice() { return price; } public void setPrice(Float price) { this.price = price; } public Integer getBookTypeId() { return bookTypeId; } public void setBookTypeId(Integer bookTypeId) { this.bookTypeId = bookTypeId; } public String getBookTypeName() { return bookTypeName; } public void setBookTypeName(String bookTypeName) { this.bookTypeName = bookTypeName; } public String getBookDesc() { return bookDesc; } public void setBookDesc(String bookDesc) { this.bookDesc = bookDesc; } public Book() { } public Book(int id, String bookName, String author, Integer number, Float price, Integer bookTypeId, String bookTypeName, String bookDesc) { this.id = id; this.bookName = bookName; this.author = author; this.number = number; this.price = price; this.bookTypeId = bookTypeId; this.bookTypeName = bookTypeName; this.bookDesc = bookDesc; } }
2.BookDao
package dao; import entity.Book; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; /** * BookManagementSystem * * @author PlutoCtx * @version 2024/5/26 9:27 * @email ctx195467@163.com * @since JDK17 */ public class BookDao { /** * 添加图书 * @param connection 连接数据库 * @param book 书籍 * @return preparedStatement.executeUpdate(),int * @throws Exception how do I know */ public int add(Connection connection, Book book)throws Exception{ String sql = "INSERT INTO book VALUES (null, ?, ?, ?, ?, ?, ?)"; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, book.getBookName()); preparedStatement.setString(2, book.getAuthor()); preparedStatement.setInt(3, book.getNumber()); preparedStatement.setFloat(4, book.getPrice()); preparedStatement.setInt(5, book.getBookTypeId()); preparedStatement.setString(6, book.getBookDesc()); return preparedStatement.executeUpdate(); } /** * 查找书籍 * @param connection 连接数据库 * @param book 书籍 * @return preparedStatement.executeUpdate(), int * @throws Exception how do I know */ public ResultSet list(Connection connection, Book book)throws Exception{ StringBuilder stringBuffer = new StringBuilder("SELECT * FROM book b,bookType bt WHERE b.bookTypeId = bt.id"); if(book.getBookName() != null && !book.getBookName().equals("")){ stringBuffer.append(" and b.bookName like '%").append(book.getBookName()).append("%'"); } if(book.getAuthor() != null && !book.getAuthor().equals("")){ stringBuffer.append(" and b.author like '%").append(book.getAuthor()).append("%'"); } if(book.getBookTypeId() != null && book.getBookTypeId()!=-1){ stringBuffer.append(" and b.bookTypeId=").append(book.getBookTypeId()); } PreparedStatement preparedStatement = connection.prepareStatement(stringBuffer.toString()); return preparedStatement.executeQuery(); } /** * 删除书籍 * @param connection 连接数据库 * @param id 书籍id号 * @return preparedStatement.executeUpdate(), int * @throws Exception how do I know */ public int delete(Connection connection,String id)throws Exception{ String sql = "DELETE FROM book " + "WHERE id = ?"; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, id); return preparedStatement.executeUpdate(); } /** * 更新书籍 * @param connection 连接数据库 * @param book 书籍 * @return preparedStatement.executeUpdate(),int * @throws Exception how do I know */ public int update(Connection connection,Book book) throws Exception{ String sql = "UPDATE book " + "SET bookName = ?, author = ?, number = ?, price = ?, bookDesc = ?, bookTypeId = ? " + "WHERE id = ?"; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, book.getBookName()); preparedStatement.setString(2, book.getAuthor()); preparedStatement.setInt(3, book.getNumber()); preparedStatement.setFloat(4, book.getPrice()); preparedStatement.setString(5, book.getBookDesc()); preparedStatement.setInt(6, book.getBookTypeId()); preparedStatement.setInt(7, book.getId()); return preparedStatement.executeUpdate(); } /** * 判断书籍是否存在 * @param connection 数据库连接 * @param bookTypeId 书类号 * @return 存在与否 * @throws Exception 异常多了什么都有可能 */ public boolean existBookByBookTypeId(Connection connection,String bookTypeId)throws Exception{ String sql = "SELECT * FROM book WHERE bookTypeId = ?"; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, bookTypeId); ResultSet rs = preparedStatement.executeQuery(); return rs.next(); } }
3.DBUtil
package utils; import java.sql.Connection; import java.sql.DriverManager; /** * BookManagementSystem * 数据库连接 * * @author PlutoCtx * @version 2024/5/26 8:06 * @email ctx195467@163.com * @since JDK17 */ public class DBUtil { /** 数据库 */ private String url = "jdbc:mysql://localhost:3306/BookBorrowingManagementSystem"; /** * 用户名 */ private String username = "root"; /** * 密码 */ private String password = "Shangxiao111"; /** * 驱动名称 */ private String jdbcName = "com.mysql.cj.jdbc.Driver"; /** * 获取数据库连接 * @return 返回连接 * @throws Exception 没连上 */ public Connection getConnection() throws Exception{ Class.forName(jdbcName); Connection connection = DriverManager.getConnection(url, username, password); return connection; } /** * 关闭数据库连接 * @param connection 数据库连接 * @throws Exception 异常 */ public void closeConnection(Connection connection) throws Exception{ if (connection != null){ connection.close(); } } }
4.BookAddInternalFrame
package view.adminOperation; import dao.BookDao; import dao.BookTypeDao; import entity.Book; import entity.BookType; import utils.DBUtil; import javax.swing.*; import javax.swing.border.LineBorder; import java.awt.event.ActionEvent; import java.sql.Connection; import java.sql.ResultSet; import java.util.Objects; import java.util.logging.Logger; /** * BookManagementSystem * 图书添加界面 * * @author PlutoCtx * @version 2024/5/26 9:08 * @email ctx195467@163.com * @since JDK17 */ public class BookAddInternalFrame extends JInternalFrame { private final JTextField bookNameTxt; private final JTextField authorTxt; private final JTextField bookNumberTxt; private final ButtonGroup buttonGroup = new ButtonGroup(); private final JTextField priceTxt; private final JComboBox bookTypeJcb; private final JTextArea bookDescTxt; private final DBUtil dbUtil = new DBUtil(); private final BookTypeDao bookTypeDao = new BookTypeDao(); private final BookDao bookDao = new BookDao(); /** * Create the frame. */ public BookAddInternalFrame() { setClosable(true); setIconifiable(true); setTitle("图书添加"); setBounds(100, 100, 450, 467); JLabel label = new JLabel("图书名称:"); bookNameTxt = new JTextField(); bookNameTxt.setColumns(10); JLabel label1 = new JLabel("图书作者:"); authorTxt = new JTextField(); authorTxt.setColumns(10); JLabel label2 = new JLabel("图书数量:"); bookNumberTxt = new JTextField(); bookNumberTxt.setColumns(10); JLabel label3 = new JLabel("图书价格:"); priceTxt = new JTextField(); priceTxt.setColumns(10); JLabel label4 = new JLabel("图书描述:"); bookDescTxt = new JTextArea(); JLabel label5 = new JLabel("图书类别:"); bookTypeJcb = new JComboBox(); JButton button = new JButton("添加"); button.addActionListener(this::bookAddActionPerformed); button.setIcon(new ImageIcon(Objects.requireNonNull(BookAddInternalFrame.class.getResource("/add.png")))); JButton button1 = new JButton("重置"); button1.addActionListener(this::resetValueActionPerformed); button1.setIcon(new ImageIcon(Objects.requireNonNull(BookAddInternalFrame.class.getResource("/reset.png")))); GroupLayout groupLayout = new GroupLayout(getContentPane()); groupLayout.setHorizontalGroup( groupLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(groupLayout.createSequentialGroup() .addGap(42) .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(groupLayout.createSequentialGroup() .addComponent(button) .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(button1) .addGap(232)) .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(label5) .addGroup(groupLayout.createSequentialGroup() .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.TRAILING) .addComponent(label4) .addComponent(label2) .addComponent(label)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(groupLayout.createSequentialGroup() .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addComponent(bookNameTxt, GroupLayout.PREFERRED_SIZE, 88, GroupLayout.PREFERRED_SIZE) .addComponent(bookNumberTxt, GroupLayout.PREFERRED_SIZE, 88, GroupLayout.PREFERRED_SIZE) .addComponent(bookTypeJcb, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(35) .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addGroup(groupLayout.createSequentialGroup() .addComponent(label1) .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(authorTxt, GroupLayout.PREFERRED_SIZE, 91, GroupLayout.PREFERRED_SIZE)) .addGroup(groupLayout.createSequentialGroup() .addComponent(label3) .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(priceTxt)))) .addComponent(bookDescTxt)) .addContainerGap(44, Short.MAX_VALUE))))) ); groupLayout.setVerticalGroup( groupLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(groupLayout.createSequentialGroup() .addGap(42) .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(label) .addComponent(bookNameTxt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(label1) .addComponent(authorTxt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addGap(29) .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(label2) .addComponent(bookNumberTxt) .addComponent(label3) .addComponent(priceTxt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addGap(33) .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(label5) .addComponent(bookTypeJcb, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addGap(30) .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(label4) .addComponent(bookDescTxt, GroupLayout.PREFERRED_SIZE, 137, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 37, Short.MAX_VALUE) .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(button) .addComponent(button1)) .addGap(42)) ); getContentPane().setLayout(groupLayout); /* * 设置文本域边框 */ bookDescTxt.setBorder(new LineBorder(new java.awt.Color(127,157,185), 1, false)); fillBookType(); } /** * 重置事件处理 * @param e event */ private void resetValueActionPerformed(ActionEvent e) { this.resetValue(); } /** * 图书添加事件处理 * @param event event */ private void bookAddActionPerformed(ActionEvent event) { String bookName = this.bookNameTxt.getText(); String author = this.authorTxt.getText(); String price = this.priceTxt.getText(); String bookDesc = this.bookDescTxt.getText(); if(bookName == null || "".equals(bookName.trim())){ JOptionPane.showMessageDialog(null, "图书名称不能为空"); return; } if(author == null || "".equals(author.trim())){ JOptionPane.showMessageDialog(null, "图书作者不能为空"); return; } if(price == null || "".equals(price.trim())){ JOptionPane.showMessageDialog(null, "图书价格不能为空"); return; } String bookNumber = bookNumberTxt.getText(); int numberOfBook = bookNumber.isEmpty() ? 0 : Integer.parseInt(bookNumber); BookType bookType = (BookType) bookTypeJcb.getSelectedItem(); int bookTypeId = bookType.getId(); Book book = new Book(bookName,author, numberOfBook, Float.parseFloat(price) , bookTypeId, bookDesc); Connection con = null; try{ con = dbUtil.getConnection(); int addNum = bookDao.add(con, book); if(addNum == 1){ JOptionPane.showMessageDialog(null, "图书添加成功"); resetValue(); }else{ JOptionPane.showMessageDialog(null, "图书添加失败"); } }catch(Exception e){ e.printStackTrace(); JOptionPane.showMessageDialog(null, "图书添加失败"); }finally{ try { dbUtil.closeConnection(con); } catch (Exception e) { e.printStackTrace(); } } } /** * 重置表单 */ private void resetValue(){ this.bookNameTxt.setText(""); this.authorTxt.setText(""); this.priceTxt.setText(""); this.bookNumberTxt.setText(""); this.bookDescTxt.setText(""); if(this.bookTypeJcb.getItemCount()>0){ this.bookTypeJcb.setSelectedIndex(0); } } /** * 初始化图书类别下拉框 */ private void fillBookType(){ Connection con = null; BookType bookType = null; try{ con = dbUtil.getConnection(); ResultSet rs = bookTypeDao.list(con, new BookType()); while(rs.next()){ bookType = new BookType(); bookType.setId(rs.getInt("id")); bookType.setBookTypeName(rs.getString("bookTypeName")); this.bookTypeJcb.addItem(bookType); } }catch(Exception e){ e.printStackTrace(); }finally{ Logger.getGlobal().info("finished!"); } } }
5.Login
package view; import dao.UserDao; import entity.User; import utils.DBUtil; import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.plaf.FontUIResource; import java.awt.*; import java.awt.event.ActionEvent; import java.sql.Connection; import java.util.Enumeration; import java.util.Objects; /** * BookManagementSystem * 登录界面 * * @author PlutoCtx * @version 2024/5/26 8:17 * @email ctx195467@163.com * @since JDK17 */ public class Login extends JFrame { private JPanel contentPane; private final JTextField userNameText; private final JPasswordField passwordText; private final DBUtil dbUtil = new DBUtil(); private final UserDao userDao = new UserDao(); /** * Create the frame */ public Login(){ //改变系统默认字体 Font font = new Font("Dialog", Font.PLAIN, 12); Enumeration<Object> keys = UIManager.getDefaults().keys(); while (keys.hasMoreElements()){ Object key = keys.nextElement(); Object value = UIManager.get(key); if (value instanceof FontUIResource){ UIManager.put(key, font); } } setResizable(false); // 用户登录 setTitle("用户登录"); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setBounds(500,250,450,343); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5,5,5,5)); setContentPane(contentPane); JLabel lblNewLabel = new JLabel("图书管理系统"); lblNewLabel.setFont(new Font("宋体", Font.BOLD, 23)); lblNewLabel.setIcon(new ImageIcon(Objects.requireNonNull(getClass().getResource("/logo.png")))); JLabel lblNewLabel1 = new JLabel("用户名:"); lblNewLabel1.setIcon(new ImageIcon(Objects.requireNonNull(getClass().getResource("/userName.png")))); JLabel lblNewLabel2 = new JLabel("密 码:"); lblNewLabel2.setIcon(new ImageIcon(Objects.requireNonNull(getClass().getResource("/password.png")))); userNameText = new JTextField(); userNameText.setColumns(10); passwordText = new JPasswordField(); JButton btnNewButton1 = new JButton("登录"); btnNewButton1.addActionListener(this::loginActionPerformed); btnNewButton1.setIcon(new ImageIcon(Objects.requireNonNull(getClass().getResource("/login.png")))); JButton btnNewButton2 = new JButton("重置"); btnNewButton2.addActionListener(this::resetValueActionPerformed); btnNewButton2.setIcon(new ImageIcon(Objects.requireNonNull(getClass().getResource("/reset.png")))); GroupLayout groupLayoutContentPane = new GroupLayout(contentPane); groupLayoutContentPane.setHorizontalGroup( groupLayoutContentPane.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(groupLayoutContentPane.createSequentialGroup() .addGroup(groupLayoutContentPane.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(groupLayoutContentPane.createSequentialGroup() .addGap(111) .addComponent(lblNewLabel)) .addGroup(groupLayoutContentPane.createSequentialGroup() .addGap(101) .addGroup(groupLayoutContentPane.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(lblNewLabel1) .addComponent(lblNewLabel2) .addComponent(btnNewButton1)) .addGap(32) .addGroup(groupLayoutContentPane.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(btnNewButton2) .addGroup(groupLayoutContentPane.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addComponent(passwordText) .addComponent(userNameText, GroupLayout.DEFAULT_SIZE, 128, Short.MAX_VALUE))))) .addContainerGap(111, Short.MAX_VALUE)) ); groupLayoutContentPane.setVerticalGroup( groupLayoutContentPane.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(groupLayoutContentPane.createSequentialGroup() .addGap(30) .addComponent(lblNewLabel) .addGap(26) .addGroup(groupLayoutContentPane.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(groupLayoutContentPane.createSequentialGroup() .addComponent(lblNewLabel1) .addGap(29) .addGroup(groupLayoutContentPane.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(lblNewLabel2) .addComponent(passwordText, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) .addComponent(userNameText, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addGap(36) .addGroup(groupLayoutContentPane.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(btnNewButton1) .addComponent(btnNewButton2)) .addContainerGap(60, Short.MAX_VALUE)) ); contentPane.setLayout(groupLayoutContentPane); // 居中 this.setLocationRelativeTo(null); } /** * 登录事件处理 * @param evt action */ private void loginActionPerformed(ActionEvent evt) { String userName = this.userNameText.getText(); String password = new String(this.passwordText.getPassword()); if (userName == null || userName.equals("")){ JOptionPane.showMessageDialog(null, "用户名不能为空"); return; } if (password == null || password.equals("")){ JOptionPane.showMessageDialog(null, "密码不能为空"); return; } // 调用dao层方法 User user = new User(userName, password); Connection con = null; try { con = dbUtil.getConnection(); User currentUser = userDao.login(con, user); if (currentUser != null){ dispose(); if (currentUser.getStatus() == 1) { new AdminMainFrame(currentUser).setVisible(true); JOptionPane.showMessageDialog(null, "登录成功"); } else { new UserMainFrame(currentUser).setVisible(true); JOptionPane.showMessageDialog(null, "登录成功"); } }else { JOptionPane.showMessageDialog(null, "用户名或密码错误"); } } catch (Exception e) { e.printStackTrace(); }finally { try { dbUtil.closeConnection(con); }catch (Exception e){ e.printStackTrace(); } } } /** * 重置事件处理 * @param evt action */ private void resetValueActionPerformed(ActionEvent evt){ this.userNameText.setText(""); this.passwordText.setText(""); } }
三、配置
1️⃣ 想把文件夹直接导入到你的 idea 中吗?看这里哦!
2️⃣ 你需要打开 navicat 等数据库可视化软件,并且执行 sql 文件夹里的数据库文件。赶快试试吧!
3️⃣ 如果必要的话,记得要修改 DBUtil.java 中的用户名、连接、密码哦。
4️⃣ 最后就是运行 Main 了,期待你的成果!#database #java #idea #navicat #coding #程序猿