JDBC编程相关知识(实现图书管理系统进阶版)(上):https://developer.aliyun.com/article/1520473
d、Administrator类
管理员的主要功能是对图书进行增加、删除、查看以及查找,管理员类继承User类,需要对父类定义的接口数组完善将自己特有的方法进行填充。对于重写身份验证方法,使用select name,password from administrator ,遍历结果集得到姓名和密码,若有对应的密码和密码则登录成功,否则登录失败。
import operate.*; import util.DBUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Scanner; public class Administrator extends User{ public Administrator(){ } public Administrator(String name, String password) { super(name,password); this.operates=new Operate[]{ new ExitOpe(), new AddBook(), new DelBook(), new DisplayBook(), new FindBook() }; } @Override public int menu() { System.out.println("*******************************************"); System.out.println(" 1.添加图书 2.删除图书 "); System.out.println(" 3.显示图书 4.查找图书 "); System.out.println(" 0.退出系统 "); System.out.println("*******************************************"); System.out.println("请输入您的操作:"); Scanner sc = new Scanner(System.in); int option = sc.nextInt(); return option; } @Override public boolean authentication(String name,String pwd) throws SQLException { Connection connection= DBUtil.getConnection(); String sql="select name,password from administrator where name=?"; PreparedStatement statement=connection.prepareStatement(sql); statement.setString(1,name); ResultSet resultSet=statement.executeQuery(); if(resultSet.next()){ String na=resultSet.getString("name"); String pw=resultSet.getString("password"); if(pw.equals(pwd)&&na.equals(name)){ return true; } } return false; } }
e、RegularUser类
普通用户类同样继承User类,内部实现与管理员类相似。
import operate.*; import util.DBUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Scanner; public class RegularUser extends User{ public RegularUser(){ } public RegularUser(String name, String password) { super(name,password); this.operates=new Operate[]{ new ExitOpe(), new BorrowBook(), new ReturnBook(), new DisplayBook(), new FindBook(), }; } @Override public int menu() { System.out.println("*******************************************"); System.out.println(" 1.借阅图书 2.归还图书 "); System.out.println(" 3.显示图书 4.查找图书 "); System.out.println(" 0.退出系统 "); System.out.println("*******************************************"); System.out.println("请输入您的操作:"); Scanner sc = new Scanner(System.in); int option = sc.nextInt(); return option; } @Override public boolean authentication(String name, String pwd) throws SQLException { Connection connection= DBUtil.getConnection(); String sql="select name,password from regularuser where name=?"; PreparedStatement statement=connection.prepareStatement(sql); statement.setString(1,name); ResultSet resultSet=statement.executeQuery(); if(resultSet.next()){ String na=resultSet.getString("name"); String pw=resultSet.getString("password"); if(pw.equals(pwd)&&na.equals(name)){ return true; } } return false; } }
4、实现操作类
a、Operate接口
创建一个接口,内部定义一个抽象的work方法,然后操作类都实现这个接口,并重写work方法。
import book.Bookshelf; import java.sql.SQLException; public interface Operate { void work(Bookshelf books) throws SQLException; }
b、 添加图书方法
由于书架当时的初始容量为10000,但还是进行了判断,如果容量已满则无法添加,再进一步输入要添加图书的信息,利用图书类中的equals()方法对添加的图书与已经存放的图书,若有重复则无法添加,否则使用insert插入语句进行添加,完成对数据库的更新,并且要将该图书添加到书架类的数组中。
public class AddBook implements Operate{ @Override public void work(Bookshelf books) throws SQLException { if(books.getCurrentSize()>= books.getSize()){ System.out.println("书架已满,无法继续添加"); }else{ Scanner sc=new Scanner(System.in); System.out.println("请输入图书信息:"); System.out.println("图书编号:"); int id=sc.nextInt(); System.out.println("图书名称:"); String name=sc.next(); System.out.println("图书作者:"); String author = sc.next(); System.out.println("图书价格:"); int price = sc.nextInt(); System.out.println("图书主题:"); sc.nextLine(); String theme= sc.nextLine(); Book book = new Book(id,name, author, price, theme); for (int i = 0; i < books.getCurrentSize(); i++) { if(book.equals(books.getBook(i))){ System.out.println("该图书已经存在,无法继续添加!"); return; } } String sql="insert into book(id,name,author,price,theme) values(?,?,?,?,?)"; Connection connection= DBUtil.getConnection(); PreparedStatement statement=connection.prepareStatement(sql); statement.setInt(1,id); statement.setString(2,name); statement.setString(3,author); statement.setDouble(4,price); statement.setString(5,theme); books.addBook(book); books.setCurrentSize(books.getCurrentSize()+1); int ret=statement.executeUpdate(); if(ret>0){ System.out.println("添加成功!"); } statement.close(); connection.close(); } } }
c、删除图书
输入要删除的图书名称,利用书架类的数组遍历,此处不使用select语句进行查找是后面对书架进行删除时需要得到图书在书架的位置,找到后使用delete语句删除图书,然后再使用循环覆盖删除书架中的该图书。
public class DelBook implements Operate{ @Override public void work(Bookshelf books) throws SQLException { System.out.println("请输入要删除的图书名称"); Scanner sc=new Scanner(System.in); String name=sc.nextLine(); int pos=-1; for (int i = 0; i < books.getCurrentSize(); i++) { if(name.equals(books.getBook(i).getName())){ pos=i; break; } } if(pos==-1){ System.out.println("未找到您要删除的图书"); }else{ Connection connection= DBUtil.getConnection(); String sql="delete from book where name=?"; PreparedStatement statement=connection.prepareStatement(sql); statement.setString(1,name); int ret=statement.executeUpdate(); if(ret>0){ System.out.println("删除成功!"); } for(int i= pos+1;i<books.getCurrentSize();i++){ Book book=books.getBook(i); books.modify(i-1,book); } books.modify(books.getCurrentSize(),null); books.setCurrentSize(books.getCurrentSize()-1); statement.close(); connection.close(); } } }
d、显示图书
显示所有的图书信息,此处使用select语句对book表进行全列查询,此处也可以遍历书架得到所有图书的信息。
public class DisplayBook implements Operate{ @Override public void work(Bookshelf books) throws SQLException { Connection connection= DBUtil.getConnection(); String sql="select * from book"; PreparedStatement statement=connection.prepareStatement(sql); ResultSet resultSet = statement.executeQuery(); System.out.println("===================================================================================================================="); while(resultSet.next()){ int id=resultSet.getInt("id"); String name=resultSet.getString("name"); String author=resultSet.getString("author"); Double price=resultSet.getDouble("price"); String theme=resultSet.getString("theme"); boolean isBorrowed=resultSet.getBoolean("statue"); Date borrowTime=resultSet.getDate("borrow_time"); Date returnTime=resultSet.getDate("return_time"); System.out.println("Book{" + "id=" + id + ", name='" + name + '\'' + ", author='" + author + '\'' + ", price=" + price + ", theme='" + theme + '\'' + ", isBorrowed=" + (isBorrowed?"已借出":"未借出") + ", borrowTime=" + borrowTime + ", returnTime=" + returnTime + '}'); } System.out.println("===================================================================================================================="); resultSet.close(); statement.close(); connection.close(); } }
e、查找图书
此处使用的是select语句对图书名称进行精确查询,也使用循环遍历书架更为方便。
public class FindBook implements Operate{ @Override public void work(Bookshelf books) throws SQLException { System.out.println("请输入要查找的图书名称"); Scanner sc=new Scanner(System.in); String str=sc.nextLine(); int pos=-1; Connection connection= DBUtil.getConnection(); String sql="select * from book where name=?"; PreparedStatement statement=connection.prepareStatement(sql); statement.setString(1,str); ResultSet resultSet = statement.executeQuery(); if(resultSet==null){ System.out.println("未找到您要找的书籍"); return; } System.out.println("===================================================================================================================="); while(resultSet.next()){ int id=resultSet.getInt("id"); String name=resultSet.getString("name"); String author=resultSet.getString("author"); Double price=resultSet.getDouble("price"); String theme=resultSet.getString("theme"); boolean isBorrowed=resultSet.getBoolean("statue"); Date borrowTime=resultSet.getTime("borrow_time"); Date returnTime=resultSet.getTime("return_time"); System.out.println("Book{" + "id=" + id + ", name='" + name + '\'' + ", author='" + author + '\'' + ", price=" + price + ", theme='" + theme + '\'' + ", isBorrowed=" + (isBorrowed?"已借出":"未借出") + ", borrowTime=" + borrowTime + ", returnTime=" + returnTime + '}'); } System.out.println("===================================================================================================================="); resultSet.close(); statement.close(); connection.close(); } }
f、借阅图书
在借阅图书时,首先对输入的图书进行查找,若有才能进行借阅,使用update语句对图书的是否借出还有借阅时间进行修改,在创建图书类的日期是使用的是util包的Date类,但是在book表中的datetime是sql包的Date类,需要进行转换,对数据库中的book表完成更新后,同时也要修改书架上的图书信息。
public class BorrowBook implements Operate{ @Override public void work(Bookshelf books) throws SQLException { System.out.println("请输入要借阅的图书名称"); Scanner sc=new Scanner(System.in); String name=sc.nextLine(); int pos=-1; for (int i = 0; i < books.getCurrentSize(); i++) { if(name.equals(books.getBook(i).getName())){ pos=i; break; } } if(pos==-1){ System.out.println("未找到您需要的图书"); }else{ if(books.getBook(pos).isBorrowed()==true){ System.out.println("该图书已经借出"); return; } Date date=new Date(System.currentTimeMillis()); java.sql.Date sd=new java.sql.Date(date.getTime()); Connection connection= DBUtil.getConnection(); String sql1="update book set borrow_time=? where name=?"; PreparedStatement statement1=connection.prepareStatement(sql1); statement1.setDate(1,sd); statement1.setString(2,name); String sql2="update book set statue=? where name=?"; PreparedStatement statement2=connection.prepareStatement(sql2); Boolean flag=true; statement2.setBoolean(1,flag); statement2.setString(2,name); statement1.executeUpdate(); statement1.close(); statement2.executeUpdate(); statement2.close(); connection.close(); books.getBook(pos).setBorrowed(true); books.getBook(pos).setBorrowTime(date); System.out.println("借阅成功!"); } } }
g、归还图书
在归还图书时,也要对图书的借阅状态和归还时间进行修改,操作与借阅图书类似。
public class ReturnBook implements Operate { @Override public void work(Bookshelf books) throws SQLException { System.out.println("请输入要归还的图书名称"); Scanner sc=new Scanner(System.in); String name=sc.nextLine(); int pos=-1; for (int i = 0; i < books.getCurrentSize(); i++) { if(name.equals(books.getBook(i).getName())){ pos=i; break; } } if(pos==-1){ System.out.println("未找到您需要的图书"); }else{ Date date=new Date(System.currentTimeMillis()); java.sql.Date sd=new java.sql.Date(date.getTime()); Connection connection= DBUtil.getConnection(); String sql1="update book set return_time=? where name=?"; PreparedStatement statement1=connection.prepareStatement(sql1); statement1.setDate(1,sd); statement1.setString(2,name); String sql2="update book set statue=? where name=?"; PreparedStatement statement2=connection.prepareStatement(sql2); Boolean flag=false; statement2.setBoolean(1,flag); statement2.setString(2,name); statement1.executeUpdate(); statement1.close(); statement2.executeUpdate(); statement2.close(); connection.close(); books.getBook(pos).setBorrowed(false); books.getBook(pos).setReturnTime(date); System.out.println("归还成功!"); } } }
h、退出系统
使用System.exit(0)方法退出系统,虽然该方法没有任何异常,但因为重写了Operate中的work方法,work方法抛出了sql异常,那么该方法也需要抛出异常。
public class ExitOpe implements Operate{ @Override public void work(Bookshelf books) throws SQLException { System.out.println("退出成功,欢迎下次使用!"); System.exit(0); } }
5、Main
在测试类中需要实现登录函数,由于在登录时才知道用户身份,所以使用User类为返回值进行向上转型,在登录函数中首先选择身份,然后对身份进行验证,验证成功后,即登录成功。
public class Main { public static User login() throws SQLException { System.out.println("请选择登录身份:1)管理员 2)普通用户"); Scanner sc=new Scanner(System.in); int option=sc.nextInt(); System.out.println("请输入姓名:"); String name=sc.next(); System.out.println("请输入密码:"); String pwd=sc.next(); if(option==1){ boolean flag=new Administrator().authentication(name,pwd); if(flag){ System.out.println("登陆成功!"); return new Administrator(name,pwd); }else{ System.out.println("姓名或密码输入有误"); } }else if(option==2){ boolean flag=new RegularUser().authentication(name,pwd); if(flag){ System.out.println("登陆成功!"); return new RegularUser(name,pwd); }else{ System.out.println("姓名或密码输入有误"); } }else{ System.out.println("输入有误"); } return null; } public static void main(String[] args) throws SQLException { Bookshelf books=new Bookshelf(); User user=login(); while(true){ int ret=user.menu(); user.doWork(ret,books); } } }
6、效果演示
管理员和普通用户表如下所示:
运行效果演示:
管理员:
普通用户: