簡體   English   中英

Spring Data JPA findOne() 更改為 Optional 如何使用?

[英]Spring Data JPA findOne() change to Optional how to use this?

我正在用Java8學習SpringBoot2.0

我遵循了一些博客制作教程示例。

教程源代碼為:

@GetMapping("/{id}/edit")
public String edit(@PathVariable Long id, Model model) {
  model.addAttribute("categoryDto", categoryService.findOne(id));
  return "category/edit";
}

但是這段代碼拋出了這個錯誤:

categoryService.findOne(id)

我正在考慮將 JPA findOne()方法更改為Optional< S >

如何解決?

更多信息:

這是 categoryService 方法:

public Category findOne(Long id) {
  return categoryRepository.findOne(id);
}

至少從2.0版本開始, Spring-Data-Jpa修改了findOne()
現在, findOne()既沒有相同的簽名,也沒有相同的行為。
以前,它在CrudRepository接口中定義為:

T findOne(ID primaryKey);

現在,您將在CrudRepository找到的單個findOne()方法是在QueryByExampleExecutor接口中定義的QueryByExampleExecutor

<S extends T> Optional<S> findOne(Example<S> example);

這最終由SimpleJpaRepository實現,它是CrudRepository接口的默認實現。
此方法是按示例搜索查詢,您不希望將其作為替代。

實際上,在新的 API 中,行為相同的方法仍然存在,只是方法名稱發生了變化。
它在CrudRepository接口中從findOne()重命名為findById()

Optional<T> findById(ID id); 

現在它返回一個Optional ,這對於防止NullPointerException來說還不錯。

因此,調用的實際方法現在是Optional<T> findById(ID id)

怎么用那個?
學習Optional用法。 以下是有關其規格的重要信息:

可能包含也可能不包含非空值的容器對象。 如果存在值,isPresent() 將返回 true,get() 將返回該值。

提供了依賴於所包含值的存在與否的其他方法,例如 orElse()(如果值不存在則返回默認值)和 ifPresent()(如果該值存在則執行代碼塊)。


關於如何將OptionalOptional<T> findById(ID id)一起使用的一些提示。

通常,當您按 id 查找實體時,您希望返回它或在未檢索到的情況下進行特定處理。

以下是三個經典用法示例。

  1. 假設如果找到實體,您想要獲取它,否則您想要獲取默認值。

你可以寫:

Foo foo = repository.findById(id)
                    .orElse(new Foo());

或者在有意義的情況下獲取null默認值(與 API 更改之前的行為相同):

Foo foo = repository.findById(id)
                    .orElse(null);
  1. 假設如果找到實體你想返回它,否則你想拋出一個異常。

你可以寫:

return repository.findById(id)
        .orElseThrow(() -> new EntityNotFoundException(id));
  1. 假設您想根據是否找到實體來應用不同的處理(不必拋出異常)。

你可以寫:

Optional<Foo> fooOptional = fooRepository.findById(id);
if (fooOptional.isPresent()) {
    Foo foo = fooOptional.get();
    // processing with foo ...
} else {
    // alternative processing....
}

該方法已重命名為findById(…)返回一個Optional以便您必須自己處理缺席:

Optional<Foo> result = repository.findById(…);

result.ifPresent(it -> …); // do something with the value if present
result.map(it -> …); // map the value if present
Foo foo = result.orElse(null); // if you want to continue just like before

我總是在廣泛使用的 CrudRepository 存儲庫/接口中編寫一個默認方法“findByIdOrError”

@Repository 
public interface RequestRepository extends CrudRepository<Request, Integer> {

    default Request findByIdOrError(Integer id) {
        return findById(id).orElseThrow(EntityNotFoundException::new);
    } 
}

事實上,在最新版本的 Spring Data 中, findOne 返回一個可選的。 如果要從 Optional 中檢索對象,只需在 Optional 上使用 get() 即可。 但是,首先,存儲庫應該將可選項返回給服務,然后服務處理可選項為空的情況。 之后,服務應該將對象返回給控制器。

Optional api 提供了獲取值的方法。 您可以檢查isPresent()的價值的存在,然后撥打電話,以get()或者你可以撥打電話,以get()與鏈orElse()並提供一個默認值。

您可以嘗試做的最后一件事是在自定義方法上使用@Query()

考慮一個User實體和UserRepository 在如下服務包代碼中。

Optional<User> resultUser = UserRepository.findById(userId);  //return Optional

User createdUser = resultUser.get();  //return User

現在您可以使用 getter 訪問所有用戶實體屬性。

createdUser.getId(); 
createdUser.getName();

像那樣。

自 Spring Data Commons 2.0 版以來,CrudRepository 接口的 findOne 方法已被 findById 取代。 您將 findOne(id) 替換為: findById(id).orElse(null)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM