Project Structure
The system is organized into standard MVC layers:
beans: entity classes (Book, User, Jbook)controller: request handling and menu navigationservice: business logic itnerfacesservice.impl: service implementationsdao: data access layer (not fully shown)util: database connection helper
Code Implementation
Entity Classes
Book.java
package com.xszx.beans;
public class Book {
private int id;
private String name;
private int bsum;
public Book() {}
public Book(int id, String name, int bsum) {
this.id = id;
this.name = name;
this.bsum = bsum;
}
// getters and setters
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getBsum() { return bsum; }
public void setBsum(int bsum) { this.bsum = bsum; }
@Override
public String toString() {
return "Book{id=" + id + ", name='" + name + '\'' + ", bsum=" + bsum + '}';
}
}
Jbook.java (borrowing record)
package com.xszx.beans;
import java.util.Date;
public class Jbook {
private int id;
private int uid;
private int bid;
private Date jdate;
private Date hdate;
public Jbook() {}
public Jbook(int id, int uid, int bid, Date jdate, Date hdate) {
this.id = id;
this.uid = uid;
this.bid = bid;
this.jdate = jdate;
this.hdate = hdate;
}
// getters and setters
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public int getUid() { return uid; }
public void setUid(int uid) { this.uid = uid; }
public int getBid() { return bid; }
public void setBid(int bid) { this.bid = bid; }
public Date getJdate() { return jdate; }
public void setJdate(Date jdate) { this.jdate = jdate; }
public Date getHdate() { return hdate; }
public void setHdate(Date hdate) { this.hdate = hdate; }
@Override
public String toString() {
return "Jbook{id=" + id + ", uid=" + uid + ", bid=" + bid + ", jdate=" + jdate + ", hdate=" + hdate + '}';
}
}
User.java
package com.xszx.beans;
public class User {
private int id;
private String username;
private String password;
private int role; // 1=admin, 2=member
public User() {}
public User(int id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public User(int id, String username, String password, int role) {
this.id = id;
this.username = username;
this.password = password;
this.role = role;
}
// getters and setters
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public int getRole() { return role; }
public void setRole(int role) { this.role = role; }
@Override
public String toString() {
return "User{id=" + id + ", username='" + username + '\'' + ", role=" + role + '}';
}
}
Controller Layer
BookController.java
package com.xszx.controller;
import com.xszx.beans.Book;
import com.xszx.beans.Jbook;
import com.xszx.beans.User;
import com.xszx.service.BookService;
import com.xszx.service.JbookService;
import com.xszx.service.impl.BookServiceImpl;
import com.xszx.service.impl.JbookServiceImpl;
import java.util.List;
import java.util.Scanner;
public class BookController {
private Scanner scanner = new Scanner(System.in);
private BookService bookService = new BookServiceImpl();
private JbookService jbookService = new JbookServiceImpl();
public void adminMenu(User currentUser) {
System.out.println("\n--- Admin Book Management ---");
System.out.println("[1] View books [2] Add book [3] Edit book [4] Delete book [0] Back");
int choice = scanner.nextInt();
switch (choice) {
case 1:
displayBooks();
adminMenu(currentUser);
break;
case 2:
addNewBook();
adminMenu(currentUser);
break;
case 3:
updateBook();
adminMenu(currentUser);
break;
case 4:
removeBook();
adminMenu(currentUser);
break;
case 0:
new UserController().mainMenu(currentUser);
break;
default:
System.out.println("Invalid input, try again.");
adminMenu(currentUser);
}
}
public void userMenu(User currentUser) {
System.out.println("\n--- User Book System ---");
System.out.println("[1] View books [2] Borrow book [3] Return book [4] View records [0] Back");
int choice = scanner.nextInt();
switch (choice) {
case 1:
displayBooks();
userMenu(currentUser);
break;
case 2:
borrowBook(currentUser);
userMenu(currentUser);
break;
case 3:
returnBook(currentUser);
userMenu(currentUser);
break;
case 4:
recordMenu(currentUser);
break;
case 0:
new UserController().mainMenu(currentUser);
break;
default:
System.out.println("Invalid input, try again.");
userMenu(currentUser);
}
}
private void recordMenu(User currentUser) {
System.out.println("\n--- Borrow Records ---");
System.out.println("[1] All records [2] Returned [3] Not returned [0] Back");
int choice = scanner.nextInt();
switch (choice) {
case 1:
showAllRecords(currentUser);
recordMenu(currentUser);
break;
case 2:
showReturnedRecords(currentUser);
recordMenu(currentUser);
break;
case 3:
showUnreturnedRecords(currentUser);
recordMenu(currentUser);
break;
case 0:
userMenu(currentUser);
break;
default:
System.out.println("Invalid input.");
recordMenu(currentUser);
}
}
private void showAllRecords(User user) {
List<Jbook> records = jbookService.getAllRecords(user);
records.forEach(System.out::println);
}
private void showReturnedRecords(User user) {
List<Jbook> records = jbookService.getReturnedRecords(user);
records.forEach(System.out::println);
}
private void showUnreturnedRecords(User user) {
List<Jbook> records = jbookService.getUnreturnedRecords(user);
records.forEach(System.out::println);
}
private void returnBook(User user) {
System.out.print("Enter book ID to return: ");
int bid = scanner.nextInt();
int recordId = bookService.findRecordByUserAndBook(user, bid);
if (recordId > 0) {
jbookService.processReturn(recordId);
bookService.incrementStock(bid);
bookService.updateReturnDate(bid);
System.out.println("Book returned successfully.");
} else {
System.out.println("This book is not currently borrowed or does not need return.");
}
}
private void borrowBook(User user) {
System.out.print("Enter book ID to borrow: ");
int bid = scanner.nextInt();
if (bookService.isAvailable(bid)) {
int existingRecord = bookService.findRecordByUserAndBook(user, bid);
if (existingRecord > 0) {
System.out.println("You have already borrowed this book and not returned it.");
} else {
jbookService.createBorrowRecord(user, bid);
bookService.decrementStock(bid);
bookService.updateBorrowDate(bid);
System.out.println("Book borrowed successfully.");
}
} else {
System.out.println("This book is out of stock or does not exist. Check the book list.");
}
}
private void removeBook() {
System.out.print("Enter book name to delete: ");
Book target = new Book();
target.setName(scanner.next());
Book existing = bookService.findByName(target);
if (existing != null) {
int result = bookService.delete(target);
if (result == 2) {
System.out.println("Book deleted successfully.");
} else if (result == 1) {
System.out.println("Cannot delete: book is currently borrowed.");
}
} else {
System.out.println("Book not found.");
}
}
private void updateBook() {
System.out.print("Enter book name to edit: ");
Book original = new Book();
original.setName(scanner.next());
Book existing = bookService.findByName(original);
if (existing != null) {
System.out.print("Enter new book name: ");
Book updated = new Book();
updated.setName(scanner.next());
int code = bookService.update(original, updated);
if (code == 0) {
System.out.println("Book updated.");
} else {
System.out.println("New name already exists.");
}
} else {
System.out.println("Book not found.");
}
}
private void addNewBook() {
Book book = new Book();
System.out.print("Enter book name: ");
book.setName(scanner.next());
Book existing = bookService.findByName(book);
if (existing != null) {
System.out.println("Book name conflict.");
adminMenu(null);
} else {
System.out.print("Enter stock quantity: ");
book.setBsum(scanner.nextInt());
int result = bookService.add(book);
if (result == 1) {
System.out.println("Book added successfully.");
} else {
System.out.println("Failed to add book.");
}
}
}
private void displayBooks() {
List<Book> books = bookService.getAll();
books.forEach(System.out::println);
}
}
UserController.java
package com.xszx.controller;
import com.xszx.beans.User;
import com.xszx.service.UserService;
import com.xszx.service.impl.UserServiceImpl;
import java.util.Scanner;
public class UserController {
private Scanner scanner = new Scanner(System.in);
private UserService userService = new UserServiceImpl();
public void mainMenu(User currentUser) {
System.out.println("\n--- Book Management System ---");
System.out.println("[1] Login [2] Register [0] Exit");
int choice = scanner.nextInt();
switch (choice) {
case 1:
performLogin();
break;
case 2:
performRegistration();
break;
case 0:
System.out.println("System exited. Goodbye!");
System.exit(0);
break;
default:
System.out.println("Invalid input.");
mainMenu(null);
}
}
private void performRegistration() {
User newUser = new User();
System.out.print("Enter username: ");
newUser.setUsername(scanner.next());
if (userService.isRegistered(newUser)) {
System.out.println("Username already exists.");
mainMenu(null);
} else {
System.out.print("Enter password: ");
newUser.setPassword(scanner.next());
userService.addUser(newUser);
System.out.println("Registration successful.");
mainMenu(null);
}
}
private User performLogin() {
User credentials = new User();
System.out.print("Enter username: ");
credentials.setUsername(scanner.next());
System.out.print("Enter password: ");
credentials.setPassword(scanner.next());
User loggedUser = userService.authenticate(credentials);
if (loggedUser != null) {
System.out.println("Login successful.");
BookController controller = new BookController();
if (loggedUser.getRole() == 1) {
controller.adminMenu(loggedUser);
} else {
controller.userMenu(loggedUser);
}
return loggedUser;
} else {
System.out.println("Invalid credentials.");
mainMenu(null);
return null;
}
}
}
Service Interfaces
BookService.java
package com.xszx.service;
import com.xszx.beans.Book;
import com.xszx.beans.User;
import java.util.List;
public interface BookService {
List<Book> getAll();
int add(Book book);
Book findByName(Book book);
int update(Book original, Book updated);
int delete(Book book);
boolean isAvailable(int bid);
int findRecordByUserAndBook(User user, int bid);
void decrementStock(int bid);
void updateBorrowDate(int bid);
void incrementStock(int bid);
void updateReturnDate(int bid);
}
JbookService.java
package com.xszx.service;
import com.xszx.beans.Jbook;
import com.xszx.beans.User;
import java.util.List;
public interface JbookService {
void processReturn(int recordId);
List<Jbook> getAllRecords(User user);
List<Jbook> getReturnedRecords(User user);
List<Jbook> getUnreturnedRecords(User user);
void createBorrowRecord(User user, int bid);
}
UserService.java
package com.xszx.service;
import com.xszx.beans.User;
public interface UserService {
User authenticate(User user);
boolean isRegistered(User user);
void addUser(User user);
}
Database Utility
JDBCUtil.java
package com.xszx.util;
import java.sql.*;
public class JDBCUtil {
private static final String URL = "jdbc:mysql://127.0.0.1:3306/booksystem";
private static final String DB_USER = "root";
private static final String DB_PASSWORD = "123456";
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() {
try {
return DriverManager.getConnection(URL, DB_USER, DB_PASSWORD);
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
public static void close(Connection conn, PreparedStatement ps, ResultSet rs) {
try {
if (rs != null) rs.close();
if (ps != null) ps.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Note: The dao and service.impl layers are structurally similar with SQL query implementations. A MySQL database named booksystem must be created beforehand. This system is suitable for Java course projects in second or third year of university.