第十二章 图书管理系统开发

《Java程序设计实例与操作》(丁永卫)目录

  图书管理系统会因为图书的数量、种类、提供的操作等不同而具有不同的复杂度。基本信息的维护、图书借阅、归还及查询等操作通常是图书管理系统的基本功能。在规模较大、业务较多的图书馆还需要图书的库存管理、销售管理等更加复杂的功能。
在这里插入图片描述

12.1 系统详细设计

一、开发环境

 操作系统:Windows XP
 数据库系统:Access
 编程语言: Java 6.0
 开发工具:Eclipse 3.4

二、数据库设计

  本例采用的数据库类型为Access,数据库名为“图书管理.mdb”,其中包含了3个表,分别是图书信息表book,读者信息表reader,借阅信息表borrow。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、系统模块设计

  (1)MainPro包:主要包括了登录程序、系统主程序、图书和读者信息维护程序、图书借阅管理程序,以及图书和读者信息查询程序等。
在这里插入图片描述
  (2)PublicModule包:其中包含了一组供MainPro包中各类使用的公共类 。
在这里插入图片描述

12.2 公共模块设计

一、DbOp.java

  该类用于完成基本的数据库操作,包括加载数据库驱动,创建数据库连接,执行Sql语句等。其中,其构造方法用于加载数据库驱动程序和创建数据库连接(即打开数据库);
用于查询记录的方法为executeQuery();
用于插入、删除、修改记录的方法为executeUpdate();
用于关闭数据的方法为Close()。

// DbOp.java
package PublicModule;

import java.sql.*;

import javax.swing.JOptionPane;

public class DbOp {
	// JDBC-ODBC驱动程序
	private static String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
	// 数据库url路径
	private static String url = "jdbc:odbc:bookdb";
	private static Connection con = null;

	// 构造方法。如果数据库未打开,则通过创建连接打开数据库
	private DbOp() {
		try {
			// 如果当前未创建连接,则加载JDBC驱动程序,然后创建连接
			if (con == null) {
				Class.forName(driver);
				con = DriverManager.getConnection(url);
			}
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null, "数据库未能打开!");
		}
	}

	 // 执行数据库查询工作。如果出现异常,返回null
	public static ResultSet executeQuery(String sql) {
		try {
			// 如果未创建数据库连接,则创建连接
			if (con == null)
				new DbOp();
			// 返回查询结果
			return con.createStatement().executeQuery(sql);
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, "数据库不存在,或存在错误!");
			return null;
		}
	}

	// 执行数据库更新操作。如果有问题,则返回-1
	public static int executeUpdate(String sql) {
		try {
			// 如果未创建数据库连接,则创建连接
			if (con == null)
				new DbOp();
			// 返回操作结果
			return con.createStatement().executeUpdate(sql);
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, "数据有误,记录无法正常保存或更新!");
			return -1;
		}
	}

	// 关闭数据库
	public static void Close() {
		try {
			// 如果数据库已打开,则关闭之
			if (con != null)
				con.close();
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, "数据库未打开!");
		}
	}
}

二、BookSelect.java与ReaderSelect.java

  这两个类分别用于按图书编号和读者编号查询记录,查询结果将分别保存在Book和Reader对象中。

// BookSelect.java
package PublicModule;

import java.sql.*;

import javax.swing.JOptionPane;

public class BookSelect {
	// 按图书编号查询,查询结果保存在Book类的对象中
	public static Book SelectBookById(String id) {
		String sql = "select * from book where id='" + id + "'";
		ResultSet rs = DbOp.executeQuery(sql);
		Book book = null;
		try {
			if (rs.next()) {
				book = new Book();
				book.setId(rs.getString("id"));
				book.setBooktype(rs.getString("booktype"));
				book.setBookname(rs.getString("bookname"));
				book.setAuthor(rs.getString("author"));
				book.setTranslator(rs.getString("translator"));
				book.setPublisher(rs.getString("publisher"));
				book.setPublish_time(rs.getDate("publish_time"));
				book.setPrice(rs.getFloat("price"));
				book.setStock(rs.getInt("stock"));
			}
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, "无法正常读取数据库!");
		}
		return book;
	}
}
// ReaderSelect.java
package PublicModule;

import java.sql.*;
import javax.swing.JOptionPane;

public class ReaderSelect {
	// 按读者编号查询,结果保存在Reader类的对象中
	public static Reader selectReaderById(String id) {
		String sql = "select * from reader where id='" + id + "'";
		ResultSet rs = DbOp.executeQuery(sql);
		Reader reader = null;
		try {
			if (rs.next()) {
				reader = new Reader();
				reader.setId(rs.getString("id"));
				reader.setReadername(rs.getString("readername"));
				reader.setReadertype(rs.getString("readertype"));
				reader.setSex(rs.getString("sex"));
				reader.setMax_num(rs.getInt("max_num"));
				reader.setDays_num(rs.getInt("days_num"));
			}
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, "无法正常读取数据库!");
		}
		return reader;
	}
}

三、IfBorrowBack.java

  该类中的findbook()方法用于查询指定读者是否借阅过指定图书。如果已经借阅且未归还,返回true,否则,返回false。

// IfBorrowBack.java
package PublicModule;

import java.sql.ResultSet;
import java.sql.SQLException;

import javax.swing.JOptionPane;

public class IfBorrowBack {
	// 查指定读者是否借过指定图书且未归还
	public static boolean findbook(String bookid, String readerid) {
		String sql;
		sql = "select * from borrow where book_id='";
		sql = sql + bookid + "' and reader_id='" + readerid + "' and ";
		sql = sql + "if_back='否'";
		ResultSet rs = DbOp.executeQuery(sql);
		try {
			// 如果指定读者借阅了指定图书,且未归还,返回true,否则返回false
			if (rs.next())
				return true;
			else
				return false;
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, "数据库查询失败!");
		}
		return true;
	}
}

四、公共模块中的其他类

  (1)GlobalVar.java
  (2)Book.java
  (3)Reader.java

// GlobalVar.java
package PublicModule;
public class GlobalVar {
	// 该变量用来保存登录用户名
	public static String login_user;
}

// Book.java
package PublicModule;

import java.sql.Date;

public class Book {
	private String id;
	private String bookname;
	private String booktype;
	private String author;
	private String translator;
	private String publisher;
	private Date publish_time;
	private int stock;
	private float price;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getBookname() {
		return bookname;
	}

	public void setBookname(String name) {
		this.bookname = name;
	}

	public String getBooktype() {
		return booktype;
	}

	public void setBooktype(String type) {
		this.booktype = type;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getTranslator() {
		return translator;
	}

	public void setTranslator(String translator) {
		this.translator = translator;
	}

	public String getPublisher() {
		return publisher;
	}

	public void setPublisher(String publisher) {
		this.publisher = publisher;
	}

	public Date getPublish_time() {
		return publish_time;
	}

	public void setPublish_time(Date publish_time) {
		this.publish_time = publish_time;
	}

	public int getStock() {
		return stock;
	}

	public void setStock(int stock) {
		this.stock = stock;
	}

	public float getPrice() {
		return price;
	}

	public void setPrice(float price) {
		this.price = price;
	}

}

// Reader.java
package PublicModule;

public class Reader {
	private String id;
	private String readername;
	private String readertype;
	private String sex;
	private int max_num;
	private int days_num;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getReadername() {
		return readername;
	}

	public void setReadername(String name) {
		this.readername = name;
	}

	public String getReadertype() {
		return readertype;
	}

	public void setReadertype(String type) {
		this.readertype = type;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public int getMax_num() {
		return max_num;
	}

	public void setMax_num(int max_num) {
		this.max_num = max_num;
	}

	public int getDays_num() {
		return days_num;
	}

	public void setDays_num(int days_num) {
		this.days_num = days_num;
	}
}

12.3 主模块设计

一、Login.java

  登录模块用于实现用户登录功能,也是进入系统的入口。进行系统登录时,需要输入用户名和密码,系统会查询数据库中的user表,验证用户名和密码是否正确。
在这里插入图片描述

// Login.java
package MainPro;

import java.awt.*;
import java.awt.event.*;
import java.sql.*;

import javax.swing.JOptionPane;

import PublicModule.*;

public class Login extends Frame {
	private static final long serialVersionUID = -1758475247807861408L;
	TextField text_user;
	TextField text_pass;

	public Login() {
		this.setTitle("登录");
		this.setLayout(null);
		this.setSize(260, 170);
		/* 添加标签与文本框 */
		Label lbUser = new Label("用户名:");
		Label lbPass = new Label("密    码:");
		Button btn_ok = new Button("确定");
		Button btn_cancel = new Button("取消");
		text_pass = new TextField();
		text_user = new TextField();
		lbUser.setBounds(40, 53, 60, 20);
		lbPass.setBounds(40, 83, 60, 20);
		text_user.setBounds(100, 50, 120, 20);
		text_pass.setBounds(100, 80, 120, 20);
		btn_ok.setBounds(45, 120, 80, 25); // 确定按钮
		btn_ok.addActionListener((new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_okActionPerformed(e);
			}
		}));
		btn_cancel.setBounds(135, 120, 80, 25); // 取消按钮
		btn_cancel.addActionListener((new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				DbOp.Close(); // 关闭数据库
				System.exit(0);
			}
		}));
		/* 关闭窗口 */
		this.addWindowListener(new WindowAdapter() {
			// 重写windowClosing()方法
			public void windowClosing(WindowEvent e) {
				DbOp.Close(); // 关闭数据库
				System.exit(0);
			}
		});
		add(lbUser);
		add(lbPass);
		add(text_user);
		add(text_pass);
		add(btn_ok);
		add(btn_cancel);
		setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
		this.setVisible(true); // 使窗体可见
	}

	public void btn_okActionPerformed(ActionEvent e) {
		String user = text_user.getText();
		String pass = text_pass.getText();
		String is_admin;
		// 如果用户名或密码任一为空,则终止后续操作
		if (user.equals("")||pass.equals("")) {
			JOptionPane.showMessageDialog(null, "用户名或密码不能为空!");
			return;
		}
		try {
			// 核对用户名和密码
			String sql = "select * from user where username=" + "'" + user
					+ "'and password=" + "'" + pass + "'";
			ResultSet rs = DbOp.executeQuery(sql);
			// 如果此用户存在,则记录其状态(否:不是管理员,是:是管理员)
			if (rs.next()) {
				is_admin = rs.getString("is_admin");
			} else {
				JOptionPane.showMessageDialog(null, "用户名或密码不正确!");
				return;
			}
			GlobalVar.login_user = user; // 记录登录的用户名
			ShowMain show = new ShowMain(); // 调用主程序
			// 只有管理员才能使用"基础管理"和"借阅管理"菜单
			show.setRights(is_admin);
			// 释放窗体及其全部组件的屏幕资源,即使释放登录窗体
			dispose(); // 释放当前窗体
		} catch (SQLException e1) {
			JOptionPane.showMessageDialog(null, "用户数据库有误!");
		}

	}

	public static void main(String[] args) {
		new Login();
	}
}

二、ShowMain.java

   成功登录系统后即进入系统的主界面。需要注意的是,系统会根据登录的用户类型(普通用户和管理员),决定“系统维护”和“借阅管理”菜单是否可用。
在这里插入图片描述

// ShowMain.java
package MainPro;

import java.awt.*;
import java.awt.event.*;

import PublicModule.DbOp;

public class ShowMain extends Frame {
	private static final long serialVersionUID = 5003296786441785470L;
	MenuBar menuBar1;
	Menu menu1, menu2, menu3, menu4, menu5, menu6, menu7;
	MenuItem mi_book_add, mi_book_update, mi_book_delete, mi_reader_add,
			mi_reader_update, mi_reader_delete, mi_borrow, mi_back,
			mi_query_book, mi_query_reader, mi_update_pass, mi_exit;

