我试图将ListEntity Class作为其通用参数放入List中,但List Class变为红色(Error),它建议的唯一一件事就是将List Class更改为Optional Class。
public interface RoomRepository extends CrudRepository<RoomEntity, Long> {
List<RoomEntity> findById(Long id);
}
RoomEntity Class
@Entity
@Table(name = "Room")
public class RoomEntity {
}
它们是一样的吗?
List<RoomEntity> findById(Long id);
Optional<RoomEntity> findById(Long id);
答案 0 :(得分:0)
findById方法应该通过它的id查找单个实体。毕竟,每个实体的ID都是唯一的。
您可以尝试使用findAllById
,
但我怀疑这会有很大的不同。
可选的含义是可能有也可能没有结果。 Optional的isPresent
方法将表明这一点。
答案 1 :(得分:0)
根据定义,您的findById
应始终返回1或0个实体(根据documentation进行弹簧数据方法命名),因为id
是唯一键,并且不能有更多然后在您的存储库中有一个具有此键值的条目。所以Optional
非常适合这种情况,因为它的empty
(在存储库中没有这样的密钥的条目)或具有特定值的present
(存储库中有条目)。如果您想通过某些非唯一键查询所有实体,可以说name
列,则可以将方法命名为findByName
,返回值为Iterable<Entity>
,从而为您的存储库生成实现时spring会理解结果集中可以有多个实体。
方法findById
在您要扩展的界面中已经是predefined,因此无论如何您都无法更改其返回类型。
这也可能有用:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.core-concepts
答案 2 :(得分:0)
Spring数据JPA会使查询结果符合您所需的容器
你问一个List<>
,Spring将初始化一个列表并将任何行数据添加到该列表并为你返回。因此它会:
当您询问Optional<>
时,Spring会理解您最多只需要一行数据。它将在getSingleResult()
上解释为javax.persistence.Query
。因此它会:
如果找不到任何物品,请返回Optional.empty()
如果只有一个匹配则返回Optional.of(result)
NonUniqueResultException
)在您的情况下,您可以id
找到。它在您的桌子上是独一无二的,因此Optional<>
应符合您的目的。
但请注意,您的List<RoomEntity> findById(Long id);
定义是正确的,它不会给您编译错误(变为红色)。您是否导入了List
界面?
答案 3 :(得分:0)
Optional和List是两个非常不同的概念。
CrudRepository findAllById方法返回am Iterable。 findById方法返回一个Optional。
可以使用iterable逐个访问集合的元素,因此可以与List类一起使用。
Optional是一个容器对象,可能包含也可能不包含非null值(零个或一个元素)。这将包含一个元素,如果有一个元素,则列表中的元素不多。
CrudRepository :: findAllById可以向它发送多个ID,因此可以返回多个元素,这样做的方法是返回一个可以用来逐个选择每个返回结果的iterable。 findById方法只能发送一个ID,因此如果它存在(包装在Optional中),则返回该元素;如果不存在,则返回Optional.none。
如果您要查找要返回的列表,因为您打算发送多个ID,请使用findAllById方法。如果您只想要ID的特定元素,那么使用findById方法,但是您必须打开它返回的Optional对象,然后才能使用Optional.get,Optional.isPresent或者使用它在流管道之外使用它在流管道中调用地图或flatmap。