上次写了个银行小试牛刀,这次期末考核,尝试了个大一点的家伙,图书管理系统,要求基本不变,但涉及到大量增删改查,让我足足写了6000行代码(冗余估计有一半2333),文章只展示关键代码以及说明,运行截图在最后

项目要求:
数据存到内存,编号是动态的
1:管理员登陆后,可查询所有图书信息,用户信息。管理员能添加和删除用户。
2:用户登录后,每个人最多可借10本书,可借书,还书(相关数量是动态变化的)并且用户的借阅状态要会发生改变。
3:系统支持最多三个用户(包含管理员)同时登录,可切换用户状态(登录和注销)。除管理员外用户只能查询书库实时信息和本人信息。
4:调取当前系统时间,计算罚款(罚金由管理员输入指定,默认罚金为1元,超限时间为30秒,罚金数额=超限时间*默认罚金)
(备注:用户最少5个人,图书最少20种)
5: 输出美观,逻辑清楚。

  1. 项目要求分析

要求清楚了,基本上还是GUI和数据库的使用(jdbc),涉及到大量的增删改查以 及数据处理,还应有清晰的MVC分包,那我们开干

  1. 项目结构
  2. Javaee图书管理 javagui图书管理系统_java

  3. 核心技术
    简单的就不讲了,比如GUI设计,增删改查处理,核心流程一句话即可概括:由View包接收数据,借由Service传至Dao层处理,并完成与数据库的数据交互.数据交互主要使用的是Jdbc中一个叫QueryRunner的工具类完成数据库的增删改查.
  4. 部分代码举例展示

view层中的注册界面

package com.vector.view;

import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

import com.vector.bean.Admin;
import com.vector.bean.User;
import com.vector.bean.UserType;
import com.vector.service.AdminRegister;
import com.vector.service.UserRegister;
import com.vector.service.UserTypeFindByTypeService;
import com.vector.service.impl.AdminRegisterImpl;
import com.vector.service.impl.UserRegisterImpl;
import com.vector.service.impl.UserTypeFindByTypeServiceImpl;

