-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: 장소 좋아요 기능 도메인 설계 및 뼈대코드 작성 #344
Changes from all commits
510e5c3
165cbc4
b91f142
c59ecc4
c41b35b
9a0d661
7f16f7f
299ef66
742c563
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package com.now.naaga.like.domain; | ||
|
||
import com.now.naaga.common.domain.BaseEntity; | ||
import com.now.naaga.place.domain.Place; | ||
import com.now.naaga.player.domain.Player; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.EnumType; | ||
import jakarta.persistence.Enumerated; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import java.util.Objects; | ||
|
||
@Entity | ||
public class PlaceLike extends BaseEntity { | ||
|
||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Id | ||
private Long id; | ||
|
||
@ManyToOne | ||
@JoinColumn(name = "place_id") | ||
private Place place; | ||
|
||
@ManyToOne | ||
@JoinColumn(name = "player_id") | ||
private Player player; | ||
|
||
@Enumerated(EnumType.STRING) | ||
private PlaceLikeType placeLikeType; | ||
|
||
protected PlaceLike() { | ||
} | ||
|
||
public PlaceLike(final Place place, | ||
final Player player, | ||
final PlaceLikeType placeLikeType) { | ||
this(null, place, player, placeLikeType); | ||
} | ||
|
||
public PlaceLike(final Long id, | ||
final Place place, | ||
final Player player, | ||
final PlaceLikeType placeLikeType) { | ||
this.id = id; | ||
this.place = place; | ||
this.player = player; | ||
this.placeLikeType = placeLikeType; | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public Place getPlace() { | ||
return place; | ||
} | ||
|
||
public Player getPlayer() { | ||
return player; | ||
} | ||
|
||
public PlaceLikeType getType() { | ||
return placeLikeType; | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
final PlaceLike placeLike = (PlaceLike) o; | ||
return Objects.equals(id, placeLike.id); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(id); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "PlaceLike{" + | ||
"id=" + id + | ||
", placeId=" + place.getId() + | ||
", playerId=" + player.getId() + | ||
", placeLikeType=" + placeLikeType + | ||
'}'; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.now.naaga.like.domain; | ||
|
||
public enum PlaceLikeType { | ||
|
||
LIKE, | ||
DISLIKE, | ||
; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.now.naaga.like.repository; | ||
|
||
import com.now.naaga.like.domain.PlaceLike; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface PlaceLikeRepository extends JpaRepository<PlaceLike, Long> { | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package com.now.naaga.placestatistics; | ||
|
||
import com.now.naaga.common.domain.BaseEntity; | ||
import com.now.naaga.place.domain.Place; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.OneToOne; | ||
import java.util.Objects; | ||
|
||
@Entity | ||
public class PlaceStatistics extends BaseEntity { | ||
|
||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Id | ||
private Long id; | ||
|
||
@OneToOne | ||
@JoinColumn(name = "place_id") | ||
private Place place; | ||
|
||
private Long likeCount; | ||
|
||
Comment on lines
+20
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. likeCount를 place 테이블에 두지 않고 따로 테이블을 뺀 이유가 궁금합니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 역정규화로 집계를 나타내는 컬럼이 빠졌다는 것은 위에서 설명이 되어있으니 왜 테이블로 뒀는지 설명드리겠습니다!! 2가지 관점에서 볼 수 있을 것 같은데요.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 특정 장소에 대한 좋아요 요청이 오면,
만약 위의 흐름대로 진행된다면 또, 정리하자면
가 궁금합니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1번트랜잭션을 잘 짜놓지 않으면 정합성 문제가 발생할 수 있습니다. 2번PlaceStatistics를 제거하면 PlaceLike의 FK만으로는 인덱싱이 불가합니다. |
||
protected PlaceStatistics() { | ||
|
||
} | ||
|
||
public PlaceStatistics(final Place place, | ||
final Long likeCount) { | ||
this(null, place, likeCount); | ||
} | ||
|
||
|
||
public PlaceStatistics(final Long id, | ||
final Place place, | ||
final Long likeCount) { | ||
this.id = id; | ||
this.place = place; | ||
this.likeCount = likeCount; | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public Place getPlace() { | ||
return place; | ||
} | ||
|
||
public Long getLikeCount() { | ||
return likeCount; | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
final PlaceStatistics that = (PlaceStatistics) o; | ||
return Objects.equals(id, that.id); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(id); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "PlaceStatistics{" + | ||
"id=" + id + | ||
", placeId=" + place.getId() + | ||
", likeCount=" + likeCount + | ||
'}'; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.now.naaga.placestatistics.repository; | ||
|
||
import com.now.naaga.placestatistics.PlaceStatistics; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface PlaceStatisticsRepository extends JpaRepository<PlaceStatistics, Long> { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package com.now.naaga.common.builder; | ||
|
||
import com.now.naaga.like.domain.PlaceLike; | ||
import com.now.naaga.like.domain.PlaceLikeType; | ||
import com.now.naaga.like.repository.PlaceLikeRepository; | ||
import com.now.naaga.place.domain.Place; | ||
import com.now.naaga.player.domain.Player; | ||
import java.util.Optional; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class PlaceLikeBuilder { | ||
|
||
@Autowired | ||
private PlaceLikeRepository placeLikeRepository; | ||
Comment on lines
+13
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 코코닥의 명작..! |
||
|
||
@Autowired | ||
private PlaceBuilder placeBuilder; | ||
|
||
@Autowired | ||
private PlayerBuilder playerBuilder; | ||
|
||
private PlaceLikeType placeLikeType; | ||
|
||
private Optional<Place> place; | ||
|
||
private Optional<Player> player; | ||
|
||
public PlaceLikeBuilder init() { | ||
this.placeLikeType = PlaceLikeType.LIKE; | ||
this.place = Optional.empty(); | ||
this.player = Optional.empty(); | ||
return this; | ||
} | ||
|
||
public PlaceLikeBuilder placeLikeType(final PlaceLikeType placeLikeType) { | ||
this.placeLikeType = placeLikeType; | ||
return this; | ||
} | ||
|
||
public PlaceLikeBuilder place(final Place persistedPlace) { | ||
this.place = Optional.ofNullable(persistedPlace); | ||
return this; | ||
} | ||
|
||
public PlaceLikeBuilder player(final Player persistedPlayer) { | ||
this.player = Optional.ofNullable(persistedPlayer); | ||
return this; | ||
} | ||
|
||
public PlaceLike build() { | ||
final Place persistePlace = place.orElseGet(this::getPersistedPlace); | ||
final Player persistedPlayer = player.orElseGet(this::getPersistedPlayer); | ||
final PlaceLike placeLike = new PlaceLike(persistePlace, persistedPlayer, placeLikeType); | ||
return placeLikeRepository.save(placeLike); | ||
} | ||
|
||
private Player getPersistedPlayer() { | ||
return playerBuilder.init() | ||
.build(); | ||
} | ||
|
||
private Place getPersistedPlace() { | ||
return placeBuilder.init() | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.now.naaga.common.builder; | ||
|
||
import com.now.naaga.place.domain.Place; | ||
import com.now.naaga.placestatistics.PlaceStatistics; | ||
import com.now.naaga.placestatistics.repository.PlaceStatisticsRepository; | ||
import java.util.Optional; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class PlaceStatisticsBuilder { | ||
|
||
@Autowired | ||
private PlaceStatisticsRepository placeStatisticsRepository; | ||
|
||
@Autowired | ||
private PlaceBuilder placeBuilder; | ||
|
||
private Long likeCount; | ||
|
||
private Optional<Place> place; | ||
|
||
public PlaceStatisticsBuilder init() { | ||
this.place = Optional.empty(); | ||
this.likeCount = 0L; | ||
return this; | ||
} | ||
|
||
public PlaceStatisticsBuilder likeCount(final Long likeCount) { | ||
this.likeCount = likeCount; | ||
return this; | ||
} | ||
|
||
public PlaceStatisticsBuilder place(final Place persistedPlace) { | ||
this.place = Optional.ofNullable(persistedPlace); | ||
return this; | ||
} | ||
|
||
public PlaceStatistics build() { | ||
final Place persistePlace = place.orElseGet(this::getPersistedPlace); | ||
final PlaceStatistics placeStatistics = new PlaceStatistics(persistePlace, likeCount); | ||
return placeStatisticsRepository.save(placeStatistics); | ||
} | ||
|
||
private Place getPersistedPlace() { | ||
return placeBuilder.init() | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.now.naaga.common.fixture; | ||
|
||
import com.now.naaga.like.domain.PlaceLike; | ||
import com.now.naaga.like.domain.PlaceLikeType; | ||
|
||
public class PlaceLikeFixture { | ||
|
||
public static PlaceLike PLACE_LIKE() { | ||
return new PlaceLike(PlaceFixture.PLACE(), PlayerFixture.PLAYER(), PlaceLikeType.LIKE); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.now.naaga.common.fixture; | ||
|
||
import com.now.naaga.placestatistics.PlaceStatistics; | ||
|
||
public class PlaceStatisticsFixture { | ||
|
||
public static PlaceStatistics PLACE_STATISTICS() { | ||
return new PlaceStatistics(PlaceFixture.PLACE(), 0L); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이넘 굿이에요~!