Spring 存储库 休眠 基于关联实体列表构建实体列表



我正在使用 Spring boot 1.5 和 Hibernate。我有 2 个实体,Person 和 PersonDetail,它们并不总是存在。我需要根据人员列表检索人员详细信息列表,即使匹配的人员详细信息不存在也是如此。

所以我在PersonService中编写了buildFromPersonList,它运行良好。但是,我已经用 1000 个 Person 条目填充了我的数据库,不幸的是,构建 PersonDetails 列表大约需要 3,5 秒。

由于性能问题,我正在尝试在 JPQL 中执行此操作,请查看 findAllByPeople 并帮助我改进它以从 PersonList 获取 PersonDetails 并在存在时检索匹配的 PersonDetails。

这是我的实体

@Entity
@Table(name = "person")
public class Person{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected Long id;
    //name,birthdate ...
}
@Entity
@Table(name = "person_details")
public class PersonDetails{
// private details accessible only for authorized user
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected Long id;
    @OneToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name = "id_person",insertable = true,updatable=true,nullable = false)
    protected Person person;
}

存储 库

@Transactional
public interface PersonDetailsRepository extends JpaRepository<PersonDetails,Long> {
    PersonDetails findByPerson(Person person);
    // @Query("SELECT CASE WHEN (pd is not null ) THEN pd ELSE (new PersonDetails(p)) END  FROM Person p left join PersonDetails pd on p.id=pd.person.id")
    @Query("SELECT new PersonDetails(p) FROM Person p")
    List<PersonDetails> findAllByPersons();
}

服务

@Service
public class PersonDetailsService {
    private final PersonDetailsRepository personDetailsRepository;
    private final PersonService personService;
    // constructors + findall, findOne,save
    @Override
    public List<PersonDetails> findAll() {
        List<Person> personList=personService.findAll();
        return buildFromList(personList);
     //   return personDetailsRepository.findAllByPerson();
    }
    private List<PersonDetails> buildFromPersonList( List<Person> personList) {
        List<PersonDetails> personDetailsList= new ArrayList<>();
        for (Person person:personList) {
            PersonDetails personDetails = personDetailsRepository.findByPersonperson);
            if(personDetails==null){
                personDetails=new PersonDetails();
                personDetails.setPerson(person);
            }
            personDetailsList.add(personDetail);
        }
        return personDetailsList;
    }
}

更新 : 我已经实现了基于 TheBakker 想法的新解决方案,但加载仍然需要太多时间(仅 800 个条目在 1 毫秒到 1 秒之间(。有没有人有更快检索的想法?这是我的新代码:

@Transactional
public interface PersonDetailsRepository extends JpaRepository<PersonDetails,Long> {
    //..
    @Query("SELECT new PersonDetails(p) FROM Person p WHERE p.id not in (SELECT pd.person.id From PersonDetails pd)")
List<PersonDetails> findAllPersonNotInPersonDetails();
}
 @Service
public class PersonDetailsService {
    @Override
    public List<PersonDetails> findAll() {
       List<PersonDetails> personDetailsList=personDetailsRepository.findAll();
   /*       personDetailsList.addAll(personDetailsRepository.findAllPersonsNotInPersonDetails());
    return personDetailsList;*/
return Stream.concat(personDetailsList.stream(), agentDetailsRepository.findAllPersonNotInPersonDetails().stream())
                .collect(Collectors.toList())
    }
}

实际上,您在数据库中执行 1000 个选择查询,以获取每个单独的 Person 的 personDetail。

更快(但仍然可以完善(的事情是执行 2 个查询:

  1. 一个获取数据库中已有的所有人员详细信息
  2. 另一个将从您的列表中获取所有没有 PersonDetails 的人,您需要为其循环并实例化一个。

这样,您在 2 中更改了 1000 个查询/事务,并且您肯定会获得一些查询/事务。

最新更新