public class Register extends JDialog {
	public void register() {
		this.setTitle("注册");
		int width = Toolkit.getDefaultToolkit().getScreenSize().width;
		int height = Toolkit.getDefaultToolkit().getScreenSize().height;
		this.setBounds(width / 2 - 200, height / 2 - 180, 780, 492);
		// 普通用户注册Tab
		Container c = this.getContentPane();
		c.setLayout(null);
		JTextField name = new JTextField();

		name.setBounds(156, 66, 65, 30);
		name.setFont(new Font("宋体", Font.PLAIN, 18));

		JPasswordField password1 = new JPasswordField();

		password1.setBounds(156, 114, 150, 30);
		password1.setFont(new Font("宋体", Font.PLAIN, 18));
		JPasswordField password2 = new JPasswordField();

		password2.setFont(new Font("宋体", Font.PLAIN, 18));
		password2.setBounds(156, 168, 150, 30);

		JTextField department = new JTextField();
		department.setFont(new Font("宋体", Font.PLAIN, 18));
		department.setBounds(156, 222, 150, 30);

		JTextField sex = new JTextField();
		sex.setFont(new Font("宋体", Font.PLAIN, 16));
		sex.setBounds(462, 66, 65, 30);

		JTextField age = new JTextField();
		age.setBounds(618, 66, 65, 30);
		age.setFont(new Font("宋体", Font.PLAIN, 16));

		JTextField PhoneNumber = new JTextField();
		PhoneNumber.setFont(new Font("宋体", Font.PLAIN, 18));
		PhoneNumber.setBounds(533, 114, 150, 30);
		JButton j1 = new JButton("注册");
		JButton j2 = new JButton("取消");
		j1.setBounds(12, 385, 72, 36);
		j1.setFont(new Font("宋体", Font.PLAIN, 14));
		j2.setBounds(685, 385, 72, 36);
		j2.setFont(new Font("宋体", Font.PLAIN, 14));
		JRadioButton j3 = new JRadioButton("我已阅读服务条款");
		j3.setBounds(340, 335, 150, 40);
		j3.setFont(new Font("宋体", Font.PLAIN, 14));
		JLabel a1 = new JLabel("姓名");
		a1.setFont(new Font("宋体", Font.PLAIN, 20));
		a1.setBounds(96, 60, 40, 40);
		JLabel a2 = new JLabel("密码");
		a2.setFont(new Font("宋体", Font.PLAIN, 20));
		a2.setBounds(96, 108, 40, 40);
		JLabel a3 = new JLabel("再次输入密码");
		a3.setFont(new Font("宋体", Font.PLAIN, 20));
		a3.setBounds(10, 130, 150, 100);
		JLabel a4 = new JLabel("所属系部");
		a4.setFont(new Font("宋体", Font.PLAIN, 20));
		a4.setBounds(49, 187, 100, 100);
		JLabel a5 = new JLabel("性别");
		a5.setFont(new Font("宋体", Font.PLAIN, 20));
		a5.setBounds(395, 30, 100, 100);
		JLabel a6 = new JLabel("年龄");
		a6.setFont(new Font("宋体", Font.PLAIN, 20));
		a6.setBounds(550, 30, 100, 100);
		JLabel a7 = new JLabel("手机号码");
		a7.setFont(new Font("宋体", Font.PLAIN, 20));
		a7.setBounds(425, 78, 100, 100);
		JTextField a8 = new JTextField();
		a8.setBounds(240, 300, 310, 30);
		a8.setText("    <服务条款> :  我说啥就是啥,你看着办");
		a8.setForeground(Color.RED);
		a8.setFont(new Font("宋体", Font.PLAIN, 14));
		JLabel a10 = new JLabel("账号");
		a10.setFont(new Font("宋体", Font.PLAIN, 20));
		a10.setBounds(425, 130, 100, 100);
		JLabel a11 = new JLabel("(6-9位)");
		a11.setFont(new Font("宋体", Font.PLAIN, 14));
		a11.setBounds(330, 114, 60, 24);
		JLabel a12 = new JLabel("(6-9位)");
		a12.setFont(new Font("宋体", Font.PLAIN, 14));
		a12.setBounds(330, 168, 60, 24);
		JLabel a13 = new JLabel("注:普通用户请设置10位账号");
		a13.setFont(new Font("宋体", Font.PLAIN, 14));
		a13.setBounds(425, 220, 300, 24);
		a13.setForeground(Color.RED);
		JTextField account = new JTextField();
		account.setBounds(533, 168, 150, 30);
		account.setFont(new Font("宋体", Font.PLAIN, 18));
		JLabel a16 = new JLabel("身份");
		a16.setFont(new Font("宋体", Font.PLAIN, 20));
		a16.setBounds(240, 60, 40, 40);
		JTextField a17 = new JTextField();
		a17.setBounds(300, 66, 65, 30);
		a17.setFont(new Font("宋体", Font.PLAIN, 18));

		c.add(a1);
		c.add(a2);
		c.add(a3);
		c.add(a4);
		c.add(a5);
		c.add(a6);
		c.add(a7);
		c.add(a8);
		c.add(name);
		c.add(password1);
		c.add(password2);
		c.add(sex);
		c.add(department);
		c.add(age);
		c.add(PhoneNumber);
		c.add(account);
		c.add(j1);
		c.add(j2);
		c.add(j3);
		c.add(a10);
		c.add(a11);
		c.add(a12);
		c.add(a13);
		c.add(a16);
		c.add(a17);

		// 管理员注册Tab
		JPanel JP = new JPanel();
		JP.setLayout(null);
		JLabel a18 = new JLabel("账号");
		a18.setFont(new Font("宋体", Font.PLAIN, 20));
		a18.setBounds(300, 60, 40, 40);
		JLabel a19 = new JLabel("密码");
		a19.setFont(new Font("宋体", Font.PLAIN, 20));
		a19.setBounds(300, 110, 40, 40);
		JLabel a20 = new JLabel("再次输入密码");
		a20.setFont(new Font("宋体", Font.PLAIN, 20));
		a20.setBounds(220, 160, 150, 40);
		JButton a21 = new JButton("注册");
		JButton a22 = new JButton("取消");
		a21.setBounds(12, 385, 72, 36);
		a21.setFont(new Font("宋体", Font.PLAIN, 14));
		a22.setBounds(685, 385, 72, 36);
		a22.setFont(new Font("宋体", Font.PLAIN, 14));
		JRadioButton a23 = new JRadioButton("我已阅读服务条款");
		a23.setBounds(340, 335, 150, 40);
		a23.setFont(new Font("宋体", Font.PLAIN, 14));
		JTextField a24 = new JTextField();
		a24.setBounds(240, 300, 310, 30);
		a24.setText("    <服务条款> :  我说啥就是啥,你看着办");
		a24.setForeground(Color.RED);
		a24.setFont(new Font("宋体", Font.PLAIN, 14));
		JTextField a25 = new JTextField();
		a25.setFont(new Font("宋体", Font.PLAIN, 18));
		a25.setBounds(370, 65, 150, 30);
		JPasswordField a26 = new JPasswordField();
		a26.setBounds(370, 115, 150, 30);
		a26.setFont(new Font("宋体", Font.PLAIN, 18));
		JPasswordField a27 = new JPasswordField();
		a27.setBounds(370, 165, 150, 30);
		a27.setFont(new Font("宋体", Font.PLAIN, 18));
		JLabel a28 = new JLabel("注:管理员请设置6位账号与6位密码");
		a28.setFont(new Font("宋体", Font.PLAIN, 14));
		a28.setBounds(300, 220, 250, 24);
		a28.setForeground(Color.RED);
		JP.add(a18);
		JP.add(a19);
		JP.add(a20);
		JP.add(a21);
		JP.add(a22);
		JP.add(a23);
		JP.add(a24);
		JP.add(a25);
		JP.add(a26);
		JP.add(a27);
		JP.add(a28);

		// Tab
		JTabbedPane tab1 = new JTabbedPane();
		tab1.setFont(new Font("宋体", Font.PLAIN, 14));

		// 创建第 1 个选项卡
		tab1.addTab("普通用户注册", c);
		// 创建第 2 个选项卡
		tab1.addTab("管理员注册", JP);

		this.setContentPane(tab1);

		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				dispose();
			}
		});
		this.setResizable(false);
		this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		this.setVisible(true);
		j2.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				setVisible(false);
			}

		}

		);
		a22.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				setVisible(false);
			}

		}

		);
		j1.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				String d1 = name.getText();
				String d2 = password1.getText();
				String d3 = department.getText();
				String d4 = sex.getText();
				String d5 = age.getText();
				String d6 = PhoneNumber.getText();
				String d7 = account.getText();
				String d8 = a17.getText();
				User us = new User();
				if (d1.length() == 0 || d2.length() < 6 || d2.length() > 9 || d3.length() == 0 || d4.length() == 0
						|| d5.length() == 0 || d6.length() == 0 || d7.length() != 10 || d8.length() == 0) {
					JOptionPane.showMessageDialog(null, "请输入完整信息.", "提示", JOptionPane.CANCEL_OPTION);
				} else {
					if (d2.equals(password2.getText())) {
						if (j3.isSelected()) {

							us.setAccount(d7);
							us.setAge(d5);
							us.setDepartment(d3);
							us.setName(d1);
							us.setPassword(d2);
							us.setPhone(d6);
							us.setSex(d4);
							us.setType(d8);
							UserRegister use = new UserRegisterImpl();
							use.register(us);
							JOptionPane.showMessageDialog(null, "注册成功.", "提示", JOptionPane.INFORMATION_MESSAGE);
							setVisible(false);
						} else {
							JOptionPane.showMessageDialog(null, "请同意服务条款.", "提示", JOptionPane.CANCEL_OPTION);
						}
					} else {
						JOptionPane.showMessageDialog(null, "两次密码不一致.", "提示", JOptionPane.CANCEL_OPTION);
					}
				}
			}

		}

		);
		a21.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				String d1 = a25.getText();
				String d2 = a26.getText();
				Admin ad = new Admin();
				if (d1.length() != 6 || d2.length() == 0) {
					JOptionPane.showMessageDialog(null, "请输入完整信息.", "提示", JOptionPane.CANCEL_OPTION);
				} else {
					if (d2.equals(a27.getText())) {
						if (a23.isSelected()) {
							ad.setAccount(d1);
							ad.setPassword(d2);
							AdminRegister adm = new AdminRegisterImpl();
							adm.register(ad);
							JOptionPane.showMessageDialog(null, "注册成功.", "提示", JOptionPane.INFORMATION_MESSAGE);
							setVisible(false);
						} else {
							JOptionPane.showMessageDialog(null, "请同意服务条款.", "提示", JOptionPane.CANCEL_OPTION);
						}
					} else {
						JOptionPane.showMessageDialog(null, "两次密码不一致.", "提示", JOptionPane.CANCEL_OPTION);
					}
				}
			}

		}

		);

	}

	public static void main(String[] args) {
		Register register = new Register();
		register.register();
	}
}