	public void setRights(String rights) {
		// 如果不是管理员,则禁止用户维护图书信息和读者信息
		// 以及禁止进行借阅管理,即只能查询
		if (rights.equals("否")) {
			menu1.setEnabled(false);
			menu5.setEnabled(false);
		}
	}

	public ShowMain() {
		setTitle("图书管理系统");
		setLayout(new BorderLayout());
		setSize(640, 480);
		menuBar1 = new MenuBar();
		menu5 = new Menu("基础维护");// 基础维护菜单
		menu6 = new Menu("图书维护");// 图书维护菜单
		mi_book_add = new MenuItem("添加");// 添加图书菜单
		mi_book_update = new MenuItem("修改");// 修改图书菜单
		mi_book_delete = new MenuItem("删除");// 删除图书菜单
		menu7 = new Menu("读者维护");// 读者维护菜单
		mi_reader_add = new MenuItem("添加读者");// 添加读者菜单
		mi_reader_update = new MenuItem("修改读者");
		mi_reader_delete = new MenuItem("删除读者");
		menu1 = new Menu("借阅管理");
		mi_borrow = new MenuItem("借书管理");
		mi_back = new MenuItem("还书管理");
		menu2 = new Menu("查询管理");
		mi_query_book = new MenuItem("图书查询");
		mi_query_reader = new MenuItem("读者查询");
		menu3 = new Menu("系统管理");
		mi_update_pass = new MenuItem("修改密码");
		mi_exit = new MenuItem("退出系统");
		// 添加图书菜单
		mi_book_add.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new BookAdd();
			}
		});
		mi_book_update.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new BookUpdate();
			}
		});
		mi_book_delete.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new BookDelete();
			}
		});
		mi_reader_add.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new ReaderAdd();
			}
		});
		mi_reader_update.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new ReaderUpdate();
			}
		});
		mi_reader_delete.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new ReaderDelete();
			}
		});

		mi_borrow.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new Borrow();
			}
		});

		mi_back.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new Back();
			}
		});
		mi_query_book.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new BookQuery();
			}
		});
		mi_query_reader.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new ReaderQuery();
			}
		});

		mi_update_pass.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new UpdatePassword();
			}
		});
		mi_exit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				DbOp.Close(); // 关闭数据库
				System.exit(0);
			}
		});
		/* 关闭窗口 */
		this.addWindowListener(new WindowAdapter() {
			// 重写windowClosing()方法
			public void windowClosing(WindowEvent e) {
				DbOp.Close(); // 关闭数据库
				System.exit(0);
			}
		});
		menu5.add(menu6);
		menu6.add(mi_book_add);
		menu6.add(mi_book_update);
		menu6.add(mi_book_delete);
		menu5.add(menu7);
		menu7.add(mi_reader_add);
		menu7.add(mi_reader_update);
		menu7.add(mi_reader_delete);
		menu5.add(menu1);
		menu1.add(mi_borrow);
		menu1.add(mi_back);
		menu5.add(menu2);
		menu2.add(mi_query_book);
		menu2.add(mi_query_reader);
		menu5.add(menu3);
		menu3.add(mi_update_pass);
		menu3.add(mi_exit);
		menuBar1.add(menu5);
		menuBar1.add(menu1);
		menuBar1.add(menu2);
		menuBar1.add(menu3);
		setMenuBar(menuBar1);
		setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
		setVisible(true); // 使窗体可见
	}

	// 增加main()方法,主要为了调试程序界面
	public static void main(String[] args) {
		new ShowMain();
	}
}

三、 BookAdd.java

  该模块用于输入图书信息。其设计要点主要有:① 为确保图书编号的唯一性,图书编号不能重复;② 当出版时间、定价、库存数量无效时,可通过捕捉异常来处理;③ 正常输入并保存记录后,要给出提示信息;④ 输入并保存一个记录后,应清空文本框,让用户能够继续输入下一个记录。
在这里插入图片描述

// BookAdd.java
package MainPro;

import java.awt.*;
import java.awt.event.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import javax.swing.JOptionPane;

import PublicModule.*;

public class BookAdd extends Frame {
	private static final long serialVersionUID = 377287301994613384L;
	Label lbbookid = new Label("图书编号");
	Label lbbookname = new Label("图书名称");
	Label lbbooktype = new Label("图书类别");
	Label lbauthor = new Label("作者");
	Label lbtranslator = new Label("译者");
	Label lbpublisher = new Label("出版社");
	Label lbpublish_time = new Label("出版时间");
	Label lbprice = new Label("定价");
	Label lbstock = new Label("库存数量");
	Button saveBtn = new Button("保存");
	Button closeBtn = new Button("关闭");
	TextField tf_bookid = new TextField();
	TextField tf_bookname = new TextField();
	TextField tf_author = new TextField();
	TextField tf_translator = new TextField();
	TextField tf_publisher = new TextField();
	TextField tf_publish_time = new TextField();
	TextField tf_price = new TextField();
	TextField tf_stock = new TextField();
	Choice tf_booktype = new Choice();

	BookAdd() {
		setLayout(null);
		setTitle("添加图书");
		setSize(500, 250);
		lbbookid.setBounds(50, 50, 50, 20); // 图书编号
		tf_bookid.setBounds(110, 50, 100, 20);
		lbbookname.setBounds(240, 50, 50, 20); // 图书名称
		tf_bookname.setBounds(300, 50, 100, 20);
		lbbooktype.setBounds(50, 80, 50, 20); // 图书类别
		tf_booktype.setBounds(110, 80, 100, 20);
		tf_booktype.add("科技");
		tf_booktype.add("文学");
		tf_booktype.add("社科");
		tf_booktype.add("其他");
		lbauthor.setBounds(240, 80, 50, 20); // 作者
		tf_author.setBounds(300, 80, 100, 20);
		lbtranslator.setBounds(50, 110, 50, 20); // 设置译者
		tf_translator.setBounds(110, 110, 100, 20);
		lbpublisher.setBounds(240, 110, 50, 20); // 出版社
		tf_publisher.setBounds(300, 110, 100, 20);
		lbpublish_time.setBounds(50, 140, 50, 20); // 出版时间
		tf_publish_time.setBounds(110, 140, 100, 20);
		lbprice.setBounds(240, 140, 50, 20); // 定价
		tf_price.setBounds(300, 140, 100, 20);
		lbstock.setBounds(50, 170, 50, 20); // 库存数量
		tf_stock.setBounds(110, 170, 100, 20);

		saveBtn.setBounds(150, 210, 80, 25); // 保存按钮
		saveBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_saveActionPerformed(e);
			}
		});
		closeBtn.setBounds(280, 210, 80, 25);// 关闭按钮
		closeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dispose(); // 释放当前窗体
			}
		});
		/* 关闭窗口 */
		this.addWindowListener(new WindowAdapter() {
			// 重写windowClosing()方法
			public void windowClosing(WindowEvent e) { // 关闭当前窗口
				dispose(); // 释放当前窗体
			}
		});
		add(lbbookid);
		add(lbbookname);
		add(lbbooktype);
		add(lbauthor);
		add(lbtranslator);
		add(lbpublisher);
		add(lbpublish_time);
		add(lbprice);
		add(lbstock);
		add(saveBtn);
		add(closeBtn);
		add(tf_bookid);
		add(tf_bookname);
		add(tf_author);
		add(tf_translator);
		add(tf_publisher);
		add(tf_publish_time);
		add(tf_price);
		add(tf_stock);
		add(tf_booktype);
		setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
		setVisible(true); // 使窗体可见
	}

	// 保存记录
	private void btn_saveActionPerformed(ActionEvent e) {
		String id = tf_bookid.getText();
		String bookname = tf_bookname.getText();
		String booktype = tf_booktype.getSelectedItem().toString();
		String author = tf_author.getText();
		String translator = tf_translator.getText();
		String publisher = tf_publisher.getText();
		String publish_time = tf_publish_time.getText();
		// 如果图书编号为空,则终止保存记录操作
		if (id.equals("")) {
			JOptionPane.showMessageDialog(null, "图书编号不能为空!");
			return;
		}
		// 如果图书编号重复,则记录无效,需修改图书编号
		if (IfBookIdExit(id)) {
			JOptionPane.showMessageDialog(null, "图书编号重复!");
			return;
		}
		try {
			// -------------------------------------------------
			// 以下程序用于检查日期是否有效。如果日期无效,则会
			// 产生ParseException异常
			// 创建一个简单日期格式对象,注意:MM一定要用大写
			// 这是用户输入日期的格式:年-月,如2010-7、2009-10等
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
			// 将字符串转换为日期。如果日期无效,将抛出ParseException异常
			// 因此,本语句主要用来判断日期格式是否有效
			sdf.parse(tf_publish_time.getText());
			// -------------------------------------------------
			float price = Float.parseFloat(tf_price.getText());
			int stock = Integer.parseInt(tf_stock.getText());
			// 将记录保存到book表中
			String sql = "insert into book(id,bookname,booktype,"
					+ "author,translator,"
					+ "publisher,publish_time,price,stock) values('" + id
					+ "','" + bookname + "','" + booktype + "','" + author
					+ "','" + translator + "','" + publisher + "','"
					+ publish_time + "','" + price + "','" + stock + "')";
			int i = DbOp.executeUpdate(sql);
			if (i == 1) {
				JOptionPane.showMessageDialog(null, "图书添加成功!");
				// 清空全部文本框
				clearAllTextfield();
			}
		} catch (ParseException e2) {
			JOptionPane.showMessageDialog(null, "出版时间格式错误(年—月)!");
		} catch (NumberFormatException e1) {
			JOptionPane.showMessageDialog(null, "库存数量和价格错误,应为数字!");
		}
	}

	// 判断Book表中是否存在指定编号的图书,如果存在,返回true,否则,返回false
	private boolean IfBookIdExit(String id) {
		String sql = "select * from book where id='" + id + "'";
		ResultSet rs = DbOp.executeQuery(sql);
		try {
			if (rs.next())
				return true;
			else
				return false;
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, "无法正常读取数据库!");
		}
		return false;
	}

	// 清空全部文本框
	private void clearAllTextfield() {
		tf_bookid.setText("");
		tf_bookname.setText("");
		tf_author.setText("");
		tf_translator.setText("");
		tf_publisher.setText("");
		tf_publish_time.setText("");
		tf_price.setText("");
		tf_stock.setText("");
	}

	// 增加main()方法,主要为了调试程序界面
	public static void main(String[] args) {
		new BookAdd();
	}
}

四、BookUpdate.java

  该模块用来修改图书信息。使用该功能模块时,用户应首先在“图书编号”编辑框中输入要修改图书的图书编号,然后单击“查询”按钮,将所选图书的其他数据显示出来,接下来就可以对这些数据进行修改了。
在这里插入图片描述

// BookUpdate.java
package MainPro;

import java.awt.*;
import java.awt.event.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import javax.swing.JOptionPane;

import PublicModule.*;

public class BookUpdate extends Frame {
	private static final long serialVersionUID = -7074630570516408587L;
	Label lbbookid_1 = new Label("图书编号");
	Label lbbookid = new Label("图书编号");
	Label lbbookname = new Label("图书名称");
	Label lbbooktype = new Label("图书类别");
	Label lbauthor = new Label("作者");
	Label lbtranslator = new Label("译者");
	Label lbpublisher = new Label("出版社");
	Label lbpublish_time = new Label("出版时间");
	Label lbprice = new Label("定价");
	Label lbstock = new Label("库存数量");
	Button saveBtn = new Button("保存");
	Button closeBtn = new Button("关闭");
	Button queryBtn = new Button("查询");
	TextField tf_bookid_1 = new TextField();
	TextField tf_bookid = new TextField();
	TextField tf_bookname = new TextField();
	TextField tf_author = new TextField();
	TextField tf_translator = new TextField();
	TextField tf_publisher = new TextField();
	TextField tf_publish_time = new TextField();
	TextField tf_price = new TextField();
	TextField tf_stock = new TextField();
	Choice tf_booktype = new Choice();

