Skip to content

Commit

Permalink
#23 - 방문명소 기록시 명소명과 사진URL 저장
Browse files Browse the repository at this point in the history
* MemberAttraction 과 attraction 둘다 가지고있던 명소명을 Attraction에만 가지게끔 설계변경.

* 불필요하게 Wrapper 타입으로 설정되어있던 memberId 파라미터를 원시타입으로 변경
  • Loading branch information
youngreal committed Sep 1, 2024
1 parent 6346762 commit a4bbf42
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 66 deletions.
10 changes: 2 additions & 8 deletions src/main/java/com/dnd/dndtravel/map/domain/MemberAttraction.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,30 +36,24 @@ public class MemberAttraction {
private String memo; // 방문기록 메모
private LocalDate localDate; // 방문 날짜
private String region; // 지역
private int photosCount; // 사진 개수, 필요한가?
private String attractionName; // 명소 이름

@Builder
private MemberAttraction(Member member, Attraction attraction, String memo, LocalDate localDate, String region,
int photosCount, String attractionName) {
private MemberAttraction(Member member, Attraction attraction, String memo, LocalDate localDate, String region) {
this.member = member;
this.attraction = attraction;
this.memo = memo;
this.localDate = localDate;
this.region = region;
this.photosCount = photosCount;
this.attractionName = attractionName;
}

public static MemberAttraction of(Member member, Attraction attraction, String memo, LocalDate localDate,
String region, String attractionName) {
String region) {
return MemberAttraction.builder()
.member(member)
.attraction(attraction)
.memo(memo)
.localDate(localDate)
.region(region)
.attractionName(attractionName)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

public interface MemberAttractionRepository extends JpaRepository<MemberAttraction, Long>,
MemberAttractionRepositoryCustom {
MemberAttraction findByAttractionIdAndMemberId(Long attractionId, Long memberId);

List<MemberAttraction> findByMemberId(Long memberId);
List<MemberAttraction> findByMemberId(long memberId);
}

Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package com.dnd.dndtravel.map.repository;

import java.util.List;
import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;

import com.dnd.dndtravel.map.domain.Photo;
import com.dnd.dndtravel.map.repository.custom.PhotoRepositoryCustom;

public interface PhotoRepository extends JpaRepository<Photo, Long> {
public interface PhotoRepository extends JpaRepository<Photo, Long>, PhotoRepositoryCustom {

List<Photo> findByMemberAttractionId(Long id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
import com.dnd.dndtravel.map.repository.dto.projection.RecordProjection;

public interface MemberAttractionRepositoryCustom {
Long maxCursor(long memberId);

Long maxCursor(Long memberId);

List<RecordProjection> findAttractionRecords(Long memberId, Long cursorNo, int displayPerPage);

List<AttractionPhotoProjection> findByRecordDtos(List<RecordProjection> dtos);
List<RecordProjection> findAttractionRecords(long memberId, long cursorNo, int displayPerPage);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package com.dnd.dndtravel.map.repository.custom;

import static com.dnd.dndtravel.map.domain.QAttraction.attraction;
import static com.dnd.dndtravel.map.domain.QMemberAttraction.memberAttraction;
import static com.dnd.dndtravel.map.domain.QPhoto.photo;
import static com.dnd.dndtravel.member.domain.QMember.member;

import java.util.List;

import com.dnd.dndtravel.map.repository.dto.projection.AttractionPhotoProjection;
import com.dnd.dndtravel.map.repository.dto.projection.RecordProjection;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Projections;
Expand All @@ -28,7 +27,7 @@ public class MemberAttractionRepositoryImpl implements MemberAttractionRepositor
* from memberAttraction ma
*/
@Override
public Long maxCursor(Long memberId) {
public Long maxCursor(long memberId) {
return jpaQueryFactory.select(memberAttraction.id.max())
.from(memberAttraction)
.fetchOne();
Expand All @@ -44,41 +43,25 @@ public Long maxCursor(Long memberId) {
*/

@Override
public List<RecordProjection> findAttractionRecords(Long memberId, Long cursorNo, int displayPerPage) {
public List<RecordProjection> findAttractionRecords(long memberId, long cursorNo, int displayPerPage) {
return jpaQueryFactory.select(Projections.constructor(RecordProjection.class,
memberAttraction.id,
ExpressionUtils.as(JPAExpressions
.select(memberAttraction.id.count())
.from(memberAttraction)
.where(memberAttraction.member.id.eq(member.id)), entireRecordCount
),
memberAttraction.attractionName,
memberAttraction.memo,
memberAttraction.localDate,
memberAttraction.region
memberAttraction.region,
attraction
))
.from(memberAttraction)
.join(member).on(memberAttraction.member.id.eq(member.id))
.where(memberAttraction.member.id.eq(memberId)
.and(memberAttraction.id.gt(cursorNo)))
.join(attraction).on(memberAttraction.attraction.id.eq(attraction.id))
.where(memberAttraction.id.lt(cursorNo))
.orderBy(memberAttraction.id.desc())
.limit(displayPerPage)
.fetch();
}

@Override
public List<AttractionPhotoProjection> findByRecordDtos(List<RecordProjection> recordDtos) {
List<Long> memberAttractionIds = recordDtos.stream()
.map(RecordProjection::getMemberAttractionId)
.toList();

return jpaQueryFactory.select(
Projections.constructor(AttractionPhotoProjection.class,
memberAttraction.id,
photo.url))
.from(photo)
.join(photo.memberAttraction, memberAttraction)
.where(photo.memberAttraction.id.in(memberAttractionIds))
.fetch();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.dnd.dndtravel.map.repository.custom;

import java.util.List;

import com.dnd.dndtravel.map.repository.dto.projection.AttractionPhotoProjection;
import com.dnd.dndtravel.map.repository.dto.projection.RecordProjection;

public interface PhotoRepositoryCustom {

List<AttractionPhotoProjection> findByRecordDtos(List<RecordProjection> dtos);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.dnd.dndtravel.map.repository.custom;

import static com.dnd.dndtravel.map.domain.QMemberAttraction.memberAttraction;
import static com.dnd.dndtravel.map.domain.QPhoto.photo;

import java.util.List;

import com.dnd.dndtravel.map.repository.dto.projection.AttractionPhotoProjection;
import com.dnd.dndtravel.map.repository.dto.projection.RecordProjection;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class PhotoRepositoryImpl implements PhotoRepositoryCustom {

private final JPAQueryFactory jpaQueryFactory;

@Override
public List<AttractionPhotoProjection> findByRecordDtos(List<RecordProjection> recordDtos) {
List<Long> memberAttractionIds = recordDtos.stream()
.map(RecordProjection::getMemberAttractionId)
.toList();

return jpaQueryFactory.select(
Projections.constructor(AttractionPhotoProjection.class,
memberAttraction.id,
photo.url))
.from(photo)
.join(photo.memberAttraction, memberAttraction)
.where(photo.memberAttraction.id.in(memberAttractionIds))
.fetch();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import com.dnd.dndtravel.map.domain.Attraction;

import lombok.Getter;

Expand All @@ -14,28 +15,33 @@
public class RecordProjection {
private final long memberAttractionId;
private final long entireRecordCount;
private final String attractionName;
private String attractionName;
private final String memo;
private final LocalDate visitDate;
private final String region;
private final Attraction attraction;
private List<String> photoUrls;

public RecordProjection(long memberAttractionId, long entireRecordCount, String attractionName, String memo,
LocalDate visitDate, String region) {
public RecordProjection(long memberAttractionId, long entireRecordCount, String memo,
LocalDate visitDate, String region, Attraction attraction) {
this.memberAttractionId = memberAttractionId;
this.entireRecordCount = entireRecordCount;
this.attractionName = attractionName;
this.memo = memo;
this.visitDate = visitDate;
this.region = region;
this.attraction = attraction;
}

public void inputPhotoUrls(List<AttractionPhotoProjection> attractionPhotoProjections) {
if (attractionPhotoProjections != null) {
this.photoUrls = attractionPhotoProjections.stream()
.map(AttractionPhotoProjection::photoUrl)
.filter(Objects::nonNull)
.collect(Collectors.toList());
.toList();
}
}

public void inputAttractionNames() {
this.attractionName = this.attraction.getName();
}
}
30 changes: 10 additions & 20 deletions src/main/java/com/dnd/dndtravel/map/service/MapService.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ public void recordAttraction(RecordDto recordDto, long memberId) {
Attraction attraction = attractionRepository.findByName(recordDto.attractionName())
.orElseGet(() -> attractionRepository.save(Attraction.of(region, recordDto.attractionName())));

// 유저가 이미 기록한적 없는 방문명소면 DB에 저장
MemberAttraction memberAttraction = recordMemberAttraction(recordDto, attraction, member);
MemberAttraction memberAttraction = memberAttractionRepository.save(
MemberAttraction.of(member, attraction, recordDto.memo(),
recordDto.dateTime(), recordDto.region()));

// 사진 업로드
savePhotos(recordDto.photos(), memberAttraction);
Expand All @@ -98,21 +99,22 @@ public List<AttractionRecordResponse> allRecords(long memberId, long cursorNo, i

// 첫 커서값인 경우
if (cursorNo <= 0) {
cursorNo = memberAttractionRepository.maxCursor(member.getId()) - displayPerPage;
cursorNo = memberAttractionRepository.maxCursor(member.getId());
}

List<RecordProjection> attractionRecords = memberAttractionRepository.findAttractionRecords(memberId, cursorNo, displayPerPage);

//해당 DTO에 존재하는 memberAttractionId들로 photo url 매핑
setPhotoToRecords(attractionRecords);
// 명소명 저장
attractionRecords.forEach(RecordProjection::inputAttractionNames);
// 사진 URL 저장
setPhotoUrlsWithJoin(attractionRecords);

return attractionRecords.stream()
.map(AttractionRecordResponse::from)
.toList();
}

private void setPhotoToRecords(List<RecordProjection> attractionRecords) {
List<AttractionPhotoProjection> attractionPhotos = memberAttractionRepository.findByRecordDtos(
private void setPhotoUrlsWithJoin(List<RecordProjection> attractionRecords) {
List<AttractionPhotoProjection> attractionPhotos = photoRepository.findByRecordDtos(
attractionRecords);

Map<Long, List<AttractionPhotoProjection>> attractionPhotoIds = attractionPhotos.stream()
Expand All @@ -138,18 +140,6 @@ private List<RegionDto> updateRegionDto(List<RegionDto> regions, List<MemberRegi
.toList();
}

private MemberAttraction recordMemberAttraction(RecordDto recordDto, Attraction attraction, Member member) {
MemberAttraction memberAttraction = memberAttractionRepository.findByAttractionIdAndMemberId(
attraction.getId(), member.getId());

if (memberAttraction == null) {
memberAttraction = MemberAttraction.of(member, attraction, recordDto.memo(),
recordDto.dateTime(), recordDto.region(), recordDto.attractionName());
memberAttractionRepository.save(memberAttraction);
}
return memberAttraction;
}

private void updateRegionVisitCount(Member member, Region region) {
MemberRegion memberRegion = memberRegionRepository.findByMemberIdAndRegionId(member.getId(),
region.getId());
Expand Down

0 comments on commit a4bbf42

Please sign in to comment.