Spring JPA 聯表查詢

木水愛婷妹子發表於2019-03-06

簡要背景說明:

  • 使用者角色表 P_USER_ROLE和使用者資料表 P_USER
  • 一個使用者角色必定有一個使用者資料,但多個使用者角色可以共用一個使用者資料
  • P_USER_ROLE 中USER_DATA_ID 為P_USER 的主鍵

需求:查詢使用者角色列表(含使用者詳細資料),所以在查詢使用者角色的同時,希望關聯查詢使用者資料

實現步驟1/2:

在UserRole(P_USER_ROLE 的實體物件),增加User(P_USER的實體物件)屬性,並生成get/set

/**
 * 使用者資料
 */
private User user;
/**
 * 使用者資料
 */
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "user_data_id", updatable = false, insertable = false, nullable = false)
public User getUser() {
    return user;
}

public void setUser(User user) {
    this.user = user;
}

實現步驟2/2:

在原有分頁查詢條件Specification(查詢P_USER_ROLE)中追加Specification查詢條件(查詢P_USER)

@Override
    public Page<UserRole> query(Map<String, Object> parameters, Long currentPage, Long pageSize) throws CodeException {
        List<Sort.Order> orders = OrderBuildable.create(parameters);
        Specification specification = SpecificationFactory.create(this.getGenericClass(), parameters).and(new Specification<UserRole>() {
            @Override
            public Predicate toPredicate(Root<UserRole> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                Join<UserRole, User> userJoin = root.join("user", JoinType.INNER);
                String nickName = (String) parameters.get("qry_like_nickName");
                if (StringUtils.isNotBlank(nickName)) {
                    predicates.add(criteriaBuilder.like(userJoin.get("nickName").as(String.class), "%" + nickName + "%"));
                }
                String name = (String) parameters.get("qry_like_name");
                if (StringUtils.isNotBlank(name)) {
                    predicates.add(criteriaBuilder.like(userJoin.get("name").as(String.class), "%" + name + "%"));
                }
                query.where((Predicate[]) predicates.toArray(new Predicate[0]));
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        });
        int page = currentPage.intValue();
        if (page > 0) {
            --page;
        } else {
            page = 0;
        }
        PageRequest pageable;
        if (orders != null && !orders.isEmpty()) {
            pageable = PageRequest.of(page, pageSize.intValue(), Sort.by(orders));
        } else {
            pageable = PageRequest.of(page, pageSize.intValue());
        }
        return this.getRepository().findAll(specification, pageable);
    }

相關文章