[인스타그램 클론 코딩][Spring boot] 9. 스토리(메인) 페이지

2024. 2. 22. 17:10·프로젝트/인스타그램 클론 코딩
728x90
반응형

✅ 필요한 것

  • 게시글을 올린 user 정보 (이름, 프로필사진)
  • 사진에 대한 정보
  • 캡션에 대한 정보
  • 좋아요, 댓글에 대한 정보 (좀 뒤에 구현 예정)

 

📌 ImageDto

package yerong.InstagramCloneCoding.web.dto.image;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.*;
import yerong.InstagramCloneCoding.domain.user.User;

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class ImageDto {

    private Long id;
    private String caption;
    private String postImageUrl;
    private Long userId;
    private String username;
    private String profileImageUrl;
}
  • 필요한 정보들을 담을 dto 생성

 

📌 Image 엔티티

package yerong.InstagramCloneCoding.domain.image;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.*;
import lombok.*;
import yerong.InstagramCloneCoding.domain.user.User;

@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Builder
@Entity
public class Image {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "image_id")
    private Long id;

    private String caption;
    private String postImageUrl;

    @JsonIgnoreProperties({"images"}) //user에 있는 images는 무시
    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;

    //좋아요

    //댓글

}

 

  • user에 @JsonIgnoreProperties를 걸어줘서 무한로딩을 방지

 

📌 Image Repository

package yerong.InstagramCloneCoding.repository.image;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import yerong.InstagramCloneCoding.domain.image.Image;

import java.util.List;

@Repository
public interface ImageRepository extends JpaRepository<Image, Long> {
    @Query(value = "SELECT * from image where user_id = :principalId OR user_id In (SELECT to_user_id FROM subscribe WHERE from_user_id = :principalId) ", nativeQuery = true)
    List<Image> mStory(Long principalId);

}
  • 자신이 구독한 사람들의 이미지들과 나의 이미지를 가져오는 코드 구현

 

📌 ImageApiController

package yerong.InstagramCloneCoding.web.api;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import yerong.InstagramCloneCoding.config.auth.PrincipalDetails;
import yerong.InstagramCloneCoding.service.ImageService;
import yerong.InstagramCloneCoding.web.dto.CMRespDto;
import yerong.InstagramCloneCoding.web.dto.image.ImageDto;

import java.util.List;

@RequiredArgsConstructor
@RestController
@Slf4j
public class ImageApiController {

    private final ImageService imageService;
    @GetMapping("/api/image")
    public ResponseEntity<CMRespDto<?>> imageStory(@AuthenticationPrincipal PrincipalDetails principalDetails){
        List<ImageDto> imageDtos = imageService.imageStory(principalDetails.getUser().getId());
      
        return new ResponseEntity<CMRespDto<?>>(new CMRespDto<>(1, "이미지 정보 가져오기 성공", imageDtos), HttpStatus.OK);
    }
}
  • 이미지 정보를 들고오는 controller

 

✔️ 페이징하기

 

📌 ImageApiController

package yerong.InstagramCloneCoding.web.api;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import yerong.InstagramCloneCoding.config.auth.PrincipalDetails;
import yerong.InstagramCloneCoding.service.ImageService;
import yerong.InstagramCloneCoding.web.dto.CMRespDto;
import yerong.InstagramCloneCoding.web.dto.image.ImageDto;

import java.util.List;

@RequiredArgsConstructor
@RestController
public class ImageApiController {

    private final ImageService imageService;
    @GetMapping("/api/image")
    public ResponseEntity<CMRespDto<?>> imageStory(
            @AuthenticationPrincipal PrincipalDetails principalDetails,
            @PageableDefault(size = 3)Pageable pageable
            ){
        Page<ImageDto> imageDtos = imageService.imageStory(principalDetails.getUser().getId(), pageable);

        return new ResponseEntity<CMRespDto<?>>(new CMRespDto<>(1, "이미지 정보 가져오기 성공", imageDtos), HttpStatus.OK);
    }
}
  •  @PageableDefault 추가 
    • size = 3 : 3개씩 뽑아옴

📌 ImageServiceImpl

package yerong.InstagramCloneCoding.service.impl;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yerong.InstagramCloneCoding.domain.image.Image;
import yerong.InstagramCloneCoding.domain.user.User;
import yerong.InstagramCloneCoding.handler.exception.CustomValidationApiException;
import yerong.InstagramCloneCoding.repository.image.ImageRepository;
import yerong.InstagramCloneCoding.repository.user.UserRepository;
import yerong.InstagramCloneCoding.service.ImageService;
import yerong.InstagramCloneCoding.web.dto.image.ImageDto;
import yerong.InstagramCloneCoding.web.dto.image.ImageUploadDto;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
@RequiredArgsConstructor
public class ImageServiceImpl implements ImageService {

    private final ImageRepository imageRepository;
    private final UserRepository userRepository;


    @Transactional(readOnly = true)
    @Override
    public Page<ImageDto> imageStory(Long principalId, Pageable pageable){
        Page<Image> images = imageRepository.mStory(principalId, pageable);
        return images.map(image -> ImageDto.builder()
                        .id(image.getId())
                        .caption(image.getCaption())
                        .postImageUrl(image.getPostImageUrl())
                        .userId(image.getUser().getId())
                        .username(image.getUser().getUsername())
                        .profileImageUrl(image.getUser().getProfileImageUrl())
                        .build());
    }
    @Value("${file.path}")
    private String uploadFolder;

