一 什么是 Spring Data JPA
Spring Data JPA 是 Spring 框架的一个子项目,它简化了基于 JPA (Java Persistence API) 的数据访问层开发。它通过提供一套抽象接口,减少了开发者编写重复性的数据访问代码的工作量,使开发者可以专注于业务逻辑而非数据访问细节。
Spring Data JPA 的核心优势:
- 减少样板代码,通过继承接口即可获得基本的 CRUD 操作
- 支持通过方法名自动生成查询语句
- 提供分页、排序等常见数据访问功能
- 与 Spring 生态完美集成
二 环境搭建
1 创建 Maven 项目并添加依赖
首先创建一个 Maven 项目,项目名为SpringDataJPA-Demo,在 pom.xml
中添加以下依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.yqd</groupId><artifactId>SpringDataJPA-Demo</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><name>SpringDataJPA-Demo</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.20</version><scope>provided</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
2 配置数据库连接
在 src/main/resources
目录下创建 application.yml
文件:
spring:datasource:url: jdbc:mysql://localhost:3306/springbootdata?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&characterEncoding=utf-8username: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driverjpa:show-sql: true
3 导入数据库
-- 创建数据库并设置字符集
CREATE DATABASE IF NOT EXISTS springbootdata;
CHARACTER SET utf8;
COLLATE utf8_unicode_ci;-- 使用该数据库
USE springbootdata;-- 创建书籍表(如果不存在)
CREATE TABLE IF NOT EXISTS books (id BIGINT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(200) NOT NULL,author VARCHAR(100) NOT NULL,press VARCHAR(100),status VARCHAR(20)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
三 代码实现
1. Book 实体类
package com.yqd.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.persistence.*;@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "books")
public class Book {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;@Column(nullable = false, length = 200)private String name;@Column(nullable = false, length = 100)private String author;@Column(length = 100)private String press;@Column(length = 20)private String status;
}
2. BookRepository 接口
package com.yqd.repository;import com.yqd.entity.Book;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;import java.util.List;@Repository
public interface BookRepository extends JpaRepository<Book, Integer> {// 根据作者查询书籍List<Book> findByAuthor(String author);// 根据状态查询书籍List<Book> findByStatus(String status);// 根据出版社查询书籍List<Book> findByPress(String press);// 根据作者和状态查询书籍List<Book> findByAuthorAndStatus(String author,String status);@Modifying@Query("delete from Book b where b.id = :id")List<Book> deleteBookById(@Param("id") Integer id);
}
3. BookService 服务类
package com.yqd.service;import com.yqd.entity.Book;
import com.yqd.repository.BookRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.Optional;@Service
public class BookService {@Autowiredprivate BookRepository bookRepository;// 创建书籍public Book createBook(Book book) {return bookRepository.save(book);}// 获取所有书籍public List<Book> getAllBooks() {return bookRepository.findAll();}// 根据ID获取书籍public Optional<Book> getBookById(Integer id) {return bookRepository.findById(id);}// 更新书籍public Book updateBook(Integer id, Book bookDetails) {return bookRepository.findById(id).map(book -> {book.setName(bookDetails.getName());book.setAuthor(bookDetails.getAuthor());book.setPress(bookDetails.getPress());book.setStatus(bookDetails.getStatus());return bookRepository.save(book);}).orElseThrow(() -> new RuntimeException("Book not found with id: " + id));}// 删除书籍public void deleteBook(Integer id) {bookRepository.deleteById(id);}// 根据作者查询书籍public List<Book> getBooksByAuthor(String author) {return bookRepository.findByAuthor(author);}// 根据状态查询书籍public List<Book> getBooksByStatus(String status) {return bookRepository.findByStatus(status);}// 根据出版社查询书籍public List<Book> getBooksByPress(String press) {return bookRepository.findByPress(press);}
}
4. BookController 控制器
package com.yqd.controller;import com.yqd.entity.Book;
import com.yqd.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;import java.util.List;
import java.util.Optional;@RestController
@RequestMapping("/api/books")
public class BookController {@Autowiredprivate BookService bookService;// 创建书籍@PostMappingpublic ResponseEntity<Book> createBook(@RequestBody Book book) {Book createdBook = bookService.createBook(book);return new ResponseEntity<>(createdBook, HttpStatus.CREATED);}// 获取所有书籍@GetMappingpublic ResponseEntity<List<Book>> getAllBooks() {List<Book> books = bookService.getAllBooks();return new ResponseEntity<>(books, HttpStatus.OK);}// 根据ID获取书籍@GetMapping("/{id}")public ResponseEntity<Book> getBookById(@PathVariable Integer id) {Optional<Book> book = bookService.getBookById(id);return book.map(ResponseEntity::ok).orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));}// 更新书籍@PutMapping("/{id}")public ResponseEntity<Book> updateBook(@PathVariable Integer id, @RequestBody Book bookDetails) {try {Book updatedBook = bookService.updateBook(id, bookDetails);return new ResponseEntity<>(updatedBook, HttpStatus.OK);} catch (RuntimeException e) {return new ResponseEntity<>(HttpStatus.NOT_FOUND);}}// 删除书籍@DeleteMapping("/{id}")public ResponseEntity<Void> deleteBook(@PathVariable Integer id) {bookService.deleteBook(id);return new ResponseEntity<>(HttpStatus.NO_CONTENT);}// 根据作者查询书籍@GetMapping("/author/{author}")public ResponseEntity<List<Book>> getBooksByAuthor(@PathVariable String author) {List<Book> books = bookService.getBooksByAuthor(author);return new ResponseEntity<>(books, HttpStatus.OK);}// 根据状态查询书籍@GetMapping("/status/{status}")public ResponseEntity<List<Book>> getBooksByStatus(@PathVariable String status) {List<Book> books = bookService.getBooksByStatus(status);return new ResponseEntity<>(books, HttpStatus.OK);}// 根据出版社查询书籍@GetMapping("/press/{press}")public ResponseEntity<List<Book>> getBooksByPress(@PathVariable String press) {List<Book> books = bookService.getBooksByPress(press);return new ResponseEntity<>(books, HttpStatus.OK);}
}
5. 主应用类
package com.yqd;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringDataJPADemo
{public static void main(String[] args) {SpringApplication.run(SpringDataJPADemo.class, args);}
}
四 测试 API
应用启动后,可以使用以下 API 进行测试:
-
创建书籍:
POST /api/books
{"name": "楚辞","author": "屈原","press": "中国文联出版社","status": "0" }{"name": "纳兰词","author": "纳兰性德","press": "中国文联出版社","status": "1" }{"name": "西游记","author": "吴承恩","press": "中国文联出版社","status": "2" }
-
获取所有书籍:
GET /api/books
-
根据 ID 获取书籍:
GET /api/books/1
-
更新书籍:
PUT /api/books/1
-
删除书籍:
DELETE /api/books/1
-
按作者查询:
GET /api/books/author/李四
-
按状态查询:
GET /api/books/status/已借出
-
按出版社查询:
GET /api/books/press/编程出版社
-
按作者与状态查询: