暑假写了个图书管理系统,编译器用的是eclipse,加入了WindowBuilder插件做界面(做的特丑),数据库用的是MySQL。
实现了图书的查询,借阅,归还,删除,增加。用户的删除,查询。分为管理员和用户。
源码地址(GitHub):https://github.com/best-bo-cai/books_management
从项目开始,无从下手,随着学习的深入,慢慢的熟悉了开发流程,先把整体框架搭起来,这个过程可以减少后续的一些麻烦,做数据库前先想好需求,把数据库做出来,我用的Navicat,管理表方便。然后把model类(实体类)写出来,一般是一个表写一个,把他单独放在一个包里,然后实现功能,需要界面做界面,需要工具做工具。界面单独放在一个包frame(或view),工具单独放在一个包里util,还有数据库访问层Dao.以上均为个人理解。
上面这个表有个问题,phone前多了个空格,后面出错好几次,在代码中加了空格才对,不细心导致的,要注意。
package com.java.util;
/**
* 数据库工具类
*/
import java.sql.Connection;
import java.sql.DriverManager;
public class Connect {
Connection con;
/**
* 连接数据库
* @return
*/
public Connection loding() {//加载数据库
try {
Class.forName("com.mysql.cj.jdbc.Driver");
System.out.println("成功加载数据库驱动!");
}
catch(Exception e){
System.out.println("加载数据库驱动出错!");
e.printStackTrace();//在命令行打印异常信息在程序中出错的位置及原因
}
//连接数据库
try {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/book_admin?serverTimezone=UTC","root","147258369");//这里是MySQL数据库的用户名和密码
System.out.println("成功连接数据库服务器");
}
catch(Exception e1){
System.out.println("连接数据库服务器出现错误");
}
return con;
}
/**
* 关闭数据库
* @param con
* @throws Exception
*/
public void closeCon (java.sql.Connection con)throws Exception {//关闭数据库
if(con!=null){
con.close();
}
}
}
util包下还有另一个类,判断字符串是否为空的类
package com.java.util;
/**
* 判断字符串是否为空
* @author admin
*
*/
public class StringNull {
/**
* 判断是否为空
* @param str
* @return
*/
public static boolean isEmpty(String str) {
if(str==null||"".equals(str.trim())) {
return true;//1真
}else {
return false;//0假
}
}
/**
* 判断是否不为空
* @param str
* @return
*/
public static boolean isNotEmpty(String str) {
if(str!=null&&!"".equals(str.trim())) {
return true;
}else {
return false;
}
}
}
我的界面很简洁,因为难的不会,这不重要。
首先看看主界面,用的WindowBuilder插件做的。
注册界面,只能注册用户,不能注册管理员。
功能界面,写了两个界面,一个用户的,一个管理员的。
查询界面,借阅界面,归还界面,开始没规划好,就放在了一个界面
删除功能,以删除界面演示,删除用户一样
添加图书
查找图书
以图书类为例子,get/set方法和构造方法都可以自动生成,如下图,先鼠标右击(前提先写好成员变量)
哇
package com.java.model;
/**
* 图书信息
* @author admin
*
*/
public class Book {
private int book_id;//图书编号
private String book_name;//图书姓名
private String book_writer;//作者
private String book_publish;//出版社
private String book_status;//状态
public Book() {
super();
}
public Book(int book_id) {
super();
this.book_id = book_id;
}
public Book(int book_id, String book_name, String book_writer, String book_publish, String book_status) {
super();
this.book_id = book_id;
this.book_name = book_name;
this.book_writer = book_writer;
this.book_publish = book_publish;
this.book_status = book_status;
}
public int getBook_id() {
return book_id;
}
public void setBook_id(int book_id) {
this.book_id = book_id;
}
public String getBook_name() {
return book_name;
}
public void setBook_name(String book_name) {
this.book_name = book_name;
}
public String getBook_writer() {
return book_writer;
}
public void setBook_writer(String book_writer) {
this.book_writer = book_writer;
}
public String getBook_publish() {
return book_publish;
}
public void setBook_publish(String book_publish) {
this.book_publish = book_publish;
}
public String getBook_status() {
return book_status;
}
public void setBook_status(String book_status) {
this.book_status = book_status;
}
}
Dao包下的数据库访问层,以Book为例
package com.java.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.java.model.Book;
import com.java.util.StringNull;
/**
*
* @author admin
*
*/
public class BookDao {
/**
* 查询图书
* @param con
* @param book
* @return
* @throws Exception
*/
public ResultSet query(Connection con,Book book)throws Exception{
ResultSet resultUser = null;
StringBuffer sql = new StringBuffer("select * from book");
//数据库模糊查询
if(StringNull.isNotEmpty(book.getBook_name())) {
sql.append(" and book_name like '%"+book.getBook_name()+"%'");
}
if(StringNull.isNotEmpty(book.getBook_writer())) {
sql.append(" and book_writer like '%"+book.getBook_writer()+"%'");
}
if(StringNull.isNotEmpty(book.getBook_publish())) {
sql.append(" and book_publish like '%"+book.getBook_publish()+"%'");
}
PreparedStatement pstmt = (PreparedStatement)con.prepareStatement(sql.toString().replaceFirst("and", "where"));
return pstmt.executeQuery();
}
/**
* 查询图书
* @param con
* @param book
* @return
* @throws Exception
*/
public ResultSet query2(Connection con,Book book)throws Exception{
ResultSet resultUser = null;
String sql = "select * from book where book_id=?";
PreparedStatement pstmt = (PreparedStatement)con.prepareStatement(sql);
pstmt.setInt(1, book.getBook_id());
return pstmt.executeQuery();
}
/**
* 图书信息修改
* @param con
* @param book
* @return
* @throws Exception
*/
public int update(Connection con,Book book)throws Exception {
String sql = "update book set book_status=? where book_id=?";
PreparedStatement pstmt = (PreparedStatement)con.prepareStatement(sql);
pstmt.setString(1, book.getBook_status());
pstmt.setInt(2, book.getBook_id());
return pstmt.executeUpdate();
}
/**
* 添加图书信息
* @param con
* @param book
* @return
* @throws Exception
*/
public int add(Connection con,Book book)throws Exception{
String sql = "insert into book values(?,?,?,?,?)";
PreparedStatement pstmt = (PreparedStatement)con.prepareStatement(sql);
pstmt.setInt(1, book.getBook_id());
pstmt.setString(2, book.getBook_name());
pstmt.setString(3, book.getBook_writer());
pstmt.setString(4, book.getBook_publish());
pstmt.setString(5, book.getBook_status());
return pstmt.executeUpdate();
}
public int delete(Connection con,int bookId) throws Exception{
String sql = "delete from book where book_id = ?";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setInt(1, bookId);
return pstmt.executeUpdate();
}
}
frame包下的视图层和控制功能,以图书查询,借阅,归还界面为例,大部分代码是WindowBuilder插件生成的。
package com.java.frame;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JTextField;
import javax.swing.JFormattedTextField;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.Vector;
import java.awt.event.ActionEvent;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import com.java.dao.BookDao;
import com.java.dao.BookInformationDao;
import com.java.model.Book;
import com.java.model.BookInformation;
import com.java.util.Connect;
import com.java.util.StringNull;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class QueryBookInterface extends JFrame {
private JPanel contentPane;
private JTextField book_nameTxt;
private JTextField book_writerTxt;
private JTextField book_publishTxt;
private Connect conutil= new Connect();
private BookDao bookDao= new BookDao();
private BookInformationDao bookInformationDao = new BookInformationDao();
public static String readerName;
public static String adminName;
/**
* Launch the application.
*/
JFrame frame = new JFrame();
private JTable bookTable;
private JPanel panel;
private JLabel lblNewLabel;
private JButton borrowButton;
private JLabel label;
private JLabel label_4;
private JLabel label_5;
private JTextField book_RBnameTxt;
private JTextField book_RBwriterTxt;
private JTextField book_RBpublishTxt;
private JTextField book_RBstatusTxt;
private JButton returnButton;
private JTextField book_RBidTxt;
/**
* Create the frame.
*/
public QueryBookInterface() {
setTitle("\u56FE\u4E66\u7684\u67E5\u8BE2\uFF0C\u501F\u9605\uFF0C\u5F52\u8FD8");
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
setBounds(100, 100, 920, 686);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
JButton queryButton = new JButton("\u67E5\u8BE2");
queryButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
queryBookTable(e);
}
});
JLabel label_1 = new JLabel("\u56FE\u4E66\u540D\u5B57:");
JLabel label_2 = new JLabel("\u56FE\u4E66\u4F5C\u8005\uFF1A");
JLabel label_3 = new JLabel("\u51FA\u7248\u793E\uFF1A");
book_nameTxt = new JTextField();
book_nameTxt.setColumns(10);
book_writerTxt = new JTextField();
book_writerTxt.setColumns(10);
book_publishTxt = new JTextField();
book_publishTxt.setColumns(10);
JScrollPane scrollPane = new JScrollPane();
panel = new JPanel();
GroupLayout gl_contentPane = new GroupLayout(contentPane);
gl_contentPane.setHorizontalGroup(
gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(42)
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addComponent(label_2)
.addComponent(label_1)
.addComponent(label_3))
.addGap(28)
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addComponent(queryButton, GroupLayout.PREFERRED_SIZE, 132, GroupLayout.PREFERRED_SIZE)
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING, false)
.addComponent(book_nameTxt)
.addComponent(book_writerTxt)
.addComponent(book_publishTxt, GroupLayout.PREFERRED_SIZE, 286, GroupLayout.PREFERRED_SIZE))))
.addGroup(gl_contentPane.createSequentialGroup()
.addContainerGap()
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 435, GroupLayout.PREFERRED_SIZE)))
.addGap(34)
.addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, 388, GroupLayout.PREFERRED_SIZE)
.addContainerGap(21, Short.MAX_VALUE))
);
gl_contentPane.setVerticalGroup(
gl_contentPane.createParallelGroup(Alignment.TRAILING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(42)
.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 566, Short.MAX_VALUE))
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(84)
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addComponent(label_1)
.addComponent(book_nameTxt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addPreferredGap(ComponentPlacement.RELATED, 52, Short.MAX_VALUE)
.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
.addComponent(label_2)
.addComponent(book_writerTxt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(51)
.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
.addComponent(label_3)
.addComponent(book_publishTxt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addComponent(queryButton, GroupLayout.PREFERRED_SIZE, 36, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 277, GroupLayout.PREFERRED_SIZE)
.addGap(11)))
.addGap(21))
);
lblNewLabel = new JLabel("\u56FE\u4E66\u540D\u5B57\uFF1A");
borrowButton = new JButton("\u501F\u9605");
borrowButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
borrowBook();
}
});
label = new JLabel("\u4F5C\u8005\uFF1A");
label_4 = new JLabel("\u51FA\u7248\u793E\uFF1A");
label_5 = new JLabel("\u72B6\u6001\uFF1A");
book_RBnameTxt = new JTextField();
book_RBnameTxt.setColumns(10);
book_RBwriterTxt = new JTextField();
book_RBwriterTxt.setColumns(10);
book_RBpublishTxt = new JTextField();
book_RBpublishTxt.setColumns(10);
book_RBstatusTxt = new JTextField();
book_RBstatusTxt.setColumns(10);
returnButton = new JButton("\u5F52\u8FD8");
returnButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
returnBook();
}
});
JLabel label_6 = new JLabel("\u7F16\u53F7\uFF1A");
book_RBidTxt = new JTextField();
book_RBidTxt.setColumns(10);
GroupLayout gl_panel = new GroupLayout(panel);
gl_panel.setHorizontalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addGap(28)
.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
.addComponent(lblNewLabel)
.addComponent(label)
.addComponent(label_4)
.addComponent(label_5)
.addComponent(label_6))
.addGap(32)
.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING)
.addComponent(book_RBidTxt, GroupLayout.DEFAULT_SIZE, 286, Short.MAX_VALUE)
.addGroup(gl_panel.createSequentialGroup()
.addComponent(borrowButton)
.addPreferredGap(ComponentPlacement.RELATED, 160, Short.MAX_VALUE)
.addComponent(returnButton))
.addComponent(book_RBwriterTxt, Alignment.LEADING, 286, 286, Short.MAX_VALUE)
.addComponent(book_RBnameTxt, GroupLayout.DEFAULT_SIZE, 286, Short.MAX_VALUE)
.addComponent(book_RBpublishTxt, Alignment.LEADING, 286, 286, Short.MAX_VALUE)
.addComponent(book_RBstatusTxt, Alignment.LEADING, 286, 286, Short.MAX_VALUE))
.addContainerGap())
);
gl_panel.setVerticalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addGap(22)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(lblNewLabel)
.addComponent(book_RBnameTxt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(24)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(label)
.addComponent(book_RBwriterTxt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(label_4)
.addComponent(book_RBpublishTxt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(label_5)
.addComponent(book_RBstatusTxt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING)
.addComponent(book_RBidTxt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(label_6))
.addPreferredGap(ComponentPlacement.RELATED, 17, Short.MAX_VALUE)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(returnButton)
.addComponent(borrowButton))
.addContainerGap())
);
panel.setLayout(gl_panel);
bookTable = new JTable();
bookTable.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
bookTableMousePressed(e);
}
});
bookTable.setFillsViewportHeight(true);
bookTable.setModel(new DefaultTableModel(
new Object[][] {
},
new String[] {
"\u7F16\u53F7", "\u56FE\u4E66\u540D\u5B57", "\u4F5C\u8005", "\u51FA\u7248\u793E", "\u72B6\u6001"
}
) {
boolean[] columnEditables = new boolean[] {
false, false, false, false, false
};
public boolean isCellEditable(int row, int column) {
return columnEditables[column];
}
});
scrollPane.setViewportView(bookTable);
contentPane.setLayout(gl_contentPane);
this.fillTable(new Book());//初始化图书信息
}
/**
* 归还图书函数
*/
protected void returnBook() {
String bookId = this.book_RBidTxt.getText();
String bookName = this.book_RBnameTxt.getText();
String bookPublish =this.book_RBpublishTxt.getText();
String bookWriter = this.book_RBwriterTxt.getText();
String bookStatus = this.book_RBstatusTxt.getText();
if(StringNull.isEmpty(bookId)) {
JOptionPane.showMessageDialog(null, "图书信息不能为空!");
return ;
}
Connection con = null;
try {
BookInformation bi = new BookInformation(Integer.parseInt(bookId));
Book book = new Book(Integer.parseInt(bookId));
book.setBook_status("0");//把图书状态改变为0
con = conutil.loding();
ResultSet rs = bookInformationDao.returnn(con,bi);//得到符合bookId的那一行。
//读者对比,只有借此书的读者才能还此书
if((rs.next() && rs.getString(2).equals(readerName))||((StringNull.isNotEmpty(adminName))&&rs.getString(5).equals("1"))) {
bookInformationDao.delete(con, Integer.parseInt(bookId));//删除借书表里的哪一行数据
bookDao.update(con, book);//更新图书表中的图书状态
JOptionPane.showMessageDialog(null, "归还成功!");
return ;
}else{
JOptionPane.showMessageDialog(null, "归还失败!");
return ;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
conutil.closeCon(con);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 接受用户ID,从其它类接受
* @param id
*/
public static void setReaderId(String name) {
readerName = name;
}
public static void setAdminId(String name) {
adminName = name;
}
/**
* 借书
*/
private void borrowBook() {
String bookId = this.book_RBidTxt.getText();
String bookName = this.book_RBnameTxt.getText();
String bookPublish = this.book_RBpublishTxt.getText();
String bookWriter = this.book_RBwriterTxt.getText();
String bookStatus = this.book_RBstatusTxt.getText();
if(StringNull.isEmpty(bookId)) {
JOptionPane.showMessageDialog(null, "图书信息不能为空!");
return;
}
if(bookStatus.equals("1")) {
JOptionPane.showMessageDialog(null, "该图书已被借走了!");
return;
}
Connection con = null;
try {
con = conutil.loding();
BookInformation bi;
if(StringNull.isNotEmpty(readerName)) {
bi = new BookInformation(Integer.parseInt(bookId), readerName, null, null, "1");//读者
}else {
bi = new BookInformation(Integer.parseInt(bookId), adminName, null, null, "1");//管理员
}
Book book =new Book(Integer.parseInt(bookId), bookName, bookWriter, bookPublish, "1");
int find = bookInformationDao.add(con, bi);
int flag = bookDao.update(con, book);
if(1 != find ||1 != flag) {
JOptionPane.showMessageDialog(null, "借阅失败!");
return;
}else {
JOptionPane.showMessageDialog(null, "借阅成功!");
return;
}
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "借阅失败!");
return ;
}finally {
try {
conutil.closeCon(con);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 添加到面板中
* @param e
*/
private void bookTableMousePressed(MouseEvent e) {
int row = bookTable.getSelectedRow();
book_RBnameTxt.setText((String)bookTable.getValueAt(row, 1));
book_RBwriterTxt.setText((String)bookTable.getValueAt(row, 2));
book_RBpublishTxt.setText((String)bookTable.getValueAt(row, 3));
book_RBstatusTxt.setText((String)bookTable.getValueAt(row, 4));
book_RBidTxt.setText((String)bookTable.getValueAt(row, 0));
}
/**
* 图书信息查询
*/
private void queryBookTable(ActionEvent e) {
//书名查询,作者,出版社
String book_name = this.book_nameTxt.getText();
String book_writer = this.book_writerTxt.getText();
String book_publish = this.book_publishTxt.getText();
Book book =new Book();
book.setBook_name(book_name);
book.setBook_writer(book_writer);
book.setBook_publish(book_publish);
this.fillTable(book);
}
/**
* 初始化图书信息
* @param book
*/
private void fillTable(Book book) {
DefaultTableModel dtm = (DefaultTableModel) bookTable.getModel();
dtm.setRowCount(0);
Connection con = null;
try {
con = conutil.loding();
ResultSet rs = bookDao.query(con, book);
while(rs.next()) {
Vector v = new Vector();
v.add(rs.getString("book_id"));
v.add(rs.getString("book_name"));
v.add(rs.getString("book_writer"));
v.add(rs.getString("book_publish"));
if(rs.getString("book_status").equals("1")) {
v.add("已借出");
}else {
v.add("未借出");
}
dtm.addRow(v);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
conutil.closeCon(con);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}