    @Override
    @Transactional
    public void imageUpload(Long userId, ImageUploadDto imageUploadDto){


        UUID uuid = UUID.randomUUID();
        String imageFileName = uuid + "_" + imageUploadDto.getFile().getOriginalFilename();
        Path imageFilePath = Paths.get(uploadFolder+imageFileName);
        try{
            Files.write(imageFilePath, imageUploadDto.getFile().getBytes());
        }
        catch (Exception e){
            e.printStackTrace();
        }
        User user = userRepository.findById(userId).orElseThrow(() -> new CustomValidationApiException("찾을 수 없는 Id 입니다."));
        Image image = imageUploadDto.toEntity(imageFileName, user);

        Image savedImage = imageRepository.save(image);
        user.addImage(savedImage);
    }
}
  • List를 Page로 바꾸고 pageable을 받아옴

 

📌 ImageRepository

package yerong.InstagramCloneCoding.repository.image;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import yerong.InstagramCloneCoding.domain.image.Image;

import java.util.List;

@Repository
public interface ImageRepository extends JpaRepository<Image, Long> {
    @Query(value = "SELECT * from image where user_id = :principalId OR user_id In (SELECT to_user_id FROM subscribe WHERE from_user_id = :principalId) ORDER BY image_id DESC ", nativeQuery = true)
    Page<Image> mStory(Long principalId, Pageable pageable);

}
  • 페이징 코드 추가

 

 

 


PREV

 

[인스타그램 클론 코딩][Spring boot] 8. 구독 정보 뷰 렌더링

✅ 구독 정보를 누르면 page User의 구독 정보를 볼 수 있음 ✅ 여기서 구독취소/구독하기 버튼은 로그인한 user를 기준으로 구분되어야 함. 📌 UserProfileDto package yerong.InstagramCloneCoding.web.dto.user; impor

nyeroni.tistory.com

NEXT

 

[인스타그램 클론 코딩][Spring boot] 10. 좋아요 구현

📌 Likes 엔티티 구현 package yerong.InstagramCloneCoding.domain.likes; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import jakarta.persistence.*; import lombok.*; import yerong.InstagramCloneCoding.domain.BaseTimeEntity; import yero

nyeroni.tistory.com

 

 

728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'프로젝트 > 인스타그램 클론 코딩' 카테고리의 다른 글

[인스타그램 클론 코딩][Spring boot] 11. 댓글 구현  (0) 2024.03.01
[인스타그램 클론 코딩][Spring boot] 10. 좋아요 및 인기 페이지 구현  (0) 2024.02.23
[인스타그램 클론 코딩][Spring boot] 8. 구독 정보 뷰 렌더링  (0) 2024.02.21
[인스타그램 클론 코딩][Spring boot] 7. 프로필 페이지  (2) 2024.02.20
[인스타그램 클론 코딩][Spring boot] 6. 구독하기  (1) 2024.02.19
'프로젝트/인스타그램 클론 코딩' 카테고리의 다른 글
  • [인스타그램 클론 코딩][Spring boot] 11. 댓글 구현
  • [인스타그램 클론 코딩][Spring boot] 10. 좋아요 및 인기 페이지 구현
  • [인스타그램 클론 코딩][Spring boot] 8. 구독 정보 뷰 렌더링
  • [인스타그램 클론 코딩][Spring boot] 7. 프로필 페이지
예롱메롱
예롱메롱
  • 예롱메롱
    예롱이의 개발 블로그
    예롱메롱
  • 전체
    오늘
    어제
    • 전체보기 (274)
      • 프로젝트 (35)
        • Wedle (12)
        • 인스타그램 클론 코딩 (13)
        • 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 (10)
      • 인프런 Spring 강의 정리 (79)
        • 스프링 입문 - 코드로 배우는 스프링 부트, 웹 .. (7)
        • Spring 핵심 원리 - 기본편 (9)
        • 모든 개발자를 위한 HTTP 웹 기본 지식 (8)
        • 자바 ORM 표준 JPA 프로그래밍 - 기본편 (11)
        • 실전! 스프링 부트와 JPA 활용1 - 웹 애플리.. (6)
        • 실전! 스프링 부트와 JPA 활용2 - API 개.. (5)
        • 실전! 스프링 데이터 JPA (7)
        • 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 (7)
        • 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 (11)
        • 실전! Querydsl (8)
      • Cloud (3)
      • Spring (6)
        • spring boot (5)
        • 소셜로그인 (1)
      • Docker (2)
      • DevOps (0)
      • Coding Test (114)
        • Programmers (37)
        • Baekjoon (76)
      • KB It's Your Life 6기 (1)
      • CS (18)
        • 알고리즘 (13)
        • 컴퓨터 구조 (1)
        • Operating System (0)
        • Network (0)
        • Database (4)
      • git (1)
      • Language (15)
        • Java (5)
        • C++ (6)
        • Python (4)
    • GITHUB GITHUB
    • INSTAGRAM INSTAGRAM
  • hELLO· Designed By정상우.v4.10.3
예롱메롱
[인스타그램 클론 코딩][Spring boot] 9. 스토리(메인) 페이지
상단으로

티스토리툴바