# Spring Boot Crud 操作示例与 Hibernate

> 原文： [https://howtodoinjava.com/spring-boot2/spring-boot-crud-hibernate/](https://howtodoinjava.com/spring-boot2/spring-boot-crud-hibernate/)

学习在 [**spring boot**](https://howtodoinjava.com/spring-boot-tutorials/) 应用程序中为 **CURD 操作**创建 api / 方法，该应用程序使用 [**Hibernate**](https://howtodoinjava.com/hibernate-tutorials/) / jpa 持久性 api 修改数据库中的数据。

## 1\. 概述

在此示例中，我们将创建原始操作并通过 [REST API](http://restfulapi.net/) 公开它们，以便 UI 客户端可以调用这些操作。 演示操作使客户端能够修改数据库中的员工记录。

该演示的目的是展示使这些交互成为可能的细节，而不涉及现实应用中涉及的业务逻辑的复杂性。

## 2\. Maven 依赖

在此示例中，我们使用 maven 在项目中添加运行时 jar。 如果您使用 gradle，请查找相关的依赖项。

`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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.howtodoinjava.demo</groupId>
    <artifactId>SpringBoot2Demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringBoot2Demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </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>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </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>

```

*   `spring-boot-starter-web`：用于使用 Spring MVC 构建 Web 层，包括 REST API 和应用程序。 使用 Tomcat 作为默认的嵌入式容器。
*   `spring-boot-starter-data-jpa`：它包括 spring 数据，hibernate，HikariCP，[JPA API](https://howtodoinjava.com/jpa-tutorials-and-examples/) ，**JPA 实现（默认为 Hibernate）**，JDBC 和其他必需的库。
*   `h2`：尽管我们可以使用`application.properties`文件中的数据源属性轻松添加任何数据库，但我们仍在使用 h2 数据库来减少不必要的复杂性。
*   `spring-boot-starter-test`：用于通过包含 [JUnit](https://howtodoinjava.com/junit-4/)，Hamcrest 和 [Mockito](https://howtodoinjava.com/mockito/junit-mockito-example/) 的库来测试 Spring Boot 应用程序。

## 3\. Hibernate 配置

#### 3.1. 实体和存储库

使用数据库中数据的第一步是在 JPA 实体类中对其结构建模，并为其创建存储库接口。

尽可能扩展`JpaRepository`接口，以允许在运行时为任何给定的实体类自动创建存储库实现。 实体类别的类型及其 ID 字段在`JpaRepository`的通用参数中指定。

请记住，仅包含 JPA API 注解（`javax.persistence.*`）可使 Hibernate 与应用程序代码脱钩。

`EmployeeEntity.java`

```java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="TBL_EMPLOYEES")
public class EmployeeEntity {

    @Id
    @GeneratedValue
    private Long id;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    @Column(name="email", nullable=false, length=200)
    private String email;

    //Setters and getters

    @Override
    public String toString() {
        return "EmployeeEntity [id=" + id + ", firstName=" + firstName + 
                ", lastName=" + lastName + ", email=" + email   + "]";
    }
}

```

`EmployeeRepository.java`

```java
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.howtodoinjava.demo.entity.EmployeeEntity;

@Repository
public interface EmployeeRepository 
        extends JpaRepository<EmployeeEntity, Long> {

}

```

#### 3.2. 数据源配置

要连接到数据库，我们必须配置数据源。 我们正在使用 H2 数据库，因此将使用各自的属性。

另外，我们使用了几个其他属性来启用 [H2](https://howtodoinjava.com/spring-boot2/h2-database-example/) 控制台和大量日志记录。

`application.properties`

```java
spring.datasource.url=jdbc:h2:file:~/test
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

# Enabling H2 Console
spring.h2.console.enabled=true

# Custom H2 Console URL
spring.h2.console.path=/h2-console

# create database schema from SQL files
spring.jpa.hibernate.ddl-auto=none

#Turn Statistics on and log SQL stmts
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.generate_statistics=false
#logging.level.org.hibernate.type=trace
#logging.level.org.hibernate.stat=debug

logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%n

```

## 4\. 服务（使用存储库）

服务层是可选的 – 仍然建议执行其他业务逻辑（如果有）。 通常，我们将在此处与存储库连接以进行原始操作。

`EmployeeService.java`

```java
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.howtodoinjava.demo.entity.EmployeeEntity;
import com.howtodoinjava.demo.exception.RecordNotFoundException;
import com.howtodoinjava.demo.repository.EmployeeRepository;

@Service
public class EmployeeService {

    @Autowired
    EmployeeRepository repository;

    public List<EmployeeEntity> getAllEmployees()
    {
        List<EmployeeEntity> employeeList = repository.findAll();

        if(employeeList.size() > 0) {
            return employeeList;
        } else {
            return new ArrayList<EmployeeEntity>();
        }
    }

    public EmployeeEntity getEmployeeById(Long id) throws RecordNotFoundException 
    {
        Optional<EmployeeEntity> employee = repository.findById(id);

        if(employee.isPresent()) {
            return employee.get();
        } else {
            throw new RecordNotFoundException("No employee record exist for given id");
        }
    }

    public EmployeeEntity createOrUpdateEmployee(EmployeeEntity entity) throws RecordNotFoundException 
    {
        Optional<EmployeeEntity> employee = repository.findById(entity.getId());

        if(employee.isPresent()) 
        {
            EmployeeEntity newEntity = employee.get();
            newEntity.setEmail(entity.getEmail());
            newEntity.setFirstName(entity.getFirstName());
            newEntity.setLastName(entity.getLastName());

            newEntity = repository.save(newEntity);

            return newEntity;
        } else {
            entity = repository.save(entity);

            return entity;
        }
    } 

    public void deleteEmployeeById(Long id) throws RecordNotFoundException 
    {
        Optional<EmployeeEntity> employee = repository.findById(id);

        if(employee.isPresent()) 
        {
            repository.deleteById(id);
        } else {
            throw new RecordNotFoundException("No employee record exist for given id");
        }
    } 
}

```

## 5\. REST 控制器

最后，通过 MVC URL 或 REST 端点公开所有操作。 客户将与这些端点连接以获取/更新/删除员工记录。

请注意注解`@RestController`，`@RequestMapping`，[`@GetMapping`](https://howtodoinjava.com/spring5/webmvc/controller-getmapping-postmapping/)，`@PostMapping`和`@DeleteMapping`，它们将各种 URI 映射到控制器方法。

`EmployeeController.java`

```java
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.howtodoinjava.demo.entity.EmployeeEntity;
import com.howtodoinjava.demo.exception.RecordNotFoundException;
import com.howtodoinjava.demo.service.EmployeeService;

@RestController
@RequestMapping("/employees")
public class EmployeeController 
{
    @Autowired
    EmployeeService service;

    @GetMapping
    public ResponseEntity<List<EmployeeEntity>> getAllEmployees() {
        List<EmployeeEntity> list = service.getAllEmployees();

        return new ResponseEntity<List<EmployeeEntity>>(list, new HttpHeaders(), HttpStatus.OK);
    }

    @GetMapping("/{id}")
    public ResponseEntity<EmployeeEntity> getEmployeeById(@PathVariable("id") Long id) 
                                                    throws RecordNotFoundException {
        EmployeeEntity entity = service.getEmployeeById(id);

        return new ResponseEntity<EmployeeEntity>(entity, new HttpHeaders(), HttpStatus.OK);
    }

    @PostMapping
    public ResponseEntity<EmployeeEntity> createOrUpdateEmployee(EmployeeEntity employee)
                                                    throws RecordNotFoundException {
        EmployeeEntity updated = service.createOrUpdateEmployee(employee);
        return new ResponseEntity<EmployeeEntity>(updated, new HttpHeaders(), HttpStatus.OK);
    }

    @DeleteMapping("/{id}")
    public HttpStatus deleteEmployeeById(@PathVariable("id") Long id) 
                                                    throws RecordNotFoundException {
        service.deleteEmployeeById(id);
        return HttpStatus.FORBIDDEN;
    }

}

```

## 6\. Spring Boot Crud 操作演示

现在，完成编码部分后，启动 spring boot 应用程序。 它将与 H2 数据库控制台一起使用所有 URL 端点。

*   `HTTP GET http://localhost:8080/employees`

    `Console`

    ```java
    Hibernate: 
        select
            employeeen0_.id as id1_0_,
            employeeen0_.email as email2_0_,
            employeeen0_.first_name as first_na3_0_,
            employeeen0_.last_name as last_nam4_0_ 
        from
            tbl_employees employeeen0_

    ```

    `API Response`

    ```java
    [
        {
            "id": 1,
            "firstName": "Lokesh",
            "lastName": "Gupta",
            "email": "abc@gmail.com"
        },
        {
            "id": 2,
            "firstName": "Deja",
            "lastName": "Vu",
            "email": "xyz@email.com"
        },
        {
            "id": 3,
            "firstName": "Caption",
            "lastName": "America",
            "email": "cap@marvel.com"
        }
    ]

    ```

*   `HTTP GET http://localhost:8080/employees/2`

    `Console`

    ```java
    Hibernate: 
        select
            employeeen0_.id as id1_0_0_,
            employeeen0_.email as email2_0_0_,
            employeeen0_.first_name as first_na3_0_0_,
            employeeen0_.last_name as last_nam4_0_0_ 
        from
            tbl_employees employeeen0_ 
        where
            employeeen0_.id=?

    ```

    `API Response`

    ```java
    {
        "id": 2,
        "firstName": "Deja",
        "lastName": "Vu",
        "email": "xyz@email.com"
    }

    ```

在有关**在具有 JPA Hibernate**来管理后端数据更新的 Spring Boot 应用程序中创建和公开 CRUD 操作的注解中，向您提问。

学习愉快！

[下载源码](https://howtodoinjava.com/wp-content/downloads/spring-boot-hibernate-crud-demo.zip)