java图书管理系统
一、 引言
图书管理系统是一个用于图书馆或书店管理图书信息、借阅记录和读者信息的应用程序。本系统使用Java Swing框架进行开发,提供直观的用户界面,方便图书馆管理员或书店工作人员对图书信息进行管理。以下是系统的设计、功能和实现的详细报告。
二、系统设计
技术选型:
前端框架: Java Swing
后端语言: Java
数据库: 使用文件存储图书信息
系统架构:
MVC(Model-View-Controller)架构,以确保系统的可维护性和扩展性。
Model: 数据模型,包括图书、读者和借阅记录等类。
View: 用户界面,使用Swing组件实现各种窗口和表格。
Controller: 控制器,处理用户输入、调用业务逻辑和更新视图。
三、 系统功能
图书管理:
添加图书信息,包括书名、作者、出版社、出版日期等。
修改图书信息,支持编辑已有图书的属性。
删除图书,从系统中移除不需要的图书。
查询图书,根据书名、作者等条件进行搜索。
读者管理:
添加读者信息,包括姓名、学号(或工号)、联系方式等。
修改读者信息,更新读者的个人信息。
删除读者,从系统中注销读者账号。
查询读者,根据姓名、学号等条件进行搜索。
借阅管理:
借书,记录图书的借阅信息,包括借阅日期和应还日期。
还书,更新图书的借阅状态,计算逾期天数和罚金。
查询借阅记录,查看读者的借阅历史。
四、 用户界面
登录界面: 提供用户名和密码登录系统。
主界面: 显示图书管理、读者管理和借阅管理等功能按钮。
图书管理界面: 包括添加、修改、删除和查询图书的功能。
读者管理界面: 包括添加、修改、删除和查询读者的功能。
借阅管理界面: 包括借书、还书和查询借阅记录的功能。
五、数据库
1.book_admin表:存储管理员信息。
CREATE TABLE book_admin
(
username
varchar(20) NOT NULL COMMENT ‘用户名’,
password
varchar(20) NOT NULL COMMENT ‘密码’,
PRIMARY KEY (username
),
UNIQUE KEY UNIQUE
(username
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.book_info表:存储图书信息。
CREATE TABLE book_info
(
bookId
int NOT NULL AUTO_INCREMENT COMMENT ‘图书id’,
bookName
varchar(50) NOT NULL COMMENT ‘图书名称’,
author
varchar(50) NOT NULL COMMENT ‘图书作者’,
– 其他字段…
PRIMARY KEY (bookId
),
UNIQUE KEY UNIQUE
(bookName
)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
3.book_lend表:存储借阅信息。
CREATE TABLE book_lend
(
lendId
int NOT NULL AUTO_INCREMENT COMMENT ‘借阅id’,
bookName
varchar(50) NOT NULL COMMENT ‘图书名称’,
userName
varchar(20) NOT NULL COMMENT ‘借阅者名称’,
– 其他字段…
PRIMARY KEY (lendId
)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
4.book_type表:存储图书类别信息。
CREATE TABLE book_type
(
typeId
int NOT NULL AUTO_INCREMENT COMMENT ‘类别id’,
typeName
varchar(50) NOT NULL COMMENT ‘类别名称’,
typeDesc
varchar(100) DEFAULT NULL COMMENT ‘类别描述’,
PRIMARY KEY (typeId
),
UNIQUE KEY UNIQUE
(typeName
)
) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
5.book_user表:存储用户信息。
CREATE TABLE book_user
(
username
varchar(20) NOT NULL COMMENT ‘用户名’,
password
varchar(20) NOT NULL COMMENT ‘密码’,
PRIMARY KEY (username
),
UNIQUE KEY UNIQUE
(username
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
六、程序截图
七、代码
InfoFrame.java
package com.wang.view.minorframe;import com.wang.utils.ImageData;
import com.wang.view.baseview.MinorFrame;import javax.swing.*;
import java.awt.*;/*** 关于我们界面*/
public class InfoFrame extends MinorFrame {public InfoFrame() {super("关于我们",840,590);initFrame();}private void initFrame(){JPanel jp = new JPanel(){@Overrideprotected void paintComponent(Graphics g) {super.paintComponent(g);ImageData.info.paintIcon(this, g, 0, 0);}};jp.setLayout(null);JLabel jl1 = new JLabel("欢迎使用图书管理系统!");jl1.setBounds(20,20,600,50);jl1.setFont(new Font("方正舒体", Font.PLAIN, 40));JLabel jl2 = new JLabel("工作邮箱:xxx");jl2.setBounds(20,70,600,50);jl2.setFont(new Font("方正舒体", Font.PLAIN, 40));jp.add(jl1);jp.add(jl2);setContentPane(jp);}
}
LendBookFrame.java
package com.wang.view.minorframe;import com.wang.bean.Book;
import com.wang.bean.LendInfo;
import com.wang.service.BookService;
import com.wang.service.LendInfoService;
import com.wang.service.TypeService;
import com.wang.service.impl.BookServiceImpl;
import com.wang.service.impl.LendInfoServiceImpl;
import com.wang.service.impl.TypeServiceImpl;
import com.wang.view.baseview.MinorFrame;import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Date;
import java.util.*;
import java.util.List;/*** 借阅图书界面*/
public class LendBookFrame extends MinorFrame {private JTable table;private DefaultTableModel tdm;private final BookService bookService = new BookServiceImpl();private final TypeService typeService = new TypeServiceImpl();private final LendInfoService lendInfoService = new LendInfoServiceImpl();private JRadioButton jrb1, jrb2;private JComboBox<String> jcb1, jcb2;private JTextField jtf1, jtf2, jtf3, jtf4, jtf5, jtf6;private JTextArea jta;public LendBookFrame(String username) {super("图书借阅", 800, 650);initFrame(username);}private void initFrame(String username){JPanel jp = new JPanel() {public void paintComponent(Graphics g) {super.paintComponent(g);g.drawLine(120, 330, getWidth() - 50, 330);g.drawLine(50, 580, getWidth() - 50, 580);g.drawLine(50, 330, 50, 580);g.drawLine(getWidth() - 50, 330, getWidth() - 50, 580);g.drawLine(120, 30, getWidth() - 50, 30);g.drawLine(50, 100, getWidth() - 50, 100);g.drawLine(50, 30, 50, 100);g.drawLine(getWidth() - 50, 30, getWidth() - 50, 100);}};jp.setLayout(null);initTable();JLabel jl1 = new JLabel("搜索条件");JLabel jl2 = new JLabel("图书名称:");JLabel jl3 = new JLabel("图书作者:");JLabel jl4 = new JLabel("图书类别:");JLabel jl5 = new JLabel("表单操作");JLabel jl6 = new JLabel("图书名称:");JLabel jl7 = new JLabel("图书作者:");JLabel jl8 = new JLabel("作者性别:");JLabel jl9 = new JLabel("图书价格:");JLabel jl10 = new JLabel("图书库存:");JLabel jl11 = new JLabel("图书类别:");JLabel jl12 = new JLabel("图书描述:");jtf1 = new JTextField();jtf2 = new JTextField();jtf3 = new JTextField();jtf4 = new JTextField();jtf5 = new JTextField();jtf6 = new JTextField();jta = new JTextArea(20, 20);jta.setLineWrap(true);JScrollPane j = new JScrollPane();jrb1 = new JRadioButton("男");jrb2 = new JRadioButton("女");ButtonGroup bg = new ButtonGroup();bg.add(jrb1);bg.add(jrb2);jrb1.setSelected(true);jcb1 = new JComboBox<>();jcb2 = new JComboBox<>();JButton jb1 = new JButton("查询");JButton jb2 = new JButton("借阅");JScrollPane jsp = new JScrollPane(table);jtf3.setEnabled(false);jtf4.setEnabled(false);jtf5.setEnabled(false);jtf6.setEnabled(false);jta.setEnabled(false);jcb2.setEnabled(false);jrb1.setEnabled(false);jrb2.setEnabled(false);jl1.setBounds(57, 20, 70, 20);jl2.setBounds(60, 55, 70, 20);jl3.setBounds(237, 55, 70, 20);jl4.setBounds(385, 55, 70, 20);jl5.setBounds(57, 320, 70, 20);jtf1.setBounds(125, 57, 100, 20);jtf2.setBounds(302, 57, 70, 20);jb1.setBounds(657, 42, 60, 20);jb2.setBounds(657, 72, 60, 20);jsp.setBounds(50, 125, 686, 180);jcb1.setBounds(455, 57, 180, 20);jcb2.setBounds(510, 397, 180, 20);jl6.setBounds(100, 355, 70, 20);jl7.setBounds(310, 355, 70, 20);jl8.setBounds(520, 355, 70, 20);jtf3.setBounds(170, 357, 130, 20);jtf4.setBounds(380, 357, 130, 20);jrb1.setBounds(590, 355, 40, 20);jrb2.setBounds(640, 355, 40, 20);jl9.setBounds(100, 395, 70, 20);jl10.setBounds(270, 395, 70, 20);jl11.setBounds(440, 395, 70, 20);jtf5.setBounds(170, 397, 90, 20);jtf6.setBounds(340, 397, 90, 20);jl12.setBounds(100, 438, 70, 20);j.setBounds(170, 440, 522, 120);fillBookTypeName();j.setViewportView(jta);jp.add(jl1);jp.add(jl2);jp.add(jl3);jp.add(jl4);jp.add(jl5);jp.add(jl6);jp.add(jl7);jp.add(jl8);jp.add(jl9);jp.add(jl10);jp.add(jl11);jp.add(jl12);jp.add(jtf1);jp.add(jtf2);jp.add(jtf3);jp.add(jtf4);jp.add(jtf5);jp.add(jtf6);jp.add(j);jp.add(jrb1);jp.add(jrb2);jp.add(jcb1);jp.add(jcb2);jp.add(jb1);jp.add(jb2);jp.add(jsp);table.addMouseListener(new MouseAdapter() {@Overridepublic void mousePressed(MouseEvent e) {bookMousePressed();}});jb1.addActionListener(this::searchAction);jb2.addActionListener(actionEvent ->lendAction(username));setContentPane(jp);}//查询按钮private void searchAction(ActionEvent e) {//表格先清空选择table.removeRowSelectionInterval(0, table.getRowCount() - 1);//模糊查找String strOfName = jtf1.getText().trim();String strOfAuthor = jtf2.getText().trim();//String strOfType = (String) jcb1.getSelectedItem();if ("".equals(strOfName) && "".equals(strOfAuthor) && "请选择……".equals(strOfType)) {JOptionPane.showMessageDialog(null, "请输入查询信息!", "警告", JOptionPane.WARNING_MESSAGE);return;}List<Book> list = new ArrayList<>();if (!"".equals(strOfName)) {list.addAll(bookService.getBookListByBookName(strOfName));}if (!"".equals(strOfAuthor)) {list.addAll(bookService.getBookListByAuthor(strOfAuthor));}if (!"".equals(strOfType)) {list.addAll(bookService.getBookListByTypeName(strOfType));}if (list.size() == 0) {JOptionPane.showMessageDialog(null, "未查询到指定结果!");return;}for (Book book : list) {for (int j = 0; j < tdm.getRowCount(); j++) {//将查询到的book根据书名得到表中行数选择得到的行数if (book.getBookId().equals(table.getValueAt(j, 0))) {table.addRowSelectionInterval(j, j);break;}}}//随机展出一个查询到的book对象的信息Book book = list.get((int) ((Math.random() * 100) % list.size()));jtf3.setText(book.getBookName());jtf4.setText(book.getAuthor());jtf5.setText(String.valueOf(book.getPrice()));jtf6.setText(String.valueOf(book.getBookNum()));jta.setText(book.getBookDesc());if ("男".equals(book.getGender())) {jrb1.setSelected(true);} else {jrb2.setSelected(true);}jcb2.setSelectedItem(book.getTypeName());JOptionPane.showMessageDialog(null, "共查询到" + table.getSelectedRowCount() + "条结果!");}//借阅按钮private void lendAction(String username) {if (table.getSelectedRowCount() > 1) {JOptionPane.showMessageDialog(null, "不支持同时借阅多本图书!", "警告", JOptionPane.WARNING_MESSAGE);return;}//获取选中行int row = table.getSelectedRow();if (row == - 1) { //没有选择JOptionPane.showMessageDialog(null, "请选择待借阅图书!", "警告", JOptionPane.WARNING_MESSAGE);return;}if (Integer.parseInt(String.valueOf(table.getValueAt(row, 5))) == 0) {JOptionPane.showMessageDialog(null, "该书无库存!", "警告", JOptionPane.WARNING_MESSAGE);return;}int isFlag = JOptionPane.showConfirmDialog(null, "是否借阅?");if (isFlag > 0) {return;}String bookName = (String) table.getValueAt(row, 1);//执行借阅bookService.lendBook(bookName); //库存减一//填入借阅信息lendInfoService.lendBook(new LendInfo(null, bookName, username, new Date(System.currentTimeMillis()), "未归还"));//更新数量Long newNum = (Long) table.getValueAt(row, 5) - 1;table.setValueAt(newNum, row, 5);jtf6.setText(String.valueOf(newNum));JOptionPane.showMessageDialog(null, "借阅成功!");}//监听鼠标点击事件private void bookMousePressed() {int row = table.getSelectedRow();jtf3.setText(String.valueOf(table.getValueAt(row, 1)));jtf4.setText(String.valueOf(table.getValueAt(row, 2)));jtf5.setText(String.valueOf(table.getValueAt(row, 4)));jtf6.setText(String.valueOf(table.getValueAt(row, 5)));String gender = String.valueOf(table.getValueAt(row, 3));if ("男".equals(gender)) {jrb1.setSelected(true);} else {jrb2.setSelected(true);}String typeName = String.valueOf(table.getValueAt(row, 6));jcb2.setSelectedItem(typeName);jta.setText(String.valueOf(table.getValueAt(row, 7)));}//初始化表格private void initTable() {//创建表格String[] columnNames = {"编号", "图书名称", "作者", "作者性别", "图书价格","图书库存", "图书类别", "图书描述"};Object[][] rowType = bookService.getAllBookToArray();tdm = new DefaultTableModel(rowType, columnNames);table = new JTable(tdm) {@Overridepublic boolean isCellEditable(int row, int column) {return false; //不可编辑,但可以选择}};//DefaultTableCellRenderer dtcr = new DefaultTableCellRenderer();//单元格渲染器dtcr.setHorizontalAlignment(JLabel.CENTER);//居中显示table.setDefaultRenderer(Object.class, dtcr);//设置渲染器ttable.getColumnModel().getColumn(0).setPreferredWidth(30);table.getColumnModel().getColumn(1).setPreferredWidth(100);table.getColumnModel().getColumn(2).setPreferredWidth(100);table.getColumnModel().getColumn(3).setPreferredWidth(50);table.getColumnModel().getColumn(4).setPreferredWidth(50);table.getColumnModel().getColumn(5).setPreferredWidth(50);table.getColumnModel().getColumn(6).setPreferredWidth(100);table.getColumnModel().getColumn(7).setPreferredWidth(180);table.getTableHeader().setReorderingAllowed(false); //不可改变列的位置}//初始化类别下拉菜单private void fillBookTypeName() {jcb1.addItem("请选择……");jcb2.addItem("请选择……");List<com.wang.bean.Type> types = typeService.getAllTypeToList();for (com.wang.bean.Type type : types) {jcb1.addItem(type.getTypeName());jcb2.addItem(type.getTypeName());}}
}
OwnLendInfoFrame.java
package com.wang.view.minorframe;import com.wang.bean.LendInfo;
import com.wang.service.BookService;
import com.wang.service.LendInfoService;
import com.wang.service.impl.BookServiceImpl;
import com.wang.service.impl.LendInfoServiceImpl;
import com.wang.view.baseview.MinorFrame;import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.sql.Date;/*** 个人借阅信息界面*/
public class OwnLendInfoFrame extends MinorFrame {private JTable table;private DefaultTableModel tdm;private final LendInfoService lendInfoService = new LendInfoServiceImpl();private final BookService bookService = new BookServiceImpl();public OwnLendInfoFrame(String username, boolean isFlag) {super("个人借阅信息", 500, 350);initFrame(username,isFlag);}private void initFrame(String username,boolean isFlag) {JPanel jp = new JPanel();jp.setLayout(null);initTable(username, isFlag);JScrollPane j = new JScrollPane(table);j.setBounds(30, 30, 425, 220);jp.add(j);if (isFlag) {JButton jb = new JButton("归还");jp.add(jb);jb.setBounds(360, 260, 60, 20);jb.addActionListener(actionEvent -> returnAction(username));}setContentPane(jp);}//归还按钮private void returnAction(String username) {if (table.getSelectedRowCount() > 1) {JOptionPane.showMessageDialog(null, "不支持同时归还多本图书!", "警告", JOptionPane.WARNING_MESSAGE);return;}//获取选中行int row = table.getSelectedRow();if (row == - 1) { //没有选择JOptionPane.showMessageDialog(null, "请选择待归还图书!", "警告", JOptionPane.WARNING_MESSAGE);return;}int isFlag = JOptionPane.showConfirmDialog(null, "是否归还?");if (isFlag > 0) {return;}int lendId = (int) table.getValueAt(row, 0);String bookName = (String) table.getValueAt(row, 1);Date lendDate = (Date) table.getValueAt(row, 2);bookService.returnBook(bookName); //库存加一lendInfoService.returnBook(new LendInfo(lendId, bookName, username, lendDate, new Date(System.currentTimeMillis()).toString())); //填入归还日期tdm.removeRow(row);JOptionPane.showMessageDialog(null, "归还成功!");}//初始化表格private void initTable(String username,boolean isFlag) {//创建表格String[] columnNames = {"借阅编号", "图书名称", "借阅时间", "归还时间"};Object[][] rowType;if(isFlag) {rowType = lendInfoService.getOwnLendInfo(username);} else{rowType = lendInfoService.getOwnReturnInfo(username);}tdm = new DefaultTableModel(rowType, columnNames);table = new JTable(tdm) {@Overridepublic boolean isCellEditable(int row, int column) {return false; //不可编辑,但可以选择}};//DefaultTableCellRenderer dtcr = new DefaultTableCellRenderer();//单元格渲染器dtcr.setHorizontalAlignment(JLabel.CENTER);//居中显示table.setDefaultRenderer(Object.class, dtcr);//设置渲染器ttable.getColumnModel().getColumn(0).setPreferredWidth(60);table.getColumnModel().getColumn(1).setPreferredWidth(205);table.getColumnModel().getColumn(2).setPreferredWidth(80);table.getColumnModel().getColumn(3).setPreferredWidth(80);table.getTableHeader().setReorderingAllowed(false); //不可改变列的位置}
}
RegisterFrame.java
package com.wang.view.minorframe;import com.wang.bean.User;
import com.wang.service.UserService;
import com.wang.service.impl.UserServiceImpl;
import com.wang.utils.ImageData;
import com.wang.view.baseview.MinorFrame;import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;/*** 用户注册界面*/
public class RegisterFrame extends MinorFrame {private JTextField jtf;private JPasswordField jpf1, jpf2;private JButton jb1, jb3;private final UserService userService = new UserServiceImpl();public RegisterFrame() {super("注册框", 500, 380);initFrame();}private void initFrame(){JPanel jp = new JPanel(){@Overrideprotected void paintComponent(Graphics g) {super.paintComponent(g);ImageData.bg.paintIcon(this, g, 0, 0);}};jp.setLayout(null);JLabel jl1 = new JLabel();JLabel jl2 = new JLabel();JLabel jl3 = new JLabel();jl1.setText(" 用 户 名:");jl1.setIcon(ImageData.un);jl2.setText(" 密 码:");jl2.setIcon(ImageData.pw);jl3.setText(" 确认密码:");jl3.setIcon(ImageData.pw);jl1.setBounds(60, 45, 165, 25);jl2.setBounds(60, 100, 165, 25);jl3.setBounds(60, 155, 165, 25);jl1.setFont(new Font("方正舒体", Font.PLAIN, 25));jl2.setFont(new Font("方正舒体", Font.PLAIN, 25));jl3.setFont(new Font("方正舒体", Font.PLAIN, 25));jtf = new JTextField();jpf1 = new JPasswordField();jpf2 = new JPasswordField();jtf.setBounds(225, 48, 200, 25);jtf.setFont(new Font("方正舒体", Font.PLAIN, 25));jpf1.setBounds(225, 103, 200, 25);jpf1.setFont(new Font("方正舒体", Font.PLAIN, 25));jpf1.setEchoChar('\u2605');jpf2.setBounds(225, 158, 200, 25);jpf2.setFont(new Font("方正舒体", Font.PLAIN, 25));jpf2.setEchoChar('\u2605');jb1 = new JButton("确认");JButton jb2 = new JButton("取消");jb3 = new JButton("重置");jb1.setBounds(70, 230, 80, 40);jb1.setFont(new Font("方正舒体", Font.PLAIN, 20));jb2.setBounds(200, 230, 80, 40);jb2.setFont(new Font("方正舒体", Font.PLAIN, 20));jb3.setBounds(330, 230, 80, 40);jb3.setFont(new Font("方正舒体", Font.PLAIN, 20));jtf.addKeyListener(new KeyAdapter() {@Overridepublic void keyTyped(KeyEvent e) {char c = e.getKeyChar();if (c == KeyEvent.VK_ENTER) {jpf1.grabFocus();}}});jpf1.addKeyListener(new KeyAdapter() {@Overridepublic void keyTyped(KeyEvent e) {char c = e.getKeyChar();if (c == KeyEvent.VK_ENTER) {jpf2.grabFocus();}}});jpf2.addKeyListener(new KeyAdapter() {@Overridepublic void keyTyped(KeyEvent e) {char c = e.getKeyChar();if (c == KeyEvent.VK_ENTER) {jb1.doClick();}}});jp.add(jl1);jp.add(jl2);jp.add(jl3);jp.add(jtf);jp.add(jpf1);jp.add(jpf2);jp.add(jb1);jp.add(jb2);jp.add(jb3);jb1.addActionListener(this::registerAction);jb2.addActionListener(this::cancelAction);jb3.addActionListener(this::resetAction);setContentPane(jp);}//注册按钮private void registerAction(ActionEvent e) {String username = jtf.getText().trim();String password1 = String.valueOf(jpf1.getPassword()).trim();String password2 = String.valueOf(jpf2.getPassword()).trim();if ("".equals(username)) {JOptionPane.showMessageDialog(null, "用户名不能为空!", "警告", JOptionPane.WARNING_MESSAGE);return;}if ("".equals(password1)) {JOptionPane.showMessageDialog(null, "密码不能为空!", "警告", JOptionPane.WARNING_MESSAGE);return;}if ("".equals(password2)) {JOptionPane.showMessageDialog(null, "请确认你的密码!", "警告", JOptionPane.WARNING_MESSAGE);return;}if (!password1.equals(password2)) {JOptionPane.showMessageDialog(null, "两次输入的密码不一致!", "警告", JOptionPane.WARNING_MESSAGE);jb3.doClick();return;}if ("root".equals(username)) {JOptionPane.showMessageDialog(null, "用户名已存在!", "错误", JOptionPane.ERROR_MESSAGE);jb3.doClick();return;}User user = new User(username, password1);boolean isSuccess = userService.registerUser(user);if (isSuccess) {JOptionPane.showMessageDialog(null, "注册成功!");this.dispose();} else {JOptionPane.showMessageDialog(null, "用户名已存在!", "错误", JOptionPane.ERROR_MESSAGE);jb3.doClick();}}//取消按钮private void cancelAction(ActionEvent e) {this.dispose();}//重置按钮private void resetAction(ActionEvent e) {jtf.setText("");jpf1.setText("");jpf2.setText("");}
}
八、结论
图书管理系统采用Java Swing框架,实现了图书、读者和借阅记录的基本管理功能。通过清晰的系统设计、直观的用户界面和严谨的测试,确保了系统的可用性和稳定性。未来的改进方向可以考虑引入更复杂的数据库系统、增加图书推荐算法等功能,提升系统的智能化和用户体验。
九、交流与联系
q:969060742 文档、代码、sql、程序资源
相关文章:
java图书管理系统
一、 引言 图书管理系统是一个用于图书馆或书店管理图书信息、借阅记录和读者信息的应用程序。本系统使用Java Swing框架进行开发,提供直观的用户界面,方便图书馆管理员或书店工作人员对图书信息进行管理。以下是系统的设计、功能和实现的详细报告。 二…...
大屏自适应容器组件-Vue3+TS
1.引言 在做数字大屏时,图表能跟着浏览器的尺寸自动变化,本文采用Vue3前端框架,采用TypeScript语言,封装了一个大屏自适应组件,将需要显示的图表放入组件的插槽中,就能实现自适应屏幕大小的效果。 2.实际…...
java图书信息管理
一、项目概述 本图书信息管理系统旨在提供一个直观的用户界面,用于管理图书馆或书店的图书信息。系统包括图书添加、查询、借阅和归还等功能。 二、系统架构 系统采用JavaSwing作为前端UI框架,后端使用Java Servlet处理业务逻辑,数据存储在…...
apache服务器出现No input file specified.解决方案
APACHE服务器出现No input file specified.解决方案 thinkcmf程序默认的.htaccess里面的规则: <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php/$1 [QSA…...
你写过的最蠢的代码是?——全栈开发篇
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
正点原子嵌入式linux驱动开发——TF-A初探
上一篇笔记中,正点原子的文档简单讲解了一下什么是TF-A,并且也学习了如何编译TF-A。但是TF-A是如何运行的,它的一个运行流程并未涉及。TF-A的详细运行过程是很复杂的,涉及到很多ARM处理器底层知识,所以这一篇笔记的内容…...
【网安别学成开发】之——python篇
经典入门编程题 1.猜数字 经典的猜数字游戏,几乎所有人学编程时都会做。 功能描述: 随机选择一个三位以内的数字作为答案。用户输入一个数字,程序会提示大了或是小了,直到用户猜中。 #!/usr/bin/env python3import randomresu…...
vue图片显示
一、Vue图片显示方法: 1.直接使用<img>标签: 最简单的方法是使用<img>标签,并将图片的URL作为src属性的值。例如: <img src"path/to/your/image.jpg" alt"Image"> 如果是绝对路径&#x…...
S32K144 GPIO编程
前面的文章介绍了如何在MDK-Keil下面进行S32K144的开发,下面就使用该工程模板进行GPIO LED的编程试验。 1. 开发环境 S32K144EVB-Q100开发板MDK-Keil Jlink 2. 硬件连接 S32K144EVB-Q100开发板关于LED的原理图如下: 也就是具体连接关系如下…...
域名备案流程(个人备案,腾讯云 / 阿里云)
文章目录 1.网站备案的目的2.备案准备的材料2.1 网站域名2.2 云资源或备案授权码2.3 电子材料 3.首次个人备案准备的材料3.1 主体相关3.2 域名相关3.3 网站相关3.4 网站服务相关3.5 变更相关 4.个人备案流程4.1 登录系统4.2 填写备案信息🍀 填写备案省份ἴ…...
子网ip和子网掩码的关系
子网ip和子网掩码的关系 一个IP地址被分为两部分:网络地址和主机地址。这是通过子网掩码来实现的。 子网掩码(Subnet Mask)是一个32位的二进制数,它用来区分一个IP地址中的网络地址和主机地址。在子网掩码中,网络地址…...
openGauss学习笔记-88 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用将磁盘表转换为MOT
文章目录 openGauss学习笔记-88 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用将磁盘表转换为MOT88.1 前置条件检查88.2 转换88.3 转换示例 openGauss学习笔记-88 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用将磁盘表转换为MOT …...
网络-Ajax
文章目录 前言一、Ajax优点:缺点: 二、使用步骤XNLHttpRequest对象完整代码 总结 前言 本文主要记录Ajax技术的简介,以及用法。 一、Ajax Ajax是一组用于在Web浏览器和Web服务器之间进行异步通信的Web开发技术。 它代表着Asynchronous Java…...
Autowired和Resource的关系
相同点对于下面的代码来说,如果是Spring容器的话,两个注解的功能基本是等价的,他们都可以将bean注入到对应的field中 不同点但是请注意,这里说的是基本相同,说明还是有一些不同点的: byName和byType匹配顺…...
HashTable, HashMap, ConcurrentHashMap 之间的区别
HashMap: 线程不安全. key 允许为 null。 Hashtable: 线程安全. 使用 synchronized 锁 Hashtable 对象, 效率较低. key 不允许为 null.。只是简单的把关键方法上加上了 synchronized 关键字。如 get 和 set ,这相当于直接针对 Hashtable 对象本身加锁,如…...
Maven下载源码出现:Cannot download sources Sources not found for org.springframwork...
Maven下载源码出现:Cannot download sources Sources not found for org.springframwork… 最近重装了IDEA再次查看源码时发现总是报错,网上找了很多,发现解决方法都是在项目终端执行如下命令: mvn dependency:resolve -Dclassi…...
C进阶--字符函数和字符串函数介绍
✨ 更多细节参考 cplusplus.com/reference/cstring/ 使用方式: ⭕ 求字符串长度 🖌 strlen 函数原型: size_t strlen ( const char * str ); 作用: 获取字符串长度 ✨补充: ⭐字符串以 \0 作为结束标志&…...
算法通关村第五关-二叉树遍历(层数优先)之经典问题:简单的层序遍历、层序遍历分层、自底向上的层序遍历
基础知识(青铜挑战) 了解二叉树的基础知识 实战训练(白银挑战) 简单的层序遍历 基本的层序遍历思路很清晰: 给你一个二叉树根节点,你需要创建一个队列 queue 来遍历节点,一个链表 list 来存储…...
C++左右值及引用
1 左值和右值 简单记法:能取地址的是左值,不能取地址的是右值 右值一般是常量 例: i 是右值,因为先把 i 赋值给临时变量,临时变量在1,而临时变量是将亡值,&i取地址会报错 i是左值…...
如何备份和恢复数据库
目录 1.xtrabackup 是什么2.全量备份3.增量备份4.使用备份进行恢复5.原理6.参考 本文主要介绍如何使用xtrabackup 进行数据库的备份和恢复,并在最后介绍了原理。 1.xtrabackup 是什么 XtraBackup是由Percona开发的一款开源的MySQL数据库备份工具。它可以对InnoDB和…...
简化数据库操作:探索 Gorm 的约定优于配置原则
文章目录 使用 ID 作为主键数据库表名TableName临时指定表名列名时间戳自动填充CreatedAtUpdatedAt时间戳类型Gorm 采用约定优于配置的原则,提供了一些默认的命名规则和行为,简化开发者的操作。 使用 ID 作为主键 默认情况下,GORM 会使用 ID 作为表的主键: type User st…...
保姆级Anaconda安装教程
一.anaconda下载 建议使用清华大学开源软件镜像站进行下载,使用官网下载速度比较慢。 anaconda清华大学开源软件镜像站 : https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 一路next即可,注意添加环境变量得选项都勾上。 二.验证…...
你写过的最蠢的代码是?——后端篇
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页: 🐅🐾猫头虎的博客🎐《面试题大全专栏》 🦕 文章图文并茂🦖…...
快速幂
876. 快速幂求逆元 - AcWing题库 AC代码: #include <iostream> #include <cstring> #include <algorithm>using namespace std;typedef long long ll;int n;int qmi(int a,int k,int p) {int res1;while(k){if(k&1)res(ll)res*a%p;k>&…...
【题解 动态规划】 Colored Rectangles
题目描述: 分析: 乍一看我还以为是贪心! 猫 想想感觉没问题 但是局部最优并不能保证全局最优 比如这组数据 19 19 19 19 20 20 20 20如果按照贪心的做法,答案是20*20*2 但是其实答案是19*20*4 因此这道题用贪心是不对的 于是我…...
VsCode好用的扩展插件
开发插件推荐: 别名路径跳转 >> 点击引用的变量名,ctrl 点击 跳转文件Auto Rename Tag >> 修改标签前缀,后缀标签会同时修改Chinees 中文(简体)Code Runner >> 纯js文件右键点击run code即可底部终端打印file-icons-mac >> ma…...
Linux shell编程学习笔记4:修改命令行提示符格式(内容和颜色)
一、命令行提示符格式内容因shell类型而异 Linux终端命令行提示符内容格式则因shell的类型而异,例如CoreLinux默认的shell是sh,其命令行提示符为黑底白字,内容为: tcbox:/$ 其中,tc为当前用户名,box为主机…...
vue-引入使用main.js全局常量
common.js 命名什么都可以,用来定义常量的 定义了之后使用export让此暴露出去 const QRaddress http://localhost:9875export{QRaddress, } main.js //引入刚刚的js import {QRaddress} from /config/common.js挂载 Vue.prototype.$QRaddress QRaddress使用 …...
【C语言】【动态内存管理】malloc,free,calloc,realloc
1.malloc函数 void* malloc(size_t size)功能:向内存申请字节为 size大小的空间 使用时要包含头文件:<stdlib.h> 开辟成功:返回开辟好的空间初始地址的指针 开辟失败:返回空指针 NULL 使用举例: (malloc和free…...
Linux性能优化--性能工具-系统CPU
2.0.概述 本章概述了系统级的Linux性能工具。这些工具是你追踪性能问题时的第一道防线。它们能展示整个系统的性能情况和哪些部分表现不好。 1.理解系统级性能的基本指标,包括CPU的使用情况。 2.明白哪些工具可以检索这些系统级性能指标。 2.1CPU性能统计信息 为…...
兴化网站建设/广告推广怎么做最有效
知识点:掌握 appSettings 的配置与在程序中的访问 、掌握使用 connectionStrings 配置数据库连接字符串 、 掌握自定义错误信息的方法 、 掌握身份验证和权限控制 、 掌握网站的发布和部署 1、 配置文件 1.1 配置文件概述 什么是配置文件?配置文件就是具有规范化数据格式的…...
电影网站建设费用/必应站长平台
函数说明示例String.fromCharCode()返回Unicode码对应的字符串String.fromCharCode(20013); // "中"charCodeAt()返回字符的Unicode码中.charCodeAt(); // 20013charAt()返回指定位置的字符abc.charAt(1); // "b"concat()连接两个字符串ab.concat(cd); // …...
中企动力做的网站后台如何登陆/推广普通话手抄报内容
Vue-Router 原理实现1.1Vue-Router 使用步骤1.2动态路由1.3嵌套路由1.4编程式导航1.5Hash 和 History 模式区别History 模式History 模式 - Node.jsHistory 模式 - nginx1.6Vue Router 实现原理Vue Router 模拟实现 ( History模式 )Vue Router - ConstructorVue Router - insta…...
重庆做营销网站建设/今日重大新闻头条十条
前言:貌似时隔上一篇博客已经过了很久了,这里再写一下关于vi(vim,gvim)的配置 一、vi编辑器的配置文件及目录需要提到的是,vi编辑器的配置文件主要有两个地方1. ~/.vimrc #这里以.开头说明…...
云服务器安装win系统做网站/谷歌推广公司哪家好
nexus5、nexus6可以刷安卓6.0系统了,想要学习nexus5、nexus6怎么刷安卓6.0系统的朋友可以一起来学习!提示:刷机当然存在风险,并且开发者预览版也很不完善,无法作为主力机使用,刷机前请备份好自己的数据。首…...
暴雪网易2023后不代理了/seo外包费用
查看自己的ip和采用什么方式上网(网通/电信)http://www.whatchina.com/html/sip.asp本文转自 xcf007 51CTO博客,原文链接:http://blog.51cto.com/xcf007/161180,如需转载请自行联系原作者...