Объединение 3 таблиц и поиск по последним - PullRequest
3 голосов
/ 30 января 2020

У меня есть объект Property, который имеет идентификатор для объекта City. Городской объект, который имеет идентификатор для государственного объекта. И государственная организация, у которой есть идентификатор для страны.

Мне нужно найти все свойства в стране.

Мое решение таково:

protected Specification<Property> createSpecification(PropertyCriteria criteria) {
    ...
    if (criteria.getCountryId() != null) {
            StateCriteria stateCriteria = new StateCriteria();
            stateCriteria.setCountryId(criteria.getCountryId());
            List<StateDTO> states = stateQueryService.findByCriteria(stateCriteria);
            List<Long> statesIds = states.stream().map(StateDTO::getId).collect(Collectors.toList());

            LongFilter statesInCountry = new LongFilter();
            statesInCountry.setIn(statesIds);

            CityCriteria cityCriteria = new CityCriteria();
            cityCriteria.setStateId(statesInCountry);
            List<CityDTO> cities = cityQueryService.findByCriteria(cityCriteria);
            List<Long> citiesId = cities.stream().map(CityDTO::getId).collect(Collectors.toList());

            LongFilter citiesInState = new LongFilter();
            citiesInState.setIn(citiesId);

            specification = specification.and(buildSpecification(citiesInState,
                root -> root.join(Property_.city, JoinType.LEFT).get(City_.id)));
    }
    ...
}

Есть ли лучшее решение с использованием buildSpecification()? Мне действительно трудно понять, что в действительности делают функции из QueryService из-за параметризации типа.

Заранее спасибо!

1 Ответ

2 голосов
/ 30 января 2020

Чтобы получить все Property в Country, вы должны присоединиться к сущностям и применить фильтр к идентификатору страны.

protected Specification<Property> createSpecification(PropertyCriteria criteria) {
    ...
    if (criteria.getCountryId() != null) {
        specification = specification.and(buildSpecification(criteria.getCountryId(),
            root -> root.join(Property_.city, JoinType.LEFT)
                        .join(City_.state, JoinType.LEFT)
                        .join(State_.country, JoinType.LEFT)
                        .get(Country_.id)));
    }
    ...
}

Проверьте, выполняет ли это то, что вам нужно.

...