图书管理系统 订阅
图书管理系统,是一个由人、计算机等组成的能进行管理信息的收集、传递、加工、保存、维护和使用的系统。利用信息控制企业的行为;帮助企业实现其规划目标。 展开全文
图书管理系统,是一个由人、计算机等组成的能进行管理信息的收集、传递、加工、保存、维护和使用的系统。利用信息控制企业的行为;帮助企业实现其规划目标。
信息
定    义
能进行图书馆管理系统能实测
特    点
界面必须始终一致
中文名
图书管理系统
外文名
Library management system
图书管理系统概念
图书馆管理系统,能进 行图书馆管理系统能实测国民经济和企业的各种运行情况;利用过去的数据预测未来;从企业全局出发辅助企业进行管理决策;利用信息控制企业的行为;帮助企业实现其规划目标。图书馆管理系统合运用了管理科学,系统科学,运筹学,统计学,计算机科学等学科的知识。可以通俗的简化的描述图书馆管理系统的三要素:系统的观点、数学的方法以及计算机的应用。图书馆管理系统概念结构主要由四大部分组成即信息源、信息处理器、信息用户、信息管理者组成。
收起全文
精华内容
下载资源
问答
  • 图书管理系统(Java MySQL)

    万次阅读 多人点赞 2018-12-22 15:48:09
    (完整代码+实训报告): https://download.csdn.net/download/qq_35793285/10896342 (完整代码): ... ...管理员登录 图书借阅信息管理 图书信息管理 管理员更改密码 退出系统 二,工具 E...

    (完整代码+实训报告):

    链接: https://pan.baidu.com/s/1kogzA1G_lOstSQP6yo-cSw 提取码: yugt 

     

    觉着有用就点个赞哦~

     

    一,功能

    1. 管理员登录
    2. 图书借阅信息管理
    3. 图书信息管理
    4. 管理员更改密码
    5. 退出系统

    二,工具

    • Eclipse Version: 2018-09 (4.9.0)
    • MySQL Workbench 8.0 CE
    • mysql-connector-java-8.0.13.jar

    三、效果图:

    登录界面:

    主界面:

    借阅书籍管理:

    个人书库管理:

    更改密码:

     

    四、数据库设计

         1)图书表

         2)用户表

    两个数据表间没有关联:

    五、JAVA层次分析

     (1)逻辑图

    (2)包结构,采用MVC三层架构组织各个模块

     

    六、主要Java代码分析

     

    Dao类(以BookDao为例)

    package pers.cyz.dao;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;
    
    import pers.cyz.model.Book;
    import pers.cyz.util.DBUtil;
    
    /**
     * 数据库图书表信息数据访问对象类,包含增加图书信息、删除图书信息
     * 、更新图书信息、查询图书信息、查询借阅信息和归还图书
     * 
     * @author 1651200111 陈彦志
     */
    public class BookDao {
    
    
    	/**
    	 * 增加图书信息
    	 */
        public void addBook(Book book) throws Exception{
        	// 首先拿到数据库的连接
            Connection con = DBUtil.getConnection();
            String sql="insert into tb_books"
            		// ISBN、书名、图书价格、图书作者、出版社
            		+ "(ISBN, book_name, book_price, book_author, published_house,"
            		// 分类号、借书人姓名、借书人电话、借书日期,已借天数
            		+ "book_category, borrower_name, borrower_phone) "
            		+ "values("
            		/*
            		 * 参数用?表示,相当于占位符,然后在对参数进行赋值。当真正执行时,
            		 * 这些参数会加载在SQL语句中,把SQL语句拼接完整才去执行。这样就会减少对数据库的操作
            		 */
            		+ "?,?,?,?,?,?,?,?)";
            /*
             * prepareStatement这个方法会将SQL语句加载到驱动程序conn集成程序中,
             * 但是并不直接执行,而是当它调用execute()方法的时候才真正执行;
             */
            PreparedStatement psmt = con.prepareStatement(sql);
            // 先对应SQL语句,给SQL语句传递参数
            psmt.setString(1, book.getISBN());
            psmt.setString(2, book.getBookName());
            psmt.setFloat(3, book.getPrice());
            psmt.setString(4, book.getAuthor());
            psmt.setString(5, book.getPublishHouse());
            psmt.setString(6, book.getBookCategory());
            
            if (book.getBorrowerName() == null || book.getBorrowerName() == "") {
            	psmt.setString(7, null);
            }
            else {
            	  psmt.setString(7, book.getBorrowerName());
            }
          
            if (book.getBorrowerPhone() == null || book.getBorrowerPhone() == "") {
            	 psmt.setString(8, null);  
            }
            else {
            	psmt.setString(8, book.getBorrowerPhone());  
            }
            
            //执行SQL语句
            psmt.execute();
    
        }
    	
      
        /**
         * 删除图书信息
         */
          public void delBook(int ID) throws SQLException{
        	  // 首先拿到数据库的连接
              Connection con=DBUtil.getConnection();
              String sql="" + 
                      "DELETE FROM tb_books "+               
                      // 参数用?表示,相当于占位符
                      "WHERE ID = ?";
              // 预编译sql语句
              PreparedStatement psmt = con.prepareStatement(sql);
              // 先对应SQL语句,给SQL语句传递参数
              psmt.setInt(1, ID);
              // 执行SQL语句
              psmt.execute();    
          }
    	    
    
    	/**
    	 * 更新图书信息
    	 */
        public void changeBook(Book book) throws SQLException{
        	// 首先拿到数据库的连接
            Connection con=DBUtil.getConnection();
            String sql="update tb_books "
            		+ "set ISBN = ?, book_name = ?, book_price = ?, book_author = ?"
                    + ",published_house = ?, book_category = ?, borrower_name = ?, borrower_phone = ? "
                    // 参数用?表示,相当于占位符 
            		+ "where ID = ?";
            // 预编译sql语句
            PreparedStatement psmt = con.prepareStatement(sql);
            // 先对应SQL语句,给SQL语句传递参数
            psmt.setString(1, book.getISBN());
            psmt.setString(2, book.getBookName());
            psmt.setFloat(3, book.getPrice());
            psmt.setString(4, book.getAuthor());
            psmt.setString(5, book.getPublishHouse());
            psmt.setString(6, book.getBookCategory());
            if (book.getBorrowerName().equals("")) {
            	psmt.setString(7, null);
            }
            else {
            	 psmt.setString(7, book.getBorrowerName());
            }
           
            if (book.getBorrowerPhone().equals("")) {
            	psmt.setString(8, null);
            }
            else {
            	 psmt.setString(8, book.getBorrowerPhone());
            }
            psmt.setInt(9, book.getID());
            // 执行SQL语句
            psmt.execute();    
        }
    
    	        
    
    	/**
    	 * 查询书籍信息
    	 */
    	public List<Book> query() throws Exception{	       
    		Connection con = DBUtil.getConnection();	        
    		Statement stmt = con.createStatement();	       
    		ResultSet rs = stmt.executeQuery("select "
    				// ISBN、书名、作者、图书价格、出版社
    				+ "ID, ISBN, book_name, book_author, book_price, published_house, "
    				// 分类号、借书人姓名、借书人电话
    				+ "book_category, borrower_name, borrower_phone "
    				+ "from tb_books");	      
    		List<Book> bookList = new ArrayList<Book>();	       
    		Book book = null;	   
    		// 如果对象中有数据,就会循环打印出来
    		while (rs.next()){	           
    			book = new Book();	     
    			book.setID(rs.getInt("ID"));
    			book.setISBN(rs.getString("ISBN"));
    			book.setBookName(rs.getString("book_name"));	       
    			book.setAuthor(rs.getString("book_author"));
    			book.setPrice(rs.getFloat("book_price"));
    			book.setPublishHouse(rs.getString("published_house"));
    			book.setBookCategory(rs.getString("book_category"));
    			book.setBorrowerName(rs.getString("borrower_name"));
    			book.setBorrowerPhone(rs.getString("borrower_phone"));
    			bookList.add(book);	        
    		}	       
    		return bookList;	  
    	}
    
    
    	/**
    	 * 查询借阅信息
    	 * 
    	 * @return
    	 * 		bookList
    	 */
    	public List<Book> borrowQuery() throws Exception{	       
    		Connection con = DBUtil.getConnection();	        
    		Statement stmt = con.createStatement();	       
    		ResultSet rs = stmt.executeQuery(""
    				// ID、书名、借书人姓名、借书人电话
    				+ "SELECT ID, book_name, borrower_name, borrower_phone "
    				+ "FROM tb_books "
    				+ "WHERE borrower_name IS NOT NULL"
    				);	      
    		List<Book> bookList = new ArrayList<Book>();	       
    		Book book = null;	     
    		// 如果对象中有数据,就会循环打印出来
    		while (rs.next()){	           
    			book = new Book();	     
    			book.setID(rs.getInt("ID"));
    			book.setBookName(rs.getString("book_name"));	       
    			book.setBorrowerName(rs.getString("borrower_name"));
    			book.setBorrowerPhone(rs.getString("borrower_phone"));
    			bookList.add(book);	        
    		}	       
    		return bookList;	  
    	}
    
    	/**
    	 * 更新图书信息,归还图书
    	 */
        public void returnBook(Book book) throws SQLException{
        	// 首先拿到数据库的连接
            Connection con=DBUtil.getConnection();
            String sql="UPDATE tb_books "
            		// ISBN、图书名称、作者、价格
            		+ "SET "
            		// 借书人姓名、借书人电话
            		+ "borrower_name = ?, borrower_phone = ? "
                    // 参数用?表示,相当于占位符 
            		+ "WHERE ID = ?";
            // 预编译sql语句
            PreparedStatement psmt = con.prepareStatement(sql);
            // 先对应SQL语句,给SQL语句传递参数
            psmt.setString(1, book.getBorrowerName());
            psmt.setString(2, book.getBorrowerPhone());
            psmt.setInt(3, book.getID());
            // 执行SQL语句
            psmt.execute();    
        }
    	
    
    }
    

    重点内容 :

    JDBC进行简单的数据库增删改查

    详细参考:https://www.cnblogs.com/Qian123/p/5339164.html#_labelTop

     

    Model类(以Book为例)

    package pers.cyz.model;
    
    /**
     * 图书模型类,包含数据库图书表各对应的字段get、set方法
     * 
     * @author 1651200111 陈彦志
     */
    public class Book {
    	private int ID;
    	// ISBN号
    	private String ISBN;
    	// 图书名称
    	private String bookName;
    	// 图书价格
    	private float price;
    	// 图书作者
    	private String author;
    	// 出版社
    	private String publishedHouse;
    	// 图书分类号
    	private String bookCategory;
    	// 借书人姓名
    	private String borrowerName;
    	// 借书人电话
    	private String borrowerPhone;
    
    	/**
    	 * 获取ID
    	 */
    	public int getID() {
    		return ID;
    	}
    	/**
    	 * 设置ID
    	 */
    	public void setID(int iD) {
    		ID = iD;
    	}
    	
    	/**
    	 * 获取ISBN
    	 */
    	public String getISBN() {
    		return ISBN;
    	}
    	/**
    	 * 设置ISBN
    	 */
    	public void setISBN(String iSBN) {
    		ISBN = iSBN;
    	}
    	
    	
    	/**
    	 * 获取图书名称
    	 */
    	public String getBookName() {
    		return bookName;
    	}
    	/**
    	 * 设置图书名称
    	 */
    	public void setBookName(String bookName) {
    		this.bookName = bookName;
    	}
    	
    	
    	/**
    	 * 获取图书价格
    	 */
    	public float getPrice() {
    		return price;
    	}
    	/**
    	 * 设置图书价格
    	 */
    	public void setPrice(float price) {
    		this.price = price;
    	}
    	
    	
    	/**
    	 * 获取图书作者
    	 */
    	public String getAuthor() {
    		return author;
    	}
    	/**
    	 * 设置图书作者
    	 */
    	public void setAuthor(String author) {
    		this.author = author;
    	}
    	
    	
    	/**
    	 * 获取出版社
    	 */
    	public String getPublishHouse() {
    		return publishedHouse;
    	}
    	/**
    	 * 设置出版社
    	 */
    	public void setPublishHouse(String publishedHouse) {
    		this.publishedHouse = publishedHouse;
    	}
    	
    	
    	/**
    	 * 获取图书分类信息
    	 */
    	public String getBookCategory() {
    		return bookCategory;
    	}
    	/**
    	 * 设置图书分类信息
    	 */
    	public void setBookCategory(String bookCategory) {
    		this.bookCategory = bookCategory;
    	}
    	
    	
    	/**
    	 * 获取借书人姓名
    	 */
    	public String getBorrowerName() {
    		return borrowerName;
    	}
    	/**
    	 * 设置借书人姓名
    	 */
    	public void setBorrowerName(String borrowerName) {
    		this.borrowerName = borrowerName;
    	}
    	
    	
    	/**
    	 * 获取借书人电话
    	 */
    	public String getBorrowerPhone() {
    		return borrowerPhone;
    	}
    	/**
    	 * 设置借书人电话
    	 */
    	public void setBorrowerPhone(String borrowerPhone) {
    		this.borrowerPhone = borrowerPhone;
    	}
    
    
    }
    

    重点内容 :

    主要就是数据库对应表中各对应的字段get、set方法

        Eclipse技巧:

            Shift + alt + s  -> Generate Getters and Setters -> Select all -> Generate 自动生成set、get方法

     

    Controller类(以BookAction为例)

    package pers.cyz.controller;
    
    import java.util.List;
    
    import javax.swing.JTable;
    import javax.swing.JTextField;
    
    import pers.cyz.dao.BookDao;
    import pers.cyz.model.Book;
    
    
    /**
     * 图书信息行为控制类,包含增加图书、删除图书
     * 、 修改图书、和初始化个人书库管理窗体表格
     * 
     * @author 1651200111 陈彦志
     */
    public class BookAction {
    	
     
            
    	/**
    	 * 初始化窗体表格
    	 * @return
    	 * 		results
    	 */
    	@SuppressWarnings("rawtypes")
    	public Object[][] initializTable(String[] columnNames) throws Exception{
    		BookDao bookDao = new BookDao();
    		List list = bookDao.query();
    		Object[][] results = new Object[list.size()][columnNames.length];
    		
    		for(int i = 0; i < list.size(); i++) {
    			Book book = (Book)list.get(i);				
    	
    			results[i][0] = book.getID();
    			results[i][1] = book.getBookName();
    			results[i][2] = book.getAuthor();
    			results[i][3] = book.getPrice();
    			results[i][4] = book.getISBN();
    			results[i][5] = book.getPublishHouse();
    			results[i][6] = book.getBookCategory();	
    	
    			String borrowerName =  book.getBorrowerName();
    			if (borrowerName == null) {	
    				borrowerName = "";	
    				results[i][7] = borrowerName;
    			}
    			else {	
    				results[i][7] = borrowerName;
    			}
    			
    			String borrowerPhone = book.getBorrowerPhone();	
    			if (borrowerPhone == null) {		
    				borrowerPhone = "";	
    				results[i][8] = borrowerPhone;
    			}	
    			else {	
    				results[i][8] = borrowerPhone;
    			}
    		}	   	
    		return results;
    }
    	
    	
     	/**
     	 * 添加图书信息
     	 */
    	public void addBookInformation (JTextField textFieldISBN, JTextField textFieldName
    			,JTextField textFieldPrice, JTextField textFieldAuthor, JTextField textFieldPublishedHouse
    			, JTextField textFieldBookCategory, JTextField textFieldBorrowName
    			, JTextField textFieldBorrowPhone) throws Exception {
    	
            BookDao bookDao=new BookDao();
            Book book=new Book();     
            
            book.setISBN(textFieldISBN.getText());      
            book.setBookName(textFieldName.getText());
            float price = Float.parseFloat(textFieldPrice.getText());
            book.setPrice(price);
            book.setAuthor(textFieldAuthor.getText());
            book.setPublishHouse(textFieldPublishedHouse.getText());
            book.setBookCategory(textFieldBookCategory.getText());
            
            if (textFieldBorrowName.getText() == null ||textFieldBorrowName.getText() == "" ) {
            	book.setBorrowerName(null);
            }
            else {
            	 book.setBorrowerName(textFieldBorrowName.getText());
            }
           
            if (textFieldBorrowPhone.getText() == null || textFieldBorrowPhone.getText() == "") {
            	book.setBorrowerPhone(null);
            }
            else {
            	book.setBorrowerPhone(textFieldBorrowPhone.getText());
            }
            
            //添加图书
            bookDao.addBook(book);
    	}
    	
    	
    
    	/**
    	 * 删除图书信息
    	 */
    	public void delBookInformation (JTable table) throws Exception {
    	
    		int selRow = table.getSelectedRow();
    		int ID = Integer.parseInt(table.getValueAt(selRow, 0).toString());
    		
            BookDao bookDao=new BookDao();
            Book book=new Book();     
            
            book.setID(ID);
       
            // 删除图书信息
            bookDao.delBook(ID);
    	}
    	
    	
    	/**
    	 * 修改图书信息
    	 */
    	public void changeBookInformation (JTextField textFieldISBN, JTextField textFieldName
    			,JTextField textFieldPrice, JTextField textFieldAuthor, JTextField textFieldPublishedHouse
    			, JTextField textFieldBookCategory, JTextField textFieldBorrowerName
    			, JTextField textFieldBorrowerPhone, JTable table) throws Exception{
    		
            BookDao bookDao=new BookDao();
            Book book=new Book();     
           
    		int selRow = table.getSelectedRow();
    		int ID = Integer.parseInt(table.getValueAt(selRow, 0).toString());	
            book.setID(ID);
            
            book.setISBN(textFieldISBN.getText());      
            book.setBookName(textFieldName.getText());
            book.setAuthor(textFieldAuthor.getText());
            float price = Float.parseFloat(textFieldPrice.getText());
            book.setPrice(price);
            book.setPublishHouse(textFieldPublishedHouse.getText());
            book.setBookCategory(textFieldBookCategory.getText());
            book.setBorrowerName(textFieldBorrowerName.getText());
        	book.setBorrowerPhone(textFieldBorrowerPhone.getText());
             
            //修改图书
            bookDao.changeBook(book);       
    	}
    	
    	
    }
        
        
        
    
    
    
    

     

    util类(以DBUtil为例)

    package pers.cyz.util;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    
    /**
     * 连接数据库类,包含一个对外提供获取数据库连接的方法
     * 
     * @author 1651200111 陈彦志
     */
    public class DBUtil {
    	
    	// 数据库连接路径
    	private static final String URL = "jdbc:mysql://127.0.0.1:3306/db_books?"
    			+ "useUnicode = true & serverTimezone = GMT"
    			// MySQL在高版本需要指明是否进行SSL连接
    			+ "& characterEncoding = utf8 & useSSL = false";
    	private static final String NAME = "root";
    	private static final String PASSWORD = "root";
    	private static Connection conn = null;
    	
    	// 静态代码块(将加载驱动、连接数据库放入静态块中)
    	 static{
    	        try {
    	            // 加载驱动程序
    	            Class.forName("com.mysql.cj.jdbc.Driver");
    	            // 获取数据库的连接
    	            conn = DriverManager.getConnection(URL, NAME, PASSWORD);
    	        } catch (ClassNotFoundException e) {
    	            e.printStackTrace();
    	        } catch (SQLException e) {
    	            e.printStackTrace();
    	        }
    	    }
    	 
    	 // 对外提供一个方法来获取数据库连接	    
    	 public static Connection getConnection(){     
    		 return conn;	   
    	 }
    	
    	
    }
    

    util类(以BackgroundImage为例)

    package pers.cyz.util;
    
    import java.awt.Container;
    
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    
    /**
     * 设置背景图片类
     * 
     * @author 1651200111 陈彦志
     */
    public class BackgroundImage {
    	
    	public BackgroundImage(JFrame frame,Container container,String ImageName) {
    		// 限定加载图片路径
    		ImageIcon icon= new ImageIcon("res/" + ImageName);	
    		
    		final JLabel labelBackground = new JLabel();
    		ImageIcon iconBookManageSystemBackground = icon;
    		labelBackground.setIcon(iconBookManageSystemBackground);
    		// 设置label的大小
    		labelBackground.setBounds(0,0,iconBookManageSystemBackground.getIconWidth()
    				,iconBookManageSystemBackground.getIconHeight());		
    		// 将背景图片标签放入桌面面板的最底层
    		frame.getLayeredPane().add(labelBackground,new Integer(Integer.MIN_VALUE));
    		// 将容器转换为面板设置为透明
    		JPanel panel = (JPanel)container;
    		panel.setOpaque(false);
    		
    	}
    	
    
    }
    

     

    重点内容 :

        将图片标签放在窗体底层面板,然后将窗体转化为容器,将容器面板设为透明,背景图片就设置好了,之后就可以直接在该容器中添加组件

     


    • 将所有两个或两个以上类需要用到的代码段全部封装到了公共类。
    • 整体按照MVC三层架构组织

     

    参考文章:https://www.cnblogs.com/Qian123/p/5339164.html#_labelTop

    参考文章:https://blog.csdn.net/acm_hmj/article/details/52830920

     

     

    展开全文
  • 图书管理系统

    千次下载 2009-01-01 18:10:38
    图书管理系统
  • 图书管理 系统

    千次下载 热门讨论 2008-05-18 22:41:44
    图书管理 系统 真得 不错
  • 基于Java和MySQL的图书管理系统

    万次阅读 多人点赞 2018-06-20 21:41:17
    Java图书管理系统 设计人:wangyunpeng_bio 项目需求 随着计算机的普及和应用水平的提高,经过考察比较,决定利用自己的Java知识开发小型的图书管理系统,方便图书的管理。 图书管理系统是典型的信息管理系统。...

    Java图书管理系统

    设计人:wangyunpeng_bio

    项目需求

    随着计算机的普及和应用水平的提高,经过考察比较,决定利用自己的Java知识开发小型的图书管理系统,方便图书的管理。
    图书管理系统是典型的信息管理系统。本次作业利用JAVA开发工具Eclipse和MySQL数据库来开发这个图书管理系统。该系统要解决的图书管理所要解决的问题,可以满足图书管理基本要求,包括添加、管理等功能。该系统能根据用户的需求,快捷方便的为读者提供借阅服务
    图书管理系统应有以下功能:

    1. 读者库管理
    2. 书库管理
    3. 借阅管理
    4. 读者信息查询

    图书管理系统主要针对书库的操作功能、所以系统应尽量满足需求、同时亦不可有多余或繁复的功能、令系统的操作和功能混乱。

    项目地址

    本项目地址:https://github.com/wangyunpengbio/Library/
    免费下载方法:点那个“Clone or download”,再点“Download ZIP”就行了,感兴趣的话,大家可以点个Star
    如果实在太初学者,不会下载的话,就在csdn上下载吧https://download.csdn.net/download/qq_29300341/9667678

    需求分析

    A.业务流程:

    No. 业务流程 需求
    1. 图书管理员登入系统 图书管理员需使用账号和密码登入。
    2. 新增读者资料 新增读者资料,如姓名、性别、职位等。
    3. 新增书籍资料 新增书籍资料,如书名、价格、种类等。
    4. 读者库管理 选中读者库里的读者信息,即可更新和删除。
    5. 书库管理 可以按“书编号查询”和“书名模糊查询”,继而选中书籍信息,即可更新和删除书籍分为在库和借出
    6 借阅管理 输入读者编号,即可检阅读者的数据和借阅的图书,检阅顾客的数据和购买纪录。
    7. 读者登入系统 读者需使用账号和密码登入。
    8 借书 按书名模糊搜索,选中即可借阅图书
    9 还书 检阅自己的读者信息以及已经借阅的图书,点击归还即可,不允许更改或删除读者数据,只允许查询,更改和删除功能由管理员负责。

    以下是使用 实体联系模型-Entity Relationship来分析。

    B.归纳实体和属性

    No. 业务流程 对应的实体 实体的属性值
    1. 图书管理员登入系统 Librarian nameUser password
    2. 新增读者资料 Reader idReader nameReader kind sex password
    3. 新增书籍资料 Book Author Publisher idBook,nameBook,price,kind,author,publisher Author.name, Author.workplace Publisher.name, Publisher.address
    4. 读者库管理 Reader idReader nameReader kind sex password
    5. 书库管理 Book idBook nameBook price kind autor publisher
    6. 借阅管理 Borrow idReader idBook lendDate dueDate overtime
    7. 读者登入系统 Reader idReader password
    8 借书 Borrow idReader idBook lendDate dueDate overtime
    9 还书 Borrow idReader idBook lendDate dueDate overtime

    C.实体的模型

    在这里插入图片描述

    D.ER-实体关系

    Author,Publisher To Book&Borrow&Reader To Librarian
    在这里插入图片描述

    设计

    项目文件夹中,(代码总计:4800+行)
    doc文件夹存放着生成的文档注释,可点击其中的index文件查看整个项目的注释

    Src包下面含有五个包

    • Database用于存储数据库连接操作
    • Frame用于存储各个窗体界面
    • Model用于存储各个实体(表)对应的数据模型
    • Out_of_date用于存储初始时候写的界面,后来舍弃,不再调用。
    • SqlTools用于存储操作数据库的增删改查方法

    image文件夹用于存放相关的界面图片,按钮图片
    备注:程序不同界面的入口已经全部注释掉了,MainFrame是程序的唯一入口

    程序细节设计:

    1. 登陆界面的密码回显,伴有跳转动画(此处利用了多线程,控制线程存活时间)
    2. 表格直接选中即可修改数据,更新数据时候默认有原始数据,可按不同方式搜索图书;
    3. 新增借阅信息时候,自动加入当前时间,并计算归还时间。(SQL函数NOW())
    4. 界面按钮,背景用Photoshop的重新设计,图形用户界面友好;
    5. 数据库设计达到第三范式,去除了所有非主属性对任何候选关键字的传递信依赖,冗余度低。
    6. 变量和方法命名符合规范,可读性强
    7. 不同的Model实体(表)对应不同的SqlTools操作,分开存放,程序复用性好,易扩展。
      使用
    8. 将SQL语句导入,字符集选utf8,不然有可能显示不了中文,数据库名称为library
      create database library;
    9. 推荐使用Mysql Front这个MySQL的前台,支持多句sql语句一起执行,百度第一个链接即可下载。
      http://dlsw.baidu.com/sw-search-sp/soft/6c/17997/MySQL-Front_V5.3.4.214_Setup.1435658094.exe
    10. Java环境中加入数据库的驱动,源程序里database包里DatabaseTools.java文件是有关数据库连接的操作源程序的用户名和密码皆为root,数据库名为:library不同电脑上运行需要稍微改一下这个代码。
    11. 登陆:
      图书管理员:用户名root密码 root或者wangyp密码123456
      **读者:用户名001密码 root **(注:数据库内读者的密码初始值皆为root)
    12. 在不同计算机上Eclipse使用,可能需要重新建立Java类库的路径
      本程序用1.8的jdk写的,所以最好用1.8的jre。
      代码放在1.8下面运行,连警告都不会出现,1.7和1.6显示效果不好。
      awt 和 swing 都依赖虚拟机的具体实现。所以不同平台表现不大一样。如果用javafx,界面才可以移植。
      而且编写用的笔记本电脑是高分屏,在本机上显示大小是正好的,到别的电脑上面有可能会出现界面过大的情况。
    13. 具体的文档注释已经生成,打开doc文件夹其中的index文件查看整个项目的注释
      在这里插入图片描述
    展开全文
  • 自己随便写的图书管理系统图书管理系统图书管理系统图书管理系统图书管理系统
  • Java图书管理系统

    万次阅读 多人点赞 2016-10-16 16:01:52
    项目参考自:http://www.java1234.com/a/yuanchuang/swing2/ 项目视频及代码下载地址:http://pan.baidu.com/s/1gdtVQtt 项目开发环境的搭建:...(2),图书类别管理 (3),图书管理 (4),退出二,工具(1)

    项目参考自:http://www.java1234.com/a/yuanchuang/swing2/
    项目视频及代码下载地址:链接:http://pan.baidu.com/s/1pLpQw2J 密码:cncv
    项目开发环境的搭建:http://pan.baidu.com/s/1ntzhAmH#list/path=%2F

    一,功能

    (1),用户登录
    (2),图书类别管理
    (3),图书管理
    (4),退出

    二,工具

    (1),JAVA编程:eclipes(1.8 soon版本)
    (2),SQL:mysql
    (3),Jdbc: jar(mysql-connector-java-5.1.40-bin.jar)

    三,效果展示

    (1),登录

    这里写图片描述

    (2),主界面

    这里写图片描述

    (3),图书类别添加

    这里写图片描述

    (4),图书类别管理

    这里写图片描述

    (5),图书添加

    这里写图片描述

    (6),图书管理

    这里写图片描述

    (7),关于作者

    这里写图片描述

    四,数据库设计

    这里写图片描述

    (1),t_user表

    这里写图片描述

    (2),t_bookType表

    这里写图片描述

    (3),t_book表

    这里写图片描述

    (四),Java层次分析:

    (1),逻辑图

    这里写图片描述

    (2),包结构

    这里写图片描述

    (五),数据库层级分析:

    1, ER分析

    这里写图片描述

    2, 数据

    用户: 用户编号,用户名,密码
    图书类别:图书类别编号,图书类别名称
    图书:图书编号,图书名称,图书作者,图书价格,图书描述,图书类别(外键)

    图书类别与图书之间根据图书类别相互关联

    3,数据库表的建立
    (1),t_use 用户信息表
    (2),t_bookType 图书类别管理表
    (3),t_book 图书信息管理表

    4,数据库表的关联(外键的关联)

    这里写图片描述

    (六),主要Java代码分析:

    (1),Dao 类(以BookDao为例)

    package com.java1234.dao;
    
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    import com.java1234.model.Book;
    import com.java1234.model.BookType;
    import com.java1234.util.StringUtil;
    import com.mysql.jdbc.Connection;
    import com.mysql.jdbc.PreparedStatement;
    
    /**
     * 图书Dao类
     * @author H_Pioneer
     *
     */
    public class BookDao {
    	
    	/**
    	 * 图书添加
    	 * @param con
    	 * @param book
    	 * @return
    	 * @throws Exception
    	 */
    	public int add(Connection con,Book book)throws Exception{
    		String sql="insert into t_book values(null,?,?,?,?,?,?)";
    		PreparedStatement pstmt=(PreparedStatement) con.prepareStatement(sql);
    		pstmt.setString(1, book.getBookName());
    		pstmt.setString(2, book.getAuthor());
    		pstmt.setString(3, book.getSex());
    		pstmt.setFloat(4, book.getPrice());
    		pstmt.setInt(5, book.getBookTypeId());
    		pstmt.setString(6, book.getBookDesc());
    		return pstmt.executeUpdate();
    	}
    	
    	/**
    	 * 图书信息查询
    	 * @param con
    	 * @param book
    	 * @return
    	 * @throws Exception
    	 */
    	public ResultSet list(Connection con,Book book)throws Exception{
    		StringBuffer sb=new StringBuffer("select * from t_book b,t_bookType bt where b.bookTypeId=bt.id");
    		if(StringUtil.isNotEmpty(book.getBookName())){
    			sb.append(" and b.bookName like '%"+book.getBookName()+"%'");
    		}
    		if(StringUtil.isNotEmpty(book.getAuthor())){
    			sb.append(" and b.author like '%"+book.getAuthor()+"%'");
    		}
    		if(book.getBookTypeId()!=null && book.getBookTypeId()!=-1){
    			sb.append(" and b.bookTypeId="+book.getBookTypeId());
    		}
    		PreparedStatement pstmt=(PreparedStatement) con.prepareStatement(sb.toString());
    		return pstmt.executeQuery();
    	}
    	
    	/**
    	 * 图书信息删除
    	 * @param con
    	 * @param id
    	 * @return
    	 * @throws SQLException
    	 */
    	public int delete(Connection con,String id)throws Exception{
    		String sql="delete from t_book where id=?";
    		PreparedStatement pstmt=(PreparedStatement) con.prepareStatement(sql);
    		pstmt.setString(1, id);
    		return pstmt.executeUpdate();
    	}
    	
    	/**
    	 * 图书信息修改
    	 * @param con
    	 * @param book
    	 * @return
    	 * @throws Exception
    	 */
    	public int update(Connection con,Book book)throws Exception{
    		String sql="update t_book set bookName=?,author=?,sex=?,price=?,bookDesc=?,bookTypeId=? where id=?";
    		PreparedStatement pstmt=(PreparedStatement) con.prepareStatement(sql);
    		
    		
    		pstmt.setString(1, book.getBookName());
    		pstmt.setString(2, book.getAuthor());
    		pstmt.setString(3, book.getSex());
    		pstmt.setFloat(4, book.getPrice());
    		pstmt.setString(5, book.getBookDesc());
    		pstmt.setInt(6, book.getBookTypeId());
    		pstmt.setInt(7, book.getId());
    		return pstmt.executeUpdate();
    	}
    	
    	/**
    	 * 
    	 * @param con
    	 * @param bookTypeId
    	 * @return
    	 * @throws Exception
    	 */
    	public boolean existBookByBookTypeId(Connection con,String bookTypeId)throws Exception{
    		String sql="select * from t_book where bookTypeId=?";
    		PreparedStatement pstmt=(PreparedStatement) con.prepareStatement(sql);
    		pstmt.setString(1, bookTypeId);
    		ResultSet rs = pstmt.executeQuery();
    		String string = new String();
    		return rs.next();
    	}
    }
    
    

    *重点内容::

    JDBC进行简单的数据库增删改查

    详细参考:http://www.cnblogs.com/wuyuegb2312/p/3872607.html

    (2),Model类(以BookModel为例)

    package com.java1234.model;
    
    
    /**
     * 图书实体类
     * @author H_Pioneer
     *
     */
    public class Book {
    
    	private int id; //编号
    	private String bookName;  //图书名称
    	private String author;  //作者
    	private String sex;  //性别
    	private float price;  //价格
    	private Integer bookTypeId;  //图书类别
    	private String bookTypeName;  //图书类别名称
    	private String bookDesc;  //备注
    	
    	
    	
    	public Book(int id2, String bookName, String author, String sex, float price, Integer bookTypeId, String bookDesc) {
    		super();
    		this.id = id2;
    		this.bookName = bookName;
    		this.author = author;
    		this.sex = sex;
    		this.price = price;
    		this.bookTypeId = bookTypeId;
    		this.bookDesc = bookDesc;
    	}
    
    	public Book(String bookName, String author, Integer bookTypeId) {
    		super();
    		this.bookName = bookName;
    		this.author = author;
    		this.bookTypeId = bookTypeId;
    	}
    
    	public Book(String bookName, String author, String sex, float price, Integer bookTypeId, String bookDesc) {
    		super();
    		this.bookName = bookName;
    		this.author = author;
    		this.sex = sex;
    		this.price = price;
    		this.bookTypeId = bookTypeId;
    		this.bookDesc = bookDesc;
    	}
    	
    	public Book() {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    	public String getBookName() {
    		return bookName;
    	}
    	public void setBookName(String bookName) {
    		this.bookName = bookName;
    	}
    	public String getAuthor() {
    		return author;
    	}
    	public void setAuthor(String author) {
    		this.author = author;
    	}
    	public String getSex() {
    		return sex;
    	}
    	public void setSex(String sex) {
    		this.sex = sex;
    	}
    	public float getPrice() {
    		return price;
    	}
    	public void setPrice(float price) {
    		this.price = price;
    	}
    	public Integer getBookTypeId() {
    		return bookTypeId;
    	}
    	public void setBookTypeId(Integer bookTypeId) {
    		this.bookTypeId = bookTypeId;
    	}
    	public String getBookTypeName() {
    		return bookTypeName;
    	}
    	public void setBookTypeName(String bookTypeName) {
    		this.bookTypeName = bookTypeName;
    	}
    	public String getBookDesc() {
    		return bookDesc;
    	}
    	public void setBookDesc(String bookDesc) {
    		this.bookDesc = bookDesc;
    	}
    	
    	
    }
    
    

    **重点内容::

    (1),接口类的构造方法

    (2),get,set方法

    快捷键:
    Shift+Alt+S --> Generate Getters and Setters -->选择你需要的get,set参数

    (3),构造函数的使用
    快捷键:
    (1),Shift+Alt+S -->generate constructor using fields–>使用字段生成
    (2),Shift+Alt+S -->generate constructors from…–>不使用字段从父类获取

    (三),Util类

    package com.java1234.util;
    
    import java.sql.DriverManager;
    
    import com.mysql.jdbc.Connection;
    
    /**
     * 数据库工具类
     * @author H_Pioneer
     *
     */
    
    public class DbUtil {
    	private String dbUrl = "jdbc:mysql://localhost:3306/db_book";
    	//也可以写成private String dbUrl = "jdbc:mysql:///db_book";
    	private String dbUserName = "root";
    	private String dbPassword = "123456";
    	private String jdbcName = "com.mysql.jdbc.Driver";
    	
    	/**
    	 * 获取数据库连接
    	 * @return
    	 * @throws Exception
    	 */
    	public Connection getCon()throws Exception{
    	    Class.forName(jdbcName);
    		Connection con = (Connection) DriverManager.getConnection(dbUrl,dbUserName,dbPassword);//链接数据库
    		return con;
    		
    	}
    	
    	/**
    	 * 关闭数据库连接
    	 * @param con
    	 * @throws Exception
    	 */
    	public void closeCon (java.sql.Connection con)throws Exception {
    		if(con!=null){
    			con.close();
    		}
    	}
    	
    	/**
    	 * 
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		DbUtil dbUtil = new DbUtil();
    		try {
    			dbUtil.getCon();
    			System.out.println("数据库连接成功");
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();    //在命令行打印异常信息在程序中出错的位置及原因。
    			System.out.println("数据库连接");
    		}
    				
    	}
    
    	
    }
    
    

    数据库工具类

    package com.java1234.util;
    
    import org.junit.Test;
    
    import com.mysql.jdbc.StringUtils;
    
    /**
     * 字符串工具类
     * @author H_Pioneer
     *
     */
    public class StringUtil {
    	/**
    	 * 判断是否为空
    	 * @param str
    	 * @return
    	 */
    	
    	public static boolean isEmpty(String str){
    		if(str==null||"".equals(str.trim())){
    			return true;
    	}else{
    		return false;
    	}
    	}
    	
    	/**
    	 * 判断不为空
    	 * @param str
    	 * @return
    	 */
    	public static boolean isNotEmpty(String str){
    		if(str!=null&&!"".equals(str.trim())){
    			return true;
    	    }else{
    		return false;
    	    }
    	}
    }
    

    **重点::
    工具类的使用
    (1)
    字符串工具类的总结:
    http://www.cnblogs.com/DreamDrive/p/5760588.html
    (2)
    数据库工具类的总结:
    http://kettas.iteye.com/blog/1222519

    (四),Frm类(以登录和图书类别添加为例)

    package com.java1234.view;
    
    import java.awt.EventQueue;
    import java.awt.Font;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.GroupLayout;
    import javax.swing.GroupLayout.Alignment;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JPasswordField;
    import javax.swing.JTextField;
    import javax.swing.LayoutStyle.ComponentPlacement;
    import javax.swing.border.EmptyBorder;
    
    import com.java1234.dao.UserDao;
    import com.java1234.model.User;
    import com.java1234.util.DbUtil;
    import com.java1234.util.StringUtil;
    import com.mysql.jdbc.Connection;
    
    
    public class LogOnFrm extends JFrame {
    
    	private JPanel contentPane;
    	private final JTextField textField = new JTextField();
    	private JPasswordField passwordTxt;
    	
    	private DbUtil dbUtil = new DbUtil();
    	private UserDao userDao = new UserDao();
    	private JTextField userNameTxt;
    	
    
    	/**
    	 * Launch the application.
    	 */
    	public static void main(String[] args) {
    		EventQueue.invokeLater(new Runnable() {
    			public void run() {
    				try {
    					LogOnFrm frame = new LogOnFrm();
    					frame.setVisible(true);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		});
    	}
    
    	/**
    	 * Create the frame.
    	 */
    	public LogOnFrm() {
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setAlwaysOnTop(true);
    		setTitle("管理员登录");
    		setBounds(100, 100, 450, 300);
    		contentPane = new JPanel();
    		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    		setContentPane(contentPane);
    		
    		JLabel label = new JLabel("图书管理系统");
    		label.setFont(new Font("黑体", Font.BOLD, 25));
    		label.setIcon(new ImageIcon(LogOnFrm.class.getResource("/images/logo.png")));
    		
    		JLabel lblNewLabel = new JLabel("用户名:");
    		lblNewLabel.setFont(new Font("宋体", Font.PLAIN, 13));
    		lblNewLabel.setIcon(new ImageIcon(LogOnFrm.class.getResource("/images/userName.png")));
    		
    		JLabel lblNewLabel_1 = new JLabel("密  码:");
    		lblNewLabel_1.setFont(new Font("宋体", Font.PLAIN, 13));
    		lblNewLabel_1.setIcon(new ImageIcon(LogOnFrm.class.getResource("/images/password.png")));
    		textField.setColumns(10);
    		
    		passwordTxt = new JPasswordField();
    		
    		JButton btnNewButton = new JButton("登录");
    		btnNewButton.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    			    loginActionPerformed(e);	
    			}
    		});
    		btnNewButton.setFont(new Font("宋体", Font.PLAIN, 13));
    		
    		btnNewButton.setIcon(new ImageIcon(LogOnFrm.class.getResource("/images/login.png")));
    		
    		JButton btnNewButton_1 = new JButton("重置");
    		btnNewButton_1.setFont(new Font("宋体", Font.PLAIN, 13));
    		btnNewButton_1.setIcon(new ImageIcon(LogOnFrm.class.getResource("/images/reset.png")));
    		btnNewButton_1.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				resetValueActionPerformed(e);
    			}
    		});
    		
    		userNameTxt = new JTextField();
    		userNameTxt.setColumns(10);
    		GroupLayout gl_contentPane = new GroupLayout(contentPane);
    		gl_contentPane.setHorizontalGroup(
    			gl_contentPane.createParallelGroup(Alignment.LEADING)
    				.addGroup(gl_contentPane.createSequentialGroup()
    					.addContainerGap()
    					.addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING)
    						.addGroup(gl_contentPane.createSequentialGroup()
    							.addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING)
    								.addGroup(gl_contentPane.createSequentialGroup()
    									.addComponent(textField, GroupLayout.PREFERRED_SIZE, 0, GroupLayout.PREFERRED_SIZE)
    									.addGap(223))
    								.addGroup(gl_contentPane.createSequentialGroup()
    									.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING, false)
    										.addComponent(lblNewLabel_1, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    										.addComponent(btnNewButton, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    									.addGap(50))
    								.addGroup(gl_contentPane.createSequentialGroup()
    									.addComponent(lblNewLabel, GroupLayout.PREFERRED_SIZE, 93, GroupLayout.PREFERRED_SIZE)
    									.addGap(36)))
    							.addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING)
    								.addComponent(btnNewButton_1)
    								.addGroup(Alignment.LEADING, gl_contentPane.createParallelGroup(Alignment.TRAILING, false)
    									.addComponent(passwordTxt, Alignment.LEADING)
    									.addComponent(userNameTxt, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 114, Short.MAX_VALUE)))
    							.addGap(63))
    						.addGroup(gl_contentPane.createSequentialGroup()
    							.addComponent(label, GroupLayout.PREFERRED_SIZE, 320, GroupLayout.PREFERRED_SIZE)
    							.addContainerGap())))
    		);
    		gl_contentPane.setVerticalGroup(
    			gl_contentPane.createParallelGroup(Alignment.LEADING)
    				.addGroup(gl_contentPane.createSequentialGroup()
    					.addGap(18)
    					.addComponent(label)
    					.addPreferredGap(ComponentPlacement.UNRELATED)
    					.addComponent(textField, GroupLayout.PREFERRED_SIZE, 0, GroupLayout.PREFERRED_SIZE)
    					.addGap(14)
    					.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
    						.addComponent(lblNewLabel, GroupLayout.PREFERRED_SIZE, 24, GroupLayout.PREFERRED_SIZE)
    						.addComponent(userNameTxt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
    					.addGap(45)
    					.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
    						.addComponent(passwordTxt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
    						.addComponent(lblNewLabel_1, GroupLayout.PREFERRED_SIZE, 21, GroupLayout.PREFERRED_SIZE))
    					.addGap(27)
    					.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
    						.addComponent(btnNewButton_1, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE)
    						.addComponent(btnNewButton))
    					.addContainerGap(13, Short.MAX_VALUE))
    		);
    		contentPane.setLayout(gl_contentPane);
    		
    		//设置居中显示
    		this.setLocationRelativeTo(null);
    	}
    	
        /**
         * 登录事件处理
         * @param e
         */
    	protected void loginActionPerformed(ActionEvent e) {
    		// TODO Auto-generated method stub
    		String userName = this.userNameTxt.getText();
    		String password = new String(this.passwordTxt.getPassword());
    		if(StringUtil.isEmpty(userName)){
    			JOptionPane.showMessageDialog(null,"用户名不能为空");
    			return;
    		}
    		if(StringUtil.isEmpty(password)){
    			JOptionPane.showMessageDialog(null,"密码不能为空");
    			return;
    		}
    		User user = new User(userName,password);
    		Connection con = null;
    		try{
    			con = dbUtil.getCon();
    			User currentUser=userDao.login(con, user);
    			if(currentUser!=null){
    				//JOptionPane.showMessageDialog(null,"登录成功");	
    			    dispose();
    			    new MainFrm().setVisible(true);
    			}else{
    				JOptionPane.showMessageDialog(null,"用户名密码错误");
    			}
    			
    		}catch(Exception e1){
    			e1.printStackTrace();
    			
    		}
    		
    	}
    
    	/**
         * 重置事件处理
         * @param evt
         */
        
    	private void resetValueActionPerformed(ActionEvent evt) {
    		// TODO Auto-generated method stub
    		this.userNameTxt.setText("");
    		this.passwordTxt.setText("");
    	}
    }
    
    

    **重点::

    (1),Java可视化编程

    1. windowbuilder插件的安装
    2. Window Builder→SWT Designer→SWT→Application Window→Next→窗口名→默认→Finish→s自动生成代码→Design

    这里写图片描述

    (2),对于按钮等添加事件如何与数据接口联系

    对于JFrame,JLable,JTable等,右击可以选择重命名或者添加事件即可返回代码之中,一般我们会把操作进行封装,对事件进行相应的处理

    (七),整个项目的分析与不足

    1.MVC3层架构有问题(这个只有dao层)

    正常的应该是dao层就接口不是实现类,现在的dao是正常的daoImpl,dao的实现类
    

    2.实体类(com.java1234.model包下的)可以是entity,domain

    应该尽量用entity或model,少用domain
    

    3 DbUtil和StringUtil的实现方法不好而且很多并没有实际用处

    展开全文
  • vb图书管理系统 图书管理系统 图书管理系统vb图书管理系统 图书管理系统 图书管理系统vb图书管理系统 图书管理系统 图书管理系统vb图书管理系统 图书管理系统 图书管理系统vb图书管理系统 图书管理系统 图书管理系统...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 32,619
精华内容 13,047
关键字:

图书管理系统