前言
在我们学了那么多的关于Java基础的东西,又学了数据库,三层架构,设计模式和Git工具类,一转眼间又学了那么多的内容,但是我们不能光学习不进行实践,所以我们需要来做一个两个人合作的小项目来将我们学的知识进行一个融会贯通。
一、项目前提
首先在我们做这个项目之前我们应该去好好思考思考我们能不能去做这个项目了,做这个项目需要些什么,以下就是我总结的一些需要的前提。
- 掌握java基本语法
- 熟悉使用流程控制
- 理解面向对象思想
- 熟练封装,继承,多态
- 熟悉使用接口,异常
- 熟悉使用集合
- 熟悉掌握I/o流相关操作
- 熟悉数据库操作
- 了解三层架构和常用设计模式
- 熟悉使用Git工具
二、项目要求
一、背景
- 长期以来,人们使用传统的人工方式管理图书馆的日常业务,其操作流程比较烦琐。在借书时,读者首先将要借的书和借阅证交给工作人员,然后工作人员将每本书的信息卡片和读者的借阅证放在一个小格栏里,最后在借阅证和每本书贴的借阅条上填写借阅信息。在还书时,读者首先将要还的书交给工作人员,工作人员根据图书信息找到相应的书卡和借阅证,并填好相应的还书信息。太过于繁琐了!所以,我们需求设计一个图书管理系统来方便学生的借书和图书馆管理书籍。
- 本系统功能分为读者信息管理模块、图书信息管理模块、图书借阅管理模块、基础信息维护模块和用户管理模块。
- 读者信息管理:能够对读者的基本信息进行管理,包括新增读者,如学校新来一名教师,想要借书,就必须先添加读者信息;读者信息的修改,如学生转到别的专业,此时要修改学生的基本信息;删除读者的信息,比如某个学生中途退学了,可以将其信息删除。查询读者的信息,比如有同学拾到了一张借阅卡,卡上有学生的编号,通过此号来查询学生的联系电话,从而可以找到学生。
- 图书信息管理:能够对图书的基本信息进行管理,包括新增图书,学校每年会购进新书,此时需要将新书的信息录入系统中;图书信息的修改,如学生借书后将图书丢失,此时需要修改图书的总数量,使总数减1;删除图书,学校在购进新书的同时,每年会对过期的图书进行清理,不再提供借阅,此时就需要将这些图书的信息从系统中删除。查询图书的信息,比如要查看有哪些是Java相关的书籍或者指定ISBN号的图书等。
- 图书借阅信息管理:能够对图书的借阅信息进行记录,包括读者信息、图书信息、借阅时间等信息。
- 图书归还信息管理:能够对图书的借阅信息进行记录,包括读者信息、图书信息、归还时间、是否超期、罚金等信息。
系统用户信息管理:能够对系统用户的信息进行管理,包括增加新的系统操作用户,对当前系统用户的密码进行修改,以及删除某一用户。
二、系统功能结构
三、准备工作
在我们写这个项目之前我们什么都没有,只有一个需求图书管理系统,所以我们需要先写几个需求文档出来,把一个空洞的需求转化为我们需要的实打实的几个文档和上图一样的功能具体化,才能更好的写出来一个好的程序。正所谓磨刀不误砍柴工。写需求文档就相当于磨刀了,只有写清楚了没一个需求我们写代码的时候才没有那么多的修修改改,确定好了之后直接实现那个功能就好了。我们做这个项目的时候写了四个文档,接口文档,需求文档,数据库文档,和需求说明书。
二、项目讲解
一、系统用例图
我们把这个图书管理系统写成了两个主要的操作人员,一个是管理人员和借书还书的操作员。
每个人员的具体权限如下图所示:
使用该系统有两个角色用户,分别为操作员和管理员。
操作员:负责图书的增删查改,读者信息的增删查改,图书的借阅,基本信息的维护。
管理员:负责管理操作人员,可以注册账号,管理罚金,查询操作人员信息,查询罚金信息,查询员工工作日志。
二、部分代码展示
整个项目的构建图:
数据库所建表:
管理员类代码:
package IDAL;
import Entity.Admin;
import java.util.List;
/**
* @author 不想掉头发$
* @version 1.0
* @date 2021年12月15日
*/
public interface AdminPort {
/**
* 增:注册管理员
* @param args sql语句填充列表
* @return 0,1
*/
public int registerAdmin(Object...args);
/**
* 删:删除管理员
* @param args sql语句填充列表
* @return 0,1
*/
public int deleteAdmin(Object...args);
/**
* 改:管理员密码
* @param args sql语句填充列表
* @return 0,1
*/
public int updatePassWord(Object...args);
/**
* 查:查询管理员是否存在(通过管理员名)
* @param args sql语句填充列表
* @retrun boolean true/false
*/
public Admin selectAdminByName(Object...args);
public List<Admin> selectAllAdmin();
}
package Entity;
/**
* @author 不想掉头发$
* @version 1.0
* @date 2021年12月15日
*/
public class Admin {
private int adminId;
private String adminName;
private String adminPassWord;
private String phone;
public Admin() {
}
public int getAdminId() {
return adminId;
}
public void setAdminId(int adminId) {
this.adminId = adminId;
}
public String getAdminName() {
return adminName;
}
public void setAdminName(String adminName) {
this.adminName = adminName;
}
public String getAdminPassWord() {
return adminPassWord;
}
public void setAdminPassWord(String adminPassWord) {
this.adminPassWord = adminPassWord;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
package DAL;
import Entity.Admin;
import IDAL.AdminPort;
import Utils.JDBCUtils;
import java.sql.Connection;
import java.util.List;
/**
* @author 不想掉头发$
* @version 1.0
* @date 2021年12月17日
*/
public class AdminDao extends BaseDao<Admin> implements AdminPort {
@Override
public int registerAdmin(Object...args) {
int result = 0;
Connection conn =null;
try {
conn = DruidConnectionPool.getConnection();
String sql = "insert into admin (adminName,adminPassword,phone) values(?,?,?)";
result=update(conn,sql,args);
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,null);
}
return result;
}
@Override
public int deleteAdmin(Object... args) {
int result = 0;
Connection conn =null;
try {
conn = DruidConnectionPool.getConnection();
String sql = "delete from admin where adminId = ?";
result=update(conn,sql,args);
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,null);
}
return result;
}
@Override
public int updatePassWord(Object...args) {
int result = 0;
Connection conn =null;
try {
conn = DruidConnectionPool.getConnection();
String sql = "update admin set adminPassWord = ? where adminId = ?";
result=update(conn,sql,args);
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,null);
}
return result;
}
@Override
public Admin selectAdminByName(Object...args) {
Admin result = null;
Connection conn =null;
try {
conn = DruidConnectionPool.getConnection();
String sql = "select * from admin where adminName = ?";
return getBean(conn, sql, args);
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,null);
}
return null;
}
@Override
public List<Admin> selectAllAdmin() {
List<Admin> result = null;
Connection conn =null;
try {
conn = DruidConnectionPool.getConnection();
String sql = "select * from admin ";
return getBeanList(conn, sql);
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,null);
}
return null;
}
public void showAllAdminByName(){
List<Admin> admins = selectAllAdmin();
if (admins!=null){
System.out.println("管理员列表如下:");
System.out.println("管理员Id"+"\t"+"姓名:");
for (int i=0;i<admins.size();i++){
System.out.println((i+1)+"\t"+admins.get(i).getAdminName());
}
}else{
System.out.println("暂无数据!");
}
}
}
package BLL;
import DAL.*;
import Entity.FineBill;
import Entity.Operator;
import Entity.ReaderType;
import java.io.IOException;
import java.util.List;
/**
* @author 不想掉头发$
* @version 1.0
* @date 2021年12月21日
*/
public class AdminService {
private static LogDao logDao=null;
private static OperatorDao operatorDao=null;
private static ReaderTypeDao readerTypeDao=null;
private static FineBillDao fineBillDao=null;
static{
if(logDao==null){
logDao=new LogDao();
}
if (operatorDao==null){
operatorDao=new OperatorDao();
}
if(readerTypeDao==null){
readerTypeDao=new ReaderTypeDao();
}
if(fineBillDao==null){
fineBillDao=new FineBillDao();
}
}
//员工工作日志(待完成)
/**
* 展示操作日志(包括,管理员进行的操作员的增删改查+操作员的一系列操作)
*/
public void showOperationLog() throws IOException {
logDao.showoperate();
}
//借阅金额设定(设置读者类型的罚金金额)
/**
* 展示所有的读者类型信息
* @return 读者类型列表
*/
public List<ReaderType> showAllReaderType() {
List<ReaderType> readerTypes = null;
readerTypes = readerTypeDao.selectAllReaderTypes();
if (readerTypes!=null){
System.out.println("ID"+"\t读者类型名称"+"\t类型最大可借阅本数"+"\t最大借阅天数"+"\t罚金");
for (int i=0; i<readerTypes.size(); i++){
System.out.println((i+1) +readerTypes.get(i).toString());
}
return readerTypes;
}else {
System.out.println("暂无记录");
}
return null;
}
/**
* 管理员修改读者类型罚金
* (读者表与读者类型表通过读者类型Id连接修改所有)
* @return 0,1
*/
public int setFineByReaderType(int readerTypeId,double fine){
ReaderType readerType = null;
if((readerType = readerTypeDao.selectReaderTypeById(readerTypeId))!=null){
return readerTypeDao.updateReaderTypeFineById(fine, readerTypeId);
}
return 0;
}
//操作员信息管理 增 删 改 查 四个功能
/**
* 管理员注册操作员
* @param operatorName 操作员用户名
* @param operatorPassword 操作员密码
* @param phone 操作员电话
* @return 0,1
*/
public int insertOperator(String operatorName,String operatorPassword,String phone){
Operator operator = null ;
if ((operator = operatorDao.selectOperatorByName(operatorName))==null){
return operatorDao.registerOperator(operatorName,operatorPassword,phone);
}else {
System.out.println("操作员用户名已被使用");
return 0;
}
}
/**
* 根据操作员Id删除操作员
* @param operatorId
* @return
*/
public int deleteOperator(int operatorId){
Operator operator = null ;
if ((operator = operatorDao.selectOperatorById(operatorId))!=null){
return operatorDao.deleteOperator(operatorId);
}
return 0;
}
/**
* 根据传入参数修改,操作员的,密码/电话
* @param args
* @return
*/
public int updateOperator(Object...args){
return operatorDao.updateOperator(args);
}
public Operator operatorsExists(String operatorName){
Operator operator = operatorDao.selectOperatorByName(operatorName);
if (operator!=null){
return operator;
}
return null;
}
/**
* 查询操作员列表
* @return
*/
public List<Operator> selectAllOperators(){
List<Operator> operators = operatorDao.selectAllOperators();
if (operators!=null){
return operators;
}
return null;
}
/**
* 展示所有的操作员信息
*/
public void showAllOperators(){
List<Operator> operators = selectAllOperators();
if (operators!=null){
System.out.println("ID"+"\t操作员姓名");
for (int i=0;i<operators.size();i++){
System.out.println((i+1)+
operators.get(i).toString());
}
}else {
System.out.println("暂无数据!!!");
}
}
//罚金账单查询
/**
* 查询罚金账单
* 并展示
*/
public void showFineBills(){
List<FineBill> fineBills = null;
if ((fineBills = fineBillDao.queryAllBill())!=null){
System.out.println("ID"+"\t读者ID"+"\t图书ID"+"\t借阅时间"+"\t归还时间"+"\t罚金");
for (int i=0;i<fineBills.size();i++){
System.out.println( (i+1)
+fineBills.get(i).toString());
}
}else {
System.out.println("暂无数据!");
}
}
}
我们是通过去实现相关的接口然后再实例化相关的类来进行方法的调用,最后再在界面上调用,达到层层分离,减少代码的冗余,增加代码的可读性和可扩展性。
三、总结
在我们写这个代码的时候也遇到了许许多多的问题,首先就是我们在使用Git来进行合作的时候总是会造成代码冲突,也搞明白了我们在使用GIt的时候我们不能只创建一个分支,我们应该多使用几个分支将没有错误的代码放在一个分支,将经常改动的代码方法放到一个分支,这样不会造成因为操作失误什么的将写好的代码全部丢失然后重头再来。我们在设计数据库和每一个功能的时候花的时间比较多,但是这个是很有必要的,当我们把文档写好数据库创好之后我们在写代码的时候,就不会去想下一步需要做什么,而是时刻知道我们应该做什么,因为在写文档的时候我们已经将整个流程进行了一个了解。当然还是有一些大大小小的问题但是我们遵循文档去做就没有什么问题了,每个问题也得到了应该有的解决。
完整代码:
链接:https://pan.baidu.com/s/1ZVmQZiIVvf4YDvTsyxpzNw
提取码:1234