简体   繁体   English

(Spring boot) Optional<> Class 可以像 List<> Class 吗?

[英](Spring boot) can Optional<> Class be like List<> Class?

Im trying to put the RoomEntity Class in the List as its generic parameter but the List Class turns red(Error) and the only thing that it suggests is for me to change the List Class to Optional Class.我试图将 RoomEntity 类放在列表中作为其通用参数,但列表类变为红色(错误),它建议我将列表类更改为可选类。

public interface RoomRepository extends CrudRepository<RoomEntity, Long> {
    List<RoomEntity> findById(Long id);
}

RoomEntity Class房间实体类

@Entity
@Table(name = "Room")
public class RoomEntity {

}

are they the same?他们是一样的吗?

List<RoomEntity> findById(Long id); 
Optional<RoomEntity> findById(Long id);

Spring data JPA will fit the query result to your desired container Spring data JPA 将使查询结果适合您所需的容器

You ask a List<> , Spring will initialize a list and add any row data to that list and return it for you.您询问List<> ,Spring 将初始化一个列表并将任何行数据添加到该列表并为您返回。 Hence it will:因此它将:

  1. Return empty list if no items found如果没有找到项目,则返回空列表
  2. Return populated list if items found如果找到项目,则返回填充列表

When you ask an Optional<> , Spring will understand that you want at most one row data.当您询问Optional<> ,Spring 会理解您最多需要一行数据。 It will interpreted as getSingleResult() on javax.persistence.Query .它将解释为javax.persistence.Query上的getSingleResult() Hence it will:因此它将:

  1. Return Optional.empty() if no items found如果没有找到项目,则返回Optional.empty()

  2. Return Optional.of(result) if exactly one match如果完全匹配,则返回Optional.of(result)

  3. Throw exceptions if there are more than one match (The one I remember is NonUniqueResultException )如果有多个匹配项,则抛出异常(我记得的是NonUniqueResultException

In your case, you find by id .在您的情况下,您可以通过id找到。 It's unique on your table so Optional<> should fit your purpose.它在你的桌子上是独一无二的,所以Optional<>应该适合你的目的。

But note that your List<RoomEntity> findById(Long id);但请注意,您的List<RoomEntity> findById(Long id); definition is correct and it won't give you compiler error (turn red).定义是正确的,它不会给你编译错误(变成红色)。 Have you imported the List interface?你有没有导入List界面?

Optional and List are two very different concepts. Optional 和 List 是两个截然不同的概念。

The CrudRepository findAllById method returns an Iterable. CrudRepository findAllById 方法返回一个 Iterable。 The findById method returns an Optional. findById 方法返回一个 Optional。

An iterable can be used to access one by one the elements of a collection and so can be used in conjunction with the List class.可迭代对象可用于一个一个访问集合的元素,因此可以与 List 类结合使用。

An Optional is a container object which may or may not contain a non-null value (zero or one elements). Optional 是一个容器对象,它可能包含也可能不包含非空值(零或一个元素)。 This will have a single element in it, not many elements like in a List, if there is one.这将有一个元素,而不是像 List 中的很多元素,如果有的话。

The CrudRepository::findAllById can have more than one ID sent to it and so can return more than one element, the way it does this is to return an iterable you can use to select each of the returned results one by one. CrudRepository::findAllById 可以有多个 ID 发送给它,因此可以返回多个元素,它这样做的方式是返回一个可迭代对象,您可以使用它来逐个选择每个返回的结果。 The findById method can only be sent a single ID and so returns that element if it is present (wrapped in an Optional), or an Optional.none if it is not. findById 方法只能发送一个 ID,因此如果该元素存在(包装在 Optional 中),则返回该元素,否则返回 Optional.none。

If you are looking for a list to be returned because you intend to send in multiple IDs then use the findAllById method.如果您正在寻找要返回的列表,因为您打算发送多个 ID,请使用 findAllById 方法。 If you want a specific element by ID only, then use the findById method but then you will have to unwrap the Optional object it is returned in before you can use it outside of a stream pipeline using Optional.get, Optional.isPresent, or using a map or flatmap call over it in a streams pipeline.如果您只需要 ID 的特定元素,则使用 findById 方法,但是您必须先解开它返回的 Optional 对象,然后才能使用 Optional.get、Optional.isPresent 或使用它在流管道之外使用它在流管道中对其进行 map 或 flatmap 调用。

The findById method is supposed to look for a single entity by it's id. findById 方法应该通过它的 id 查找单个实体。 After all, ids are unique for every entity.毕竟,每个实体的 id 都是唯一的。

You can try to use findAllById , but I doubt it'll make much difference.您可以尝试使用findAllById ,但我怀疑它会产生很大的不同。

What Optional means is that there may or may not be a result. Optional 的意思是可能有也可能没有结果。 The isPresent method of Optional will indicate this. Optional 的isPresent方法将表明这一点。

Your findById by definition should always return 1 or 0 entities(according to documentation for spring data method naming), as your id is a unique key, and there cannot be more then one entry in your repository with such key value.根据定义,您的findById应始终返回 1 或 0 个实体(根据 spring 数据方法命名的文档),因为您的id是唯一键,并且您的存储库中不能有多个具有此类键值的条目。 So Optional suits perfectly well for this situation, because its either empty (no entry with such key in repository) or present with specific value(there is entry in repository).所以Optional西服非常清楚这种情况,因为它无论是empty或(在仓库等重要的条目) present与特定值(有在库条目)。 If you want to query all entities by some not unique key, lets say name column, you can name your method findByName , with return value of Iterable<Entity> , thus when generating implementation for your repository spring will understand that there can be more than 1 entity in result set.如果你想通过一些不唯一的键查询所有实体,比如name列,你可以命名你的方法findByName ,返回值Iterable<Entity> ,因此在为你的存储库生成实现时,spring 会明白可以有多个结果集中有 1 个实体。

Method findById is already predefined in interface you are extending, so you couldn't change it return type anyway.方法findById已经在您要扩展的接口中预定义,因此无论如何您都无法更改它的返回类型。

This also might be usefull: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.core-concepts这也可能有用: https : //docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.core-concepts

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM