Spring Data – CrudRepository save() Method – Spring Data – CrudRepository save()方法

最后修改: 2018年 9月 15日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

CrudRepository is a Spring Data interface for generic CRUD operations on a repository of a specific type. It provides several methods out of the box for interacting with a database.

CrudRepository是一个Spring Data接口,用于对特定类型的资源库进行通用的CRUD操作。它提供了几种与数据库交互的方法。

In this tutorial, we’ll explain how and when to use the CrudRepository save() method.

在本教程中,我们将解释如何以及何时使用CrudRepository save()方法。

To learn more about Spring Data repositories, take a look at our article that compares CrudRepository to other repository interfaces of the framework.

要了解有关 Spring Data 存储库的更多信息,请看我们的文章,该文章将CrudRepository与框架的其他存储库接口进行了对比。

2. Dependencies

2.依赖性

We’ll have to add Spring Data and H2 database dependencies to our pom.xml file:

我们必须将Spring DataH2数据库依赖关系添加到我们的pom.xml文件。

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

3. Example Application

3.应用实例

First, let’s create our Spring Data entity called MerchandiseEntity. This class will define the data types that will get persisted to the database when we call the save() method:

首先,让我们创建名为MerchandiseEntity的Spring Data实体。这个类将定义数据类型,当我们调用save()方法时,这些数据将被持久化到数据库中。

@Entity
public class MerchandiseEntity {
 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private double price;

    private String brand;

    public MerchandiseEntity() {
    }

    public MerchandiseEntity(String brand, double price) {
        this.brand = brand;
        this.price = price;
    }
}

Next let’s create a CrudRepository interface to work with the MerchandiseEntity:

接下来,让我们创建一个CrudRepository接口,与MerchandiseEntity一起工作。

@Repository
public interface InventoryRepository 
  extends CrudRepository<MerchandiseEntity, Long> {
}

Here we specify the entity’s class and the entity id’s class, MerchandiseEntity and Long. When an instance of this repository is instantiated, the underlying logic will automatically be in place for working with our MerchandiseEntity class.

在这里我们指定了实体的类和实体ID的类,MerchandiseEntityLong。当这个资源库的实例被实例化时,底层逻辑将自动到位,以便与我们的MerchandiseEntity类一起工作。

So with very little code, we’re already able to start using the save() method.

因此,只需很少的代码,我们就已经能够开始使用save()方法。

4. CrudRepository save() to Add a New Instance

4.CrudRepository save()添加一个新实例

Let’s create a new instance of MerchandiseEntity and save it to the database using the InventoryRepository:

让我们创建一个新的MerchandiseEntity实例,并使用InventoryRepository将其保存到数据库。

InventoryRepository repo = context
  .getBean(InventoryRepository.class);

MerchandiseEntity pants = new MerchandiseEntity(
  "Pair of Pants", BigDecimal.ONE);
pants = repo.save(pants);

Running this will create a new entry in the database table for MerchandiseEntity. Notice that we never specified an id. The instance is initially created with a null value for its id, and when we call the save() method, an id is automatically generated.

运行这个程序将在数据库表中为MerchandiseEntity创建一个新条目。请注意,我们从未指定一个id。该实例最初创建时,其id值为空,当我们调用save() 方法时,id会自动生成。

The save() method returns the saved entity, including the updated id field.

save() 方法返回保存的实体,包括更新的id字段。

5. CrudRepository save() to Update an Instance

5.CrudRepository save() 更新一个实例

We can use the same save() method to update an existing entry in our database. Suppose we saved a MerchandiseEntity instance with a specific title:

我们可以使用同样的save()方法来更新我们数据库中的现有条目。假设我们保存了一个带有特定标题的MerchandiseEntity实例。

MerchandiseEntity pants = new MerchandiseEntity(
  "Pair of Pants", 34.99);
pants = repo.save(pants);

Later, we found that we wanted to update the price of the item. We could then simply get the entity from the database, make the change, and use the save() method as before.

后来,我们发现我们想更新该物品的价格。然后我们可以简单地从数据库中获取实体,进行更改,并像以前一样使用save()方法。

Assuming we know the id of the item (pantsId), we can use the CRUDRepository method findById to get our entity from the database:

假设我们知道项目的idpantsId),我们可以使用CRUDRepository方法findById从数据库中获取实体。

MerchandiseEntity pantsInDB = repo.findById(pantsId).get(); 
pantsInDB.setPrice(44.99); 
repo.save(pantsInDB);

Here we’ve updated our original entity with a new price and saved the changes back to the database.

在这里,我们用一个新的价格更新了我们的原始实体,并将变化保存回数据库。

We need to keep in mind that calling save() to update an object inside a transactional method is not mandatory.

我们需要记住,交易方法内调用save()来更新一个对象不是强制性的

When we use findById() to retrieve an entity within a transactional method, the returned entity is managed by the persistence provider. So, any change to that entity will be automatically persisted in the database, regardless of whether we are invoking the save() method. Now, let’s create a simple test case to confirm this:

当我们使用findById()在事务性方法中检索一个实体时,返回的实体是由持久化提供者管理的。因此,对该实体的任何更改都将自动持久化在数据库中,无论我们是否调用save()方法。现在,让我们创建一个简单的测试案例来确认这一点。

@Test
@Transactional
public void shouldUpdateExistingEntryInDBWithoutSave() {
    MerchandiseEntity pants = new MerchandiseEntity(
      ORIGINAL_TITLE, BigDecimal.ONE);
    pants = repository.save(pants);

    Long originalId = pants.getId();

    // Update using setters
    pants.setTitle(UPDATED_TITLE);
    pants.setPrice(BigDecimal.TEN);
    pants.setBrand(UPDATED_BRAND);

    Optional<MerchandiseEntity> resultOp = repository.findById(originalId);

    assertTrue(resultOp.isPresent());
    MerchandiseEntity result = resultOp.get();

    assertEquals(originalId, result.getId());
    assertEquals(UPDATED_TITLE, result.getTitle());
    assertEquals(BigDecimal.TEN, result.getPrice());
    assertEquals(UPDATED_BRAND, result.getBrand());
}

6. Conclusion

6.结论

In this brief article, we covered the use of CrudRepository‘s save() method. We can use this method to add a new entry into our database, as well as to update an existing one.

在这篇简短的文章中,我们介绍了CrudRepository的save()方法的使用。我们可以使用这个方法在我们的数据库中添加一个新条目,也可以更新一个现有的条目。

As usual, the code for the article is over on GitHub.

像往常一样,文章的代码在GitHub上