	public BookUpdate() {
		setLayout(null);
		setTitle("修改图书");
		setSize(500, 280);
		lbbookid_1.setBounds(100, 40, 50, 20); // 图书编号
		tf_bookid_1.setBounds(160, 40, 100, 20);
		queryBtn.setBounds(280, 40, 80, 20); // 查询按钮
		queryBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_queryActionPerformed(e);
			}
		});
		lbbookid.setBounds(50, 80, 50, 20); // 图书编号
		tf_bookid.setBounds(110, 80, 100, 20);
		tf_bookid.setEditable(false); // 禁止修改图书编号
		lbbookname.setBounds(240, 80, 50, 20); // 图书名称
		tf_bookname.setBounds(300, 80, 100, 20);
		lbbooktype.setBounds(50, 110, 50, 20); // 图书类别
		tf_booktype.setBounds(110, 110, 100, 20);
		tf_booktype.add("科技");
		tf_booktype.add("文学");
		tf_booktype.add("社科");
		tf_booktype.add("其他");
		lbauthor.setBounds(240, 110, 50, 20); // 作者
		tf_author.setBounds(300, 110, 100, 20);
		lbtranslator.setBounds(50, 140, 50, 20); // 译者
		tf_translator.setBounds(110, 140, 100, 20);
		lbpublisher.setBounds(240, 140, 50, 20); // 出版社
		tf_publisher.setBounds(300, 140, 100, 20);
		lbpublish_time.setBounds(50, 170, 50, 20); // 出版时间
		tf_publish_time.setBounds(110, 170, 100, 20);
		lbprice.setBounds(240, 170, 50, 20); // 价格
		tf_price.setBounds(300, 170, 100, 20);
		lbstock.setBounds(50, 200, 50, 20); // 库存数量
		tf_stock.setBounds(110, 200, 100, 20);

		saveBtn.setBounds(150, 240, 80, 25); // 保存按钮
		saveBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_saveActionPerformed(e);
			}

		});
		closeBtn.setBounds(280, 240, 80, 25); // 关闭按钮
		closeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dispose(); // 释放当前窗体
			}
		});

		/* 关闭窗口 */
		this.addWindowListener(new WindowAdapter() {
			// 重写windowClosing()方法
			public void windowClosing(WindowEvent e) {
				dispose(); // 释放当前窗体
			}
		});
		add(lbbookid);
		add(lbbookid_1);
		add(lbbookname);
		add(lbbooktype);
		add(lbauthor);
		add(lbtranslator);
		add(lbpublisher);
		add(lbpublish_time);
		add(lbprice);
		add(lbstock);
		add(saveBtn);
		add(closeBtn);
		add(queryBtn);
		add(tf_bookid);
		add(tf_bookname);
		add(tf_author);
		add(tf_translator);
		add(tf_publisher);
		add(tf_publish_time);
		add(tf_price);
		add(tf_stock);
		add(tf_bookid_1);
		add(tf_booktype);
		setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
		setVisible(true); // 使窗体可见
	}

	// 按图书编号查询图书记录
	public void btn_queryActionPerformed(ActionEvent e)  {
		String id = tf_bookid_1.getText();
		// 如果图书编号为空,则查询操作终止
		if (id.equals("")) {
			JOptionPane.showMessageDialog(null, "图书编号不能为空!");
			return;
		}
		// 按编号查询图书,结果存入book对象中
		Book book = BookSelect.SelectBookById(id);
		// 如果查询到结果,将其显示在各文本框中
		if (book != null) {
			tf_bookid.setText(book.getId());
			tf_bookname.setText(book.getBookname());
			// 将Choice的选定项设置为其名称等于指定字符串的项
			tf_booktype.select(book.getBooktype());
			tf_author.setText(book.getAuthor());
			tf_translator.setText(book.getTranslator());
			tf_publisher.setText(book.getPublisher());
			tf_publish_time.setText(book.getPublish_time().toString());
			tf_price.setText(String.valueOf(book.getPrice()));
			tf_stock.setText(String.valueOf(book.getStock()));
		} else
			JOptionPane.showMessageDialog(null, "图书编号有误,查无此书!");
	}

	// 保存修改的记录
	private void btn_saveActionPerformed(ActionEvent e) {
		String id = tf_bookid.getText();
		String bookname = tf_bookname.getText();
		String booktype = tf_booktype.getSelectedItem().toString();
		String author = tf_author.getText();
		String translator = tf_translator.getText();
		String publisher = tf_publisher.getText();
		String publish_time = tf_publish_time.getText();
		// 如果图书编号为空,则终止保存记录操作
		if (id.equals("")) {
			JOptionPane.showMessageDialog(null, "图书编号不能为空!");
			return;
		}
		try {
			// -------------------------------------------------
			// 以下程序用于检查日期是否有效。如果日期无效,则会
			// 产生ParseException异常
			// 创建一个简单日期格式对象,注意:MM一定要用大写
			// 这是用户输入日期的格式:年-月,如2010-7、2009-10等
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
			// 将字符串转换为日期
			sdf.parse(tf_publish_time.getText());
			// -------------------------------------------------
			float price = Float.parseFloat(tf_price.getText());
			int stock = Integer.parseInt(tf_stock.getText());
			String sql = "update book set bookname='" + bookname
					+ "',booktype='" + booktype + "',author='" + author
					+ "',translator='" + translator + "',publisher='"
					+ publisher + "',publish_time='" + publish_time
					+ "',price='" + price + "',stock='" + stock
					+ "' where id='" + id + "'";
			int i = DbOp.executeUpdate(sql);
			if (i == 1) {
				JOptionPane.showMessageDialog(null, "图书信息修改成功!");
				// 清空全部文本框
				clearAllTextfield();
			} else
				JOptionPane.showMessageDialog(null, "数据有误,图书信息修改失败!");
		} catch (ParseException e2) {
			JOptionPane.showMessageDialog(null, "出版时间格式错误(年—月)!");
		} catch (NumberFormatException e1) {
			JOptionPane.showMessageDialog(null, "价格或库存数量错误,应为数字!");
		}
	}

	// 清空全部文本框
	private void clearAllTextfield() {
		tf_bookid_1.setText("");
		tf_bookid.setText("");
		tf_bookname.setText("");
		tf_author.setText("");
		tf_translator.setText("");
		tf_publisher.setText("");
		tf_publish_time.setText("");
		tf_price.setText("");
		tf_stock.setText("");
	}

	public static void main(String[] args) {
		new BookUpdate();
	}
}

五、BookDelete.java

  该模块用于根据图书编号删除所选图书。执行删除操作时,用户应首先在“图书编号”编辑框中输入要删除的图书编号,然后单击“查询”按钮,调出该图书的相关信息,供用户进行确认。如果确认无误,即可单击“删除”按钮删除所选图书。
在这里插入图片描述

// BookDelete.java
package MainPro;

import java.awt.*;
import java.awt.event.*;
import javax.swing.JOptionPane;

import PublicModule.*;

public class BookDelete extends Frame {
	private static final long serialVersionUID = 7451605980497182697L;
	Label lbbookid_1 = new Label("图书编号");
	Label lbbookid = new Label("图书编号");
	Label lbbookname = new Label("图书名称");
	Label lbbooktype = new Label("图书类别");
	Label lbauthor = new Label("作者");
	Label lbtranslator = new Label("译者");
	Label lbpublisher = new Label("出版社");
	Label lbpublish_time = new Label("出版时间");
	Label lbprice = new Label("定价");
	Label lbstock = new Label("库存数量");
	Button saveBtn = new Button("删除");
	Button closeBtn = new Button("关闭");
	Button queryBtn = new Button("查询");
	TextField tf_bookid = new TextField();
	TextField tf_bookname = new TextField();
	TextField tf_author = new TextField();
	TextField tf_translator = new TextField();
	TextField tf_publisher = new TextField();
	TextField tf_publish_time = new TextField();
	TextField tf_price = new TextField();
	TextField tf_stock = new TextField();
	TextField tf_bookid1 = new TextField();
	Choice tf_booktype = new Choice();

	public BookDelete() {
		setLayout(null);
		setTitle("删除图书");
		setSize(500, 280);
		lbbookid_1.setBounds(100, 40, 50, 20);// 图书编号
		tf_bookid1.setBounds(160, 40, 100, 20);
		queryBtn.setBounds(280, 40, 80, 20); // 查询按钮
		queryBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_queryActionPerformed(e);
			}
		});
		lbbookid.setBounds(50, 80, 50, 20); // 图书编号
		tf_bookid.setBounds(110, 80, 100, 20);
		lbbookname.setBounds(240, 80, 50, 20); // 图书名称
		tf_bookname.setBounds(300, 80, 100, 20);
		lbbooktype.setBounds(50, 110, 50, 20); // 图书类别
		tf_booktype.setBounds(110, 110, 100, 20);
		tf_booktype.add("科技");
		tf_booktype.add("文学");
		tf_booktype.add("社科");
		tf_booktype.add("其他");
		lbauthor.setBounds(240, 110, 50, 20); // 作者
		tf_author.setBounds(300, 110, 100, 20);
		lbtranslator.setBounds(50, 140, 50, 20); // 译者
		tf_translator.setBounds(110, 140, 100, 20);
		lbpublisher.setBounds(240, 140, 50, 20); // 出版社
		tf_publisher.setBounds(300, 140, 100, 20);
		lbpublish_time.setBounds(50, 170, 50, 20); // 出版时间
		tf_publish_time.setBounds(110, 170, 100, 20);
		lbprice.setBounds(240, 170, 50, 20); // 价格
		tf_price.setBounds(300, 170, 100, 20);
		lbstock.setBounds(50, 200, 50, 20);// 库存数量
		tf_stock.setBounds(110, 200, 100, 20);

		saveBtn.setBounds(150, 240, 80, 25); // 删除按钮
		saveBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_delActionPerformed(e);

			}
		});
		closeBtn.setBounds(280, 240, 80, 25); // 关闭按钮
		closeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dispose(); // 释放当前窗体
			}
		});

		/* 关闭窗口 */
		this.addWindowListener(new WindowAdapter() {
			// 重写windowClosing()方法
			public void windowClosing(WindowEvent e) {
				dispose(); // 释放当前窗体
			}
		});
		add(lbbookid); // 将各组件增加到窗体中
		add(lbbookid_1);
		add(lbbookname);
		add(lbbooktype);
		add(lbauthor);
		add(lbtranslator);
		add(lbpublisher);
		add(lbpublish_time);
		add(lbprice);
		add(lbstock);
		add(saveBtn);
		add(closeBtn);
		add(queryBtn);
		add(tf_bookid);
		add(tf_bookname);
		add(tf_author);
		add(tf_translator);
		add(tf_publisher);
		add(tf_publish_time);
		add(tf_price);
		add(tf_stock);
		add(tf_bookid1);
		add(tf_booktype);
		setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
		setVisible(true); // 使窗体可见
	}

	private void btn_delActionPerformed(ActionEvent e) {
		String id = tf_bookid.getText();
		// 如果图书编号为空,则删除操作终止
		if (id.equals("")) {
			JOptionPane.showMessageDialog(null, "图书编号不能为空!");
			return;
		}
		String sql = "delete from book where id='" + id + "'";
		int i = DbOp.executeUpdate(sql);
		if (i == 1) {
			JOptionPane.showMessageDialog(null, "图书信息删除成功!");
			// 清空全部文本框
			clearAllTextfield();
		} else
			JOptionPane.showMessageDialog(null, "图书信息删除失败!");
	}

	private void btn_queryActionPerformed(ActionEvent e) {
		String id = tf_bookid1.getText();
		// 如果图书编号为空,则查询操作终止
		if (id.equals("")) {
			JOptionPane.showMessageDialog(null, "图书编号不能为空!");
			return;
		}
		// 按编号查询图书,结果存入book对象中
		Book book = BookSelect.SelectBookById(id);
		// 如果查询到结果,将其显示在各文本框中
		if (book != null) {
			tf_bookid.setText(book.getId());
			tf_bookid.setEditable(false);
			tf_bookname.setText(book.getBookname());
			// 将Choice的选定项设置为其名称等于指定字符串的项
			tf_booktype.select(book.getBooktype());
			tf_author.setText(book.getAuthor());
			tf_translator.setText(book.getTranslator());
			tf_publisher.setText(book.getPublisher());
			tf_publish_time.setText(book.getPublish_time().toString());
			tf_price.setText(String.valueOf((book.getPrice())));
			tf_stock.setText(String.valueOf(book.getStock()));
		} else
			JOptionPane.showMessageDialog(null, "图书编号有误,查无此书!");
	}

	// 清空全部文本框
	private void clearAllTextfield() {
		tf_bookid1.setText("");
		tf_bookid.setText("");
		tf_bookname.setText("");
		tf_author.setText("");
		tf_translator.setText("");
		tf_publisher.setText("");
		tf_publish_time.setText("");
		tf_price.setText("");
		tf_stock.setText("");
	}

	// 增加main()方法,主要为了调试程序界面
	public static void main(String[] args) {
		new BookDelete();
	}
}

