Skip to content

Commit

Permalink
아이템 수정 & 데이로그 수정 & 아이템 oridinal 수정 재업로드 (#710)
Browse files Browse the repository at this point in the history
* refactor: 아이템, 데이로그 수정 쿼리 개선

* refactor: 아이템 수정 로직 변경
  • Loading branch information
hgo641 authored and jjongwa committed Oct 19, 2023
1 parent 7231143 commit cbd3a3e
Show file tree
Hide file tree
Showing 15 changed files with 343 additions and 105 deletions.
18 changes: 18 additions & 0 deletions backend/src/main/java/hanglog/category/domain/Category.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import java.util.Objects;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -28,4 +29,21 @@ public class Category extends BaseEntity {

@Column(nullable = false, length = 50)
private String korName;

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Category category)) {
return false;
}
return Objects.equals(id, category.id) && Objects.equals(engName, category.engName)
&& Objects.equals(korName, category.korName);
}

@Override
public int hashCode() {
return Objects.hash(id, engName, korName);
}
}
18 changes: 18 additions & 0 deletions backend/src/main/java/hanglog/expense/domain/Expense.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import java.util.Objects;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.SQLDelete;
Expand Down Expand Up @@ -59,4 +60,21 @@ public Expense(
) {
this(null, currency, amount, category);
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Expense expense)) {
return false;
}
return Objects.equals(currency, expense.currency) && Objects.equals(amount, expense.amount)
&& Objects.equals(category, expense.category);
}

@Override
public int hashCode() {
return Objects.hash(currency, amount, category);
}
}
3 changes: 1 addition & 2 deletions backend/src/main/java/hanglog/image/domain/Image.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package hanglog.image.domain;

import static jakarta.persistence.CascadeType.PERSIST;
import static jakarta.persistence.FetchType.LAZY;
import static jakarta.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;
Expand Down Expand Up @@ -32,7 +31,7 @@ public class Image extends BaseEntity {
@Column(nullable = false, unique = true)
private String name;

@ManyToOne(fetch = LAZY, cascade = {PERSIST})
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "item_id")
private Item item;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package hanglog.image.domain.repository;

import hanglog.image.domain.Image;
import java.util.List;

