jpa 列表元素上的Spring休眠orderBy

r7xajy2e  于 2022-11-14  发布在  Spring
关注(0)|答案(2)|浏览(133)
@Entity
class Person{
   private int id;
   @OneToMany(mappedBy=owner)
   private List<Pet> pets;
}

@Entity
class Pet{
  private name;
  private ZonedDateTime birthDate;
  @ManyToOne
  @JoinColumn(name="owner_id")
  private Person owner;
}

我想找到所有的人,并按他们最大的宠物生日排序

我唯一能解决这个问题的方法是通过@Formula,类似于

@Entity
class Person{
   private int id;
   private List<Pet> pets;

   @Formula("(SELECT p.birth_date FROM pet p WHERE p.owner_id = id order by p.birth_date ASC LIMIT 1)")
   private ZonedDateTime oldestPetBirthday;
}

然后

public List<Person> findPersonByOrderByOldestPetBirthdayAsc

但是我不想使用原始SQL,我正在寻找类似

public List<Person> findPersonByOrderByPetsTop1OrderByBirthDateAsc

或者使用可分页,例如:

PageRequest.of(page,pageSize,Sort.by(ASC, "pets.sort(BirthDateComparator).get(0)"))

这可能吗?

68de4m5k

68de4m5k1#

尝试在一对多集合对象上使用@javax.persistence.OrderBy包中的@OrderBy注解。

@OrderBy("birthDate")
private List<Pet> pets;
kb5ga3dv

kb5ga3dv2#

您的公式解决方案是可以的,但存在一些问题。无论如何,由于您不想编写SQL,您将不得不使用类似Blaze-Persistence实体视图的东西。
我创建这个库是为了允许在JPA模型和自定义接口或抽象类定义的模型之间进行简单的Map,就像Spring Data Projections一样。其思想是您可以按照自己喜欢的方式定义目标结构(域模型),并通过JPQL表达式将属性(getter)Map到实体模型。
使用Blaze-Persistence Entity-Views时,您的用例的DTO模型可能如下所示:

@EntityView(Person.class)
public interface PersonDto {
    @IdMapping
    Long getId();
    @Limit(limit = "1", order = "birthDate desc)
    @Mapping("pets")
    OldestPetDto getOldestPet();

    @EntityView(Pet.class)
    interface OldestPetDto {
        @IdMapping
        Long getId();
        ZonedDateTime getBirthDate();
    }
}

查询是将实体视图应用于查询的问题,最简单的是按id查询。
PersonDto a = entityViewManager.find(entityManager, PersonDto.class, id);
Spring Data 集成允许您像Spring Data 投影一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

Page<PersonDto> findAll(Pageable pageable);

最好的部分是,它只会获取实际需要的状态!
此外,您可以为oldestPet.birthDate添加一个Sort,它将像您希望的那样工作!

相关问题