Library management system based on Java

Keywords: Java JavaSE

preface

After a lapse of two weeks, I once again wrote a Java practice case - "library management system", which is a simplified version of the library management system. It is estimated that it will be further developed after my own technology is improved. I don't think it will be long

Previous case articles, interested partners can jump to check it by themselves! The corresponding source code is attached:

1, Preliminary preparation

Before starting to do things, you must prepare the following things. JDK and IDE do not necessarily need to be unified. This is just the version I use. When you're ready, take our brains and you can do it

  • Programming language: Java
  • Operating environment: JDK1.8
  • IDE : IDEA 2020
  • Reserve knowledge: Java Foundation

2, Demand analysis

In this case, it is divided into administrator side and ordinary user side, with different functional permissions.

  1. administrators
functional module functional analysisremarks
View booksIt is used for users to view all books existing in the libraryNon croppable
Add booksUsed by administrators to add books in the libraryNon croppable
Delete bookUsed by the administrator to delete books in the libraryNon croppable
Modify booksIt is used by the administrator to modify the basic information of books in the libraryNon croppable
Exit functionUsed to exit the current accountNon croppable
  1. Ordinary users
functional module functional analysisremarks
View booksIt is used for users to view all books existing in the libraryNon croppable
Borrow booksIt is used for users to borrow books existing in the libraryNon croppable
Return booksUsed to return borrowed booksNon croppable
Exit functionUsed to exit the current accountNon croppable

