ZetCode

Spring Boot CrudRepository

最后修改时间:2023年7月20日

SpringBoot CrudRepository 教程展示了如何在 Spring Boot 应用程序中使用 CrudRepository 管理数据。

Spring 是一个流行的 Java 应用程序框架。Spring Boot 旨在以最小的努力创建独立的、生产级的基于 Spring 的应用程序。

Spring Data

Spring Data 是一个基于 Spring 的数据访问编程模型。它减少了处理数据库和数据存储所需的代码量。它由几个模块组成。 Spring Data JPA 简化了使用 JPA 技术的 Spring 应用程序的开发。

使用 Spring Data,我们为应用程序中的每个域实体定义一个存储库接口。一个存储库包含用于执行 CRUD 操作、排序和分页数据的方法。@Repository 是一个标记注解,它指示基础接口是一个存储库。存储库是通过扩展特定的存储库接口创建的,例如 CrudRepositoryPagingAndSortingRepositoryJpaRepository

Spring Data 与 Spring MVC 控制器有高级集成,并提供从存储库方法名称动态派生查询的功能。

CrudRepository

CrudRepository 实现了基本的 CRUD 操作,包括 count、delete、deleteById、save、saveAll、findById 和 findAll。

Spring Boot CrudRepository 示例

以下 Spring Boot 应用程序使用 CrudRepository 管理一个 User 实体。 数据保存在 H2 数据库中。 我们使用一个 RESTful 控制器。

build.gradle
...
src
├───main
│   ├───java
│   │   └───com
│   │       └───zetcode
│   │           │   Application.java
│   │           │   MyRunner.java
│   │           ├───controller
│   │           │       MyController.java
│   │           ├───model
│   │           │       User.java
│   │           ├───repository
│   │           │       UserRepository.java
│   │           └───service
│   │                   UserService.java
│   └───resources
└───test
    ├── java
    └── resources

这是项目结构。

build.gradle
plugins {
    id 'org.springframework.boot' version '3.1.1'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'java'
}

group = 'com.zetcode'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'com.h2database:h2'
}

这是 Gradle 构建文件。 spring-boot-starter-web 是用于构建 Web(包括 RESTful)应用程序的启动器,使用 Spring MVC。 spring-boot-starter-data-jpa 是一个用于将 Spring Data JPA 与 Hibernate 一起使用的启动器。 h2 将 H2 测试数据库引入项目。

com/zetcode/model/User.java
package com.zetcode.model;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.util.Objects;

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String firstName;
    private String lastName;
    private String email;

    public User() {}

    public User(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {

        this.firstName = firstName;
    }

    public String getLastName() {

        return lastName;
    }

    public void setLastName(String lastName) {

        this.lastName = lastName;
    }

    public String getEmail() {

        return email;
    }

    public void setEmail(String email) {

        this.email = email;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(id, user.id) &&
                Objects.equals(firstName, user.firstName) &&
                Objects.equals(lastName, user.lastName) &&
                Objects.equals(email, user.email);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, firstName, lastName, email);
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("User{");
        sb.append("id=").append(id);
        sb.append(", firstName='").append(firstName).append('\'');
        sb.append(", lastName='").append(lastName).append('\'');
        sb.append(", email='").append(email).append('\'');
        sb.append('}');
        return sb.toString();
    }
}

这是 User 实体。

com/zetcode/service/UserService.java
package com.zetcode.service;

import com.zetcode.model.User;
import com.zetcode.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserService {

    private final UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public List<User> findAll() {

        var it = userRepository.findAll();

        var users = new ArrayList<User>();
        it.forEach(users::add);

        return users;
    }

    public Long count() {

        return userRepository.count();
    }

    public void deleteById(Long userId) {

        userRepository.deleteById(userId);
    }
}

这是服务类。该类提供了三种方法,用于查找所有用户、计算用户数量以及按 Id 删除用户。

@Service
public class UserService {

服务类用 Spring 中的 @Service 注解修饰。

private final UserRepository userRepository;

@Autowired
public UserService(UserRepository userRepository) {
    this.userRepository = userRepository;
}

我们注入 UserRepository

public List<User> findAll() {

    var it = userRepository.findAll();

    var users = new ArrayList<User>();
    it.forEach(e -> users.add(e));

    return users;
}

findAll 方法调用 userRepositoryfindAll 方法并检索所有用户。

com/zetcode/repository/UserRepository.java
package com.zetcode.repository;

import com.zetcode.model.User;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends CrudRepository<User, Long> {
}

UserRepository 继承自 CrudRepository。 它提供了实体的类型及其主键的类型。

com/zetcode/controller/MyController.java
package com.zetcode.controller;

import com.zetcode.model.User;
import com.zetcode.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class MyController {

    private final UserService userService;

    @Autowired
    public MyController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/users")
    public List<User> allUsers() {

        return userService.findAll();
    }

    @GetMapping("/users/count")
    public Long count() {

        return userService.count();
    }

    @DeleteMapping("/users/{id}")
    public void delete(@PathVariable String id) {

        Long userId = Long.parseLong(id);
        userService.deleteById(userId);
    }
}

控制器类为三个请求提供映射。 我们可以获取所有用户、计算用户数量以及按其 ID 删除用户。 数据以 JSON 格式返回。

@GetMapping("/users")
public List<User> allUsers() {

    return userService.findAll();
}

对于获取所有用户,我们使用 @GetMapping 注解。

@DeleteMapping("/users/{id}")
public void delete(@PathVariable String id) {

    Long userId = Long.parseLong(id);
    userService.deleteById(userId);
}

我们使用 @DeleteMapping 删除特定用户。

com/zetcode/MyRunner.java
package com.zetcode;

import com.zetcode.model.User;
import com.zetcode.repository.UserRepository;
import jakarta.transaction.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyRunner implements CommandLineRunner {

    private static final Logger logger = LoggerFactory.getLogger(MyRunner.class);

    private final UserRepository userRepository;

    @Autowired
    public MyRunner(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    @Transactional
    public void run(String... args) throws Exception {

        logger.info("initializing users");

        var u1 = new User("Paul", "Smith", "paul.smith@gmail.com");
        userRepository.save(u1);

        var u2 = new User("Robert", "Black", "rb34@gmail.com");
        userRepository.save(u2);

        var u3 = new User("John", "Doe", "jdoe@gmail.com");
        userRepository.save(u3);
    }
}

MyRunner 中,我们为应用程序设置数据。

var u1 = new User("Paul", "Smith", "paul.smith@gmail.com");
userRepository.save(u1);

我们创建一个新用户,并使用存储库的 save 方法保存它。

com/zetcode/Application.java
package com.zetcode;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

`Application` 设置了 Spring Boot 应用程序。

$ ./gradlew bootRun

我们启动应用程序。

$ curl localhost:8080/users
[{"id":1,"firstName":"Paul","lastName":"Smith","email":"paul.smith@gmail.com"},
{"id":2,"firstName":"Robert","lastName":"Black","email":"rb34@gmail.com"},
{"id":3,"firstName":"John","lastName":"Doe","email":"jdoe@gmail.com"}]

我们使用 curl 工具测试应用程序。

在本文中,我们使用 CrudRepository 管理了我们的应用程序数据。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出 所有 Spring Boot 教程