六、BookQuery.java

  该模块用于根据图书名称、作者、出版社、出版时间等信息进行图书查询。这四个条件之间的关系为逻辑与关系。如果在某个编辑框中不输入内容,则忽略该条件。如果在四个编辑框中均不输入任何内容,表示显示全部图书信息。
在这里插入图片描述

// BookQuery.java
package MainPro;

import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import java.text.*;
import java.util.*;
import java.util.Date;

import javax.swing.*;

import PublicModule.*;

public class BookQuery extends JFrame {
	private static final long serialVersionUID = -3045513015088987091L;
	JTable table;
	JScrollPane scrollPane;
	Label lbbookname = new Label("图书名称");
	Label lbauthor = new Label("作        者");
	Label lbpublisher = new Label("出  版  社");
	Label lbpublish_time = new Label("出版时间");
	Label lbnotes = new Label("(年—月)");
	TextField tf_bookname = new TextField("");
	TextField tf_author = new TextField("");
	TextField tf_publisher = new TextField("");
	TextField tf_publish_time = new TextField("");
	Button queryBtn = new Button("查询");
	Button closeBtn = new Button("关闭");
	String[] heads = { "图书编号", "图书名称", "图书类别", "作者", "译者", "出版社", "出版日期", "定价",
			"库存数量" };

	// 构造方法
	public BookQuery() {
		setTitle("图书查询"); // 设置窗体标题
		setSize(800, 500); // 设置窗体尺寸
		setLayout(null); // 取消窗体布局
		lbbookname.setBounds(170, 20, 50, 20); // 书名
		tf_bookname.setBounds(230, 20, 160, 20);
		lbauthor.setBounds(410, 20, 50, 20); // 作者
		tf_author.setBounds(470, 20, 160, 20);
		lbpublisher.setBounds(170, 50, 50, 20); // 出版社
		tf_publisher.setBounds(230, 50, 160, 20);
		lbpublish_time.setBounds(410, 40, 50, 20); // 出版时间
		lbnotes.setBounds(405, 60, 60, 20);
		tf_publish_time.setBounds(470, 50, 160, 20);

		queryBtn.setBounds(300, 90, 80, 25); // 查询按钮
		queryBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_queryActionPerformed(e);
			}
		});
		closeBtn.setBounds(420, 90, 80, 25);// 关闭按钮
		closeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dispose(); // 释放当前窗体
			}
		});

		/* 关闭窗口 */
		this.addWindowListener(new WindowAdapter() {
			// 重写windowClosing()方法
			public void windowClosing(WindowEvent e) {
				dispose(); // 释放当前窗体
			}
		});
		add(lbbookname); // 将各组件添加到窗体中
		add(tf_bookname);
		add(lbauthor);
		add(tf_author);
		add(lbpublisher);
		add(tf_publisher);
		add(lbpublish_time);
		add(lbnotes);
		add(tf_publish_time);
		add(queryBtn);
		add(closeBtn);
		setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
		setVisible(true); // 使窗体可见
	}

	private void btn_queryActionPerformed(ActionEvent e) {
		try {
			String bookname, author, publisher, publishtime;
			String sql, sql1, sql2, sql3, sql4, sql5;
			String pubyear, pubmonth;
			bookname = tf_bookname.getText();
			author = tf_author.getText();
			publisher = tf_publisher.getText();
			publishtime = tf_publish_time.getText();
			// 创建一条基本的SQL语句,表示选出表中全部记录
			sql = "select * from book ";
			// 如果书名不空,生成sql1字句
			if (bookname.equals(""))
				sql1 = "";
			else
				sql1 = " bookname like '" + bookname + "%' ";
			// 如果作者不空,生成sql2字句
			if (author.equals(""))
				sql2 = "";
			else {
				sql2 = " author like '" + author + "%' ";
				if (!bookname.equals("")) // 如果书名不为空
					sql2 = " and " + sql2;
			}
			// 如果出版社不空,生成sql3字句
			if (publisher.equals(""))
				sql3 = "";
			else {
				sql3 = "publisher like '" + publisher + "%' ";
				// 如果书名和作者有一项不为空
				if (!(bookname.equals("") && author.equals("")))
					sql3 = " and " + sql3;
			}
			// 如果出版日期不空,生成sql4字句
			if (publishtime.equals("")) {
				sql4 = "";
			} else {
				// 创建一个简单日期格式对象,注意:MM一定要用大写
				// 这是用户输入日期的格式:年-月,如2010-7、2009-10等
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
				// 创建一个Calendar对象
				Calendar cal = new GregorianCalendar();
				// 将字符串转换为日期
				Date pubtime = sdf.parse(tf_publish_time.getText());
				// 使用给定日期设置cal的时间
				cal.setTime(pubtime);
				// 获取年
				pubyear = String.valueOf(cal.get(Calendar.YEAR));
				// 获取月
				pubmonth = String.valueOf(cal.get(Calendar.MONTH) + 1);
				sql4 = " year(publish_time)=" + pubyear + " and ";
				sql4 = sql4 + "month(publish_time)=" + pubmonth;
				// 如果书名、作者或出版社有一项不为空
				if (!(bookname.equals("") && author.equals("") && publisher
						.equals("")))
					sql4 = " and " + sql4;
			}
			sql5 = sql1 + sql2 + sql3 + sql4;
			// 如果已设置任意一项条件,则修改SQL语句
			if (!sql5.equals("")) {
				sql = sql + " where " + sql5;
			}
			// 执行查询
			ResultSet rs = DbOp.executeQuery(sql);
			// 创建一个对象二维数组
			Object[][] bookq = new Object[30][heads.length];
			int i = 0; // 定义一个变量
			while (rs.next()) { // 将查询结果赋予Book数组
				bookq[i][0] = rs.getString("id");
				bookq[i][1] = rs.getString("bookname");
				bookq[i][2] = rs.getString("booktype");
				bookq[i][3] = rs.getString("author");
				bookq[i][4] = rs.getString("translator");
				bookq[i][5] = rs.getString("publisher");
				bookq[i][6] = rs.getDate("publish_time");
				bookq[i][7] = rs.getFloat("price");
				bookq[i][8] = rs.getInt("stock");
				i++;
			}
			table = new JTable(bookq, heads); // 创建一个表格
			// 创建一个显示表格的JScrollPane
			scrollPane = new JScrollPane(table);
			// 设置JScrollPane的位置和尺寸
			scrollPane.setBounds(20, 140, 760, 300);
			// 将JScrollPane添加到窗体中
			add(scrollPane);
		} catch (ParseException e2) {
			JOptionPane.showMessageDialog(null, "出版时间格式错误(年—月)!");
		} catch (SQLException e1) {
			JOptionPane.showMessageDialog(null, "数据库不存在,或存在错误!");
		}
	}

	// 为了便于调试程序,特别创建main方法
	public static void main(String[] args) {
		new BookQuery();
	}
}

七、读者信息的录入、修改、删除和查询模块

  读者信息的录入、修改、删除和查询模块与图书相关模块在功能和设计上完全类似。

// ReaderAdd.java
package MainPro;

import java.awt.*;
import java.awt.event.*;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.swing.JOptionPane;

import PublicModule.*;

public class ReaderAdd extends Frame {
	private static final long serialVersionUID = -2399939451497711745L;
	Label lbreaderid = new Label("读者编号");
	Label lbreadername = new Label("读者姓名");
	Label lbreadertype = new Label("读者类别");
	Label lbsex = new Label("性别");
	Label lbmax_num = new Label("可借数量");
	Label lbdays_num = new Label("可借天数");
	TextField tf_readerid = new TextField();
	TextField tf_readername = new TextField();
	TextField tf_max_num = new TextField();
	TextField tf_days_num = new TextField();
	Choice tf_readertype = new Choice();
	Choice tf_sex = new Choice();
	Button saveBtn = new Button("保存");
	Button closeBtn = new Button("关闭");

	public ReaderAdd() {
		setLayout(null);
		setTitle("添加读者信息");
		setSize(500, 200);
		lbreaderid.setBounds(50, 50, 50, 20); // 读者编号
		tf_readerid.setBounds(110, 50, 100, 20);
		lbreadername.setBounds(240, 50, 50, 20); // 读者姓名
		tf_readername.setBounds(300, 50, 100, 20);
		lbreadertype.setBounds(50, 80, 50, 20); // 读者类别
		tf_readertype.setBounds(110, 80, 100, 20);
		tf_readertype.add("教师");
		tf_readertype.add("学生");
		tf_readertype.add("职工");
		lbsex.setBounds(240, 80, 50, 20); // 性别
		tf_sex.setBounds(300, 80, 100, 20);
		tf_sex.add("男");
		tf_sex.add("女");
		lbmax_num.setBounds(50, 110, 50, 20); // 最大可借数
		tf_max_num.setBounds(110, 110, 100, 20);
		lbdays_num.setBounds(240, 110, 50, 20); // 最大可借天数
		tf_days_num.setBounds(300, 110, 100, 20);

		saveBtn.setBounds(150, 150, 80, 25); // 保存按钮
		saveBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_saveActionPerformed(e);
			}
		});
		closeBtn.setBounds(280, 150, 80, 25);// 关闭按钮
		closeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dispose(); // 释放当前窗体
			}
		});

		/* 关闭窗口 */
		this.addWindowListener(new WindowAdapter() {
			// 重写windowClosing()方法
			public void windowClosing(WindowEvent e) {
				dispose(); // 释放当前窗体
			}
		});
		add(lbreaderid);
		add(lbreadername);
		add(lbreadertype);
		add(lbsex);
		add(lbmax_num);
		add(lbdays_num);
		add(tf_readerid);
		add(tf_readername);
		add(tf_max_num);
		add(tf_days_num);
		add(tf_readertype);
		add(tf_sex);
		add(saveBtn);
		add(closeBtn);
		setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
		setVisible(true); // 使窗体可见
	}

	private void btn_saveActionPerformed(ActionEvent e) {
		String id = tf_readerid.getText();
		String name = tf_readername.getName();
		String type = tf_readertype.getSelectedItem().toString();
		String sex = tf_sex.getSelectedItem().toString();
		// 如果读者编号为空,则终止保存记录操作
		if (id.equals("")) {
			JOptionPane.showMessageDialog(null, "读者编号不能为空!");
			return;
		}
		// 如果读者编号重复,则记录无效,需修改读者编号
		if (IfReaderIdExit(id)) {
			JOptionPane.showMessageDialog(null, "读者编号重复!");
			return;
		}
		try {
			int max_num = Integer.parseInt(tf_max_num.getText());
			int days_num = Integer.parseInt(tf_days_num.getText());
			String sql = "insert into reader(id,name,type,sex,"
					+ "max_num,days_num) values('" + id + "','" + name + "','"
					+ type + "','" + sex + "','" + max_num + "','" + days_num
					+ "')";
			int i = DbOp.executeUpdate(sql);
			if (i == 1) {
				JOptionPane.showMessageDialog(null, "读者添加成功!");
				// 清空全部文本框
				clearAllTextfield();
			}
		} catch (NumberFormatException e1) {
			JOptionPane.showMessageDialog(null, "最大可借数或"
					+ "最大可借天数错误,应为整数!");
		}
	}

	// 判断Reader表中是否存在指定编号的读者,如果存在,返回true,否则,返回false
	private boolean IfReaderIdExit(String id) {
		String sql = "select * from reader where id='" + id + "'";
		ResultSet rs = DbOp.executeQuery(sql);
		try {
			if (rs.next())
				return true;
			else
				return false;
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, "无法正常读取数据库!");
		}
		return false;
	}

	// 清空全部文本框
	private void clearAllTextfield() {
		tf_readerid.setText("");
		tf_readername.setText("");
		tf_max_num.setText("");
		tf_days_num.setText("");
	}

	// 增加main()方法,主要为了调试程序界面
	public static void main(String[] args) {
		new ReaderAdd();
	}
}

// ReaderUpdate.java
package MainPro;

import java.awt.*;
import java.awt.event.*;
import javax.swing.JOptionPane;

import PublicModule.*;

public class ReaderUpdate extends Frame {
	private static final long serialVersionUID = -4657058729583467505L;
	Label lbreaderid_1 = new Label("读者编号");
	Label lbreaderid = new Label("读者编号");
	Label lbreadername = new Label("读者姓名");
	Label lbreadertype = new Label("读者类别");
	Label lbsex = new Label("性别");
	Label lbmax_num = new Label("可借数量");
	Label lbdays_num = new Label("可借天数");
	TextField tf_readerid1 = new TextField();
	TextField tf_readerid = new TextField();
	TextField tf_readername = new TextField();
	TextField tf_max_num = new TextField();
	TextField tf_days_num = new TextField();
	Choice tf_readertype = new Choice();
	Choice tf_sex = new Choice();
	Button queryBtn = new Button("查询");
	Button saveBtn = new Button("保存");
	Button closeBtn = new Button("关闭");

	public ReaderUpdate() {
		setLayout(null);
		setTitle("修改读者信息");
		setSize(500, 240);
		lbreaderid_1.setBounds(100, 40, 50, 20); // 读者编号
		tf_readerid1.setBounds(160, 40, 100, 20);
		queryBtn.setBounds(290, 40, 80, 20); // 查询按钮
		queryBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_queryActionPerformed(e);
			}
		});
		lbreaderid.setBounds(50, 80, 50, 20); // 读者编号
		tf_readerid.setBounds(110, 80, 100, 20);
		tf_readerid.setEditable(false); // 禁止修改读者编号
		lbreadername.setBounds(240, 80, 50, 20); // 读者姓名
		tf_readername.setBounds(300, 80, 100, 20);
		lbreadertype.setBounds(50, 110, 50, 20); // 读者类别
		tf_readertype.setBounds(110, 110, 100, 20);
		tf_readertype.add("教师");
		tf_readertype.add("学生");
		tf_readertype.add("职工");
		lbsex.setBounds(240, 110, 50, 20); // 性别
		tf_sex.setBounds(300, 110, 100, 20);
		tf_sex.add("男");
		tf_sex.add("女");
		lbmax_num.setBounds(50, 140, 50, 20); // 最大可借数
		tf_max_num.setBounds(110, 140, 100, 20);
		lbdays_num.setBounds(240, 140, 50, 20); // 最大可借天数
		tf_days_num.setBounds(300, 140, 100, 20);

		saveBtn.setBounds(150, 180, 80, 25); // 保存按钮
		saveBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_saveActionPerformed(e);
			}
		});
		closeBtn.setBounds(280, 180, 80, 25);// 关闭按钮
		closeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dispose(); // 释放当前窗体
			}
		});

		/* 关闭窗口 */
		this.addWindowListener(new WindowAdapter() {
			// 重写windowClosing()方法
			public void windowClosing(WindowEvent e) {
				dispose(); // 释放当前窗体
			}
		});
		add(lbreaderid_1);
		add(lbreaderid);
		add(lbreadername);
		add(lbreadertype);
		add(lbsex);
		add(lbmax_num);
		add(lbdays_num);
		add(tf_readerid1);
		add(tf_readerid);
		add(tf_readername);
		add(tf_max_num);
		add(tf_days_num);
		add(tf_readertype);
		add(tf_sex);
		add(saveBtn);
		add(closeBtn);
		add(queryBtn);
		setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
		setVisible(true); // 使窗体可见
	}

	private void btn_queryActionPerformed(ActionEvent e) {
		String id = tf_readerid1.getText();
		// 如果读者编号为空,则终止查询操作
		if (id.equals("")) {
			JOptionPane.showMessageDialog(null, "读者编号不能为空!");
			return;
		}
		// 按编号查询读者,结果存入reader对象中
		Reader reader = ReaderSelect.selectReaderById(id);
		// 如果查询到结果,将其显示在各文本框中
		if (reader != null) {
			tf_readerid.setText(reader.getId());
			tf_readername.setText(reader.getReadername());
			// 将Choice的选定项设置为其名称等于指定字符串的项
			tf_readertype.select(reader.getReadertype());
			tf_sex.select(reader.getSex());
			tf_days_num.setText(String.valueOf(reader.getDays_num()));
			tf_max_num.setText(String.valueOf(reader.getMax_num()));
		} else
			JOptionPane.showMessageDialog(null, "读者编号有误,查无此人!");
	}

	private void btn_saveActionPerformed(ActionEvent e) {
		String id = tf_readerid.getText();
		String readername = tf_readername.getText();
		String readertype = tf_readertype.getSelectedItem().toString();
		// 如果读者编号为空,则终止保存记录操作
		if (id.equals("")) {
			JOptionPane.showMessageDialog(null, "读者编号不能为空!");
			return;
		}
		try {
			int max_num = Integer.parseInt(tf_max_num.getText());
			int days_num = Integer.parseInt(tf_days_num.getText());
			String sex = tf_sex.getSelectedItem().toString();
			String sql = "update reader set readername='" + readername
					+ "',readertype='" + readertype + "',days_num='" + days_num
					+ "',sex='" + sex + "',max_num='" + max_num
					+ "' where id='" + id + "'";
			int i = DbOp.executeUpdate(sql);
			if (i == 1) {
				JOptionPane.showMessageDialog(null, "读者信息修改成功!");
				// 清空全部文本框
				clearAllTextfield();
			} else
				JOptionPane.showMessageDialog(null, "读者信息修改失败!");
		} catch (NumberFormatException e1) {
			JOptionPane.showMessageDialog(null, "最大可借数或最大可借" 
					+ "天数错误,应为整数!");
		}
	}

	// 清空全部文本框
	private void clearAllTextfield() {
		tf_readerid1.setText("");
		tf_readerid.setText("");
		tf_readername.setText("");
		tf_max_num.setText("");
		tf_days_num.setText("");
	}

	// 增加main()方法,主要为了调试程序界面
	public static void main(String[] args) {
		new ReaderUpdate();
	}
}

// ReaderDelete.java
package MainPro;

import java.awt.*;
import java.awt.event.*;
import javax.swing.JOptionPane;

import PublicModule.*;

public class ReaderDelete extends Frame {
	private static final long serialVersionUID = 8992814149454286463L;
	Label lbreaderid = new Label("读者编号");
	Label lbreaderid_1 = new Label("读者编号");
	Label lbreadername = new Label("读者姓名");
	Label lbreadertype = new Label("读者类别");
	Label lbsex = new Label("性别");
	Label lbmax_num = new Label("可借数量");
	Label lbdays_num = new Label("可借天数");
	TextField tf_readerid = new TextField();
	TextField tf_readername = new TextField();
	TextField tf_max_num = new TextField();
	TextField tf_days_num = new TextField();
	TextField tf_readerid1 = new TextField();
	Choice tf_readertype = new Choice();
	Choice tf_sex = new Choice();
	Button queryBtn = new Button("查询");
	Button delBtn = new Button("删除");
	Button closeBtn = new Button("关闭");

	public ReaderDelete() {
		setLayout(null);
		setTitle("删除读者信息");
		setSize(500, 240);
		lbreaderid_1.setBounds(100, 40, 50, 20); // 读者编号
		tf_readerid1.setBounds(160, 40, 100, 20);
		queryBtn.setBounds(290, 40, 80, 20); // 查询按钮
		queryBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_queryActionPerformed(e);
			}
		});
		lbreaderid.setBounds(50, 80, 50, 20); // 读者编号
		tf_readerid.setBounds(110, 80, 100, 20);
		lbreadername.setBounds(240, 80, 50, 20); // 读者姓名
		tf_readername.setBounds(300, 80, 100, 20);
		lbreadertype.setBounds(50, 110, 50, 20); // 读者类别
		tf_readertype.setBounds(110, 110, 100, 20);
		tf_readertype.add("教师");
		tf_readertype.add("学生");
		tf_readertype.add("职工");
		lbsex.setBounds(240, 110, 50, 20); // 性别
		tf_sex.setBounds(300, 110, 100, 20);
		tf_sex.add("男");
		tf_sex.add("女");
		lbmax_num.setBounds(50, 140, 50, 20); // 最大可借数
		tf_max_num.setBounds(110, 140, 100, 20);
		lbdays_num.setBounds(240, 140, 50, 20); // 最大可借天数
		tf_days_num.setBounds(300, 140, 100, 20);

		delBtn.setBounds(150, 180, 80, 25); // 删除按钮
		delBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_delActionPerformed(e);
			}
		});
		closeBtn.setBounds(280, 180, 80, 25); // 关闭按钮
		closeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dispose(); // 释放当前窗体
			}
		});

		/* 关闭窗口 */
		this.addWindowListener(new WindowAdapter() {
			// 重写windowClosing()方法
			public void windowClosing(WindowEvent e) {
				dispose(); // 释放当前窗体
			}
		});
		add(lbreaderid); // 将各组件添加到窗体中
		add(lbreaderid_1);
		add(lbreadername);
		add(lbreadertype);
		add(lbsex);
		add(lbmax_num);
		add(lbdays_num);
		add(tf_readerid);
		add(tf_readername);
		add(tf_max_num);
		add(tf_days_num);
		add(tf_readerid1);
		add(tf_readertype);
		add(tf_sex);
		add(delBtn);
		add(closeBtn);
		add(queryBtn);
		setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
		setVisible(true); // 使窗体可见
	}

	private void btn_delActionPerformed(ActionEvent e) {
		String id = tf_readerid.getText();
		// 如果读者编号为空,则终止删除操作
		if (id.equals("")) {
			JOptionPane.showMessageDialog(null, "读者编号不能为空!");
			return;
		}
		String sql = "delete from reader where id='" + id + "'";
		int i = DbOp.executeUpdate(sql);
		if (i == 1) {
			JOptionPane.showMessageDialog(null, "读者信息删除成功!");
			// 清空全部文本框
			clearAllTextfield();
		} else
			JOptionPane.showMessageDialog(null, "读者编号有误,查无此人!");
	}

	private void btn_queryActionPerformed(ActionEvent e) {
		String id = tf_readerid1.getText();
		if (id.equals("")) {
			JOptionPane.showMessageDialog(null, "读者编号不能为空!");
			return;
		}
		// 按编号查询读者,结果存入reader对象中
		Reader reader = ReaderSelect.selectReaderById(id);
		// 如果查询到结果,将其显示在各文本框中
		if (reader != null) {
			tf_readerid.setText(reader.getId());
			tf_readerid.setEditable(false);
			tf_readername.setText(reader.getReadername());
			// 将Choice的选定项设置为其名称等于指定字符串的项
			tf_readertype.select(reader.getReadertype());
			tf_sex.select(reader.getSex());
			tf_max_num.setText(String.valueOf(reader.getMax_num()));
			tf_days_num.setText(String.valueOf(reader.getDays_num()));
		} else
			JOptionPane.showMessageDialog(null, "读者编号有误,查无此人!");
	}

	// 清空全部文本框
	private void clearAllTextfield() {
		tf_readerid1.setText("");
		tf_readerid.setText("");
		tf_readername.setText("");
		tf_max_num.setText("");
		tf_days_num.setText("");
	}

	// 增加main()方法,主要为了调试程序界面
	public static void main(String[] args) {
		new ReaderDelete();
	}
}