public interface CustomImageRepository {

void saveAll(final List<Image> images);

void deleteAll(final List<Image> images);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package hanglog.image.infrastructure;

import hanglog.image.domain.Image;
import hanglog.image.domain.repository.CustomImageRepository;
import java.time.LocalDateTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;

@RequiredArgsConstructor
@Repository
public class CustomImageRepositoryImpl implements CustomImageRepository {

private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;

@Override
public void saveAll(final List<Image> images) {
final String sql = """
INSERT INTO image (created_at, modified_at, item_id, name, status)
VALUES (:createdAt, :modifiedAt, :itemId, :name, :status)
""";
namedParameterJdbcTemplate.batchUpdate(sql, getImageToSqlParameterSources(images));
}

@Override
public void deleteAll(final List<Image> images) {
final String sql = """
DELETE FROM image WHERE id IN (:imageIds)
""";
namedParameterJdbcTemplate.update(sql, getDeletedImageIdsSqlParameterSources(images));
}

private SqlParameterSource getDeletedImageIdsSqlParameterSources(final List<Image> images) {
final List<Long> imageIds = images.stream()
.map(Image::getId)
.toList();
return new MapSqlParameterSource("imageIds", imageIds);
}

private MapSqlParameterSource[] getImageToSqlParameterSources(final List<Image> images) {
return images.stream()
.map(this::getImageToSqlParameterSource)
.toArray(MapSqlParameterSource[]::new);
}

private MapSqlParameterSource getImageToSqlParameterSource(final Image image) {
final LocalDateTime now = LocalDateTime.now();
return new MapSqlParameterSource()
.addValue("createdAt", now)
.addValue("modifiedAt", now)
.addValue("itemId", image.getItem().getId())
.addValue("name", image.getName())
.addValue("status", image.getStatus().name());
}
}
13 changes: 8 additions & 5 deletions backend/src/main/java/hanglog/trip/domain/Item.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import static hanglog.global.exception.ExceptionCode.INVALID_EXPENSE_UNDER_MIN;
import static hanglog.global.exception.ExceptionCode.INVALID_RATING;
import static hanglog.global.type.StatusType.USABLE;
import static jakarta.persistence.CascadeType.MERGE;
import static jakarta.persistence.CascadeType.PERSIST;
import static jakarta.persistence.CascadeType.REMOVE;
import static jakarta.persistence.EnumType.STRING;
Expand Down Expand Up @@ -68,19 +67,19 @@ public class Item extends BaseEntity {

private String memo;

@OneToOne(fetch = LAZY, cascade = {PERSIST, MERGE, REMOVE}, orphanRemoval = true)
@OneToOne(fetch = LAZY, cascade = REMOVE)
@JoinColumn(name = "place_id")
private Place place;

@ManyToOne(fetch = LAZY, cascade = {PERSIST})
@ManyToOne(fetch = LAZY, cascade = PERSIST)
@JoinColumn(name = "day_log_id", nullable = false)
private DayLog dayLog;

@OneToOne(fetch = LAZY, cascade = {PERSIST, MERGE, REMOVE}, orphanRemoval = true)
@OneToOne(fetch = LAZY, cascade = REMOVE)
@JoinColumn(name = "expense_id")
private Expense expense;

@OneToMany(mappedBy = "item", fetch = LAZY, cascade = {PERSIST, MERGE, REMOVE}, orphanRemoval = true)
@OneToMany(mappedBy = "item", fetch = LAZY, cascade = REMOVE)
private List<Image> images = new ArrayList<>();

public Item(
Expand Down Expand Up @@ -198,4 +197,8 @@ private boolean isInvalidRatingFormat(final Double rating) {
public void changeOrdinal(final int ordinal) {
this.ordinal = ordinal;
}

public boolean isSpot() {
return itemType.isSpot();
}
}
19 changes: 19 additions & 0 deletions backend/src/main/java/hanglog/trip/domain/Place.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import java.math.BigDecimal;
import java.util.Objects;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand Down Expand Up @@ -55,4 +56,22 @@ public Place(
this.longitude = longitude;
this.category = category;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Place place)) {
return false;
}
return Objects.equals(name, place.name) && Objects.equals(latitude, place.latitude)
&& Objects.equals(longitude, place.longitude) && Objects.equals(category,
place.category);
}

@Override
public int hashCode() {
return Objects.hash(name, latitude, longitude, category);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@
public interface CustomItemRepository {

List<ItemElement> findItemIdsByDayLogIds(final List<Long> dayLogIds);

void updateOrdinals(final List<Long> orderedItemIds);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,35 @@

import hanglog.trip.domain.DayLog;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface DayLogRepository extends JpaRepository<DayLog, Long> {

@Query("""
SELECT dayLog
FROM DayLog dayLog
LEFT JOIN FETCH dayLog.items items
WHERE dayLog.id = :dayLogId
""")
Optional<DayLog> findWithItemsById(@Param("dayLogId") final Long dayLogId);

@Query("""
SELECT dayLog
FROM DayLog dayLog
LEFT JOIN FETCH dayLog.items items
LEFT JOIN FETCH items.images images
LEFT JOIN FETCH items.expense expense
LEFT JOIN FETCH items.place place
LEFT JOIN FETCH expense.category expense_category
LEFT JOIN FETCH place.category place_category
WHERE dayLog.id = :dayLogId
""")
Optional<DayLog> findWithItemDetailsById(@Param("dayLogId") final Long dayLogId);

@Modifying
@Query("""
UPDATE DayLog dayLog
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import hanglog.trip.domain.repository.CustomItemRepository;
import hanglog.trip.dto.ItemElement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;

@RequiredArgsConstructor
Expand All @@ -34,4 +37,24 @@ WHERE i.day_log_id IN (:dayLogIds)
parameters.addValue("dayLogIds", dayLogIds);
return namedParameterJdbcTemplate.query(sql, parameters, elementRowMapper);
}

@Override
public void updateOrdinals(final List<Long> orderedItemIds) {
final String sql = "UPDATE item SET ordinal = :newOrdinal WHERE id = :itemId";
final SqlParameterSource[] sqlParameterSources = getUpdateOrdinalsSqlParameterSources(orderedItemIds);
namedParameterJdbcTemplate.batchUpdate(sql, sqlParameterSources);
}

private SqlParameterSource[] getUpdateOrdinalsSqlParameterSources(final List<Long> orderedItemIds) {
final SqlParameterSource[] sqlParameterSources = new MapSqlParameterSource[orderedItemIds.size()];
for (int i = 0; i < orderedItemIds.size(); i++) {
final Long itemId = orderedItemIds.get(i);
final int newOrdinal = i + 1;
final Map<String, Object> sqlParameterSource = new HashMap<>();
sqlParameterSource.put("newOrdinal", newOrdinal);
sqlParameterSource.put("itemId", itemId);
sqlParameterSources[i] = new MapSqlParameterSource(sqlParameterSource);
}
return sqlParameterSources;
}
}
21 changes: 5 additions & 16 deletions backend/src/main/java/hanglog/trip/service/DayLogService.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
import static hanglog.global.exception.ExceptionCode.INVALID_ORDERED_ITEM_IDS;
import static hanglog.global.exception.ExceptionCode.NOT_FOUND_DAY_LOG_ID;
import static hanglog.global.exception.ExceptionCode.NOT_FOUND_TRIP_ID;
import static hanglog.global.exception.ExceptionCode.NOT_FOUND_TRIP_ITEM_ID;

import hanglog.global.exception.BadRequestException;
import hanglog.trip.domain.DayLog;
import hanglog.trip.domain.Item;
import hanglog.trip.domain.repository.CustomItemRepository;
import hanglog.trip.domain.repository.DayLogRepository;
import hanglog.trip.domain.repository.ItemRepository;
import hanglog.trip.dto.request.DayLogUpdateTitleRequest;
import hanglog.trip.dto.request.ItemsOrdinalUpdateRequest;
import hanglog.trip.dto.response.DayLogResponse;
Expand All @@ -29,7 +28,7 @@
public class DayLogService {

private final DayLogRepository dayLogRepository;
private final ItemRepository itemRepository;
private final CustomItemRepository customItemRepository;

@Transactional(readOnly = true)
public DayLogResponse getById(final Long id) {
Expand All @@ -41,7 +40,7 @@ public DayLogResponse getById(final Long id) {
}

public void updateTitle(final Long id, final DayLogUpdateTitleRequest request) {
final DayLog dayLog = dayLogRepository.findById(id)
final DayLog dayLog = dayLogRepository.findWithItemsById(id)
.orElseThrow(() -> new BadRequestException(NOT_FOUND_DAY_LOG_ID));
validateAlreadyDeleted(dayLog);

Expand All @@ -62,13 +61,13 @@ private void validateAlreadyDeleted(final DayLog dayLog) {
}

public void updateOrdinalOfItems(final Long dayLogId, final ItemsOrdinalUpdateRequest itemsOrdinalUpdateRequest) {
final DayLog dayLog = dayLogRepository.findById(dayLogId)
final DayLog dayLog = dayLogRepository.findWithItemsById(dayLogId)
.orElseThrow(() -> new BadRequestException(NOT_FOUND_DAY_LOG_ID));
final List<Item> items = dayLog.getItems();

final List<Long> orderedItemIds = itemsOrdinalUpdateRequest.getItemIds();
validateOrderedItemIds(items, orderedItemIds);
changeOrdinalOfItemsByOrderedItemIds(orderedItemIds);
customItemRepository.updateOrdinals(orderedItemIds);
}

private void validateOrderedItemIds(final List<Item> items, final List<Long> orderedItemIds) {
Expand All @@ -81,14 +80,4 @@ private void validateOrderedItemIds(final List<Item> items, final List<Long> ord
throw new BadRequestException(INVALID_ORDERED_ITEM_IDS);
}
}

private void changeOrdinalOfItemsByOrderedItemIds(final List<Long> orderedItemIds) {
int ordinal = 1;

for (final Long itemId : orderedItemIds) {
final Item item = itemRepository.findById(itemId)
.orElseThrow(() -> new BadRequestException(NOT_FOUND_TRIP_ITEM_ID));
item.changeOrdinal(ordinal++);
}
}
}
Loading

0 comments on commit cbd3a3e

Please sign in to comment.