前言:上一篇学习了入门级知识,留了一份作业,其实创建一个图书管理系统是一个很好的实践项目,可以帮助你掌握数据库操作、前端开发和基本的CRUD(创建、读取、更新、删除)操作,数据库存储书籍信息,以及一个基本的用户界面。
首先,创建一个新的 Spring Boot 项目。你可以使用 Spring Initializr (https://start.spring.io/) 来生成项目结构,并选择以下依赖:
Spring Web
Spring Data JPA
H2 Database
生成的项目结构应该包含以下主要文件:
src/main/java/com/example/bookmanagement/BookManagementApplication.java
src/main/java/com/example/bookmanagement/controller/BookController.java
src/main/java/com/example/bookmanagement/model/Book.java
src/main/java/com/example/bookmanagement/repository/BookRepository.java
Book.java
:
package com.example.bookmanagement.model;
import javax.persistence.Entity; // 导入 JPA 实体注解
import javax.persistence.GeneratedValue; // 导入 ID 自动生成注解
import javax.persistence.GenerationType; // 导入 ID 自动生成策略
import javax.persistence.Id; // 导入 主键注解
// 定义 Book 实体类,映射到数据库表
@Entity
public class Book {
@Id // 主键注解
@GeneratedValue(strategy = GenerationType.IDENTITY) // 自动生成主键值
private Long id; // 书籍 ID
private String title; // 书名
private String author; // 作者
private int year; // 出版年份
private String genre; // 类型
// 默认构造函数
public Book() {}
// 带参构造函数
public Book(String title, String author, int year, String genre) {
this.title = title;
this.author = author;
this.year = year;
this.genre = genre;
}
// Getter 和 Setter 方法
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
}
BookRepository.java
:
package com.example.bookmanagement.repository;
import com.example.bookmanagement.model.Book; // 导入 Book 实体类
import org.springframework.data.jpa.repository.JpaRepository; // 导入 JPA 仓库接口
import org.springframework.stereotype.Repository; // 导入 Repository 注解
// BookRepository 接口,继承 JpaRepository,提供 CRUD 操作
@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
}
BookController.java
:
package com.example.bookmanagement.controller;
import com.example.bookmanagement.model.Book; // 导入 Book 实体类
import com.example.bookmanagement.repository.BookRepository; // 导入 BookRepository
import org.springframework.beans.factory.annotation.Autowired; // 导入自动注入注解
import org.springframework.http.ResponseEntity; // 导入 HTTP 响应实体类
import org.springframework.web.bind.annotation.*; // 导入 REST 控制器注解
import java.util.List; // 导入 List 类
import java.util.Optional; // 导入 Optional 类
// 定义 REST 控制器类,处理书籍相关请求
@RestController
@RequestMapping("/books") // 映射到 /books 路径
public class BookController {
@Autowired // 自动注入 BookRepository
private BookRepository bookRepository;
// 获取所有书籍信息
@GetMapping
public List<Book> getBooks() {
return bookRepository.findAll(); // 查询所有书籍并返回
}
// 添加新书籍
@PostMapping
public ResponseEntity<String> addBook(@RequestBody Book book) {
bookRepository.save(book); // 保存新书籍到数据库
return ResponseEntity.status(201).body("Book added successfully!"); // 返回成功消息
}
// 更新书籍信息
@PutMapping("/{id}")
public ResponseEntity<String> updateBook(@PathVariable Long id, @RequestBody Book bookDetails) {
Optional<Book> optionalBook = bookRepository.findById(id); // 查询指定 ID 的书籍
if (optionalBook.isPresent()) { // 如果书籍存在
Book book = optionalBook.get();
book.setTitle(bookDetails.getTitle()); // 更新书名
book.setAuthor(bookDetails.getAuthor()); // 更新作者
book.setYear(bookDetails.getYear()); // 更新出版年份
book.setGenre(bookDetails.getGenre()); // 更新类型
bookRepository.save(book); // 保存更新后的书籍
return ResponseEntity.ok("Book updated successfully!"); // 返回成功消息
} else {
return ResponseEntity.status(404).body("Book not found!"); // 如果书籍未找到,返回 404 错误
}
}
// 删除书籍
@DeleteMapping("/{id}")
public ResponseEntity<String> deleteBook(@PathVariable Long id) {
if (bookRepository.existsById(id)) { // 如果书籍存在
bookRepository.deleteById(id); // 删除书籍
return ResponseEntity.ok("Book deleted successfully!"); // 返回成功消息
} else {
return ResponseEntity.status(404).body("Book not found!"); // 如果书籍未找到,返回 404 错误
}
}
}
application.properties
:
# H2 Database 配置
spring.datasource.url=jdbc:h2:mem:testdb # 使用内存中的 H2 数据库
spring.datasource.driver-class-name=org.h2.Driver # H2 驱动
spring.datasource.username=sa # 数据库用户名
spring.datasource.password=password # 数据库密码
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect # JPA 方言
spring.h2.console.enabled=true # 启用 H2 控制台
在 src/main/resources/static 目录下创建一个名为 index.html 的文件。
index.html
:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Book Management Systemtitle>
<style>
body { font-family: Arial, sans-serif; }
table { width: 100%; border-collapse: collapse; margin: 20px 0; }
th, td { border: 1px solid #ddd; padding: 8px; }
th { background-color: #f4f4f4; }
form { margin: 20px 0; }
style>
head>
<body>
<h1>Book Management Systemh1>
<form id="bookForm">
<input type="hidden" id="bookId" />
<input type="text" id="title" placeholder="Title" required />
<input type="text" id="author" placeholder="Author" required />
<input type="number" id="year" placeholder="Year" required />
<input type="text" id="genre" placeholder="Genre" required />
<button type="submit">Add/Update Bookbutton>
form>
<table id="bookTable">
<thead>
<tr>
<th>IDth>
<th>Titleth>
<th>Authorth>
<th>Yearth>
<th>Genreth>
<th>Actionsth>
tr>
thead>
<tbody>tbody>
table>
<script>
const apiUrl = '/books'; // 后端 API 地址
// 获取所有书籍并显示在表格中
async function fetchBooks() {
const response = await fetch(apiUrl); // 发送 GET 请求
const books = await response.json(); // 解析 JSON 数据
const tbody = document.querySelector('#bookTable tbody');
tbody.innerHTML = ''; // 清空表格内容
books.forEach(book => {
const tr = document.createElement('tr');
tr.innerHTML = `
${book.id}
${book.title}
${book.author}
${book.year}
${book.genre}
`;
tbody.appendChild(tr); // 将新行添加到表格中
});
}
// 添加或更新书籍
async function addOrUpdateBook(event) {
event.preventDefault(); // 阻止表单默认提交
const id = document.querySelector('#bookId').value;
const title = document.querySelector('#title').value;
const author = document.querySelector('#author').value;
const year = document.querySelector('#year').value;
const genre = document.querySelector('#genre').value;
const data = { title, author, year, genre };
const method = id ? 'PUT' : 'POST'; // 如果有 ID 则更新,否则添加
const url = id ? `${apiUrl}/${id}` : apiUrl;
await fetch(url, {
method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data) // 发送 JSON 数据
});
document.querySelector('#bookForm').reset(); // 重置表单
document.querySelector('#bookId').value = ''; // 清空隐藏的 ID
fetchBooks(); // 刷新书籍列表
}
// 编辑书籍
async function editBook(id) {
const response = await fetch(`${apiUrl}/${id}`); // 获取指定 ID 的书籍
const book = await response.json(); // 解析 JSON 数据
document.querySelector('#bookId').value = book.id; // 设置隐藏的 ID
document.querySelector('#title').value = book.title; // 设置书名
document.querySelector('#author').value = book.author; // 设置作者
document.querySelector('#year').value = book.year; // 设置出版年份
document.querySelector('#genre').value = book.genre; // 设置类型
}
// 删除书籍
async function deleteBook(id) {
await fetch(`${apiUrl}/${id}`, { method: 'DELETE' }); // 发送 DELETE 请求
fetchBooks(); // 刷新书籍列表
}
// 监听表单提交事件
document.querySelector('#bookForm').addEventListener('submit', addOrUpdateBook);
fetchBooks(); // 页面加载时获取书籍列表
script>
body>
html>
1、启动 Spring Boot 应用: 在项目目录下运行以下命令启动应用:
./mvnw spring-boot:run
2、访问前端界面: 打开浏览器并访问 http://localhost:8080
,你将看到书籍管理系统的用户界面。
这段代码包括了一个简单的图书管理系统实现,涵盖了以下方面:
Java 后端
: 使用 Spring Boot 和 JPA 实现了 RESTful API,包括 CRUD 操作。数据库
:使用 H2 数据库进行书籍数据存储。前端
: 使用 HTML 和 JavaScript 创建了一个用户界面,能够进行添加、更新、删除和显示书籍操作。