Spring 规格标准多重连接?如何?

Spring Specification Criteria Multiple Joins ? How?

我在使用 Spring 项目和 Spring 数据 + 规范 + 标准 api 时遇到了困难。

我将尝试使用我们编写的一般实体来模拟这种情况,以获得简单的示例。

实体: 考虑每个实体的所有属性都传递给下面显示的构造函数

国家(长id,字符串名称,字符串iso)
State(Long id, String name, String iso)
城市(Long id, String name, String iso)

这是我的存储库:

public interface CityRepository extends PagingAndSortingRepository<City, Integer>, JpaSpecificationExecutor<City> {

}

如您所见,我不需要在存储库上实现任何东西

这是我的服务

@Service
@Transactional
public class CityService {

    @Autowired
    private CityRepository cityRepository;

    @Transactional(readOnly = true)
    public CityListVO findByNameLike(String name, PageRequest pageRequest) {
        name = "%" + name + "%";

        if (pageRequest == null) {
            List<City> result = cityRepository.findAll(fillGridCriteria(name));
            return new CityListVO(1, result.size(), result);
        } else {
            Page<City> result = cityRepository. findAll(fillGridCriteria(name), pageRequest);
            return new CityListVO(result.getTotalPages(), result.getTotalElements(), result.getContent());
        }

    }

    private static Specification<City> fillGridCriteria(String name) {
        return new Specification<City>() {

            @Override
            public Predicate toPredicate(
                    Root<City> root,
                    CriteriaQuery<?> query,
                    CriteriaBuilder builder) { 

             /*
                The current return I can do a like by name, and it works fine. 

                My problem is if for any reason I need to do multiple joins like the folow jpql: 
                select ci FROM City ci, State st, Country co where ci.st = st AND st.co = co AND co.name = 'Canada';

                How to do this from here ? Inside this method.
                How is gonna be the return for this method ?

             */

                return builder.like(root.get("name"), name.trim());
            }

        };
    }

}

让我们假设您想要他们的国家/地区名称像 name 的所有城市,并且您有一个关系模型,其中:

Country(Long id, String name, String iso)
State(Long id,Long country, String name, String iso)
City(Long id, Long state, String name, String iso)

谓词:

private static Specification<City> fillGridCriteria(String name) {
    return new Specification<City>() {

        @Override
        public Predicate toPredicate(
                Root<City> root,
                CriteriaQuery<?> query,
                CriteriaBuilder builder) { 

          return 
            builder.like(root.get("state").get("country").get("name"), name.trim());
        }

    };
}