[프로젝트] 2차 캐시의 적용/ 1차캐시와 2차캐시 차이
2023. 6. 1. 19:20
Spring
yata 프로젝트를 진행하며, 프로젝트 내 테이블과 연관관계가 많아지면서 데이터를 조회/검증 하는 데 많은 쿼리가 나가게 되었다. 또, 이러한 쿼리들이 많아지면서 데이터 베이스 서버의 네트워크 트래픽 증가의 문제가 있었습니다. 따라서 2차캐시를 도입하였다. 1차캐시와 2차캐시 네트워크를 통해 DB에 접근하는 시간 비용은 애플리케이션 서버에서 내부 메모리에 접근하는 비용보다 훨씬 비싸다. 따라서 조회한 데이터를 메모리에 캐시해서 DB접근횟수를 줄이는 것이 효율적이다. 영속성 컨텍스트 내부에는 엔티티를 보관하는 저장소가 있는데 이것을 1차캐시라 한다. 그러나 일반적 웹 애플리케이션 환경은 트랜잭션을 시작하고 종료할 때까지만 1차 캐시가 유효하다. 따라서 애플리케이션 전체로 보면 DB접근 횟수를 획기적으로 줄..
QueryDsl이란? 사용법+ 프젝 코드에 적용하기
2023. 5. 31. 19:45
Spring
QueryDsl이란? 정적 타입(컴파일 시 타입에 대한 정보를 결정)을 이용해서 SQL과 같은 쿼리를 생성할 수 있도록 해 주는 오픈소스 프레임워크 왜쓰는가? JPA를 사용하다 보면 기본 기능으로 해결되지 않는 경우에는 네이티브 쿼리를 사용하게 된다. 그런데 네이티브 쿼리는 문자열을 이어 붙이기 떄문에 오타가 발생하기 쉽고 가독성이 떨어지는 단점이 있다. Querydsl을 사용하면 자동 완성과 같은 IDE의 기능을 사용할 수 있고, 컴파일 시점에 타입이나 문법 오류를 확인할 수 있다. 또한 동적 쿼리도 쉽게 사용할 수 있어서 편리하다. 물론 경우에 따라서 적용 필요성이 다를 수 있기 때문에 프로젝트의 특성에 따라서 적절하게 선택하자 😎장점 문자가 아닌 코드로 쿼리를 작성할 수 있어 컴파일 시점에 문법 오..
[프로젝트] N+1 문제와 QueryDsl
2023. 5. 31. 17:03
Spring
🔎문제 상황 yata프로젝트 중, 1:N 관계가 맺어져 있는 리뷰 전체조회, 게시글 전체조회 시 일대다 관계로 매핑된 테이블의 조회 쿼리까지 함께 날아가는 N+1문제가 발생하였다. 🔎원인 N+1 자체가 발생하는 이유는 한쪽 테이블만 조회하고 연결된 다른 테이블은 따로 조회하기 때문이다. 연관 관계가 설정된 엔티티를 조회할 경우에 조회된 데이터 갯수(n) 만큼 연관관계의 조회 쿼리가 추가로 발생하여 데이터를 읽어오게 된다. 왜 이런 문제가 생기냐면,,, jpaRepository에 정의한 인터페이스 메서드를 실행하면 JPA는 메서드 이름을 분석해서 JPQL을 생성하여 실행하게 된다. JPQL은 SQL을 추상화한 객체지향 쿼리 언어로서 특정 SQL에 종속되지 않고 엔티티 객체와 필드 이름을 가지고 쿼리를 한다..
[JPA] Entity 클래스에서 Setter 메소드의 사용
2023. 4. 9. 15:35
Spring
Entity 클래스를 만들 떄 getter/setter를 무작정 생성하는 경우가 있다. 이렇게 되면 해당 클래스의 인스턴스 값들이 언제 어디서 변해야하는지 코드상으로 명확하게 구분할 수가 없어 차후 기능 변경시 복잡해짐 따라서 Entity클래스에는 Setter메소드의 사용을 지양하고, 많약 해당 필드의 값 변경이 필요하면 명확히 그 목적과 의도를 나타낼 수 있는 메소드를 추가하는 것이 좋다. 예를 들어 주문 취소 메소드를 만든다고 가정해보자 잘못된 예 public clsaa Order{ public void setStatus(boolean status){ //set 메소드 작성 -> 목적과 의도가 명확하지 않다. this.status = status; } } public void 주문서비스의_취소이벤트(..
Unparseable date /date <-> string 변환하기
2023. 1. 11. 17:15
Spring
기호 의미 G 연대(BC, AD) y 년도 M 월 w 년의 몇 번째 주(1~53) W 월의 몇 번째 주(1~5) D 년의 몇 번째 일(!~366) d 월의 몇 번째 일(1~31) F 월의 몇 번째 요일(1~5) E 요일 a 오전/오후 H 시간 (0~23) h 시간 (1~12) K 시간 (0~11) k 시간 (1~24) m 분 (0~59) s 초 (0~59) S 1/1000 초 (0~999) z TimeZone (General time zone) ex) GMT+9:00 Z TimeZone (RFC 822 time zone) ex) +0900 string타입으로 받은 데이터를 date 형식으로 변환하여 저장할 수 있다. 처음에는 new Date(Sysem.curruntTimeMillis())를 이용하여 나온..
Spring - 엔티티 간의 연간관계 매핑(일대다,다대일,다대다,일대일)
2022. 11. 5. 18:38
Spring
📌단방향 연관관계 한쪽 클래스만 다른 쪽 클래스의 참조 정보를 가지고 있는 관계를 단방향 연관 관계라고 한다. 📌양방향 연관 관계 양쪽 클래스가 서로의 참조 정보를 가지고 있는 관계를 양방향 연관 관계라고 한다. 📌일대다 단방향 연관 관계(일에서 다의 정보를 가지고 있음) 일대다- 일(1)에 해당하는 클래스가 다(N)에 해당하는 객체를 참조할 수 있는 관계 한명의 회원이 여러 건의 주문을 할 수 있으므로 Member와 Order는 일대다 관계이며, Member만 List 객체를 참조할 수 있으므로 단방향 관계이다. 일대다 단방향 매핑은 잘 사용하지 않는다. 위의 일대다 단반향 연관 관계에서 Order 클래스가 ‘테이블 관계에서 외래키에 해당하는 MEMBER 클래스의 참조값’을 가지고 있지 않아 일반적인 ..
Spring - JDBC기반 Domain Entity와 테이블 설계
2022. 11. 2. 11:55
Spring
👀애그리거트 루트(Aggregate Root) 선정 기준 애그리거트 내의 도메인들 중에서 다른 모든 도메인들과 직간접적으로 연관이 되어 있는 도메인 데이터베이스의 테이블 간 관계로 보자면, 애그리거트 루트는 부모 테이블이 되고, 애그리거트 루트가 아닌 다른 도메인들은 자식 테이블 즉, 애그리거트 루트(Aggregate Root)의 기본키 정보를 다른 도메인들이 외래키 형태로 가지고 있다고 볼 수 있다 관계형 데이터베이스에서 A 테이블의 기본키를 B 테이블이 가지고 있다면 A는 부모 테이블이 되고, B는 자식 테이블이 됩니다. B인 자식 테이블이 가지고 있는 A 테이블의 기본키를 외래키라고 함 📋샘플 애플리케이션 도메인 엔티티 및 테이블 설계 도메인에서 애그리거트 루트 찾기 📜애그리거트 간의 관계 회원 정..
Spring - 유효성 검증
2022. 10. 30. 14:23
Spring
MemberPostDto 클래스의 각 멤버 변수에 유효성 검증을 위한 애너테이션을 추가한 후 컨트롤러로 전달받는 DTO 매개변수 앞에 @Valid를 붙여줌 @NotBlank 값이 비어있지 않은지를 검증 null 값이나 공백(””), 스페이스(” “) 같은 값들을 모두 허용하지 않는다. 유효성 검증에 실패하면 에러 메시지(400 ‘Bad Request’)가 콘솔에 출력 @Email 유효한 이메일 주소인지를 검증 유효성 검증에 실패하면 내장된 디폴트 에러 메시지(400 ‘Bad Request’)가 콘솔에 출력 @Pattern 정규 표현식(Reqular Expression)에 매치되는 유효한 값인지를 검증 📌쿼리 파라미터(Query Parameter 또는 Query String) 및 @Pathvariable에..
Spring - Mapper 클래스의 구현, MapStruct
2022. 10. 30. 14:19
Spring
매퍼(Mapper)를 이용한 DTO 클래스 ↔ 엔티티(Entity) 클래스 매핑하는 과정을 정리해 보려 한다. 요그림에서 Controller 에서 DTO Entity Class 요 과정을 매퍼라 한다!! 먼저 매퍼클래스를 구현해보자! //MemberController에서 사용하는 DTO 클래스와 Member 간에 서로 타입을 변환해주는 매퍼(Mapper)클래스 import org.springframework.stereotype.Component; @Component // (1)스프링빈 등록을 위해 추가 public class MemberMapper { // (2) MemberPostDto를 Member로 변환 public Member memberPostDtoToMember(MemberPostDto mem..