本课设系软件工程大二学生作,拙笔狂言,恭请斧正。
开发工具:Eclipse 2020-12,Microsoft SQL server 2012
程序语言:Java

引 言
选题题目:图书管理系统
选题背景:
(1)图书室有各种图书,共一万多册。
(2)每种图书都有书名、书号(ISBN)、一名或多名作者(译者)、出版社、定价和内容简介。
(3)借书证记录有借阅者的姓名、所在单位、职业等。
(4)凭借书证借书,每次最多能借8本书。借书期限最长为30天。
需求功能:
(1)图书基本情况的录入、修改、删除等基本操作。
(2)实现借书功能。
(3)实现还书功能。
(4)实现对所有购进图书的分类查询和分类统计。
(5)能够按书名、作者等分类查询现有的图书的数量。
(6)对超期的情况能自动给出提示信息。
(7)图书管理员与借书者权限有区分。
选题意义:能够加深我们对数据库系统原理及程序设计的理论知识的理解和应用,通过设计实际的数据库系统课题,进一步熟悉数据库管理系统的操作技术,提高动手能力、分析实际项目和解决实际问题的能力,学习基本的数据库编程方法。

  1. 数据库概念模型
    1.1 需求分析
    1.1.1 图书管理员:
    ⑴查询和修改个人信息,如联系电话等。
    ⑵能对图书进行查询录入、修改、删除、分类统计等操作。
    ⑶查询、修改借书者的个人信息,包括借阅信息等。
    ⑷增加、删除借书者
    1.1.2 借书者:
    ⑴查询和修改个人信息,如联系电话等。
    ⑵查询图书信息和图书状态,即空闲在册或已借出。
    ⑶借书和还书。
    ⑷已借书籍已超时需找管理员帮助还书。
    每次最多能借8本书。借书期限最长为30天。
    1.2 概念结构设计
    1.2.1抽象出实体
    根据分析,图书管理系统主要包含图书管理员、借书者、图书三个实体。
    图书管理员:工号,姓名,性别,职称,联系电话
    借书者:借书证号,姓名,性别,联系电话,职业,所在单位
    图书:书号,书名,作者,出版社,定价,内容简介,状态,分类

数据字典:
(6个表)

表名:借书者





(该表的作用是:在用户登录成功时,将该登录的账号、登录时间写入数据库的“操作账号”表,表示当前正在使用该系统的是某某用户;例如某用户修改个人信息时,系统通过筛选最新登录时间,来保证用户修改的是自己的信息。)

1.2.2局部E-R图(图略)
图书管理员与借书者:一名图书管理员可以管理多名借书者,一名借书者可以被多名图书管理员管理。因此两者之间是多对多的联系。

借书者与图书:一名借书者一次最多可以借8本图书,一本图书可以多次借给不同的借书者。因此两者之间是多对多的联系。

图书管理员与图书:一名图书管理员可以管理多本图书,一本图书可以被多名图书管理员管理。因此两者之间是多对多的联系。

1.2.3整体E-R图(图略,将局部E-R图结合起来即得)

2 数据库逻辑模型
2.1将E-R图转化为关系模式
图书管理员(工号,姓名,性别,职称,联系电话)是图书管理员实体对应的关系模式,其中工号是图书管理员关系的主键。
借书者(借书证号,姓名,性别,联系电话,职业,所在单位)是借书者实体对应的关系模式,其中借书证号是借书者关系的主键。
图书(书号,书名,作者,出版社,定价,内容简介,状态,分类)是图书实体对应的关系模式,其中书号是图书关系的主键。
借书(借书证号,书号,借书时间,姓名,书名)为联系“借书”对应的关系模式。因为借书是图书管理员、借书者和图书之间的多对多联系,因此图书管理员、借书者和图书的主属性及借书本身的属性“借书时间”,共同构成了借书关系模式的属性,其中借书证号、书号、借书时间的组合是借书关系的主键。
还书(借书证号,书号,借书时间,还书时间,姓名,书名)为联系“还书”对应的关系模式,因为还书是图书管理员、借书者和图书之间的多对多联系,因此图书管理员、借书者和图书的主属性及借书本身的属性“还书时间”,共同构成了还书关系模式的属性,其中借书证号、书号、借书时间、还书时间的组合是还书关系的主键。

3数据库物理设计与实施
3.1创建数据库

3.2创建和管理基本表
3.2.1创建基本表






