基于Java开发的图书管理系统

基于Jsp和MySQL实现的图书管理系统 1,项目简介 1,1 课设背景 该图书管理系统应用于中小学生的图书馆中,面向的客户主要是中小学生和教师

本文包含相关资料包-----> 点击直达获取<-------

基于Jsp和MySQL实现的图书管理系统

1.项目简介

1.1 课设背景

该图书管理系统应用于中小学生的图书馆中,面向的客户主要是中小学生和教师,在用户进行图书的相关业务时,该系统能够合理有效的去管理。

通过分析可以发现,在市面上的图书管理系统基本上可以分为两类:一类是由各大高校、研究院所和大型图书馆共同开发的大型图书管理系统。大型图书管理系统的优点是设计先进、功能强大,缺点是价格昂贵、维护困难、操作复杂。因此,这类系统只在大型图书馆中适用,而对于只有一两名管理员、而且管理员的计算机素质普遍不高的普通中小学来说,则不太适用。另一类则是小型软件。此类软件只具备图书管理的基本功能,其人机交互界面普遍较差,功能较弱,软件的使用效果不太理想。根据这种情况,我们设计开发了一套适用于普通中小学校图书馆的图书管理系统。

1.2系统架构选型

  • 方案一:B/S架构
  • 可以很方便的使用
  • 升级维护的成本小
  • 不依赖于固定的开发工具、操作系统等固话软件,兼容性更强

  • 方案二:C/S架构

  • 拥有高性能,响应速度更快
  • 面向相对固定的用户群,对信息安全的控制能力更强
  • 有较强的事务处理能力,能实现复杂的业务流程

通过以上两种架构的对比,并分析用户的需求,因为本图书管理系统需要进行实时交互、对反应速度要求较高,而且中小学中针对的人群比较固定,所以不需要建立在广域网上增加安全风险。综上所述,本系统最终选型C/S模式

1.3 功能分析

1.3.1 图书流通操作

根据图书的实际流向,分别进行图书借阅、图书归还、图书预约等操作,并形成相应的记录,包括读者编号、图书编号、借阅时间、应还时间、归还时间、预约时间等信息,借书还书与预约都要经过工作人员的审核,如果图书有损坏等问题可以记录违章记录,工作人员可以采购图书入库。

1.3.2 查询功能

工作人员与读者都可以对图书信息进行灵活的查询操作。

工作人员可以查询读者的相关信息,包括读者卡信息和读者的相关借还操作,除此之外,读者还可以查询自己的个人信息和相关借阅操作,包括当前借阅图书、借阅历史、归还图书、违章记录等信息。

1.3.3 设置功能

超级管理员、工作人员、读者都可以修改自己的密码,而超级管理员可以去修改工作人员和读者的密码。超级管理员可以添加工作人员与读者,还可以注销读者卡。

1.4 系统用例图

1.4.1 读者用例图

读者所包含的用例有:

  • 登录系统(Login) :可以通过登录系统进入读者系统的主界面

  • 借书(Borrow books) :进行借书的业务

  • 还书(Return books) :可以进行还书业务

  • 预约借书(Reserve books) :对别人已经借走的书籍可以进行预约借书

  • 查询图书 :可以查询所有的书籍,并且可以通过关键字信息对书籍进行查询

  • 查询个人信息 :可以查看读者自己的信息

  • 查询当前借阅 :可以查询该读者当前已借书籍

  • 查询历史借阅 :当借书并还书后,会生成历史借阅信息,读者可以查询历史借阅

  • 查询预约信息 :查询个人预约信息

  • 违规记录 :可以查询到个人是否有违规

  • 修改密码 :读者可以修改自己账号的密码

  • 热门推荐 :会根据借书的种类与数量进行推荐

1.4.2 工作人员用例图