// ReaderQuery.java
package MainPro;

import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import javax.swing.*;
import PublicModule.*;

public class ReaderQuery extends JFrame {
	private static final long serialVersionUID = -7717113202745852409L;
	JTable table;
	JScrollPane scrollPane;
	Label lbreadername = new Label("读者姓名");
	Label lbreadertype = new Label("读者类型");
	TextField tf_readername = new TextField("");
	TextField tf_readertype = new TextField("");
	Button queryBtn = new Button("查询");
	Button closeBtn = new Button("关闭");
	String[] heads = { "读者编号", "读者姓名", "读者类型", 
			"读者性别", "最大可借数", "可借天数" };

	// 构造方法
	public ReaderQuery() {
		setTitle("读者查询"); // 设置窗体标题
		setSize(600, 500); // 设置窗体尺寸
		setLayout(null); // 取消窗体布局
		lbreadername.setBounds(70, 20, 50, 20); // 读者姓名
		tf_readername.setBounds(130, 20, 160, 20);
		lbreadertype.setBounds(310, 20, 50, 20); // 读者类别
		tf_readertype.setBounds(370, 20, 160, 20);
		queryBtn.setBounds(200, 60, 80, 25); // 查询按钮
		queryBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_queryActionPerformed(e);
			}
		});
		closeBtn.setBounds(320, 60, 80, 25); // 关闭按钮
		closeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dispose(); // 释放当前窗体
			}
		});

		/* 关闭窗口 */
		this.addWindowListener(new WindowAdapter() {
			// 重写windowClosing()方法
			public void windowClosing(WindowEvent e) {
				dispose(); // 释放当前窗体
			}
		});
		add(lbreadername); // 将各组件添加到窗体中
		add(tf_readername);
		add(lbreadertype);
		add(tf_readertype);
		add(queryBtn);
		add(closeBtn);
		setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
		setVisible(true); // 使窗体可见
	}

	private void btn_queryActionPerformed(ActionEvent e) {
		try {
			String readername, readertype;
			String sql, sql1, sql2, sql3;
			readername = tf_readername.getText();
			readertype = tf_readertype.getText();
			// 创建一条基本的SQL语句,表示选出表中全部记录
			sql = "select * from reader ";
			// 如果读者姓名不空,生成sql1字句
			if (readername.equals(""))
				sql1 = "";
			else
				sql1 = " readername like '" + readername + "%' ";
			// 如果作者不空,生成sql2字句
			if (readertype.equals(""))
				sql2 = "";
			else {
				sql2 = " readertype like '" + readertype + "%' ";
				if (!readername.equals("")) // 如果书名不为空
					sql2 = " and " + sql2;
			}
			sql3 = sql1 + sql2;
			// 如果已设置任意一项条件,则修改SQL语句
			if (!sql3.equals("")) {
				sql = sql + " where " + sql3;
			}
			// 执行查询
			ResultSet rs = DbOp.executeQuery(sql);
			// 创建一个对象二维数组
			Object[][] readerq = new Object[30][heads.length];
			int i = 0; // 定义一个变量
			while (rs.next()) { // 将查询结果赋予Book数组
				readerq[i][0] = rs.getString("id");
				readerq[i][1] = rs.getString("readername");
				readerq[i][2] = rs.getString("readertype");
				readerq[i][3] = rs.getString("sex");
				readerq[i][4] = rs.getString("max_num");
				readerq[i][5] = rs.getString("days_num");
				i++;
			}
			table = new JTable(readerq, heads); // 创建一个表格
			// 创建一个显示表格的JScrollPane
			scrollPane = new JScrollPane(table);
			// 设置JScrollPane的位置和尺寸
			scrollPane.setBounds(20, 120, 560, 300);
			// 将JScrollPane添加到窗体中
			add(scrollPane);
		} catch (SQLException e1) {
			JOptionPane.showMessageDialog(null, "数据库不存在,或存在错误!");
		}
	}

	// 为了便于调试程序,特别创建main方法
	public static void main(String[] args) {
		new ReaderQuery();
	}
}

八、Borrow.java

  该模块用于执行借书操作。用户应首先输入图书编号和读者编号,然后做如下几个判断:① 所选图书是否存在,是否有库存;② 读者是否借过此书且未归还;③ 读者当前已借且未归还的图书是否超出了允许其最大可借数。如果上述条件都满足,“借出”按钮才有效,单击之可由程序填写借书记录 。
在这里插入图片描述

// Borrow.java
package MainPro;

import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JOptionPane;

import PublicModule.*;

public class Borrow extends Frame {
	private static final long serialVersionUID = -1036076990599464079L;
	String SepLine = "-------------------------------------------------";
	Label lbbookid = new Label("图书编号");
	Label lbreaderid = new Label("读者编号");
	TextField tf_bookid = new TextField();
	TextField tf_readerid = new TextField();
	Button queryBtn = new Button("查询");

	Label lbbookinfo = new Label(SepLine + "图书信息" + SepLine);
	Label lbbookname = new Label("图书名称:");
	Label tf_bookname = new Label("xx");
	Label lbauthor = new Label("作者:");
	Label tf_author = new Label("xx");
	Label lbpublisher = new Label("出版社:");
	Label tf_publisher = new Label("xx");
	Label lbpublish_time = new Label("出版时间:");
	Label tf_publish_time = new Label("xx");
	Label lbprice = new Label("定价:");
	Label tf_price = new Label("xx");
	Label lbstock = new Label("库存数量:");
	Label tf_stock = new Label("xx");

	Label lbreaderinfo = new Label(SepLine + "读者信息" + SepLine);
	Label lbreadername = new Label("读者姓名:");
	Label tf_readername = new Label("xx");
	Label lbreadertype = new Label("读者类型:");
	Label tf_readertype = new Label("xx");
	Label lbmax_num = new Label("最大可借数:");
	Label tf_max_num = new Label("xx");
	Label lbdays_num = new Label("最大可借天数:");
	Label tf_days_num = new Label("xx");

	Label lbborrowinfo = new Label(SepLine + "借阅信息" + SepLine);
	Label lbborrowednum = new Label("该读者已借图书数量:");
	Label tf_borrowednum = new Label("xx");
	Label lbif_borrow = new Label("该读者是否可借所选图书:");
	Label tf_if_borrow = new Label("xx");
	Label lbborrow_date = new Label("借阅日期:");
	Label tf_borrow_date = new Label("xx");
	Button borrowBtn = new Button("借出");
	Button closeBtn = new Button("关闭");