4 程序设计
4.1创建窗体


4.1.1管理员


图书查询

图书添加
1.操作失败一一书号与数据库已存的数据重复、状态非“已借出”或“空闲在册”、有空项
2.操作成功一一非上述情况

图书编辑
1.输入数据正常修改
2.输入非法的或不存在的书号一一“数据库中没有该图书”
3.书号置空一一“必填”

借书管理
1.管理员输入合法的、存在的书号,操作成功,将该图书的状态改为空闲在册,并移入还书记录
2.输入非法的、不存在的或空的书号,操作失败
3.点击“还书记录”,查看借记表

读者查询与编辑
删除
文本框输入的账号合法则“操作成功”,否则“操作失败”

修改/添加
修改
1.填合法借书证号可顺利执行;不填借书证号或填非法的借书证号则显示标签提示
2.性别限定“男”或“女”,出错无法执行显示标签提示
增加
1.操作成功–每个项目都填写,且性别限定了“男”或“女”
2.操作失败–有空项或性别没有限定,显示“每个项目都必填”

修改个人信息

修改密码
1.三个密码框都输入合法的密码一一“修改成功”
2.三个密码框任意一个输入非法的密码一一“输入错误,请校检”

4.1.2借书者


图书查询

图书借阅
操作成功
1.输入“空闲在册”的书号,且在借图书不超过8本
操作失败
1.输入“已借出”的、不存在的或空的书号
2.在借图书已达到8本

图书归还
操作成功
1.输入在借的书号,且借书时间不超过30天
操作失败
1.输入不在借的、非法的或空的书号
2.输入在借的书号,但借书时间已超过30天

修改个人信息

修改密码