工作人员所包含的用例有:

  • 登录系统(Login) :可以通过登录系统进入工作人员系统的主界面

  • 读者管理(Reader Management) :读者管理用例中包括了对读者卡信息的查询和对读者借阅、预约等操作的信息查询

  • 读者信息查询(Query Reader's Info) :可以查询读者卡的信息

  • 读者操作信息查询(Query Reader's Info) :可以查询读者借阅、历史借阅、违章记录等操作信息

  • 图书管理(Book Management) :图书管理用例中包含了查询图书、添加图书、修改图书用例

  • 查询图书(Query books) :可以查询所有的书籍,并且可以通过关键字信息对书籍进行查询,还可以进行删除

  • 添加图书(Add books) :输入图书信息将图书入库

  • 修改图书(Update books) :输入图书号查询然后可以对相关信息进行修改

  • 借阅管理(Borrow Management) :借阅管理用例包含了审核借阅、违章记录、审核预约

  • 审核借阅(Verify Borrow) :可以对读者借书申请进行审核

  • 审核预约(Verify Reserve) :可以对读者预约申请进行审核

  • 违规记录(Query Uncomply) :可以查询该读者的违章记录

1.4.3 超级管理员用例图

超级管理员所包含的用例有:

  • 登录系统(Login) :可以通过登录系统进入工作人员系统的主界面

  • 添加读者(Add Reader) :输入读者信息添加读者

  • 添加工作人员(Add Worker) :输入工作人员信息添加读者

  • 查询读者信息(Query Reader) :通过读者卡号查询读者信息

  • 查询工作人员信息(Query Reader) :通过工作人员卡号查询工作人员信息

  • 注销借阅证(Delete Reader) :通过读者卡号进行注销

  • 修改读者密码(Update RPwd) :可以修改读者的密码

  • 修改工作人员密码(Update WPwd) :可以修改工作人员的密码

  • 修改密码(UpdatePwd) :可以修改自己的密码

1.5 核心业务

1.5.1 借阅功能

读者可以在超级管理员处进行注册获得读者卡,读者卡有账号和密码信息:

  • 读者输入自己的读者卡账号密码,选择读者身份,正确后即可进入读者主界面

  • 读者可以在图书查询中查看所有的图书信息,也可以通过相关信息查询某一本书。选中图书进行借阅,如果图书状态为已借出则弹出错误提示,如果为可借状态则弹出借阅信息窗口

  • 在借阅信息窗口中输入还书时间,还书日期不得早于借书日期否则会报错。提交借阅信息后修改图书状态并等待工作人员的审核

  • 工作人员审核通过之后将该借阅信息放入该读者的当前借阅信息中,在还书子界面也可以看到当前借阅的书籍。工作人员也可以给该次借阅添加违规使用信息。

至此,完成一次借阅业务。

1.5.2 还书功能

  • 读者输入自己的读者卡账号密码,选择读者身份,正确后即可进入读者主界面

  • 读者可以在还书子界面中进行还书业务。还书子界面中可以看到自己当前正在借阅的书籍,选中书籍可以进行归还,接着弹出还书确认框,点击确认后会将还书信息传给工作人员,需要工作人员的审核

  • 待工作人员进行审核后,则将这次还书信息写入还书表中。工作人员还可以对这次还书业务添加违约信息

至此,完成一次还书业务。当完成还书后,读者还可以查看自己的借阅历史,即一次完整的借书还书业务信息。

1.5.3 预约功能

  • 读者输入自己的读者卡账号密码,选择读者身份,正确后即可进入读者主界面

  • 读者可以在图书查询中查看所有的图书信息,也可以通过相关信息查询某一本书。选中图书进行预约,如果该书状态为可借则弹出错误提示,如果状态为已借出则可以预约,弹出预约信息窗口

  • 在预约信息窗口中输入预约到书时间(预约到书时间即是期望预约领书的最晚日期),预约到书日期不得早于预约开始日期否则会报错。提交预约信息后等待工作人员的审核。此时读者可以查看自己的预约信息,可以看到预约状态为等待处理

  • 工作人员可以对这次预约信息进行查询确认是否可借,如图书馆无该书则不可借,如果有书则可以推送通知。推送通知后,更新预约状态为可以借阅,读者可以查看自己的预约状态,进行图书借阅,输入相关信息完成预约借阅

至此,完成一次预约业务。

2.数据结构设计

2.1 E-R图

图书与图书种类实体

读者实体

工作人员实体

超级管理员实体

图书流通的实体联系图

2.2 数据库关系模式设计

根据前面所作出的图书管理系统需求,分析出系统开发时所需的表及其字段。系统主要的表有九张:读者卡表(Reader)、超级管理员表(SuperManager)、工作人员表(Worker)、图书表(Book)、图书分类表(Tkind)、借阅表(Nborrowing)、预约表(Qreserve)、归还表(Hreturn)、违规表(Uncomply)分别对应着实体图与图书流通联系图,关系模式如下:

  • 读者卡 (读者卡号,读者卡密码,读者姓名,读者性别,读者单位,注册日期,在借数量,最多再借数量,读者卡状态)

  • 工作人员 (工作证号,工作人员密码,工作人员姓名,工作人员性别,职务,入职日期)

  • 超级管理员 (超级管理员账号,超级管理员密码)

  • 图书 (书号,书名,作者,图书类型号,价格,入库时间,出版社,摘要,被借次数,图书状态)

  • 图书种类 (图书类型号,图书类型名)

  • 借阅 (书号,读者卡号,借书时间,应还时间,借书状态)

  • 归还 (书号,读者卡号,借书时间,归还时间)

  • 预约 (书号,读者卡号,预约开始时间,预约到书时间,预约状态)

  • 违规 (违规记录号,违规理由,书号,读者卡号,借书时间,归还时间)

2.3 数据库详细设计说明

为了更好的实施数据库,给出每个关系的详细说明:

表名 内容
BOOK 图书
TKIND 图书种类
READER 读者卡
WORKER 工作人员
SUPERMANAGER 超级管理员
NBORROWING 借阅
HRETURN 归还
QRESERVE 预约
UNCOMPLY 违规

BOOK图书表

字段名 数据类型及长度 大小 字段中文名 约束
BID VARCHAR2 15 书号 Primary Key
BNAME VARCHAR2 75 书名 Not Null
BAUTHOR VARCHAR2 100 作者 Not Null
BKIND VARCHAR2 15 图书类型号
BPRICE NUMBER 10 价格 Not Null
BDATE DATE 7 入库日期 Not Null
BPRESS VARCHAR2 50 出版社 Not Null
BSUMMARY VARCHAR2 2000 摘要 Not Null
BCNT NUMBER 11 被借次数
BSTATUS NUMBER 4 图书状态

READERS读者表

字段名 数据类型及长度 大小 字段中文名 约束
RID VARCHAR2 11 读者卡号 Primary Key
RPASSWD VARCHAR2 100 读者卡密码 Not Null
RNAME VARCHAR2 100 读者姓名 Not Null
RSEX VARCHAR2 10 读者性别
RUNIT VARCHAR2 100 读者单位 Not Null
RDATE DATE 7 注册日期 Not Null
RNUM NUMBER 10 在借数量
RTOTAL NUMBER 6 最多再借
RSTATE NUMBER 4 读者卡状态

WORKERS工作人员表

字段名 数据类型及长度 大小 字段中文名 约束
WID VARCHAR2 100 工作证号 Primary Key
WPASSWD VARCHAR2 100 工作人员密码 Not Null
WNAME VARCHAR2 200 工作人员姓名 Not Null
WSEX VARCHAR2 10 工作人员性别
WDATE DATE 7 入职日期 Not Null
WUNIT VARCHAR2 100 职务 Not Null

SUPERMANAGER超级管理员表

字段名 数据类型及长度 大小 字段中文名 约束
SID VARCHAR2 50 超级管理员账号 Primary Key
SPASSWD VARCHAR2 05 超级管理员密码 Not Null

TKIND图书分类表

字段名 数据类型及长度 大小 字段中文名 约束
TID VARCHAR2 15 图书类型号 Primary Key
TNAME VARCHAR2 100 图书类型名 Not Null

NBORROWING借阅表

字段名 数据类型及长度 大小 字段中文名 约束
NBID VARCHAR2 15 书号 Primary Key
NRID VARCHAR2 11 读者卡号
NBTIME DATE 7 借书时间
NBRTIME DATE 7 应还时间
NSTATE NUMBER 4 借书状态

HRETURN归还表

字段名 数据类型及长度 大小 字段中文名 约束
HBID VARCHAR2 15 书号 Primary Key
HRID VARCHAR2 11 读者卡号
HBTIME DATE 7 借书时间
HBRTIME DATE 7 归还时间

QRESERVE违约表

字段名 数据类型及长度 大小 字段中文名 约束
QBID VARCHAR2 15 书号 Primary Key
QRID VARCHAR2 11 读者卡号
QSDATE DATE 7 预约开始时间
QEDATE DATE 7 预约到书时间
QSTATE NUMBER 4 预约状态

UNCOMPLY预约表

字段名 数据类型及长度 大小 字段中文名 约束
UUID NUMBER 11 违规记录号 Primary Key
UREASON VARCHAR2 200 违规原因 Not Null
UBID VARCHAR2 15 书号 Not Null
URID VARCHAR2 11 读者卡号 Not Null
USDATE DATE 7 借书时间 Not Null
UEDATE DATE 7 归还时间 Not Null

3.项目实现

3.1 连接数据库

```java /* * Druid 连接池的工具类 / public class JDBCUtils { //1、定义一个成员变量 DataSource private static DataSource ds;

static {
    try {
        //2、加载配置文件
        Properties pro = new Properties();
        pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("config/druid.properties"));
        //3、获取DataSource
        ds = DruidDataSourceFactory.createDataSource(pro);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

/**
 * 从连接池中获取连接对象
 *
 * @return
 * @throws SQLException
 */
public static Connection getConnection() throws SQLException {
    return ds.getConnection();
}

/**
 * 获取连接池对象
 *
 * @return
 */
public static DataSource getDataSource() {
    return ds;
}

```

3.2 登陆实现

```java /* * 清空登录界面中表单的内容 / public void clearContent() { //清空一些登录消息 loginMsg.setText("登录信息失效,请重新登录!"); //同时清空用户的密码 userPwd.setText(""); //idGroup.selectToggle(superAdmin); }

@FXML
public void exitBtnClick() {
    System.exit(0);
}

/**
 * 登录按钮
 * @throws SQLException 
 */
@FXML
public void loginBtnClick() throws SQLException {
    //去除首尾空字符
    String Id = userID.getText().trim(), pwd = userPwd.getText();
    if(Id.isEmpty()) {
        loginMsg.setText("用户名不能为空!");
        System.out.println("用户名不能为空!");
        return;
    }
    if(pwd.isEmpty()) {
        loginMsg.setText("密码不能为空!");
        System.out.println("密码不能为空!");
        return;
    }
    //单独判断读者
    if(reader.isSelected()) {
        String strRegex = "^[\\d]{11}$"; // 11位纯数字
        boolean isNumId = Id.matches(strRegex);
        if (!isNumId) {
            loginMsg.setText("用户名格式有误,请重新输入11位有效数字!");
            return;
        }
    }

    //单选按钮的判断
    int flag = 0;
    String PwdName = null;
    String sql = null;
    if(idGroup.getSelectedToggle() == superAdmin) {
        flag = 1;
        PwdName = "SPasswd";
        //sql = "SELECT * FROM supermanager WHERE Sid = ?";
    }
    else if(idGroup.getSelectedToggle() == reader) {
        flag = 2;
        PwdName = "RPasswd";
        //sql = "SELECT * FROM readers WHERE RId = ?";
    }else {
        flag = 3;
        PwdName = "WPasswd";
        //sql = "SELECT * FROM workers WHERE WId = ?";
    }
    String[] str = ProcUtils.queryById_proc(flag,Id);

    if(str.length == 0) {
        loginMsg.setText("用户名不存在!");
        System.out.println("查询不到数据!");
    } else {

        String NowPasswd = str[1];
        System.out.println("密码:" + NowPasswd);
        if(!NowPasswd.equals(pwd)) {
            loginMsg.setText("密码错误!");
            System.out.println("密码错误!");
        } else {
            Stage stage = (Stage) anChorPane.getScene().getWindow();
            if(flag == 1) {
                //超管
                stage.setTitle("超管页面");
                stage.setScene(Main.saScene);
                Main.sac.initData();

            } else if(flag == 2) {
                //读者
                int rStatus = Integer.valueOf(str[2]);
                if(rStatus == 2) {
                    loginMsg.setText("当前账号已被注销,请联系超管~");
                    return;
                }
                System.out.println("准备进入读者界面!");
                stage.setTitle("读者页面");
                stage.setScene(Main.rcScene);
                //设置隐藏属性的值
                Main.rc.InitData(Id, str[3], rStatus == 1 ? "挂失" : "正常");
                loginMsg.setText("登录成功~");
            } else {
                //工作人员
                stage.setTitle("工作人员页面");
                stage.setScene(Main.wcScene);
                Main.wc.initData(Id, str[3]);
            }
        }
    }
    //JDBCUtils.close(rs, null, null);
}

```

3.3 业务代码

```java //填充表单数据 private void setData(List bookList) { data.clear(); for (int i = 0; i < bookList.size(); ++i) { data.add(new EmpBookLook(bookList.get(i))); System.out.println(bookList.get(i)); } bookLook.setItems(data); bookIdLook.setCellValueFactory(new PropertyValueFactory<>("BId")); bookNameLook.setCellValueFactory(new PropertyValueFactory<>("BName")); bookAuthorLook.setCellValueFactory(new PropertyValueFactory<>("BAuthor")); bookPressLook.setCellValueFactory(new PropertyValueFactory<>("BPress")); bookPriceLook.setCellValueFactory(new PropertyValueFactory<>("BPrice")); bookSummaryLook.setCellValueFactory(new PropertyValueFactory<>("BSummary")); bookStatusLook.setCellValueFactory(new PropertyValueFactory<>("BStatus")); }

//通过sql填充表单数据
private void setData(String sql, List<Object> code) {
    List<Book> bookList = template.query(sql, new BeanPropertyRowMapper<Book>(Book.class), code.toArray());
    data.clear();
    for(int i = 0; i < bookList.size(); ++i) {
        data.add(new EmpBookLook(bookList.get(i)));
    }
    bookLook.setItems(data);
    bookIdLook.setCellValueFactory(new PropertyValueFactory<EmpBookLook, String>("BId"));
    bookNameLook.setCellValueFactory(new PropertyValueFactory<EmpBookLook, String>("BName"));
    bookAuthorLook.setCellValueFactory(new PropertyValueFactory<EmpBookLook, String>("BAuthor"));
    bookPressLook.setCellValueFactory(new PropertyValueFactory<EmpBookLook, String>("BPress"));
    bookPriceLook.setCellValueFactory(new PropertyValueFactory<EmpBookLook, Double>("BPrice"));
    bookSummaryLook.setCellValueFactory(new PropertyValueFactory<EmpBookLook, String>("BSummary"));
    bookStatusLook.setCellValueFactory(new PropertyValueFactory<EmpBookLook, String>("BStatus"));
}
//选择查询条件
@FXML
public void M11Click() {
    MBbtn.setText("任意词");
}

@FXML
public void M1Click() {
    MBbtn.setText("书号");
}

@FXML
public void M2Click() {
    MBbtn.setText("书名");
}

@FXML
public void M3Click() {
    MBbtn.setText("出版社");
}

@FXML
public void M4Click() {
    MBbtn.setText("作者");
}

@FXML
public void M44Click() {
    MBbtn.setText("分类名");
    System.out.println("选择分类名作为查询条件!");
}

//详细界面
@FXML
public void bookDetailClick() {
    EmpBookLook bookDetail = bookLook.getSelectionModel().getSelectedItem();
    System.out.println(bookDetail);
    try {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/common/bookDetail.fxml"));
        Parent parent = loader.load();
        BookDetailController bc = loader.getController();
        //填充数据 一个有纯白背景和平台装饰的舞台
        Stage stage = new Stage(StageStyle.DECORATED);
        Stage faStage = (Stage) stackPane.getScene().getWindow();

        stage.setTitle("图书详情");
        stage.setScene(new Scene(parent, Main.sonWidth, Main.sonHeight));
        stage.setResizable(false);
        //注意要设置模态窗口
        stage.initModality(Modality.APPLICATION_MODAL);
        bc.initDetail(bookDetail);
        stage.initOwner(faStage);
        stage.show();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

//点击借阅按钮,响应借阅事件
@FXML
public void toBorrowClick() {
    if (Main.rc.rStatus.getText().equals("挂失")) {
        alert.setHeaderText("ERROR");
        alert.setAlertType(Alert.AlertType.ERROR);
        alert.setContentText("当前借阅证为挂失状态,请联系工作人员重新办理借阅证~");
        alert.show();
        return;
    }
    //先去查询是否还能借出,最多200本

    int rTotal = ProcUtils.queryIsBorrowByRId(accountId.getText());
    //注意大浮点数要转化为整形

    //不能再书籍了
    if (rTotal == 0) {
        alert.setAlertType(Alert.AlertType.ERROR);
        alert.setHeaderText("ERROR");
        alert.setContentText("当前借阅已达到最大可借数量:200本,不能再借阅~");
        alert.show();
        return;
    }
    EmpBookLook bookItem = bookLook.getSelectionModel().getSelectedItem();
    alert.setAlertType(Alert.AlertType.ERROR);
    alert.setHeaderText("ERROR");
    alert.setContentText("《" + bookItem.getBName() + "》已被借出,不能借阅~");
    if (bookItem.getBStatus().equals("已借出")) {
        alert.show();
        return;
    }
    try {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/reader/checkout.fxml"));
        Parent parent = loader.load();
        CheckOutController coc = loader.getController();
        Stage stage = new Stage(StageStyle.DECORATED);
        stage.setTitle("借阅信息");
        stage.setScene(new Scene(parent, Main.sonWidth, Main.sonHeight));
        stage.setResizable(false);
        Stage stageF = (Stage) librarySearchPane.getScene().getWindow();
        //通过数据库查询来设置借阅和归还信息,设置模态
        stage.initOwner(stageF);
        stage.initModality(Modality.APPLICATION_MODAL);
        stage.show();

        // 填充数据,查询数据库
        String rId = Main.rc.getReaderId();
        System.out.println(rId);
        //初始化数据
        coc.initData(accountId.getText(), bookItem.getBId(), LocalDate.now().toString(), 1);

    } catch (IOException e) {
        e.printStackTrace();
    }
}
public void initChartData() {
    //初始化图表
    bookPopularChart = new PieChart(getPopularBookGraphStatistics());
    bookPopularChart.setTitle("前20本书籍热门借阅排行榜");
    returnStackPane.getChildren().clear();
    returnStackPane.getChildren().add(bookPopularChart);
}

public ObservableList<PieChart.Data> getPopularBookGraphStatistics() {
    ObservableList<PieChart.Data> dataChart = FXCollections.observableArrayList();
    String que = "SELECT * FROM book WHERE BCnt > 0 ORDER BY BCnt DESC";
    List<Map<String, Object>> popularBooks = template.queryForList(que);
    int totBorrowCnt = 0;
    for (int i = 0, len = popularBooks.size(); i < len; ++i) {
        totBorrowCnt += Integer.parseInt(popularBooks.get(i).get("BCnt").toString());
    }
    for (int i = 0, len = popularBooks.size(); i < len; ++i) {
        //最多显示20本热门书籍
        if (i >= 20) break;
        String bpName = (String) popularBooks.get(i).get("BName");
        int bpCnt = Integer.parseInt(popularBooks.get(i).get("BCnt").toString());
        dataChart.add(new PieChart.Data(bpName + "(" + Math.round(1.0 * bpCnt / totBorrowCnt * 100) + "%)", bpCnt));
    }
    return dataChart;
}

//初始化归还书籍的表格数据
public void initReturnData(String readerId) {
    List<Book> bookBorrowList = ProcUtils.initData(readerId);
    data.clear();
    for (int i = 0; i < bookBorrowList.size(); ++i) {
        data.add(new EmpBookLook(bookBorrowList.get(i)));
    }
    needToReturn.setItems(data);
    retBookId.setCellValueFactory(new PropertyValueFactory<EmpBookLook, String>("BId"));
    retBookName.setCellValueFactory(new PropertyValueFactory<EmpBookLook, String>("BName"));
    retBookAuthor.setCellValueFactory(new PropertyValueFactory<EmpBookLook, String>("BAuthor"));
    retBookStart.setCellValueFactory(new PropertyValueFactory<EmpBookLook, String>("NBTime"));
    retBookEnd.setCellValueFactory(new PropertyValueFactory<EmpBookLook, String>("NBRTime"));
}

@FXML
public void returnBookClick() {
    System.out.println("点击归还书籍");
    if (Main.rc.rStatus.getText().equals("挂失")) {
        alert.setHeaderText("ERROR");
        alert.setAlertType(Alert.AlertType.ERROR);
        alert.setContentText("当前借阅证为挂失状态,请联系工作人员重新办理借阅证~");
        alert.show();
        return;
    }

    EmpBookLook bookLook1 = needToReturn.getSelectionModel().getSelectedItem();
    alert.setAlertType(Alert.AlertType.INFORMATION);
    alert.setHeaderText("INFORMATION");
    alert.setContentText("您确定归还《" + bookLook1.getBName() + "》这本书吗?");
    Optional<ButtonType> buttonType = alert.showAndWait();
    //String sql = "UPDATE nborrowing SET NState = 2 WHERE NState = 1 AND NBId = ? AND NRId = ?";
    if (buttonType.isPresent() && buttonType.get() == ButtonType.OK) {
        System.out.println("点击确定");
        // 需要更新正在借阅表,等待工作人员的审核, 条件是书号+读者,1表示正在借阅
        int update = ProcUtils.updateBorrowByBRId(bookLook1.getBId(), accountId.getText());
        //int update = template.update(sql, bookLook1.getBId(), accountId.getText());
        if (update > 0) {
            System.out.println("更新成功!");
            //弹窗显示等待管理员处理
            alert.setContentText("请等待图书馆工作人员的审核!");
            alert.show();
            data.remove(bookLook1);
        } else {
            System.out.println("更新失败!");
        }
    } else {
        //不做任何处理
        System.out.println("点击×");
    }
}

@FXML
public void reserveClick() {
    System.out.println("点击预约功能");
    //弹出一个界面显示
    String sql = "";
    if (Main.rc.rStatus.getText().equals("挂失")) {
        alert.setHeaderText("ERROR");
        alert.setAlertType(Alert.AlertType.ERROR);
        alert.setContentText("当前借阅证为挂失状态,请联系工作人员重新办理借阅证~");
        alert.show();
        return;
    }
    EmpBookLook bookItem = bookLook.getSelectionModel().getSelectedItem();
    if (bookItem.getBStatus().equals("可借")) {
        alert.setAlertType(Alert.AlertType.ERROR);
        alert.setHeaderText("ERROR");
        alert.setContentText("《" + bookItem.getBName() + "》可以直接借阅,请右键点击借阅该书籍~");
        alert.show();
        return;
    }
    //唯一标识:读者id+书籍id
    int aLong1 = queryForQreserveRepeat(bookItem.getBId(), accountId.getText());
    if (aLong1 > 0) {
        System.out.println("重复预约《" + bookItem.getBName() + "》");
        alert.setAlertType(Alert.AlertType.ERROR);
        alert.setHeaderText("ERROR");
        alert.setContentText("重复预约《" + bookItem.getBName() + "》");
        alert.show();
        return;
    } else {
        System.out.println("可以预约");
    }
    //有借阅也不能预约
    int aLong2 = ProcUtils.queryISReservation(bookItem.getBId(), accountId.getText());
    if (aLong2 > 0) {
        System.out.println("预约失败,《" + bookItem.getBName() + "》正在被您借阅中");
        alert.setAlertType(Alert.AlertType.ERROR);
        alert.setHeaderText("ERROR");
        alert.setContentText("预约失败,《" + bookItem.getBName() + "》正在被您借阅中");
        alert.show();
        return;
    } else {
        System.out.println("可以预约");
    }
    try {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/reader/reserveCheck.fxml"));
        Parent parent = loader.load();
        ReserveCheckController rcc = loader.getController();
        Stage stage = new Stage(StageStyle.DECORATED);
        stage.setTitle("预约信息");
        stage.setScene(new Scene(parent, Main.sonWidth, Main.sonHeight));
        stage.setResizable(false);
        Stage stageF = (Stage) librarySearchPane.getScene().getWindow();
        //通过数据库查询来设置借阅和归还信息,设置模态
        stage.initOwner(stageF);
        stage.initModality(Modality.APPLICATION_MODAL);
        stage.show();

        // 填充数据,查询数据库
        String rId = Main.rc.getReaderId();
        System.out.println(rId);
        //初始化数据
        rcc.initData(accountId.getText(), bookItem.getBId(), LocalDate.now().toString());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// 先去查询一下是否有预约该书籍,有预约则不能重复预约
public Integer queryForQreserveRepeat(String qbid, String qrid) {
    Connection conn = null;
    CallableStatement call = null;
    int res = 0;
    try {
        //1、获取数据库连接
        conn = JDBCUtils.getConnection();
        //2、定义调用存储函数的sql语句: {?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
        String sql = "{?=call PACK_BOOKMS.queryForQervRepeat_func(?,?)}";
        //3、获取执行sql对象
        call = conn.prepareCall(sql);
        //4、对于OUT参数(返回值),需要申明为输出参数类型
        call.registerOutParameter(1, OracleTypes.NUMBER);
        //5、对于IN参数,需要赋值
        call.setString(2, qbid);
        call.setString(3, qrid);
        //6、执行调用
        call.execute();
        //7、取出影响的数量
        res = call.getInt(1);
        System.out.println("是否重复预约:" + res);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        JDBCUtils.close(null, call, conn);
    }
    return res;
}

```

4.项目展示

登录功能

有三种角色:超级管理员、工作人员、读者分别可以进行登录,还可以退出界面,三种角色分别对应着三张表

超级管理员功能:

  • 添加读者

  • 添加工作人员

  • 查询读者信息

  • 查询工作人员信息

  • 注销借阅证

  • 修改读者密码

  • 修改工作人员密码

  • 修改密码

工作人员功能

  • 查询读者信息

  • 管理借阅证

  • 查询书籍信息

  • 书籍入库

  • 修改书籍信息

  • 审核借阅

  • 记录违章信息

  • 审核违约

  • 查看个人信息

  • 修改密码

读者功能

  • 热门推荐

  • 图书查询

  • 图书借阅

  • 图书预约

  • 图书归还

  • 查看个人信息

  • 查看当前借阅

  • 查看借阅历史

  • 查看预约信息

  • 查看违约记录

  • 修改密码

参考文献

  • 高校图书管理系统的设计与实现(东北大学·黄鑫)
  • 云因信息图书发行管理系统设计与实现(大连理工大学·王永辉)
  • 基于J2EE架构的某学院图书管理信息系统设计与开发(电子科技大学·戴杰)
  • 基于J2EE与UML的管理信息系统研究与应用(西南交通大学·文志刚)
  • 基于B/S架构的图书管理系统的设计与实现(电子科技大学·郭汝奇)
  • 基于SSH框架的图书馆管理系统的设计与实现(山东大学·檀雪姣)
  • 大同实验小学图书馆借还系统的设计与实现(电子科技大学·王洪宇)
  • 高校图书管理系统的设计与实现(东北大学·黄鑫)
  • 图书管理系统的设计与实现(西南交通大学·张晶)
  • 基于B/S结构的电子商务的研究与应用(哈尔滨工程大学·车彦朋)
  • 基于JSP的高校图书管理系统开发和实现(电子科技大学·朱丽萍)
  • 基于SSH框架的图书馆管理系统分析与设计(云南大学·郑晨)
  • 基于Android平台的图书管理系统手机客户端开发(电子科技大学·赵鲲)
  • 基于Web的图书管理系统的设计与实现(西安电子科技大学·丁侃)
  • 基于Android平台的图书管理系统手机客户端开发(电子科技大学·赵鲲)

本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:代码工坊 ,原文地址:https://bishedaima.com/yuanma/35309.html

相关推荐

发表回复

登录后才能评论