Utils包中时间处理的工具类

package com.vector.utils;

import java.time.LocalDate;

public class Days {
	/*
	 * 用LocalDate获取两个日期之间的天数,可正可负
	 */
	public static int betweenDays(LocalDate start, LocalDate end) {

		int sy = start.getYear();
		int ey = end.getYear();
		int days;

		if (sy < ey) {
			days = start.lengthOfYear() - start.getDayOfYear();
			for (int i = sy + 1; i < ey; i++) {
				days += LocalDate.of(i, 12, 31).lengthOfYear();
			}
			days += end.getDayOfYear();
		} else if (sy == ey) {
			days = end.getDayOfYear() - start.getDayOfYear();
		} else {
			days = end.lengthOfYear() - end.getDayOfYear();
			for (int i = ey + 1; i < sy; i++) {
				days += LocalDate.of(i, 12, 31).lengthOfYear();
			}
			days += start.getDayOfYear();
			days = -days;
		}
		return days;
	}

	/*
	 * 推算多少天以后,可正可负
	 */
	public static LocalDate reckonDate(LocalDate date, Integer days) {
		if (days >= 0)
			return date.plusDays(days);
		else
			return date.minusDays(-days);
	}

}

Dao层中实现添加入数据库的代码展示

package com.vector.dao.impl;

