当前位置:首页>行业动态> 正文

安卓图书管理系统服务器代码

基于Spring Boot构建RESTful API,集成MySQL实现数据持久化,设计Book/User实体类映射数据库表结构,通过@RestController暴露借阅/归还/查询接口,结合JWT实现权限认证,采用Lombok简化POJO

技术选型与架构设计

组件技术方案说明
后端框架Spring Boot 3.x + Java 17快速构建RESTful API,内置Tomcat容器
数据库MySQL 8.0存储用户、图书、借阅记录等核心数据
ORM框架Spring Data JPA简化数据库操作,自动生成查询方法
安全框架Spring Security + JWT实现用户认证与权限控制
日志系统Logback + ELK(可选)记录系统运行日志,便于问题追踪
API文档Swagger 3.0自动生成可视化接口文档

数据库设计

表结构设计

表名字段说明
usersid(主键): 用户唯一标识
username: 用户名
password: 加密密码
role: 用户角色(ADMIN/USER)
created_at: 创建时间
booksid(主键): 图书唯一标识
title: 书名
author: 作者
isbn: ISBN号
category: 分类
stock: 库存数量
status: 状态(AVAILABLE/BORROWED)
borrow_recordsid(主键): 记录唯一标识
user_id(外键): 借阅用户ID
book_id(外键): 图书ID
borrow_time: 借阅时间
return_time: 归还时间
due_time: 到期时间

关键约束

  • 外键约束borrow_records.user_id关联users.idborrow_records.book_id关联books.id
  • 唯一索引users.username唯一,books.isbn唯一
  • 软删除:通过status字段标记数据状态(如图书下架)

核心API设计

用户管理

功能API路径方法权限说明
用户注册/api/users/registerPOST密码需加密存储(BCrypt)
用户登录/api/users/loginPOST返回JWT令牌,包含角色信息
获取用户信息/api/users/meGETUSER/ADMIN需携带有效JWT
删除用户(管理员)/api/users/{id}DELETEADMIN仅管理员可删除普通用户

图书管理

功能API路径方法权限说明
查询所有图书/api/booksGETUSER/ADMIN支持分页、按分类/作者/ISBN筛选
添加图书(管理员)/api/booksPOSTADMIN必填字段:title, author, isbn, stock
修改图书信息/api/books/{id}PUTADMIN可修改库存、状态等
删除图书/api/books/{id}DELETEADMIN逻辑删除(status标记)

借阅管理

功能API路径方法权限说明
借阅图书/api/borrow/{bookId}POSTUSER检查库存>0且用户未超最大借阅数
归还图书/api/return/{bookId}POSTUSER更新归还时间,释放库存
查询借阅记录/api/borrow/recordsGETUSER/ADMIN分页展示借阅历史

关键代码实现

实体类定义(Java)

// User.java
@Entity
@Table(name = "users")
public class User {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password; // BCrypt加密存储
    private String role; // ADMIN/USER
    private LocalDateTime createdAt;
    // Getters/Setters省略
}
// Book.java
@Entity
@Table(name = "books")
public class Book {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    private String author;
    private String isbn;
    private String category;
    private Integer stock;
    private String status; // AVAILABLE/BORROWED
    // Getters/Setters省略
}

借阅逻辑(Service层)

// BorrowService.java
@Transactional
public void borrowBook(Long userId, Long bookId) {
    // 1. 检查图书状态
    Book book = bookRepository.findById(bookId)
        .orElseThrow(() -> new ResourceNotFoundException("Book not found"));
    if (!BookStatus.AVAILABLE.equals(book.getStatus())) {
        throw new BadRequestException("Book is not available");
    }
    // 2. 检查用户借阅数量
    int borrowCount = borrowRecordRepository.countByUserIdAndReturnTimeIsNull(userId);
    if (borrowCount >= MAX_BORROW_LIMIT) {
        throw new BadRequestException("Exceed maximum borrow limit");
    }
    // 3. 更新图书状态并保存记录
    book.setStatus(BookStatus.BORROWED);
    bookRepository.save(book);
    BorrowRecord record = new BorrowRecord();
    record.setUserId(userId);
    record.setBookId(bookId);
    record.setBorrowTime(LocalDateTime.now());
    record.setDueTime(LocalDateTime.now().plusDays(BORROW_PERIOD_DAYS));
    borrowRecordRepository.save(record);
}

JWT认证流程

// AuthController.java
@PostMapping("/login")
public ResponseEntity<TokenResponse> login(@RequestBody LoginRequest request) {
    // 1. 验证用户名密码
    User user = userRepository.findByUsername(request.getUsername())
        .orElseThrow(() -> new BadCredentialsException("Invalid credentials"));
    if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
        throw new BadCredentialsException("Invalid credentials");
    }
    // 2. 生成JWT令牌
    String token = jwtUtils.generateToken(user.getId(), user.getRole());
    // 3. 返回响应
    return ResponseEntity.ok(new TokenResponse(token, user.getRole()));
}

单元测试示例

测试场景方法名预期结果
用户注册成功testRegisterUser返回HTTP 201,用户存入数据库
图书库存不足testBorrowBookStockZero抛出BadRequestException
管理员添加图书testAdminAddBook返回HTTP 201,图书可查询到
JWT令牌验证失败testInvalidToken返回HTTP 401,拒绝访问

相关问题与解答

问题1:如何扩展系统支持图书分类管理?

解答

  1. 新增分类表:创建categories表,存储分类ID和名称。
  2. 修改图书表:在books表中添加category_id外键字段,关联categories表。
  3. API调整
    • 添加/api/categories接口用于增删改查分类。
    • 在查询图书接口中增加categoryId筛选参数。
  4. 前端适配:在图书详情页展示分类信息,并提供按分类筛选功能。

问题2:如何实现逾期归还罚款功能?

解答

  1. 数据库调整:在borrow_records表中添加fine_amount字段(默认0)。
  2. 归还逻辑修改
    • returnBook方法中检查当前时间是否超过due_time
    • 如果逾期,按每日罚款金额计算总罚款(例如每日租金的10%)。
    • 更新fine_amount字段并持久化。
  3. API扩展
    • 新增/api/fines/{userId}接口,查询用户未支付罚款总额。
    • 在用户支付罚款后,更新罚款状态并记录