Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public ResponseEntity<CategoryResponse> createCategory(
@LoginUser Long userId,
@Valid @RequestBody CategoryRequest categoryRequest) {
CategoryResponse response = categoryService.createCategory(userId, categoryRequest);
return new ResponseEntity<>(response, HttpStatus.CREATED);
return ResponseEntity.status(HttpStatus.CREATED).body(response);
}

@PatchMapping("/categories/{categoryId}")
Expand All @@ -64,7 +64,7 @@ public ResponseEntity<CategoryResponse> updateCategory(
return ResponseEntity.ok(response);
}

@DeleteMapping("/{categoryId}")
@DeleteMapping("/categories/{categoryId}")
@Operation(
summary = "카테고리 삭제",
responses = {
Expand All @@ -76,7 +76,7 @@ public ResponseEntity<Void> deleteCategory(
@LoginUser Long userId,
@PathVariable("categoryId") Long categoryId) {
categoryService.deleteCategory(userId, categoryId);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
return ResponseEntity.noContent().build();
}

@GetMapping("/users/{userId}/categories")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.jiwon.mylog.domain.comment.dto.response.CommentResponse;
import com.jiwon.mylog.domain.comment.entity.QComment;
import com.jiwon.mylog.domain.image.entity.QProfileImage;
import com.jiwon.mylog.domain.user.dto.response.UserResponse;
import com.jiwon.mylog.domain.user.entity.QUser;
import com.querydsl.core.BooleanBuilder;
Expand All @@ -23,7 +22,6 @@ public class CommentRepositoryImpl implements CommentRepositoryCustom {

private static final QComment COMMENT = QComment.comment;
private static final QUser USER = QUser.user;
private static final QProfileImage PROFILE_IMAGE = QProfileImage.profileImage;
private final JPAQueryFactory jpaQueryFactory;

@Override
Expand All @@ -45,7 +43,7 @@ public Page<CommentResponse> findByPostId(Long postId, Pageable pageable) {
USER.id,
USER.username,
USER.bio,
PROFILE_IMAGE.fileKey.coalesce(""),
USER.profileImage,
USER.status
),
COMMENT.createdAt,
Expand All @@ -55,7 +53,6 @@ public Page<CommentResponse> findByPostId(Long postId, Pageable pageable) {
)
.from(COMMENT)
.leftJoin(COMMENT.user, USER)
.leftJoin(USER.profileImage, PROFILE_IMAGE)
.where(conditions)
.orderBy(COMMENT.createdAt.desc(), COMMENT.id.desc())
.offset(pageable.getOffset())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.jiwon.mylog.domain.follow.controller;

import com.jiwon.mylog.domain.follow.dto.FollowCheckResponse;
import com.jiwon.mylog.domain.follow.dto.FollowCountResponse;
import com.jiwon.mylog.domain.follow.dto.FollowListResponse;
import com.jiwon.mylog.domain.follow.service.FollowService;
Expand Down Expand Up @@ -36,7 +37,7 @@ public ResponseEntity<Void> follow(
@LoginUser Long fromUserId,
@PathVariable("toUserId") Long toUserId) {
followService.follow(fromUserId, toUserId);
return new ResponseEntity<>(HttpStatus.OK);
return ResponseEntity.status(HttpStatus.CREATED).build();
}

@DeleteMapping("/follow/{toUserId}")
Expand All @@ -52,15 +53,15 @@ public ResponseEntity<Void> unfollow(
@LoginUser Long fromUserId,
@PathVariable("toUserId") Long toUserId) {
followService.unfollow(fromUserId, toUserId);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
return ResponseEntity.noContent().build();
}

@GetMapping("/{currentUserId}/followings/{targetUserId}")
public ResponseEntity<?> checkFollowing(
public ResponseEntity<FollowCheckResponse> checkFollowing(
@PathVariable("currentUserId") Long currentUserId,
@PathVariable("targetUserId") Long targetUserId) {
Boolean response = followService.checkFollowing(currentUserId, targetUserId);
return new ResponseEntity<>(response, HttpStatus.OK);
FollowCheckResponse response = followService.checkFollowing(currentUserId, targetUserId);
return ResponseEntity.ok(response);
}

@GetMapping("/{userId}/followings")
Expand All @@ -72,7 +73,7 @@ public ResponseEntity<?> checkFollowing(
)
public ResponseEntity<?> getFollowings(@PathVariable("userId") Long userId) {
FollowListResponse response = followService.getFollowings(userId);
return new ResponseEntity<>(response, HttpStatus.OK);
return ResponseEntity.ok(response);
}

@GetMapping("/{userId}/followers")
Expand All @@ -84,10 +85,10 @@ public ResponseEntity<?> getFollowings(@PathVariable("userId") Long userId) {
)
public ResponseEntity<?> getFollowers(@PathVariable("userId") Long userId) {
FollowListResponse response = followService.getFollowers(userId);
return new ResponseEntity<>(response, HttpStatus.OK);
return ResponseEntity.ok(response);
}

@GetMapping("/{userId}/follows")
@GetMapping("/{userId}/follows/counts")
@Operation(
summary = "특정 유저의 팔로잉/팔로워 수 조회",
responses = {
Expand All @@ -96,6 +97,6 @@ public ResponseEntity<?> getFollowers(@PathVariable("userId") Long userId) {
)
public ResponseEntity<FollowCountResponse> getFollowCounts(@PathVariable("userId") Long userId) {
FollowCountResponse response = followService.getFollowCounts(userId);
return new ResponseEntity<>(response, HttpStatus.OK);
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.jiwon.mylog.domain.follow.dto;

public record FollowCheckResponse(
boolean isFollowing
) {
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.jiwon.mylog.domain.follow.dto;

import com.jiwon.mylog.domain.user.entity.User;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@AllArgsConstructor
@Builder
@Getter
public class FollowResponse {
Expand All @@ -15,7 +17,7 @@ public static FollowResponse fromUser(User user) {
return FollowResponse.builder()
.userId(user.getId())
.username(user.getUsername())
.imageKey(user.getProfileImage() == null ? "" : user.getProfileImage().getFileKey())
.imageKey(user.getProfileImage())
.build();
}
}
14 changes: 12 additions & 2 deletions src/main/java/com/jiwon/mylog/domain/follow/entity/Follow.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -24,15 +26,23 @@
@Builder
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(
uniqueConstraints = {
@UniqueConstraint(
name = "uk_follow_from_to",
columnNames = {"from_user_id", "to_user_id"}
)
}
)
public class Follow {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private User fromUser;

@ManyToOne(fetch = FetchType.LAZY)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private User toUser;

@CreatedDate
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.jiwon.mylog.domain.follow.repository;

import com.jiwon.mylog.domain.follow.dto.FollowResponse;
import java.util.List;

public interface CustomFollowRepository {
List<FollowResponse> findFollowings(Long fromUserId);
List<FollowResponse> findFollowers(Long toUserId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,14 @@
import java.util.Optional;

@Repository
public interface FollowRepository extends JpaRepository<Follow, Long> {
public interface FollowRepository extends JpaRepository<Follow, Long>, CustomFollowRepository {
boolean existsByFromUserIdAndToUserId(Long fromUserId, Long toUserId);

@Query("select f from Follow f " +
"join fetch f.fromUser " +
"where f.fromUser.id = :fromUserId and f.toUser.id = :toUserId")
Optional<Follow> findByFromUserIdAndToUserId(@Param("fromUserId") Long fromUserId, @Param("toUserId") Long toUserId);

@Query("select " +
"sum(case when f.fromUser.id = :userId then 1 else 0 end), " +
"sum(case when f.toUser.id = :userId then 1 else 0 end) " +
"from Follow f " +
"where f.fromUser.id = :userId or f.toUser.id = :userId")
List<Object[]> countFollowsByUserId(@Param("userId") Long userId);

@Query("select f.toUser from Follow f where f.fromUser.id = :fromUserId order by f.createdAt desc")
List<User> findFollowings(@Param("fromUserId") Long fromUserId);

@Query("select f.fromUser from Follow f where f.toUser.id = :toUserId order by f.createdAt desc")
List<User> findFollowers(@Param("toUserId") Long toUserId);
long countByFromUserId(Long fromUserId);
long countByToUserId(Long toUserId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.jiwon.mylog.domain.follow.repository;

import com.jiwon.mylog.domain.follow.dto.FollowResponse;
import com.jiwon.mylog.domain.follow.entity.QFollow;
import com.jiwon.mylog.domain.user.entity.QUser;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

@RequiredArgsConstructor
@Repository
public class FollowRepositoryImpl implements CustomFollowRepository {

private final static QFollow FOLLOW = QFollow.follow;
private final static QUser USER = QUser.user;

private final JPAQueryFactory queryFactory;

@Override
public List<FollowResponse> findFollowings(Long fromUserId) {
return queryFactory
.select(Projections.constructor(FollowResponse.class,
FOLLOW.toUser.id,
FOLLOW.toUser.username,
USER.profileImage
))
.from(FOLLOW)
.join(FOLLOW.toUser, USER)
.where(FOLLOW.fromUser.id.eq(fromUserId))
.orderBy(FOLLOW.createdAt.desc())
.fetch();
}

@Override
public List<FollowResponse> findFollowers(Long toUserId) {
return queryFactory
.select(Projections.constructor(FollowResponse.class,
FOLLOW.fromUser.id,
FOLLOW.fromUser.username,
USER.profileImage
))
.from(FOLLOW)
.join(FOLLOW.fromUser, USER)
.where(FOLLOW.toUser.id.eq(toUserId))
.orderBy(FOLLOW.createdAt.desc())
.fetch();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.jiwon.mylog.domain.event.dto.follow.FollowCreatedEvent;
import com.jiwon.mylog.domain.event.dto.follow.FollowDeletedEvent;
import com.jiwon.mylog.domain.follow.dto.FollowCheckResponse;
import com.jiwon.mylog.domain.follow.dto.FollowCountResponse;
import com.jiwon.mylog.domain.follow.dto.FollowListResponse;
import com.jiwon.mylog.domain.follow.dto.FollowResponse;
Expand Down Expand Up @@ -51,7 +52,6 @@ public void follow(Long fromUserId, Long toUserId) {

@Transactional
public void unfollow(Long fromUserId, Long toUserId) {
validateFollow(fromUserId, toUserId);
validateIsFollowing(fromUserId, toUserId, false);

Follow follow = followRepository.findByFromUserIdAndToUserId(fromUserId, toUserId)
Expand All @@ -71,32 +71,27 @@ public void unfollow(Long fromUserId, Long toUserId) {
}

@Transactional(readOnly = true)
public Boolean checkFollowing(Long currentUserId, Long targetUserId) {
return followRepository.existsByFromUserIdAndToUserId(currentUserId, targetUserId);
public FollowCheckResponse checkFollowing(Long currentUserId, Long targetUserId) {
boolean isFollowing = followRepository.existsByFromUserIdAndToUserId(currentUserId, targetUserId);
return new FollowCheckResponse(isFollowing);
}

@Transactional(readOnly = true)
public FollowListResponse getFollowings(Long userId) {
List<FollowResponse> followings = followRepository.findFollowings(userId).stream()
.map(FollowResponse::fromUser)
.toList();
List<FollowResponse> followings = followRepository.findFollowings(userId);
return new FollowListResponse(followings);
}

@Transactional(readOnly = true)
public FollowListResponse getFollowers(Long userId) {
List<FollowResponse> followers = followRepository.findFollowers(userId).stream()
.map(FollowResponse::fromUser)
.toList();
List<FollowResponse> followers = followRepository.findFollowers(userId);
return new FollowListResponse(followers);
}

@Transactional(readOnly = true)
public FollowCountResponse getFollowCounts(Long userId) {
List<Object[]> counts = followRepository.countFollowsByUserId(userId);
Object[] row = counts.get(0);
Long followingsCount = row[0] != null ? ((Number) row[0]).longValue() : 0L;
Long followersCount = row[1] != null ? ((Number) row[1]).longValue() : 0L;
long followingsCount = followRepository.countByFromUserId(userId);
long followersCount = followRepository.countByToUserId(userId);
return new FollowCountResponse(followingsCount, followersCount);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,4 @@
@Repository
public interface GuestBookRepository extends JpaRepository<GuestBook, Long>, GuestBookCustom {

/***
* @Query("select new com.jiwon.mylog.domain.post.dto.response.PinnedPostResponse(p.id, p.title, p.contentPreview) " +
* "from Post p " +
* "where p.user.id = :userId and p.pinned = true and p.deletedAt is null")
* @param receiverId
* @return
*/

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.jiwon.mylog.domain.guestbook.dto.GuestBookResponse;
import com.jiwon.mylog.domain.guestbook.entity.QGuestBook;
import com.jiwon.mylog.domain.image.entity.QProfileImage;
import com.jiwon.mylog.domain.user.dto.response.UserSummaryResponse;
import com.jiwon.mylog.domain.user.entity.QUser;
import com.querydsl.core.BooleanBuilder;
Expand All @@ -23,7 +22,6 @@ public class GuestBookRepositoryImpl implements GuestBookCustom {
private final JPAQueryFactory jpaQueryFactory;
private static final QGuestBook GUEST_BOOK = QGuestBook.guestBook;
private static final QUser USER = QUser.user;
private static final QProfileImage PROFILE_IMAGE = QProfileImage.profileImage;

@Override
public Page<GuestBookResponse> getGuestBooksByReceiverId(Long receiverId, Pageable pageable) {
Expand All @@ -40,13 +38,12 @@ public Page<GuestBookResponse> getGuestBooksByReceiverId(Long receiverId, Pageab
Projections.constructor(UserSummaryResponse.class,
USER.id,
USER.username,
PROFILE_IMAGE.fileKey.coalesce("")
USER.profileImage
)
)
)
.from(GUEST_BOOK)
.join(GUEST_BOOK.writer, USER)
.leftJoin(USER.profileImage, PROFILE_IMAGE)
.where(builder)
.orderBy(GUEST_BOOK.createdAt.desc())
.offset(pageable.getOffset())
Expand Down
Loading
Loading