diff --git a/src/main/java/com/assu/server/domain/admin/repository/AdminRepository.java b/src/main/java/com/assu/server/domain/admin/repository/AdminRepository.java index f0e5d692..16d878af 100644 --- a/src/main/java/com/assu/server/domain/admin/repository/AdminRepository.java +++ b/src/main/java/com/assu/server/domain/admin/repository/AdminRepository.java @@ -29,42 +29,39 @@ List findMatchingAdmins(@Param("university") University university, @Param("department") Department department, @Param("major") Major major); - // 후보 수 카운트: 해당 partner와 ACTIVE 제휴가 없는 admin 수 - @Query(value = """ - SELECT COUNT(*) - FROM admin a + // 후보 수 카운트 + @Query(""" + SELECT COUNT(a) + FROM Admin a WHERE NOT EXISTS ( - SELECT 1 FROM paper pa - WHERE pa.admin_id = a.id - AND pa.partner_id = :partnerId - AND pa.is_activated = 'ACTIVE' + SELECT 1 FROM Paper pa + WHERE pa.admin = a + AND pa.partner.id = :partnerId + AND pa.isActivated = com.assu.server.domain.common.enums.ActivationStatus.ACTIVE ) - """, nativeQuery = true) - long countPartner(@Param("partnerId") Long partnerId); + """) + long countPartner(@Param("partnerId") Long partnerId); - // 랜덤 오프셋으로 1~N건 가져오기 (LIMIT :offset, :limit) - @Query(value = """ - SELECT a.* - FROM admin a + // 랜덤 오프셋 조회 + @Query(""" + SELECT a + FROM Admin a WHERE NOT EXISTS ( - SELECT 1 FROM paper pa - WHERE pa.admin_id = a.id - AND pa.partner_id = :partnerId - AND pa.is_activated = 'ACTIVE' + SELECT 1 FROM Paper pa + WHERE pa.admin = a + AND pa.partner.id = :partnerId + AND pa.isActivated = com.assu.server.domain.common.enums.ActivationStatus.ACTIVE ) - LIMIT :offset, :limit - """, nativeQuery = true) - List findPartnerWithOffset(@Param("partnerId") Long partnerId, - @Param("offset") int offset, - @Param("limit") int limit); + """) + List findPartnerWithOffset(@Param("partnerId") Long partnerId, Pageable pageable); @Query(""" SELECT DISTINCT a FROM Admin a LEFT JOIN FETCH a.member WHERE a.point IS NOT NULL - AND function('ST_Contains', function('ST_GeomFromText', :wkt, 4326), a.point) = true - """) + AND ST_Contains(ST_GeomFromText(:wkt, 4326), a.point) = true + """) List findAllWithinViewportWithMember(@Param("wkt") String wkt, Pageable pageable); @Query(""" diff --git a/src/main/java/com/assu/server/domain/admin/repository/StudentAdminRepository.java b/src/main/java/com/assu/server/domain/admin/repository/StudentAdminRepository.java index 024e3900..1082a9e0 100644 --- a/src/main/java/com/assu/server/domain/admin/repository/StudentAdminRepository.java +++ b/src/main/java/com/assu/server/domain/admin/repository/StudentAdminRepository.java @@ -33,7 +33,7 @@ Long countTodayUsersByAdmin( ); @Query(""" - SELECT new com.assu.server.domain.mapping.dto.StoreUsageWithPaper( + SELECT new com.assu.server.domain.admin.dto.StoreUsageWithPaper( p.id, p.store.id, p.store.name, COUNT(pu.id) ) FROM PartnershipUsage pu diff --git a/src/main/java/com/assu/server/domain/admin/service/AdminServiceImpl.java b/src/main/java/com/assu/server/domain/admin/service/AdminServiceImpl.java index 055742b1..50b937c7 100644 --- a/src/main/java/com/assu/server/domain/admin/service/AdminServiceImpl.java +++ b/src/main/java/com/assu/server/domain/admin/service/AdminServiceImpl.java @@ -11,6 +11,8 @@ import com.assu.server.global.apiPayload.code.status.ErrorStatus; import com.assu.server.global.exception.DatabaseException; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -24,14 +26,11 @@ public class AdminServiceImpl implements AdminService { private final AdminRepository adminRepository; private final PartnerRepository partnerRepository; - @Override - @Transactional - public List findMatchingAdmins(University university, Department department, Major major){ - - List adminList = adminRepository.findMatchingAdmins(university, department, major); - - return adminList; - } + @Override + @Transactional + public List findMatchingAdmins(University university, Department department, Major major){ + return adminRepository.findMatchingAdmins(university, department, major); + } @Override @Transactional(readOnly = true) @@ -40,19 +39,22 @@ public AdminResponseDTO suggestRandomPartner(Long adminId) { Admin admin = adminRepository.findById(adminId) .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_ADMIN)); - long total = partnerRepository.countUnpartneredActiveByAdmin(admin.getId()); + long total = partnerRepository.countUnpartneredActiveByAdmin(admin.getId(), com.assu.server.domain.common.enums.ActivationStatus.ACTIVE); if (total <= 0) { throw new DatabaseException(ErrorStatus.NO_AVAILABLE_PARTNER); } int offset = ThreadLocalRandom.current().nextInt((int)total); - Partner picked = partnerRepository.findUnpartneredActiveByAdminWithOffset(admin.getId(), offset); - if(picked == null) { + Pageable pageable = PageRequest.of(offset, 1); + List pickedList = partnerRepository.findUnpartneredActiveByAdminWithOffset(admin.getId(), com.assu.server.domain.common.enums.ActivationStatus.ACTIVE, pageable); + + if (pickedList.isEmpty()) { throw new DatabaseException(ErrorStatus.NO_AVAILABLE_PARTNER); } + Partner picked = pickedList.get(0); + return AdminResponseDTO.from(picked); } - -} +} \ No newline at end of file diff --git a/src/main/java/com/assu/server/domain/partner/repository/PartnerRepository.java b/src/main/java/com/assu/server/domain/partner/repository/PartnerRepository.java index 7ac8ac32..ecc86fa7 100644 --- a/src/main/java/com/assu/server/domain/partner/repository/PartnerRepository.java +++ b/src/main/java/com/assu/server/domain/partner/repository/PartnerRepository.java @@ -1,6 +1,7 @@ package com.assu.server.domain.partner.repository; import com.assu.server.domain.partner.entity.Partner; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -11,41 +12,41 @@ public interface PartnerRepository extends JpaRepository { boolean existsByPhoneNum(String phoneNum); - // 현재 admin과 'ACTIVE' 상태로 제휴 중인 partner를 제외한 후보 수 - @Query(value = """ - SELECT COUNT(*) - FROM partner p - LEFT JOIN paper pa - ON pa.partner_id = p.id - AND pa.admin_id = :adminId - AND pa.is_activated = 'ACTIVE' - WHERE pa.id IS NULL - """, nativeQuery = true) - long countUnpartneredActiveByAdmin(@Param("adminId") Long adminId); - - // 위 후보들 중에서 offset 하나만 가져오기 (랜덤 오프셋으로 1건) - @Query(value = """ - SELECT p.* - FROM partner p - LEFT JOIN paper pa - ON pa.partner_id = p.id - AND pa.admin_id = :adminId - AND pa.is_activated = 'ACTIVE' - WHERE pa.id IS NULL - LIMIT :offset, 1 - """, nativeQuery = true) - Partner findUnpartneredActiveByAdminWithOffset(@Param("adminId") Long adminId, - @Param("offset") int offset); + @Query(""" + SELECT COUNT(p) + FROM Partner p + WHERE NOT EXISTS ( + SELECT 1 FROM Paper pa + WHERE pa.partner = p + AND pa.admin.id = :adminId + AND pa.isActivated = :status + ) + """) + long countUnpartneredActiveByAdmin(@Param("adminId") Long adminId, @Param("status") com.assu.server.domain.common.enums.ActivationStatus status); + @Query(""" + SELECT p + FROM Partner p + WHERE NOT EXISTS ( + SELECT 1 FROM Paper pa + WHERE pa.partner = p + AND pa.admin.id = :adminId + AND pa.isActivated = :status + ) + """) + List findUnpartneredActiveByAdminWithOffset(@Param("adminId") Long adminId, @Param("status") com.assu.server.domain.common.enums.ActivationStatus status, Pageable pageable); + + // 반경 내 제휴업체 조회 @Query(""" SELECT DISTINCT p FROM Partner p LEFT JOIN FETCH p.member WHERE p.point IS NOT NULL - AND function('ST_Contains', function('ST_GeomFromText', :wkt, 4326), p.point) = true + AND ST_Contains(ST_GeomFromText(:wkt, 4326), p.point) = true """) List findAllWithinViewportWithMember(@Param("wkt") String wkt); + // 키워드 검색 @Query(""" SELECT DISTINCT p FROM Partner p @@ -55,6 +56,4 @@ WHERE LOWER(p.name) LIKE LOWER(CONCAT('%', :keyword, '%')) List searchPartnerByKeywordWithMember( @Param("keyword") String keyword ); - - -} +} \ No newline at end of file diff --git a/src/main/java/com/assu/server/domain/partner/service/PartnerServiceImpl.java b/src/main/java/com/assu/server/domain/partner/service/PartnerServiceImpl.java index 6340f945..9892a918 100644 --- a/src/main/java/com/assu/server/domain/partner/service/PartnerServiceImpl.java +++ b/src/main/java/com/assu/server/domain/partner/service/PartnerServiceImpl.java @@ -11,6 +11,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import java.util.List; import java.util.concurrent.ThreadLocalRandom; @@ -41,8 +43,8 @@ public PartnerResponseDTO getRandomAdmin(Long partnerId) { offset = ThreadLocalRandom.current().nextInt(0, (int)(total - limit + 1)); } - List picked = adminRepository.findPartnerWithOffset(partner.getId(), offset, limit); - + Pageable pageable = PageRequest.of(offset, limit); + List picked = adminRepository.findPartnerWithOffset(partner.getId(), pageable); List admins = picked.stream() .map(PartnerResponseDTO.AdminLiteDTO::from) .collect(Collectors.toList());