At the same time, the structure diagram of this case is attached (I'm sorry for my poor drawing)

3, Core code development

In this case, like the previous cases, MVC framework is also used to separate the business layer and view layer, improve the maintainability of the program and reduce the coupling. If yes MVC design pattern If you don't understand it, you can directly jump to Baidu Encyclopedia for viewing, or go to the search box of CSDN to find the experience of others

1. model layer

1.1. Book

This is a class that encapsulates books for future search and modification. Its encapsulation contents are as follows: provide corresponding constructors for book title, book author, book publishing house, library collection location, book borrowing status and ISBNCode variables set by imitating Chinese standard ISBN code, and rewrite toString() method in this class to display book information.

public class Book {
    private String name;        //title
    private String author;      //author
    private String publisher;   //press
    private String address;     //Collection location
    private String status;      //Borrowing status
    private String ISBNCode;    //Chinese mainland standard ISBN code

    public Book() {

    }

    public Book(String name, String author, String publisher, String address, String status) {
        this.name = name;
        this.author = author;
        this.publisher = publisher;
        this.address = address;
        this.status = status;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", publisher='" + publisher + '\'' +
                ", address='" + address + '\'' +
                ", status='" + status + '\'' +
                ", ISBNCode='" + ISBNCode + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getPublisher() {
        return publisher;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getISBNCode() {
        return ISBNCode;
    }

    public void setISBNCode(String ISBNCode) {
        this.ISBNCode = ISBNCode;
    }
}

1.2 User class

Create a User user abstract class, which encapsulates the User name, operand array, construction method and menu menu. Call the corresponding opera method in the operand array through the options returned from the menu menu

public abstract class User{
    protected String name;                  //user name
    protected IOOperation[] operations;     //Operand array

    public User() {

    }

    public User(String name) {
        this.name = name;
    }
    /**
    * @Description Define the menu abstract method and wait for the subclass of the abstract class to override it
    * @Date 20:13 2021/10/5
    * @Param []
    * @return int
    **/
    abstract public int menu();

    /**
    * @Description Call the opera method in the corresponding object through user selection
    * @Date 20:11 2021/10/5
    * @Param [selection, bookList]
    * @return void
    **/
    public void doOperation(int selection, BookList bookList) {
        operations[selection].opera(bookList);
    }
}

1.3. NormalUser class

Create a NormalUser ordinary object class, which inherits the User abstract class, instantiates the functions that ordinary users can use in the constructor, and rewrites the menu abstract method in the User abstract class. It should be noted here that when instantiating the operation object array, it cannot be instantiated in the parameterless constructor. If you need to use the parameterless constructor, because the parameterless constructor of the parent class will be called when calling the parameterless constructor, so you can't call your own parameterless constructor implicitly at the same time.

public class NormalUser extends User{
    /**
    * @Description Using the constructor, instantiate the functions that ordinary users can use
    * @Date 20:22 2021/10/5
    * @Param []
    * @return
    **/
    public NormalUser(String name) {
        super(name);
        this.operations = new IOOperation[] {
                new ExitSystem(),
                new ListAllBook(),
                new BorrowBook(),
                new ReturnBook()
        };
    }

    @Override
    public int menu() {
        System.out.println("=============================");
        System.out.println("Hello " + this.name + ", Welcome to the library management system!");
        System.out.println("1.View books");
        System.out.println("2.Borrow books");
        System.out.println("3.Return books");
        System.out.println("0.Exit the system");
        System.out.println("=============================");
        System.out.println("Please enter your choice");
        return LMSUtility.readMenuSelection(3);
    }
}

1.4. Admin class

Create an Admin ordinary object class, which inherits the User abstract class, instantiates the functions that ordinary users can use in the constructor, and rewrites the menu abstract method in the User abstract class. It should be noted that, like ordinary User classes, when instantiating the operation object array, you cannot instantiate it in a parameterless constructor if you need to use a parameterless constructor.

public class Admin extends User{
    /**
     * @Description Using the constructor, instantiate the functions that ordinary users can use
     * @Date 20:22 2021/10/5
     * @Param []
     * @return
     **/
    public Admin(String name) {
        super(name);
        //The following code block cannot be written in the parameterless constructor, otherwise it cannot be executed, resulting in empty operations
        this.operations = new IOOperation[] {
                new ExitSystem(),
                new ListAllBook(),
                new AddBook(),
                new DeleteBook(),
                new ReplaceBook()
        };
    }
    @Override
    public int menu() {
        Scanner sc = new Scanner(System.in);
        System.out.println("=============================");
        System.out.println("Hello " + this.name + ", Welcome to the library management system!");
        System.out.println("1.View books");
        System.out.println("2.Add books");
        System.out.println("3.Delete book");
        System.out.println("4.Modify books");
        System.out.println("0.Exit the system");
        System.out.println("=============================");
        System.out.println("Please enter your choice");
        int selection = new Scanner(System.in).nextInt();
        return selection;
    }
}

2. service layer

2.1 IOOperation interface

Create a user operation interface IOOperation, and let all the following operation functions be wrapped with classes to implement the interface, so as to achieve the effect of the target function

public interface IOOperation{
    public void opera(BookList books);
}

2.1. AddBook class

Create and add a Book class AddBook, which implements the IOOperation interface

public class AddBook implements IOOperation{
    @Override
    public void opera(BookList books){
        System.out.print("Please enter Book Name:");
        String name = LMSUtility.readString(30);
        System.out.print("Please enter book author:");
        String author = LMSUtility.readString(20);
        System.out.print("Please enter the book publisher:");
        String publisher = LMSUtility.readString(32);
        System.out.print("Please enter the book collection address:");
        String address = LMSUtility.readString(24);

        Book book = new Book(name, author, publisher, address, "free");
        try {
            books.addBook(book);
        } catch (BookException e) {
            System.out.println("Something went wrong!" + e.getMessage());
        }
        System.out.println("Successfully added!");
    }
}

2.2. DeleteBook class

Create and delete the book class DeleteBook, and implement the IOOperation interface

public class DeleteBook implements IOOperation{
    @Override
    public void opera(BookList books){
        System.out.print("Please enter the name of the book you want to delete ISBN Code:");
        String ISBN = LMSUtility.readString(20);
        try {
            books.deleteBook(ISBN);
        } catch (BookException e) {
            System.out.println("Something went wrong!" + e.getMessage());
        }
    }
}

2.3. ReplaceBook

Create and modify the book class ReplaceBook and implement the IOOperation interface

public class ReplaceBook implements IOOperation{
    @Override
    public void opera(BookList books) {
        if(books.getBookNumber() == 0) {
            try {
                throw new BookException("There are no books in the library at present");
            } catch (BookException e) {
                System.out.println("Something went wrong!" + e.getMessage());
            }
        }
        System.out.print("Please enter the book to be modified ISBN Code:");
        String ISBN = LMSUtility.readString(20);

        Book[] bookList = books.getBookList();
        for (int i = 0; i < books.getBookNumber(); i++) {
            if(bookList[i].getISBNCode().equals(ISBN)) {
                //Modify the book information, support carriage return and skip, and keep the original information unchanged
                System.out.print("Please enter the revised title(" + bookList[i].getName() + "): ");
                String name = LMSUtility.readString(30,bookList[i].getName());
                System.out.print("Please enter the author after modification(" + bookList[i].getAuthor() + "): ");
                String author = LMSUtility.readString(20,bookList[i].getAuthor());
                System.out.print("Please enter the revised publisher(" + bookList[i].getPublisher() + "): ");
                String publisher = LMSUtility.readString(32,bookList[i].getPublisher());
                System.out.print("Please enter the modified collection address(" + bookList[i].getAddress() + "): ");
                String address = LMSUtility.readString(24,bookList[i].getAddress());

                Book modifiedBook = new Book(name, author, publisher, address, bookList[i].getStatus());    //New book object
                modifiedBook.setISBNCode(bookList[i].getISBNCode());    //Assign the ISBN code directly
                bookList[i] = modifiedBook;     //Overwrite the new book object with the original object
                System.out.println("Modified successfully");
                return;
            }
        }
        try {
            throw new BookException("ISBN Code is \"" + ISBN + "\" Your book does not exist and cannot be modified");
        } catch (BookException e) {
            System.out.println("Something went wrong!" + e.getMessage());
        }
    }
}

2.4 ListAllBook class

Create the display book class ListAllBook and implement the IOOperation interface

public class ListAllBook implements IOOperation{
    @Override
    public void opera(BookList books){
        Book[] allBook = books.getBookList();
        System.out.println("\n============================Book information============================\n");
        for (int i = 0; i < books.getBookNumber(); i++) {
            System.out.println(allBook[i].toString());
        }
        System.out.println("\n===============================================================\n");
    }
}

2.5. BorrowBook

Create a borrowing book class, BorrowBook, and implement the IOOperation interface

public class BorrowBook implements IOOperation{
    @Override
    public void opera(BookList books) {
        if(books.getBookNumber() == 0) {
            try {
                throw new BookException("There are no books in the library at present");
            } catch (BookException e) {
                System.out.println("Something went wrong!" + e.getMessage());
            }
        }
        System.out.print("Please enter the number of books to rent ISBN Code:");
        String ISBN = LMSUtility.readString(20);
        //Traverse search books
        Book[] bookList = books.getBookList();
        for (int i = 0; i < books.getBookNumber(); i++) {
            if (bookList[i].getISBNCode().equals(ISBN)) {
                //Books have been lent out
                if(bookList[i].getStatus().equals("borrowed")) {
                    try {
                        throw new BookException("Sorry, the books have been lent out");
                    } catch (BookException e) {
                        System.out.println(e.getMessage());
                    }
                    return;
                }
                //Establish confirmation link
                System.out.print("Confirm lease<" + bookList[i].getName() + ">(Y/N)");
                char confirm = LMSUtility.readConfirmSelection();
                if(confirm == 'N') {
                    return;
                }
                bookList[i].setStatus("borrowed");
                System.out.println("Lease successful");
            }
        }
        //The book does not exist
        try {
            throw new BookException("ISBN Code is \"" + ISBN + "\" Your book does not exist and cannot be rented");
        } catch (BookException e) {
            System.out.println("Something went wrong!" + e.getMessage());
        }
    }
}

2.6. ReturnBook

Create the return book class ReturnBook and implement the IOOperation interface

public class ReturnBook implements IOOperation{
    @Override
    public void opera(BookList books) {
        System.out.print("Please enter the number of books to return ISBN Code:");
        String ISBN = LMSUtility.readString(20);
        //Traverse books
        Book[] bookList = books.getBookList();
        for (int i = 0; i < books.getBookNumber(); i++) {
            if (bookList[i].getISBNCode().equals(ISBN)) {
                //The books are still in the library
                if(bookList[i].getStatus().equals("free")) {
                    try {
                        throw new BookException("This book has not been borrowed and does not need to be returned");
                    } catch (BookException e) {
                        System.out.println("Something went wrong!" + e.getMessage());
                    }
                }
                //Establish confirmation link
                System.out.print("Confirm return<" + bookList[i].getName() + ">(Y/N)");
                char confirm = LMSUtility.readConfirmSelection();
                if(confirm == 'N') {
                    return;
                }
                bookList[i].setStatus("free");
                System.out.println("Return successful");
                return;
            }
        }
        //The book does not exist. An exception is thrown
        try {
            throw new BookException("ISBN Code is \"" + ISBN + "\" Your book does not exist and cannot be returned");
        } catch (BookException e) {
            System.out.println("Something went wrong!" + e.getMessage());
        }
    }
}

2.7 ExitSystem class

Create exit account class ExitSystem and implement IOOperation interface

public class ExitSystem implements IOOperation{
    @Override
    public void opera(BookList books) {
        System.out.print("Are you sure to exit the account(Y/N)");
        char confirm = LMSUtility.readConfirmSelection();
        if(confirm == 'N') {
            return;
        }
        System.out.println("Exit successful");
    }
}

3. view layer

3.1 LMSUtility

Create the TSUtility tool class, which encapsulates many methods to read and process keyboard data, so as to facilitate our access to the keyboard. (in fact, in order to be lazy, the previous tool classes are directly copied and fine tuned)

public class LMSUtility {
    private static Scanner sc = new Scanner(System.in);

    /**
     * @Description It is used to select the interface menu. The return type is integer and the return value is the option entered by the user
     * @Date 12:25 2021/8/29
     * @Param [maxSelection]
     * @return int
     **/
    public static int readMenuSelection(int maxSelection) {
        while(true) {
            int selection = 0;
            try {
                selection = Integer.parseInt(readKeyBoard(1,false));
            } catch (NumberFormatException e) {
                System.out.print("Incorrect input options, please re-enter:");
                continue;
            }
            if(selection < 0 || selection > maxSelection) {
                System.out.print("Incorrect input options, please re-enter:");
                continue;
            }
            return selection;
        }
    }
    /**
     * @Description Read a character, and it is not allowed to enter null, and take it as the return value of the method
     * @Date 16:56 2021/8/29
     * @Param []
     * @return char
     **/
    public static char readChar() {
        return readKeyBoard(1, false).charAt(0);
    }
    /**
     * @Description Read a character and allow to enter null. If you enter directly and no data is entered, the default value will be returned
     * @Date 20:51 2021/8/29
     * @Param [defaultValue]
     * @return char
     **/
    public static char readChar(char defaultValue) {
        String str = readKeyBoard(1, true);
        return str.length() == 0 ? defaultValue : str.charAt(0);
    }
    /**
     * @Description Read an integer with no more than two digits, and null is not allowed
     * @Date 16:51 2021/8/29
     * @Param []
     * @return int
     **/
    public static int readInt() {
        int number;
        while(true) {
            try {
                number = Integer.parseInt(readKeyBoard(2, false));
                break;
            } catch (NumberFormatException e) {
                System.out.print("Digital input error, please re-enter:");
            }
        }
        return number;
    }
    /**
     * @Description Read an integer with no more than two digits, and it is allowed to enter null. If no data is entered, enter directly and return defaultValue
     * @Date 16:39 2021/8/29
     * @Param [defaultValue]Specifies the default return value
     * @return int
     **/
    public static int readInt(int defaultValue) {
        int number;
        while(true) {
            String str = readKeyBoard(2, true);
            try {
                number = str.equals("") ? defaultValue : Integer.parseInt(str);
                break;
            } catch (NumberFormatException e) {
                System.out.print("Digital input error, please re-enter:");
            }
        }
        return number;
    }
    /**
     * @Description Read a string whose length does not exceed the limit, and null input is not allowed
     * @Date 20:54 2021/8/29
     * @Param [limit]
     * @return String
     **/
    public static String readString(int limit) {
        return readKeyBoard(limit, false);
    }
    /**
     * @Description Read a string whose length does not exceed the limit, and it is allowed to enter null. If no data is entered, enter directly and return defaultValue
     * @Date 21:00 2021/8/29
     * @Param [limit, defaultValue]
     * @return java.lang.String
     **/
    public static String readString(int limit, String defaultValue) {
        String str = readKeyBoard(limit, true);
        return str.equals("") ? defaultValue : str;
    }
    /**
     * @Description Used to confirm the selected input, read 'Y' or 'N' and take it as the return value
     * @Date 21:06 2021/8/29
     * @Param []
     * @return char
     **/
    public static char readConfirmSelection() {
        while(true) {
            char ch = readKeyBoard(1, false).toUpperCase().charAt(0);
            if(ch == 'Y' || ch == 'N') {
                return ch;
            } else {
                System.out.print("Selection error, please re select:");
            }
        }
    }
    /**
    * @Description Read the string of the length limit from the keyboard and call it only in this class, and return the value as the string.
    * @Date 22:34 2021/10/4
    * @Param [limit, blankReturn] blankReturn If it is true, an empty string can be returned; otherwise, a non empty string must be entered
    * @return java.lang.String
    **/
    private static String readKeyBoard(int limit, boolean blankReturn) {
        String line = "";
        while(sc.hasNextLine()) {
            line = sc.nextLine();
            if(line.length() == 0) {
                if(blankReturn) {
                    return line;
                } else {
                    continue;
                }
            }
            if (line.length() < 1 || line.length() > limit) {
                System.out.print("The length shall not be greater than " + limit + ", Please re-enter:");
                continue;
            }
            break;
        }
        return line;
    }
}

3.2. MainText class

Create a main test class and perform a general test on all the code developed earlier

public class MainText {
    public static void main(String[] args) {
        BookList bookList = new BookList();
        User user = login();
        while(true) {
            //Determine whether to exit the program
            if(user == null) {
                break;
            }
            int selection = user.menu();
            //Process the exit account
            if(selection == 0) {
                user = login();
                continue;
            }
            user.doOperation(selection, bookList);
        }
    }
    /**
    * @Description For user login
    * @Date 16:08 2021/10/6
    * @Param []
    * @return com.atfunny.LibraryMS.javabean.User
    **/
    public static User login() {
        System.out.println("1. Ordinary users\t\t2. administrators");
        System.out.println("0. Exit the system");
        System.out.print("Please make your choice:");
        int selection = LMSUtility.readMenuSelection(2);
        if(selection == 0) {
            return null;
        }
        System.out.print("Please enter your name:");
        String name = LMSUtility.readString(10);
        return selection == 1 ? new NormalUser(name) : new Admin(name);
    }
}

4, Test results

1. Administrator

2. Ordinary users

5, Summary

After writing this case, there are still some things to summarize. Dog, I'll list them one by one below

  1. It proves once again that it is really important to knock the code by hand. I haven't touched Java much after two weeks (I've been learning MySQL recently). Obviously, I can feel that I'm a little rusty
  2. This case is a simplified version modified according to the old library management system in the Java project. Many places are not perfect enough, just for an exercise. Interested people can consider improving it, such as using ArrayList to encapsulate different users, judging and identifying on the login interface, etc

The source code has been updated to gitee. If you need it, you can check it yourself – > Go ! ! !

Posted by musclehead on Wed, 06 Oct 2021 08:29:20 -0700