import java.sql.Connection;

import org.apache.commons.dbutils.QueryRunner;

import com.vector.bean.Admin;
import com.vector.dao.AdminAddDao;
import com.vector.utils.DataSourceUtils;

public class AdminAddDaoImpl implements AdminAddDao {

	public Admin register(Admin ad) {
		// TODO Auto-generated method stub
		Connection conn = null;
		try {
			conn = DataSourceUtils.getConnection();
			QueryRunner qr = new QueryRunner();
			String sql = " insert into admin (  account , password ) values ( ?,?) ";
			Object[] obj = { ad.getAccount(), ad.getPassword() };
			int in = qr.update(conn, sql, obj);
			System.out.println("添加了" + in + "条记录");
		} catch (Exception e1) {
			// TODO: handle exception
		} finally {
			DataSourceUtils.closeResource(conn, null, null);
		}
		return null;
	}

}

c3p0配置

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!-- c3p0默认配置,下面还可以配置多个数据库 -->
    <default-config>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/library?characterEncoding=UTF8&useSSL=false
        </property>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        <property name="initialPoolSize">6</property>
        <property name="maxPoolSize">10</property>
        <property name="maxIdleTime">10000</property>
    </default-config>
</c3p0-config>
  1. 运行截图展示 数据库分表

Javaee图书管理 javagui图书管理系统_java_02



程序运行截图

Javaee图书管理 javagui图书管理系统_数据库_03

Javaee图书管理 javagui图书管理系统_mysql_04

Javaee图书管理 javagui图书管理系统_sql_05

Javaee图书管理 javagui图书管理系统_数据库_06

Javaee图书管理 javagui图书管理系统_sql_07

Javaee图书管理 javagui图书管理系统_mysql_08

Javaee图书管理 javagui图书管理系统_java_09

Javaee图书管理 javagui图书管理系统_Javaee图书管理_10

Javaee图书管理 javagui图书管理系统_数据库_11

Javaee图书管理 javagui图书管理系统_Javaee图书管理_12