diff --git a/build.gradle b/build.gradle index 8e63f0a..5a8a9bb 100644 --- a/build.gradle +++ b/build.gradle @@ -40,6 +40,13 @@ dependencies { implementation 'io.jsonwebtoken:jjwt-impl:0.12.6' implementation 'io.jsonwebtoken:jjwt-jackson:0.12.6' + //query dsl + implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' + implementation 'com.querydsl:querydsl-sql:5.0.0' + annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta" + annotationProcessor "jakarta.persistence:jakarta.persistence-api" + annotationProcessor "jakarta.annotation:jakarta.annotation-api" + implementation 'com.azure:azure-storage-blob:12.27.0' } diff --git a/src/main/java/org/khtml/hexagonal/domain/building/application/BuildingService.java b/src/main/java/org/khtml/hexagonal/domain/building/application/BuildingService.java index 43489b9..2afb054 100644 --- a/src/main/java/org/khtml/hexagonal/domain/building/application/BuildingService.java +++ b/src/main/java/org/khtml/hexagonal/domain/building/application/BuildingService.java @@ -3,7 +3,7 @@ import lombok.RequiredArgsConstructor; import org.khtml.hexagonal.domain.building.ImageType; import org.khtml.hexagonal.domain.building.dto.BuildingUpdate; -import org.khtml.hexagonal.domain.building.dto.RecommendBuildingResult; +import org.khtml.hexagonal.domain.building.dto.RecommendBuilding; import org.khtml.hexagonal.domain.building.entity.Building; import org.khtml.hexagonal.domain.building.entity.BuildingImage; import org.khtml.hexagonal.domain.building.entity.Image; @@ -22,7 +22,6 @@ import java.util.List; import java.util.Objects; -import static org.khtml.hexagonal.domain.building.dto.RecommendBuildingResult.*; @RequiredArgsConstructor @Transactional(readOnly = true) @@ -130,26 +129,15 @@ public void updateBuildingDescription(String buildingId, Long userId, String des Building building = buildingRepository.findBuildingByGisBuildingId(buildingId) .orElseThrow(() -> new IllegalArgumentException("Building not found")); - if(!Objects.equals(building.getUser().getId(), userId)) { + if (!Objects.equals(building.getUser().getId(), userId)) { throw new IllegalArgumentException(ErrorType.DEFAULT_ERROR.getMessage()); } building.setBuildingDescription(description); } - public RecommendBuildingResult recommendBuilding() { - List buildingImages = buildingImageRepository.recommendBuilding(); - List recommendBuildings = new ArrayList<>(); - for(BuildingImage buildingImage : buildingImages) { - Building building = buildingImage.getBuilding(); - Image image = buildingImage.getImage(); - recommendBuildings.add(new RecommendBuilding( - image.getUrl(), - building.getLegalDistrictName() + " " + building.getLandLotNumber(), - building.getRepairList() - )); - } - - return new RecommendBuildingResult(recommendBuildings); + public List recommendBuilding() { + return buildingImageRepository.recommendBuilding(); } + } diff --git a/src/main/java/org/khtml/hexagonal/domain/building/dto/RecommendBuilding.java b/src/main/java/org/khtml/hexagonal/domain/building/dto/RecommendBuilding.java new file mode 100644 index 0000000..3fac3b2 --- /dev/null +++ b/src/main/java/org/khtml/hexagonal/domain/building/dto/RecommendBuilding.java @@ -0,0 +1,26 @@ +package org.khtml.hexagonal.domain.building.dto; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.Builder; +import lombok.Data; + +@Data +public class RecommendBuilding { + + private String buildingId; + private String imageUrl; + private String address; + private String repairList; + private Integer totalScore; + + @Builder + @QueryProjection + public RecommendBuilding(String buildingId, String imageUrl, String address, String repairList, Integer totalScore) { + this.buildingId = buildingId; + this.imageUrl = imageUrl; + this.address = address; + this.repairList = repairList; + this.totalScore = totalScore; + } + +} diff --git a/src/main/java/org/khtml/hexagonal/domain/building/dto/RecommendBuildingResult.java b/src/main/java/org/khtml/hexagonal/domain/building/dto/RecommendBuildingResult.java deleted file mode 100644 index f2154ec..0000000 --- a/src/main/java/org/khtml/hexagonal/domain/building/dto/RecommendBuildingResult.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.khtml.hexagonal.domain.building.dto; - -import org.khtml.hexagonal.domain.building.entity.Building; - -import java.util.List; - -public record RecommendBuildingResult( - List recommendBuildings -) { - public record RecommendBuilding( - String imageUrl, - String address, - String repairList - ) { - } -} diff --git a/src/main/java/org/khtml/hexagonal/domain/building/repository/BuildingImageRepository.java b/src/main/java/org/khtml/hexagonal/domain/building/repository/BuildingImageRepository.java index 4f253b0..70fdc71 100644 --- a/src/main/java/org/khtml/hexagonal/domain/building/repository/BuildingImageRepository.java +++ b/src/main/java/org/khtml/hexagonal/domain/building/repository/BuildingImageRepository.java @@ -8,15 +8,9 @@ import java.util.List; -public interface BuildingImageRepository extends JpaRepository { +public interface BuildingImageRepository extends JpaRepository, BuildingQueryDslRepository { @EntityGraph(attributePaths = {"image", "building"}) List findAllByBuilding(Building building); - @Query("SELECT bi FROM BuildingImage bi " + - "JOIN Building b ON bi.building.gisBuildingId = b.gisBuildingId " + - "JOIN Image i ON bi.image.id = i.id " + - "WHERE b.buildingStatus = 'REGISTERED' ORDER BY b.totalScore DESC LIMIT 10") - List recommendBuilding(); - } diff --git a/src/main/java/org/khtml/hexagonal/domain/building/repository/BuildingQueryDslRepository.java b/src/main/java/org/khtml/hexagonal/domain/building/repository/BuildingQueryDslRepository.java new file mode 100644 index 0000000..d37452c --- /dev/null +++ b/src/main/java/org/khtml/hexagonal/domain/building/repository/BuildingQueryDslRepository.java @@ -0,0 +1,11 @@ +package org.khtml.hexagonal.domain.building.repository; + +import org.khtml.hexagonal.domain.building.dto.RecommendBuilding; + +import java.util.List; + + +public interface BuildingQueryDslRepository { + + List recommendBuilding(); +} diff --git a/src/main/java/org/khtml/hexagonal/domain/building/repository/BuildingQueryDslRepositoryImpl.java b/src/main/java/org/khtml/hexagonal/domain/building/repository/BuildingQueryDslRepositoryImpl.java new file mode 100644 index 0000000..6dac53e --- /dev/null +++ b/src/main/java/org/khtml/hexagonal/domain/building/repository/BuildingQueryDslRepositoryImpl.java @@ -0,0 +1,43 @@ +package org.khtml.hexagonal.domain.building.repository; + +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import org.khtml.hexagonal.domain.building.BuildingStatus; +import org.khtml.hexagonal.domain.building.dto.QRecommendBuilding; +import org.khtml.hexagonal.domain.building.dto.RecommendBuilding; + +import java.beans.Expression; +import java.util.List; + +import static com.querydsl.core.types.dsl.Expressions.stringTemplate; +import static org.khtml.hexagonal.domain.building.entity.QBuilding.*; +import static org.khtml.hexagonal.domain.building.entity.QBuildingImage.*; +import static org.khtml.hexagonal.domain.building.entity.QImage.*; + +@RequiredArgsConstructor +public class BuildingQueryDslRepositoryImpl implements BuildingQueryDslRepository { + + private final JPAQueryFactory queryFactory; + + @Override + public List recommendBuilding() { + return queryFactory + .select(new QRecommendBuilding( + building.gisBuildingId, + image.url, + Expressions.stringTemplate("CONCAT({0}, ' ', {1})", building.legalDistrictName, building.landLotNumber), + building.repairList, + building.totalScore + )) + .from(buildingImage) + .leftJoin(building).on(buildingImage.building.eq(building)) + .leftJoin(image).on(buildingImage.image.eq(image)) + .where(building.buildingStatus.eq(BuildingStatus.REGISTERED)) + .distinct() + .orderBy(building.totalScore.desc()) + .limit(10) + .fetch(); + } + +} diff --git a/src/main/java/org/khtml/hexagonal/global/config/QueryDslConfig.java b/src/main/java/org/khtml/hexagonal/global/config/QueryDslConfig.java new file mode 100644 index 0000000..0c0bb76 --- /dev/null +++ b/src/main/java/org/khtml/hexagonal/global/config/QueryDslConfig.java @@ -0,0 +1,20 @@ +package org.khtml.hexagonal.global.config; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class QueryDslConfig { + + @PersistenceContext + private EntityManager entityManager; + + @Bean + public JPAQueryFactory queryFactory() { + return new JPAQueryFactory(entityManager); + } + +} \ No newline at end of file