	public Borrow() {
		setLayout(null);
		setTitle("借阅图书");
		setSize(500, 420);
		this.setForeground(Color.BLACK); // 设置前景色为黑色
		lbbookid.setBounds(30, 40, 50, 25); // 图书编号
		tf_bookid.setBounds(90, 40, 90, 20);
		lbreaderid.setBounds(200, 40, 50, 25); // 读者编号
		tf_readerid.setBounds(260, 40, 90, 20);
		queryBtn.setBounds(370, 40, 80, 25); // 查询按钮

		lbbookinfo.setBounds(30, 70, 440, 25); // 图书信息提示条
		lbbookname.setBounds(30, 100, 60, 25); // 图书名称
		tf_bookname.setBounds(90, 100, 200, 25);
		lbauthor.setBounds(310, 100, 60, 25); // 作者
		tf_author.setBounds(370, 100, 90, 25);
		lbpublisher.setBounds(30, 125, 60, 25); // 出版社
		tf_publisher.setBounds(90, 125, 200, 25);
		lbpublish_time.setBounds(310, 125, 60, 25); // 出版时间
		tf_publish_time.setBounds(370, 125, 90, 25);
		lbprice.setBounds(30, 150, 60, 25); // 定价
		tf_price.setBounds(90, 150, 200, 25);
		lbstock.setBounds(310, 150, 60, 25); // 库存数量
		tf_stock.setBounds(370, 150, 90, 25);

		lbreaderinfo.setBounds(30, 180, 440, 25); // 读者信息提示条
		lbreadername.setBounds(30, 205, 60, 25); // 读者姓名
		tf_readername.setBounds(90, 205, 90, 25);
		lbreadertype.setBounds(310, 205, 60, 25); // 读者类型
		tf_readertype.setBounds(370, 205, 90, 25);
		lbmax_num.setBounds(30, 230, 75, 25); // 最大可借数
		tf_max_num.setBounds(105, 230, 90, 25);
		lbdays_num.setBounds(310, 230, 85, 25); // 最大可借天数
		tf_days_num.setBounds(395, 230, 70, 25);

		lbborrowinfo.setBounds(30, 260, 440, 25); // 借阅信息提示条
		lbborrowednum.setBounds(30, 285, 120, 25);// 已借图书数量
		tf_borrowednum.setBounds(150, 285, 50, 25);
		lbif_borrow.setBounds(30, 310, 145, 25); // 是否可借
		tf_if_borrow.setBounds(175, 310, 50, 25);
		lbborrow_date.setBounds(30, 335, 60, 25);// 借书日期
		tf_borrow_date.setBounds(90, 335, 100, 25);

		borrowBtn.setBounds(160, 365, 80, 25);// 借出按钮
		borrowBtn.setEnabled(false); // 开始时禁用借出按钮
		closeBtn.setBounds(260, 365, 80, 25);// 关闭按钮

		queryBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_querywActionPerformed(e);
			}
		});

		borrowBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_borrowActionPerformed(e);
			}
		});

		closeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				setForeground(Color.BLACK); // 设置前景色为黑色
				dispose(); // 关闭窗体
			}
		});

		/* 关闭窗口 */
		this.addWindowListener(new WindowAdapter() {
			// 重写windowClosing()方法
			public void windowClosing(WindowEvent e) {
				setForeground(Color.BLACK); // 设置前景色为黑色
				dispose(); // 关闭窗体
			}
		});
		add(lbbookid);
		add(lbreaderid);
		add(queryBtn);
		add(lbbookinfo);
		add(lbbookname);
		add(lbauthor);
		add(lbpublisher);
		add(lbpublish_time);
		add(lbprice);
		add(lbstock);
		add(lbreaderinfo);
		add(lbreadername);
		add(lbreadertype);
		add(lbmax_num);
		add(lbdays_num);
		add(lbborrowinfo);
		add(lbborrowednum);
		add(lbif_borrow);
		add(lbborrow_date);
		add(borrowBtn);
		add(closeBtn);
		setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
		setVisible(true); // 使窗体可见
		setForeground(Color.RED); // 设置前景色为红色
		add(tf_bookid);
		add(tf_readerid);
		add(tf_bookname);
		add(tf_author);
		add(tf_publisher);
		add(tf_publish_time);
		add(tf_price);
		add(tf_stock);
		add(tf_readername);
		add(tf_readertype);
		add(tf_max_num);
		add(tf_days_num);
		add(tf_borrowednum);
		add(tf_if_borrow);
		add(tf_borrow_date);
	}

	// 图书和读者查询
	private void btn_querywActionPerformed(ActionEvent e) {
		String bookid = tf_bookid.getText();
		String readerid = tf_readerid.getText();
		// 如果图书编号或读者编号两者均为空,或者有一个为空,则返回
		if (bookid.equals("") || readerid.equals("")) {
			JOptionPane.showMessageDialog(null, "图书编号和读者编号均不能为空!");
			init(); // 重新初始化各参数并禁止借出按钮
			return;
		}
		// 按编号查询图书,结果存入book对象中
		Book book = BookSelect.SelectBookById(bookid);
		// 如果查询到结果,将其显示在各文本框中
		if (book != null) {
			tf_bookname.setText(book.getBookname());
			tf_author.setText(book.getAuthor());
			tf_publisher.setText(book.getPublisher());
			tf_publish_time.setText(book.getPublish_time().toString());
			tf_price.setText(String.valueOf((book.getPrice())));
			tf_stock.setText(String.valueOf(book.getStock()));
		} else {
			JOptionPane.showMessageDialog(null, "图书编号有误,查无此书!");
			init(); // 重新初始化各参数并禁止借出按钮
			return;
		}
		if (book.getStock() == 0) {
			JOptionPane.showMessageDialog(null, "图书已无库存,无法借阅!");
			init(); // 重新初始化各参数并禁止借出按钮
			return;
		}
		// 按编号查询读者,结果存入reader对象中
		Reader reader = ReaderSelect.selectReaderById(readerid);
		// 如果查询到结果,将其显示在各文本框中
		if (reader != null) {
			tf_readername.setText(reader.getReadername());
			tf_readertype.setText(reader.getReadertype());
			tf_max_num.setText(String.valueOf(reader.getMax_num()));
			tf_days_num.setText(String.valueOf(reader.getDays_num()));
		} else {
			JOptionPane.showMessageDialog(null, "读者编号有误,查无此人!");
			init(); // 重新初始化各参数并禁止借出按钮
			return;
		}
		// 查询指定读者是否已借过指定图书且未归还
		if (IfBorrowBack.findbook(bookid, readerid)) {
			JOptionPane.showMessageDialog(null, "该读者已借阅所选图书,且未归还!");
			init(); // 重新初始化各参数并禁止借出按钮
			return;
		}
		// 统计读者所借图书数量
		int borrowednum = statborrowednum(readerid);
		tf_borrowednum.setText(String.valueOf(borrowednum));
		// 如果读者已借图书尚未超出其允许最大借书量,则允许其继续借阅所选图书
		if (borrowednum < reader.getMax_num()) {
			tf_if_borrow.setText("是");
			// 创建一个简单日期格式对象,注意:MM一定要用大写
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			// 创建日期变量,其内容为当前日期
			Date currentdate = new Date();
			// 将日期按指定格式输出
			String borrowdate = sdf.format(currentdate);
			tf_borrow_date.setText(borrowdate);
			borrowBtn.setEnabled(true); // 使借出按钮有效
		} else {
			JOptionPane.showMessageDialog(null, "该读者借书过多,无法继续借阅!");
			init(); // 重新初始化各参数并禁止借出按钮
			return;
		}
	}

	// 填写借出图书记录
	private void btn_borrowActionPerformed(ActionEvent e) {
		String sql;
		String bookid = tf_bookid.getText();
		String readerid = tf_readerid.getText();
		String borrowdate = tf_borrow_date.getText();
		// 为borrow表增加借书记录
		sql = "insert into borrow (book_id,reader_id,"
				+ "borrow_date,if_back) values('" + bookid + "','" + readerid
				+ "','" + borrowdate + "','否')";
		DbOp.executeUpdate(sql);
		// 将该读者所借图书数量加1
		int iborrowednum = Integer.parseInt(tf_borrowednum.getText()) + 1;
		String cborrowednum = String.valueOf(iborrowednum);
		tf_borrowednum.setText(cborrowednum);
		// 将图书库存数量减1
		int istock = Integer.parseInt(tf_stock.getText()) - 1;
		String cstock = String.valueOf(istock);
		// 更新画面中的图书库存数量
		tf_stock.setText(cstock);
		// 更新数据库中的图书库存数量
		sql = "update book set stock='" + cstock;
		sql = sql + "' where id='" + bookid + "'";
		DbOp.executeUpdate(sql);
		JOptionPane.showMessageDialog(null, "借书成功!");
		init(); // 重新初始化各参数并禁止借出按钮
	}

	// 统计某个读者当前已借图书且未归还的数量
	private int statborrowednum(String readerid) {
		int borrowednum = 0;
		String reader_id, if_back;
		// 读取数据库中记录
		String sql = "select * from borrow";
		ResultSet rs = DbOp.executeQuery(sql);
		// 执行查询统计操作
		try {
			while (rs.next()) {
				reader_id = rs.getString("reader_id");
				if_back = rs.getString("if_back");
				if (reader_id.equals(readerid) && if_back.equals("否")) {
					borrowednum++;
				}
			}
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, "数据库统计失败!");
		}
		return borrowednum;
	}

	// 初始化各参数项并禁止借出按钮
	private void init() {
		tf_bookname.setText("xx");
		tf_author.setText("xx");
		tf_publisher.setText("xx");
		tf_publish_time.setText("xx");
		tf_price.setText("xx");
		tf_stock.setText("xx");
		tf_readername.setText("xx");
		tf_readertype.setText("xx");
		tf_max_num.setText("xx");
		tf_days_num.setText("xx");
		tf_borrowednum.setText("xx");
		tf_if_borrow.setText("xx");
		tf_borrow_date.setText("xx");
		borrowBtn.setEnabled(false); // 禁止借出按钮
	}

	// 增加main()方法,主要为了调试程序界面
	public static void main(String[] args) {
		new Borrow();
	}
}

九、Back.java

  该模块用于完成还书操作,此时只需判断该读者是否曾经借过此书且未归还就可以了。
在这里插入图片描述

// Back.java
package MainPro;

import java.awt.*;
import java.awt.event.*;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JOptionPane;

import PublicModule.*;

public class Back extends Frame {
	private static final long serialVersionUID = -1036076990599464079L;
	String SepLine = "-------------------------------------------------";
	Label lbbookid = new Label("图书编号");
	Label lbreaderid = new Label("读者编号");
	TextField tf_bookid = new TextField();
	TextField tf_readerid = new TextField();
	Button queryBtn = new Button("查询");

	Label lbbookinfo = new Label(SepLine + "图书信息" + SepLine);
	Label lbbookname = new Label("图书名称:");
	Label tf_bookname = new Label("xx");
	Label lbauthor = new Label("作者:");
	Label tf_author = new Label("xx");
	Label lbpublisher = new Label("出版社:");
	Label tf_publisher = new Label("xx");
	Label lbpublish_time = new Label("出版时间:");
	Label tf_publish_time = new Label("xx");
	Label lbprice = new Label("定价:");
	Label tf_price = new Label("xx");
	Label lbstock = new Label("库存数量:");
	Label tf_stock = new Label("xx");

	Label lbreaderinfo = new Label(SepLine + "读者信息" + SepLine);
	Label lbreadername = new Label("读者姓名:");
	Label tf_readername = new Label("xx");
	Label lbreadertype = new Label("读者类型:");
	Label tf_readertype = new Label("xx");
	Label lbmax_num = new Label("最大可借数:");
	Label tf_max_num = new Label("xx");
	Label lbdays_num = new Label("最大可借天数:");
	Label tf_days_num = new Label("xx");

	Label lbbackinfo = new Label(SepLine + "还书信息" + SepLine);
	Label lbback_date = new Label("还书日期:");
	Label tf_back_date = new Label("xx");
	Button backBtn = new Button("还书");
	Button closeBtn = new Button("关闭");

