본문 바로가기

CodeLap 프로젝트

(11)
[CodeLap] IOExcpetion 언체크 예외로 변환 (리팩토링) 최근에 스프링을 딥하게 공부하고있다. API 예외처리, 체크 예외 -> 언체크 예외로 변환 등 배운 건 많지만 실제 프로젝트에 적용할 기회가 잘 없었다. 오늘은 뭔가 고칠게 없나 싶어서 프로젝트를 둘러보고있는데.. 발견해버렸다. @PostMapping("/image-upload") public void imageUpload( @RequestPart(value = "multipartFile") MultipartFile multipartFile, ) throws IOException { studyAppService.imageUpload(multipartFile); } 컨트롤러에서, imageUpload 메소드에서 체크 예외를 던지고 있어 throws IOException을 던지고 있다. 먼저 수정하기전, 자..
CodeLap - S3로 파일 업로드(자바, 스프링부트) 유저, 스터디, 스터디 공지 등 이미지가 필요한 도메인은 다양하다. 오늘은 이미지 파일을 MultipartFile로 받아와서, S3 서버로 업로드하는 과정을 써보려고 한다. 먼저 이미지 업로드의 전체적인 과정을 설명해보자면 회원의 프로필을 수정할 때 이미지, 유저의 정보를 함께 수정할 수 있다. 1. API 서버 쪽으로 요청이 들어왔을 때, 이미지 정보와 유저 정보를 받아온다. 2. 받아온 정보를 분리(MultiPartFile과 UserDto)한다. 3. MultiPartFile의 이름을 UUID + 확장자명으로 변환 후 서버에 저장한 후, 해당 파일의 이름을 유저 DB에 저장한다. 사실 이게 끝이다. 여기서 몇가지 추가되는 과정은 S3에 파일을 저장할지 서버, 즉 인스턴스에 파일을 저장할지 인데 처음에..
[CodeLap] Github Action, AWS(EC2, S3, RDS, CodeDeploy)를 활용한 자바 + 스프링부트 백앤드 서버 배포 - 2편 1편에서는 PR이 열렸을 때 CI하는 과정까지 글을 썼었는데, 이번편에서는 본격적인 CI/CD 과정에 대해서 적어보겠다. 간단하게 요약하자면 서버를 빌드 후 zip 파일로 만들어 S3 서버에 업로드 해준 후 CodeDeploy가 EC2 서버에 배포해주고 쉘 스크립트를 실행시켜 기존 애플리케이션 삭제 -> 새 애플리케이션 배포 -> 서버 실행 이 과정을 거친다고 볼 수 있다. CodeDeploy의 동작을 설정하기 위한 yml 파일도 작성해야하는데, 리눅스 환경에서 파일 전송 위치, 디렉토리 권한, 실행될 스크립트 등을 포함한 yml 파일이다. 실행될 스크립트 파일도 직접 프로젝트 내에 코드로 작성해줘야한다. 본격적으로 CICD 과정을 진행하기 전에 만들어줘야 할 것들이 몇개 있는데, 그중 하나인 S3 버킷..
[CodeLap] DIP와 OCP를 지켜서 코드를 짜게 되면? 흔히들 말하는 객체지향의 5대원칙 SOLID. SRP (Single Responsibility Principle) : 클래스는 단 하나의 책임을 가져야 하며, 한 가지 변경 사항에 대해 한 가지 이유로만 변경되어야 합니다. OCP (Open-Closed Principle) : 클래스는 확장에는 열려 있으나, 수정에는 닫혀 있어야 합니다. 즉, 새로운 기능을 추가할 때 기존 코드를 수정하지 않아도 되도록 설계되어야 합니다. LSP (Liskov Substitution Principle) : 하위 클래스는 상위 클래스의 역할을 대체할 수 있어야 합니다. 즉, 상위 클래스의 인스턴스는 언제나 하위 클래스의 인스턴스로 대체될 수 있어야 합니다. ISP (Interface Segregation Principle)..
[CodeLap] Github Action, AWS(EC2, S3, RDS, CodeDeploy)를 활용한 자바 + 스프링부트 백앤드 서버 배포 - 1편 우선, CI/CD의 중요성에 대해서 먼저 설파하자면, 전 회사에서 프로젝트를 할 때 테스트서버를 구축했었는데, 놀고있는 노트북 한대를 서버컴퓨터로 정한 후 FileZila 등을 사용해 프로젝트를 Jar파일로 압축해 SSH로 전송하고, SSH 서버에 접속해서 프로젝트 서버 실행.. 이런식으로 했었는데, 날을 잡아서 이 과정을 반복하는게 매우 고됐고 시간낭비라는 생각을 버릴 수 없었다. 직접 겪어보니 CI/CD를 왜 해야하는지, 정말 뼈저리게 느꼈다. Github Action같은 CI/CD 툴을 사용하면, 파이프라인을 어떻게 짜느냐에 따라 다르겠지만 대개 배포과정을 자동화 해준다. AWS EC2 인스턴스를 사용하면, 해당 프로젝트에 맞는 스펙의 클라우드 컴퓨터를 대여해 서버를 열 수 있고, 사용시간에 따른 ..
[CodeLap] 조회 쿼리 성능 최적화 및 DTO 이너클래스 리팩토링 @Override public List getAllStudies(){ return queryFactory .select( constructor( GetAllStudiesStudyDto.class, QStudy.study.id, QStudy.study.name, QStudy.study.period, QStudy.study.leader.name, ExpressionUtils.as( JPAExpressions.select(count(QStudyComment.studyComment.id)) .from(QStudyComment.studyComment) .where(QStudyComment.studyComment.study.id.eq(QStudy.study.id)), "commentCount" ), Expressi..
트러블 슈팅 - Querydsl 조회 로직 메인 페이지에 상태가 DELETED가 아닌 모든 스터디를 조회 해주는 로직을 작성해야했는데, 처음에는 굉장히 간단하게 생각했다. 보여줘야 할 리스트는 다음과 같았다. 스터디 제목 스터디 리더 스터디 시작일 - 마감일 댓글 카운트 조회수 북마크 카운트 스터디 회원 수 최대 맴버 기술스택의 리스트 이렇게 한 row씩, 전체 스터디를 반환해주면 된다고 생각해서 다음과 같이 조회로직을 짰다. @Override public List getAllStudies(){ return queryFactory .select( constructor( GetAllStudiesStudyDto.class, QStudy.study.id, QStudy.study.name, QStudy.study.period, QStudy.study.l..
CodeLap - enum 클래스를 @ElementCollection으로 매핑하기. @ElementCollection은 엔티티에 컬렉션을 저장하기 위해 사용하는 어노테이션이다. RDB에서는 테이블에 컬렉션을 저장할 수 있는 기능을 지원하지 않기때문에, ORM에서는 객체에 컬렉션을 저장할 수 있는것 처럼 보이지만, 실제로는 스키마에 테이블을 하나 더 만들어서 관리한다. JPA에서는 @ElementCollection을 통해 해당 엔티티에서 컬렉션을 관리한다고 알려줄 수 있다. @ElementCollection @Enumerated(STRING) private List techStackList; create table study_tech_stack_list ( study_id bigint not null, tech_stack_list varchar(255) ); alter table stud..