4.2连接数据库
package Testv1;import java.sql.*;public class Testv10 {public static void main(String[] args) {// TODO Auto-generated method stub{String driverName="com.microsoft.sqlserver.jdbc.SQLServerDriver";String dbURL="jdbc:sqlserver://localhost:1433;DatabaseName=LibraryManagement";//个人数据库名称String userName="sa";//个人用户名String userPwd="QWEASDZXC000000";//个人密码 try{Class.forName(driverName);System.out.println("加载驱动成功!");}catch(Exception e){e.printStackTrace();System.out.println("加载驱动失败!");}try{Connection dbConn=DriverManager.getConnection(dbURL,userName,userPwd);System.out.println("连接数据库成功!");}catch(Exception e){e.printStackTrace();System.out.print("SQL Server连接失败!");}}

完整演示视频
https://www.bilibili.com/video/BV1C34y1H7NH” />添加链接描述:系统使用演示

图书查询

package Testv1;import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.EventQueue;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTable;import javax.swing.border.EmptyBorder;import javax.swing.table.DefaultTableModel;import javax.swing.table.TableModel;import javax.swing.JLabel;import javax.swing.JTextField;import javax.swing.JButton;import java.awt.event.ActionListener;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.awt.event.ActionEvent;import javax.swing.JComboBox;import java.awt.event.ItemListener;import java.awt.event.ItemEvent;public class BookFind extends JFrame {private JPanel contentPane;private JTextField textField_2;private JTextField textField_3;/** * Launch the application. */public static void main(String[] args) {EventQueue.invokeLater(new Runnable() {public void run() {try {BookFind frame = new BookFind();frame.setVisible(true);} catch (Exception e) {e.printStackTrace();}}});}/** * Create the frame. */public BookFind() {setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100, 100, 581, 391);contentPane = new JPanel();contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));setContentPane(contentPane);contentPane.setLayout(null);textField_2 = new JTextField();textField_2.setBounds(23, 7, 139, 21);contentPane.add(textField_2);textField_2.setColumns(10);JButton btnNewButton_2 = new JButton("\u8FD4\u56DE");btnNewButton_2.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {setVisible(false);}});btnNewButton_2.setBounds(462, 319, 93, 23);contentPane.add(btnNewButton_2);JLabel lblNewLabel = new JLabel("\u5171\u6709\uFF08\u672C\uFF09");lblNewLabel.setBounds(23, 323, 70, 15);contentPane.add(lblNewLabel);textField_3 = new JTextField();textField_3.setBounds(82, 320, 66, 21);contentPane.add(textField_3);textField_3.setColumns(10);JPanel panel = new JPanel();panel.setBounds(23, 38, 532, 271);contentPane.add(panel);JScrollPane scrollPane = new JScrollPane();scrollPane.setBounds(10, 46, 300, 150);panel.add(scrollPane);String []Name = {"书号", "书名", "作者", "出版社","定价","内容简介","状态","分类"};Object [][] rowData = new Object [100][8]; JTable table = new JTable(rowData, Name);table.setBounds(297, 179, -279, -124);table.setRowHeight(30);//设置行高table.getColumnModel().getColumn(0).setPreferredWidth(110); //第一列列宽table.setPreferredScrollableViewportSize(new Dimension(500 ,300));//设置滚动面板视口大小(超过该大小的行数据需要拖动滚动条)scrollPane.setViewportView(table);//把数据库表的内容显示到页面的表格try {String dbURL="jdbc:sqlserver://localhost:1433;DatabaseName=LibraryManagement";String userName="sa";String userPwd="QWEASDZXC000000";Connection dbConn = null;Statement state = null;Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");dbConn = DriverManager.getConnection(dbURL,userName,userPwd);state = dbConn.createStatement();String sql0 = "select * from 图书";ResultSet rs = state.executeQuery(sql0);Statement stateCnt = dbConn.createStatement();String sql1 = "select count(*) from 图书";ResultSet rs_1 = stateCnt.executeQuery(sql1);while(rs_1.next()) {textField_3.setText(rs_1.getString(1));}//统计int i = 0;while(rs.next() && i<rowData.length) {rowData[i][0] = rs.getString(1);rowData[i][1] = rs.getString(2); rowData[i][2] = rs.getString(3); rowData[i][3] = rs.getString(4); rowData[i][4] = rs.getString(5);rowData[i][5] = rs.getString(6);rowData[i][6] = rs.getString(7);rowData[i][7] = rs.getString(8);i++;}dbConn.close();} catch (SQLException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (ClassNotFoundException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}String []item = new String[] {"书号","书名","作者","出版社","定价","内容简介","状态","分类"};JComboBox comboBox = new JComboBox(item);comboBox.addItemListener(new ItemListener() {//不必要监听器public void itemStateChanged(ItemEvent e) {//textField_2.setText(e.getItem());}});comboBox.setBounds(172, 6, 139, 23);contentPane.add(comboBox);JButton btnNewButton = new JButton("\u67E5\u8BE2");btnNewButton.addActionListener(new ActionListener() {//查询public void actionPerformed(ActionEvent e) {String str = new String(textField_2.getText());//列元素String str_1 = new String((String) comboBox.getSelectedItem());//列名//从文本框下拉列表读取要查询的分类try {String dbURL="jdbc:sqlserver://localhost:1433;DatabaseName=LibraryManagement";String userName="sa";String userPwd="QWEASDZXC000000";Connection dbConn = null;Statement state = null;Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");dbConn = DriverManager.getConnection(dbURL,userName,userPwd);state = dbConn.createStatement();String sql0 = "select * from 图书 where "+str_1+"='"+str+"'" ;ResultSet rs = state.executeQuery(sql0);Statement stateCnt = dbConn.createStatement();String sql1 = "select count(*) from 图书 where "+str_1+"='"+str+"'"; //填入列名,列元素ResultSet rs_1 = stateCnt.executeQuery(sql1);int n = 0;while(rs_1.next()) {textField_3.setText(rs_1.getString(1));n= Integer.parseInt(rs_1.getString(1));}//统计数量int i = 0;while(rs.next() && i<rowData.length) {//显示到表格中rowData[i][0] = rs.getString(1);rowData[i][1] = rs.getString(2); rowData[i][2] = rs.getString(3); rowData[i][3] = rs.getString(4); rowData[i][4] = rs.getString(5);rowData[i][5] = rs.getString(6);rowData[i][6] = rs.getString(7);rowData[i][7] = rs.getString(8);i++;}while(i>=n && i<rowData.length) {rowData[i][0] = null;rowData[i][1] = null;rowData[i][2] = null;rowData[i][3] = null;rowData[i][4] = null;rowData[i][5] = null;rowData[i][6] = null;rowData[i][7] = null;i++;}//刷新TableModel tml = new DefaultTableModel(rowData,Name);table.setModel(tml);dbConn.close();} catch (SQLException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (ClassNotFoundException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}});btnNewButton.setBounds(363, 6, 93, 23);contentPane.add(btnNewButton);JButton btnNewButton_1 = new JButton("\u53D6\u6D88");btnNewButton_1.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {try {String dbURL="jdbc:sqlserver://localhost:1433;DatabaseName=LibraryManagement";String userName="sa";String userPwd="QWEASDZXC000000";Connection dbConn = null;Statement state = null;Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");dbConn = DriverManager.getConnection(dbURL,userName,userPwd);state = dbConn.createStatement();String sql0 = "select * from 图书";ResultSet rs = state.executeQuery(sql0);Statement stateCnt = dbConn.createStatement();String sql1 = "select count(*) from 图书";ResultSet rs_1 = stateCnt.executeQuery(sql1);while(rs_1.next()) {textField_3.setText(rs_1.getString(1));}//统计int i = 0;while(rs.next() && i<rowData.length) {rowData[i][0] = rs.getString(1);rowData[i][1] = rs.getString(2); rowData[i][2] = rs.getString(3); rowData[i][3] = rs.getString(4); rowData[i][4] = rs.getString(5);rowData[i][5] = rs.getString(6);rowData[i][6] = rs.getString(7);rowData[i][7] = rs.getString(8);i++;}TableModel tml = new DefaultTableModel(rowData,Name);table.setModel(tml);dbConn.close();} catch (SQLException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (ClassNotFoundException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}});btnNewButton_1.setBounds(462, 7, 93, 23);contentPane.add(btnNewButton_1);}}
**4.1.2出现的问题及做法**1.用户通过个人账号使用该系统,则用户的操作都绑定在该账号,如修改信息时,只能修改本账号信息而不能修改他人信息。对此,我的做法是:在用户登录成功时,将登录的账号、登录时间写入数据库的“操作账号”表,表示当前正在使用该系统的是某某用户。