	public Back() {
		setLayout(null);
		setTitle("还回图书");
		setSize(500, 310);
		this.setForeground(Color.BLACK); // 设置前景色为黑色
		lbbookid.setBounds(30, 40, 50, 20);// 图书编号
		tf_bookid.setBounds(90, 40, 90, 20);
		lbreaderid.setBounds(200, 40, 50, 20);// 读者编号
		tf_readerid.setBounds(260, 40, 90, 20);
		queryBtn.setBounds(370, 40, 80, 20); // 查询按钮

		lbbookinfo.setBounds(30, 70, 440, 20); // 图书信息提示条
		lbbookname.setBounds(30, 90, 60, 20); // 图书名称
		tf_bookname.setBounds(90, 90, 200, 20);
		lbauthor.setBounds(310, 90, 60, 20); // 作者
		tf_author.setBounds(370, 90, 90, 20);
		lbpublisher.setBounds(30, 110, 60, 20);// 出版社
		tf_publisher.setBounds(90, 110, 200, 20);
		lbpublish_time.setBounds(310, 110, 60, 20);// 出版时间
		tf_publish_time.setBounds(370, 110, 90, 20);
		lbprice.setBounds(30, 130, 60, 20); // 定价
		tf_price.setBounds(90, 130, 200, 20);
		lbstock.setBounds(310, 130, 60, 20); // 库存数量
		tf_stock.setBounds(370, 130, 90, 20);

		lbreaderinfo.setBounds(30, 150, 440, 20); // 读者信息提示条
		lbreadername.setBounds(30, 170, 60, 20); // 读者姓名
		tf_readername.setBounds(90, 170, 90, 20);
		lbreadertype.setBounds(310, 170, 60, 20); // 读者类型
		tf_readertype.setBounds(370, 170, 90, 20);
		lbmax_num.setBounds(30, 190, 75, 20); // 最大可借数
		tf_max_num.setBounds(105, 190, 90, 20);
		lbdays_num.setBounds(310, 190, 85, 20); // 最大可借天数
		tf_days_num.setBounds(395, 190, 70, 20);

		lbbackinfo.setBounds(30, 210, 440, 20); // 还书信息提示条
		lbback_date.setBounds(30, 230, 60, 20);// 还书日期
		tf_back_date.setBounds(90, 230, 100, 20);

		backBtn.setBounds(160, 260, 80, 25);// 还书按钮
		backBtn.setEnabled(false); // 开始时禁用还书按钮
		closeBtn.setBounds(260, 260, 80, 25);// 关闭按钮

		queryBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_querywActionPerformed(e);
			}
		});

		backBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btn_backActionPerformed(e);
			}
		});

		closeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				setForeground(Color.BLACK); // 设置前景色为黑色
				dispose(); // 关闭窗体
			}
		});

		/* 关闭窗口 */
		this.addWindowListener(new WindowAdapter() {
			// 重写windowClosing()方法
			public void windowClosing(WindowEvent e) {
				setForeground(Color.BLACK); // 设置前景色为黑色
				dispose(); // 关闭窗体
			}
		});
		add(lbbookid);
		add(lbreaderid);
		add(queryBtn);
		add(lbbookinfo);
		add(lbbookname);
		add(lbauthor);
		add(lbpublisher);
		add(lbpublish_time);
		add(lbprice);
		add(lbstock);
		add(lbreaderinfo);
		add(lbreadername);
		add(lbreadertype);
		add(lbmax_num);
		add(lbdays_num);
		add(lbbackinfo);
		add(lbback_date);
		add(backBtn);
		add(closeBtn);
		setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
		setVisible(true); // 使窗体可见
		setForeground(Color.RED); // 设置前景色为红色
		add(tf_bookid);
		add(tf_readerid);
		add(tf_bookname);
		add(tf_author);
		add(tf_publisher);
		add(tf_publish_time);
		add(tf_price);
		add(tf_stock);
		add(tf_readername);
		add(tf_readertype);
		add(tf_max_num);
		add(tf_days_num);
		add(tf_back_date);
	}

	// 图书和读者查询
	private void btn_querywActionPerformed(ActionEvent e) {
		String bookid = tf_bookid.getText();
		String readerid = tf_readerid.getText();
		// 如果图书编号或读者编号两者均为空,或者有一个为空,则返回
		if (bookid.equals("") || readerid.equals("")) {
			JOptionPane.showMessageDialog(null, "图书编号和读者编号均不能为空!");
			init(); // 重新初始化各参数并禁止还书按钮
			return;
		}
		// 按编号查询图书,结果存入book对象中
		Book book = BookSelect.SelectBookById(bookid);
		// 如果查询到结果,将其显示在各文本框中
		if (book != null) {
			tf_bookname.setText(book.getBookname());
			tf_author.setText(book.getAuthor());
			tf_publisher.setText(book.getPublisher());
			tf_publish_time.setText(book.getPublish_time().toString());
			tf_price.setText(String.valueOf((book.getPrice())));
			tf_stock.setText(String.valueOf(book.getStock()));
		} else {
			JOptionPane.showMessageDialog(null, "图书编号有误,查无此书!");
			init(); // 重新初始化各参数并禁止还书按钮
			return;
		}
		// 按编号查询读者,结果存入reader对象中
		Reader reader = ReaderSelect.selectReaderById(readerid);
		// 如果查询到结果,将其显示在各文本框中
		if (reader != null) {
			tf_readername.setText(reader.getReadername());
			tf_readertype.setText(reader.getReadertype());
			tf_max_num.setText(String.valueOf(reader.getMax_num()));
			tf_days_num.setText(String.valueOf(reader.getDays_num()));
		} else {
			JOptionPane.showMessageDialog(null, "读者编号有误,查无此人!");
			init(); // 重新初始化各参数并禁止还书按钮
			return;
		}
		// 查询指定读者是否借阅过指定图书,且未归还
		if (!IfBorrowBack.findbook(bookid,readerid)){
			JOptionPane.showMessageDialog(null, "该读者没有借过此种图书!");
			init(); // 重新初始化各参数并禁止还书按钮
			return;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		// 创建日期变量,其内容为当前日期
		Date currentdate = new Date();
		// 将日期按指定格式输出
		String borrowdate = sdf.format(currentdate);
		tf_back_date.setText(borrowdate);
		backBtn.setEnabled(true); // 使还书按钮有效
	}

	// 填写还书记录
	private void btn_backActionPerformed(ActionEvent e) {
		String sql;
		String bookid = tf_bookid.getText();
		String readerid = tf_readerid.getText();
		String backdate = tf_back_date.getText();
		// 更新borrow表记录
		sql = "update borrow set if_back='是',back_date='";
		sql = sql + backdate + "' where ";
		sql = sql + " book_id='" + bookid + "' and ";
		sql = sql + "reader_id='" + readerid + "' and ";
		sql = sql + "if_back='否'";
		DbOp.executeUpdate(sql);
		// 将图书库存数量加1
		int istock = Integer.parseInt(tf_stock.getText()) + 1;
		String cstock = String.valueOf(istock);
		// 更新画面中的图书库存数量
		tf_stock.setText(cstock);
		// 更新数据库中的图书库存数量
		sql = "update book set stock='" + cstock;
		sql = sql + "' where id='" + bookid + "'";
		DbOp.executeUpdate(sql);
		JOptionPane.showMessageDialog(null, "还书成功!");
		init(); // 重新初始化各参数并禁止还书按钮
	}

	// 初始化各参数项并禁止还书按钮
	private void init() {
		tf_bookname.setText("xx");
		tf_author.setText("xx");
		tf_publisher.setText("xx");
		tf_publish_time.setText("xx");
		tf_price.setText("xx");
		tf_stock.setText("xx");
		tf_readername.setText("xx");
		tf_readertype.setText("xx");
		tf_max_num.setText("xx");
		tf_days_num.setText("xx");
		tf_back_date.setText("xx");
		backBtn.setEnabled(false); // 禁止还书按钮
	}
	
	// 增加main()方法,主要为了调试程序界面
	public static void main(String[] args) {
		new Back();
	}
}

十、UpdatePassword.java

  该模块用来更该当前用户的密码 。
在这里插入图片描述

// UpdatePassword.java
package MainPro;

import java.awt.*;
import java.awt.event.*;
import javax.swing.JOptionPane;

import PublicModule.*;

public class UpdatePassword extends Frame {
	private static final long serialVersionUID = -6540483851542957663L;
	Label newPassword = new Label("请输入新密码");
	Label confirmPass = new Label("再次确认新密码");
	TextField text_1 = new TextField();
	TextField text_2 = new TextField();
	Button confirmBtn = new Button("确定");
	Button cancelBtn = new Button("取消");

	public UpdatePassword() {
		setLayout(null);
		setTitle("修改密码");
		setSize(300, 170);
		newPassword.setBounds(30, 50, 90, 30);
		text_1.setBounds(125, 53, 120, 20);
		confirmPass.setBounds(30, 80, 90, 30);
		text_2.setBounds(125, 83, 120, 20);
		confirmBtn.setBounds(70, 120, 70, 25); // 确定按钮
		confirmBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				confirmButtonPerformed(e);
			}
		});
		cancelBtn.setBounds(160, 120, 70, 25); // 关闭按钮
		cancelBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dispose(); // 释放窗体资源
			}
		});

		/* 关闭窗口 */
		this.addWindowListener(new WindowAdapter() {
			// 重写windowClosing()方法
			public void windowClosing(WindowEvent e) {
				dispose(); // 释放窗体资源
			}
		});
		add(newPassword);
		add(confirmPass);
		add(text_1);
		add(text_2);
		add(confirmBtn);
		add(cancelBtn);
		setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
		setVisible(true); // 使窗体可见
	}

	private void confirmButtonPerformed(ActionEvent e) {
		System.out.println(GlobalVar.login_user);
		String pass1 = text_1.getText();
		String pass2 = text_2.getText();
		// 如果两个密码输入框中有一个为空,则显示错误提示信息并返回
		if (pass1.equals("") || pass1.equals("")) {
			JOptionPane.showMessageDialog(null, "密码不能为空,请重新输入!");
			return;
		}
		// 如果两个密码输入框中输入的内容不一致,则显示错误提示信息并返回
		if (!pass1.equals(pass2)) {
			JOptionPane.showMessageDialog(null, "两次输入的密码不一致,请重新输入!");
			text_1.setText("");
			text_2.setText("");
			return;
		}
		String sql = "update user set password='" + pass1
				+ "' where username='" + GlobalVar.login_user + "'";
		int i = DbOp.executeUpdate(sql);
		if (i == 1) {
			JOptionPane.showMessageDialog(null, "修改密码成功!");
		} else
			JOptionPane.showMessageDialog(null, "用户数据库有误或不存在,修改密码失败!");
	}

	// 为了便于调试程序,特别创建main方法
	public static void main(String[] args) {
		new UpdatePassword();
	}
}

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图书馆管理系统使用说明书 配置源程序 附加MYSQL数据库 将TM\02\ Database\db_librarySys文件夹拷贝到mysql\data文件夹下即可,如图1.1所示。 图1.1 拷贝MYSQL数据库 将程序发布到Tomcat下 (1)将“TM\02”文件夹拷贝到Tomcat安装路径下的webapps文件夹中。 (2)选择开始菜单中的“所有程序\Apache Tomcat 6.0\Monitor Tomcat”命令,这时在windows的系统托盘中会显示标识Tomcat服务器启动状态的图标,如果显示为 ,则说明Tomcat服务器没有启动,这时可以在该图标上单击鼠标右键在弹出的快捷菜单中选择“Start Service”菜单项启动Tomcat服务器,启动后将显示为 。 (3)打开IE浏览器,在地址栏中输入http://localhost:8080/,进入“Tomcat软件管理”页面。 注意:8080为安装Tomcat时设置的端口号。 (4)单击Tomcat Manager超链接,弹出“连接到 localhost”对话框。 (5)在用户名及密码处输入登录Tomcat的用户名和密码,单击【确定】按钮。 (6)进入“Tomcat应用程序管理”页面,在此页面中单击“02”,进入本程序主页面,完成Tomcat配置。 导入所应用的包 在运行本程序时,需要将Struts 1.2和MySQL数据库驱动包拷贝到Tomcat安装路径下的webapps文件夹中的02\WEB-INF\lib文件夹中。 使用说明 系统介绍 图书馆管理系统主要的目的是实现图书馆的信息化管理。图书馆的主要业务就是新书的借阅和归还,因此系统最核心的功能便是实现图书的借阅和归还。此外,还需要提供图书的信息查询、读者图书借阅情况的查询等功能。项目实施后,能够提高图书馆的图书借阅、归还流程,提高工作效率。整个项目需要在两个月的时间内交付用户使用。 操作注意事项 (1)本系统的用户名为:tsoft,密码为:111 (2)读者类型不同,可借图书的本数也有所区别。 操作流程 (1)用户登录图书馆管理系统后,可看到图书借阅排行榜,通过排行榜可以看出借阅图书的名称、图书类型、借阅次数等相关信息。 (2)单击“系统设置”/“图书馆信息”命令,对图书馆信息进行设置操作。 (3)单击“系统设置”/“管理员设置”命令,对管理员信息进行添加、权限设置、查询及删除操作。 (4)单击“系统设置”/“参数设置”命令,对办证费用及有效期限信息进行添加操作。 (5)单击“系统设置”/“书架设置”命令,对书架信息进行添加、修改及删除操作。 (6)单击“读者管理”/“读者类型管理”命令,对读者类型信息进行添加、修改及删除操作。 (7)单击“读者管理”/“读者档案管理”命令,对读者信息进行添加、修改及删除操作。 (8)单击“图书管理”/“图书类型设置”命令,对图书类型信息进行添加、修改及删除操作。 (9)单击“图书管理”/“图书档案管理”命令,对图书信息进行添加、修改及删除操作。 (10)单击“图书借还”/“图书借阅”命令,对图书借阅信息添加操作。 (11)单击“图书借还”/“图书续借”命令,对图书续借信息进行添加操作。 (12)单击“图书借还”/“图书归还”命令,对图书归还信息进行添加操作。 (13)单击“系统查询”/“图书档案查询”命令,对图书档案信息进行查询操作。 (14)单击“系统查询”/“图书借阅查询”命令,对借阅的图书信息进行查询操作。 (15)单击“系统查询”/“借阅到期提醒”命令,对借阅到期提醒信息进行查询操作。 (16)单击“更改口令”按钮,对当前的用户密码进行修改操作。 (17)单击“退出系统”按钮,退出当前操作系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值