# Spring Boot `CrudRepository` 教程

> 原文： [http://zetcode.com/springboot/crudrepository/](http://zetcode.com/springboot/crudrepository/)

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

Spring 是流行的 Java 应用框架。 Spring Boot 致力于以最小的努力创建独立的，基于生产级别的基于 Spring 的应用。

## Spring Data

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

使用 Spring Data，我们为应用中的每个域实体定义了一个存储库接口。 存储库包含用于执行 CRUD 操作，对数据进行排序和分页的方法。 `@Repository`是标记注解，指示基础接口是存储库。 通过扩展特定的存储库接口（例如`CrudRepository`，`PagingAndSortingRepository`或`JpaRepository`）来创建存储库。

Spring Data 已与 Spring MVC 控制器进行了高级集成，并提供了从存储库方法名称派生的动态查询。

## `CrudRepository`

`CrudRepository`实现基本的 CRUD 操作，包括`count`，`delte`，`deleteById`，`save`，`saveAll`，`findById`和`findAll`。

## Spring Boot `CrudRepository` 示例

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

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

```

这是项目结构。

`pom.xml`

```java
<?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
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zetcode</groupId>
    <artifactId>crudrepositoryex</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
    </parent>

    <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>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

```

这是 Maven 构建文件。 `spring-boot-starter-web`是使用 Spring MVC 构建 Web（包括 RESTful）应用的入门程序。 `spring-boot-starter-data-jpa`是将 Spring Data JPA 与 Hibernate 结合使用的入门工具。

`com/zetcode/model/User.java`

```java
package com.zetcode.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.Objects;

@Entity
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`

```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 {

    @Autowired
    private UserRepository userRepository;

    public List<User> findAll() {

        var it = userRepository.findAll();

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

        return users;
    }

    public Long count() {

        return userRepository.count();
    }

    public void deleteById(Long userId) {

        userRepository.deleteById(userId);
    }
}

```

这是服务类。 该类提供了三种方法来查找所有用户，对用户进行计数以及按 ID 删除用户。

```java
@Service
public class UserService {

```

在 Spring 中，服务类用`@Service`注解修饰。

```java
@Autowired
private UserRepository userRepository;

```

我们注入`UserRepository`。

```java
public List<User> findAll() {

    var it = userRepository.findAll();

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

    return users;
}

```

`findAll()`方法调用`userRepository`的`findAll()`方法并检索所有用户。

`com/zetcode/repository/UserRepository.java`

```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`

```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 {

    @Autowired
    private 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 格式返回。

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

    return userService.findAll();
}

```

为了获得所有用户，我们使用`@GetMapping`注解。

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

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

```

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

`com/zetcode/Application.java`

```java
package com.zetcode;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

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

```

`Application`设置 Spring Boot 应用。

`com/zetcode/MyRunner.java`

```java
package com.zetcode;

import com.zetcode.model.User;
import com.zetcode.repository.UserRepository;
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;

import javax.transaction.Transactional;

@Component
public class MyRunner implements CommandLineRunner {

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

    @Autowired
    private 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`中，我们为应用设置了数据。

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

```

我们创建一个新用户，并使用存储库的`save()`方法将其保存。

```java
$ 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`管理了应用数据。 您可能也对相关教程感兴趣： [Spring Boot 首次 Web 应用](/articles/springbootwebfirst/)， [Spring Boot 数据 JPA `@Query`教程](/springboot/datajpaquery/)， [Spring Boot 数据 JPA `@NamedQuery`教程](/springboot/datajpanamedquery/)， [独立的 Spring 应用](/articles/standalonespring/)和 [Java 教程](/lang/java/)。

列出[所有 Spring Boot 教程](/all/#springboot)。