管理员登录监听器

JButton btnNewButton_1 = new JButton("\u767B\u5F55");btnNewButton_1.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {String strP = new String(passwordField.getPassword());//密码String strT = new String(textField.getText());//工号String dbURL="jdbc:sqlserver://localhost:1433;DatabaseName=LibraryManagement";String userName="sa";String userPwd="QWEASDZXC000000";Connection dbConn = null;String sql = "select 工号,密码 from 图书管理员";try {Statement state = null;Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");dbConn = DriverManager.getConnection(dbURL,userName,userPwd);state = dbConn.createStatement();ResultSet rs = state.executeQuery(sql);while (rs.next()) {//System.out.println(rs.getString(1)+" "+rs.getString(2));if(strT.equals(rs.getString(1)) && strP.equals(rs.getString(2))) {Calendar c = Calendar.getInstance();M_mainPage mPage = new M_mainPage();mPage.setVisible(true);lblNewLabel_3.setVisible(false);PreparedStatement pst = null;pst = dbConn.prepareStatement("insert into 操作账号 values(?,?)");//记录当前正在使用的用户pst.setString(1, strT);//插入账号pst.setTimestamp(2, new Timestamp(c.getTimeInMillis()));//插入时间戳pst.addBatch();pst.executeBatch();lblNewLabel_3.setVisible(false);}else {lblNewLabel_3.setVisible(true);}}dbConn.close();} catch (SQLException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (ClassNotFoundException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}});

修改个人信息监听器

JButton btnNewButton_1 = new JButton("\u4FDD\u5B58");//保存修改信息btnNewButton_1.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {String name = new String(textField.getText());//姓名String work = new String(textField_2.getText());//职称String sex = new String(textField_1.getText());//性别String phone = new String(textField_3.getText());//电话号码String num = new String();//工号String dbURL="jdbc:sqlserver://localhost:1433;DatabaseName=LibraryManagement";String userName="sa";String userPwd="QWEASDZXC000000";Connection dbConn = null;try {Statement state = null;Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");dbConn = DriverManager.getConnection(dbURL,userName,userPwd);state = dbConn.createStatement();//通过获得“操作账号”表的最后一行(最新一行)得到当前正在使用系统的用户是......String sql0 = "select top 1* from 操作账号 order by 时间 desc";ResultSet rs = state.executeQuery(sql0);//最后一行String s1 = new String();while(rs.next()) {s1 = rs.getString(1);}num = s1;//工号PreparedStatement pst = null;//如果文本框内容不为空,则据此修改数据库表内容if (name.equals("") == false) {String sql = "update 图书管理员 set 姓名=? where 工号=?";pst = dbConn.prepareStatement(sql);pst.setString(1, name);pst.setString(2, num);//工号是当前登录的账号,来自“操作账号”表pst.executeUpdate();}if(sex.equals("") == false) {//性别限定在“男”、“女”,出错时通过标签显示告知使用者try {String sql = "update 图书管理员 set 性别=? where 工号=?";pst = dbConn.prepareStatement(sql);pst.setString(1, sex);pst.setString(2, num);pst.executeUpdate();lblNewLabel_4.setVisible(false);}catch(Exception ee) {// TODO Auto-generated catch blockee.printStackTrace();lblNewLabel_4.setVisible(true);lblNewLabel_5.setVisible(false);}}if(work.equals("") == false) {String sql = "update 图书管理员 set 职称=? where 工号=?";pst = dbConn.prepareStatement(sql);pst.setString(1, work);pst.setString(2, num);pst.executeUpdate();}if(phone.equals("") == false) {String sql = "update 图书管理员 set 联系电话=? where 工号=?";pst = dbConn.prepareStatement(sql);pst.setString(1, phone);pst.setString(2, num);pst.executeUpdate();}Statement stateCnt = dbConn.createStatement();String sql1 = "select * from 图书管理员 where 工号='"+num+"'";ResultSet rs_1 = stateCnt.executeQuery(sql1);int i = 0;while(rs_1.next() && i<rowData.length) {rowData[i][0] = rs_1.getString(1);rowData[i][1] = rs_1.getString(2); rowData[i][2] = rs_1.getString(3); rowData[i][3] = rs_1.getString(4); rowData[i][4] = rs_1.getString(5);i++;}//刷新表格TableModel tml = new DefaultTableModel(rowData,Name);table.setModel(tml);pst.close();dbConn.close();if(lblNewLabel_4.isVisible()) {lblNewLabel_5.setVisible(false);}else {lblNewLabel_5.setVisible(true);}} catch (SQLException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (ClassNotFoundException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}});
**4.3.0增删改查**

PreparedStatement pst = null;pst = dbConn.prepareStatement("insert into 图书 values(?,?,?,?,?,?,?,?)");pst.setString(1, num);//书号pst.setString(2, name);//书名pst.setString(3, writer);//作者pst.setString(4, publish);//出版社pst.setString(5, price);//定价pst.setString(6, intro);//内容简介pst.setString(7, status);//状态pst.setString(8, cla);//分类pst.addBatch();pst.executeBatch();dbConn.close();

String sql0 = "delete from 图书 where 书号= ?";PreparedStatement pst = dbConn.prepareStatement(sql0);pst.setString(1, num);//书号pst.addBatch();pst.executeBatch();lblNewLabel_4.setVisible(true);//显示删除成功dbConn.close();

PreparedStatement pst = null;if (name.equals("") == false) {String sql = "update 图书 set 书名=? where 书号=?";pst = dbConn.prepareStatement(sql);pst.setString(1, name);pst.setString(2, num);pst.executeUpdate();}

try {String dbURL="jdbc:sqlserver://localhost:1433;DatabaseName=LibraryManagement";String userName="sa";String userPwd="QWEASDZXC000000";Connection dbConn = null;Statement state = null;Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");dbConn = DriverManager.getConnection(dbURL,userName,userPwd);//连接数据库state = dbConn.createStatement();String sql0 = "select * from 图书";ResultSet rs = state.executeQuery(sql0);Statement stateCnt = dbConn.createStatement();String sql1 = "select count(*) from 图书";ResultSet rs_1 = stateCnt.executeQuery(sql1);while(rs_1.next()) {textField_3.setText(rs_1.getString(1));}//统计总数int i = 0;//查询结果显示到Java表格组件while(rs.next() && i<rowData.length) {rowData[i][0] = rs.getString(1);rowData[i][1] = rs.getString(2); rowData[i][2] = rs.getString(3); rowData[i][3] = rs.getString(4); rowData[i][4] = rs.getString(5);rowData[i][5] = rs.getString(6);rowData[i][6] = rs.getString(7);rowData[i][7] = rs.getString(8);i++;}dbConn.close();} catch (SQLException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (ClassNotFoundException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}

完整源代码

通过百度网盘分享的文件:图书管理系统V1…
链接:https://pan.baidu.com/s/1NQczvOX0n0_g0pDx3iiIXw提取码:po48复制这段内容打开「百度网盘APP 即可获取」