|
12 | 12 | import org.tuna.zoopzoop.backend.domain.SSE.service.EmitterService; |
13 | 13 | import org.tuna.zoopzoop.backend.domain.member.entity.Member; |
14 | 14 | import org.tuna.zoopzoop.backend.domain.member.service.MemberService; |
| 15 | +import org.tuna.zoopzoop.backend.domain.space.membership.dto.etc.SpaceMemberInfo; |
15 | 16 | import org.tuna.zoopzoop.backend.domain.space.membership.entity.Membership; |
16 | 17 | import org.tuna.zoopzoop.backend.domain.space.membership.enums.Authority; |
17 | 18 | import org.tuna.zoopzoop.backend.domain.space.membership.enums.JoinState; |
|
21 | 22 | import org.tuna.zoopzoop.backend.global.rsData.RsData; |
22 | 23 |
|
23 | 24 | import java.nio.file.AccessDeniedException; |
| 25 | +import java.util.Collections; |
24 | 26 | import java.util.List; |
| 27 | +import java.util.Map; |
25 | 28 | import java.util.Optional; |
| 29 | +import java.util.stream.Collectors; |
26 | 30 |
|
27 | 31 | @Service |
28 | 32 | @RequiredArgsConstructor |
@@ -64,11 +68,11 @@ public Membership findByMemberAndSpace(Member member, Space space) { |
64 | 68 | */ |
65 | 69 | public Page<Membership> findByMember(Member member, String state, Pageable pageable) { |
66 | 70 | if (state.equalsIgnoreCase("PENDING")) { |
67 | | - return membershipRepository.findAllByMemberAndAuthorityOrderById(member, Authority.PENDING, pageable); |
| 71 | + return membershipRepository.findAllByMemberAndAuthorityWithSpace(member, Authority.PENDING, pageable); |
68 | 72 | } else if (state.equalsIgnoreCase("JOINED")) { |
69 | | - return membershipRepository.findAllByMemberAndAuthorityIsNotOrderById(member, Authority.PENDING, pageable); |
| 73 | + return membershipRepository.findAllByMemberAndAuthorityIsNotWithSpace(member, Authority.PENDING, pageable); |
70 | 74 | } else { |
71 | | - return membershipRepository.findAllByMemberOrderById(member, pageable); |
| 75 | + return membershipRepository.findAllByMemberWithSpace(member, pageable); |
72 | 76 | } |
73 | 77 | } |
74 | 78 |
|
@@ -107,6 +111,36 @@ public List<Membership> findMembersBySpace(Space space) { |
107 | 111 | return membershipRepository.findAllBySpaceAndAuthorityIsNotOrderById(space, Authority.PENDING); |
108 | 112 | } |
109 | 113 |
|
| 114 | + /** |
| 115 | + * 여러 스페이스에 속한 멤버 목록을 한 번의 쿼리로 조회 (N+1 문제 해결용) |
| 116 | + * @param spaces 조회할 스페이스 목록 |
| 117 | + * @return 스페이스 ID를 key로, 해당 스페이스의 멤버 정보 리스트를 value로 갖는 Map |
| 118 | + */ |
| 119 | + @Transactional(readOnly = true) |
| 120 | + public Map<Integer, List<SpaceMemberInfo>> findMembersBySpaces(List<Space> spaces) { |
| 121 | + if (spaces == null || spaces.isEmpty()) { |
| 122 | + return Collections.emptyMap(); |
| 123 | + } |
| 124 | + |
| 125 | + // 1. 한 번의 쿼리로 모든 스페이스의 멤버십 정보를 가져옴 |
| 126 | + List<Membership> allMemberships = membershipRepository.findAllMembersInSpaces(spaces); |
| 127 | + |
| 128 | + // 2. Space ID 별로 그룹핑하여 Map으로 변환 |
| 129 | + return allMemberships.stream() |
| 130 | + .collect(Collectors.groupingBy( |
| 131 | + membership -> membership.getSpace().getId(), // Key: Space ID |
| 132 | + Collectors.mapping( // Value: List<SpaceMemberInfo> DTO로 변환 |
| 133 | + membership -> new SpaceMemberInfo( |
| 134 | + membership.getMember().getId(), |
| 135 | + membership.getMember().getName(), |
| 136 | + membership.getMember().getProfileImageUrl(), |
| 137 | + membership.getAuthority() |
| 138 | + ), |
| 139 | + Collectors.toList() |
| 140 | + ) |
| 141 | + )); |
| 142 | + } |
| 143 | + |
110 | 144 | // ======================== 권한 조회 ======================== // |
111 | 145 | /** |
112 | 146 | * 멤버가 스페이스의 어드민 권한을 가지고 있는지 확인 |
|
0 commit comments