我正在使用Spring boot 1.5和Hibernate。我有2个实体,Person和PersonDetail并不总是存在。我需要根据Person列表检索PersonDetails列表,即使匹配的PersonDetails不存在也是如此。
所以我在PersonService中编写了buildFromPersonList,它运行良好。但是我已经在我的数据库中填充了1000个Person条目,不幸的是,构建PersonDetails列表大约需要3.5秒。
由于性能问题我试图在JPQL中进行操作,请查看findAllByPersons并帮助我改进它以从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理念的新解决方案,但它仍然需要花费太多时间来加载(仅在1000个条目之间800毫秒和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())
}
}
答案 0 :(得分:1)
实际上,您在数据库中执行了1000个选择查询,以获取每个人的personDetail。
更快(但仍可完成)的事情是进行2次查询:
这样你就可以在2中改变1000个查询/交易,你应该肯定会获得一些。