14-컬렉션과 부가 기능

컬렉션 JPA는 자바에서 기본으로 제공하는 Collection, List, Set, Map 컬렉션을 지원하고 다음 경우에 이 컬렉션을 사용할 수 있다. @OneToMany, @ManyToMany를 사용해서 일대다나 다대다 엔티티 관계를 매핑할 때 @ElementCollection을 사용해서 값 타입을 하나 이상 보관할 때 JPA와 컬렉션 하이버네이트는 엔티티를 영속 상태로 만들 때 컬렉션 필드를 하이버네이트에서 준비한 컬렉션으로 감싸서 사용한다. Collection, List ArrayList로 초기화하면 된다. Collection, List는 중복을 허용한다고 가정하므로 add() 메소드는 내부에서 어떤 비교도 하지 않고 항상 true를 반환한다. 같은 엔티티가 있는지 찾거나 삭제할 때는 equals() 메소드를 사용한다....

2025-03-05 · 4 min · 716 words

12-스프링 데이터 JPA

JPA를 사용해서 데이터 접근 계층을 개발할 때도 유사한 코드를 반복해서 개발해야 한다. 이런 문제를 해결하려면 제네릭과 상속을 적절히 사용해서 공통 부분을 처리하는 부모 클래스를 만들면 되지만, 공통 기능이 부모 클래스에 너무 종속되고 구현 클래스 상속이 가지는 단점에 노출된다. 스프링 데이터 JPA 소개 스프링 데이터 JPA는 데이터 접근 계층을 개발할 때 구현 클래스 없이 인터페이스만 작성해도 개발을 완료할 수 있다. MemberRepository.findByUsername() 처럼 직접 작성한 메소드도 메소드 이름을 분석해서 다음 JPQL을 실행한다....

2025-03-05 · 5 min · 869 words

Valid vs Validated

목표 @Valid와 @Validated의 차이점을 이해한다. @Valid와 @Validated의 사용법을 이해한다. 공통점 컨트롤러 파라미터에 @Valid, @Validated 를 붙이면, 글로벌 Validator로 검증이 된다. Spring Boot는 JSR-380의 기본 구현인 Hibernate Validator를 글로벌 Validator로 사용한다. 컨트롤러에서 @Valid vs @Validated @Valid는JSR-303의 어노테이션으로 메서드 수준의 유효성 검사에 사용한다. @Validated는 Spring에서 @Valid를 확장하기 위해 만든 어노테이션이다. @Validated는 validation group이라는 기능을 제공한다. 컨트롤러에서는 validation group 기능 유무 차이가 존재한다. 컨트롤러에서 @ReqeustBody, @ModelAttribute, @RequestPart가 붙어있는 파라미터는 ArgumentResolver에서 처리되며, @Valid나 @Validated가 있을 때 검증 실패시 MethodArgumentNotValidException 예외가 발생한다....

2025-02-25 · 2 min · 423 words

10-객체지향 쿼리 언어

객체지향 쿼리 소개 JPQL 특징 테이블이 아닌 객체를 대상으로 검색하는 객체지향 쿼리다. SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다. 다음은 JPA가 공식 지원하는 기능이다. JPQL Criteria 쿼리: JPQL을 편하게 작성하도록 도와주는 API, 빌더 클래스 모음 네이티브 SQL: JPA에서 JPQL 대신 직접 SQL을 사용할 수 있다. 다음은 JPA가 공식 지원한느 기능은 아니지만 알아둘 가치가 있다. QueryDSL: Criteria 쿼리처럼 JPQL을 편하게 작성하도록 도와주는 빌더 클래스 모음, 비표준 오픈소스 프레임워크다. JDBC 직접 사용, MyBatis 같은 SQL 매퍼 프레임워크 사용: 필요하면 JDBC를 직접 사용할 수 있다....

2025-02-25 · 10 min · 2084 words

Liveness, Readiness, Startup Probe

목표 Liveness probe, Readiness probe, Startup probe의 차이점을 이해한다. Liveness probe 컨테이너를 재시작 해야되는지 판단할 때 사용한다. liveness probe에 반복해서 실패하면, 컨테이너가 재시작된다. 반복해서 실행되므로 liveness probe에는 무거운 작업을 하면 안된다. liveness probe는 readiness probe가 성공하는 것을 기다리지 않고 실행된다. 만약 liveness probe가 실행되기 전에 지연이 필요하면, startup probe를 사용하거나 initialDelaySeconds 값을 설정함녀 된다. 예시: 애플리케이션이 데드락에 빠졌으면 이를 탐지하여 재시작한다. Readiness probe 컨테이너가 트래픽을 받을 수 있는 상태인지 판단할 때 사용한다....

2025-02-20 · 1 min · 165 words

Spring에서 로깅 시 각 요청마다 식별자 만들기

배경 로그 모니터링할 때 각 로그가 서로 연관이 있는지, 한 요청에 대해서 어떤 순서로 로그가 남았는지 확인이 필요한 상황이 있었다. 로그를 남길 때 요청마다 고유한 식별자를 만들어서 로그에 같이 남도록 구현한다. 현재 프로젝트는 Logback을 사용해 로그를 남기고 있다. MDC MDC는 log4j나 logback이 로그를 남길 때 Appedner가 접근할 수 있는 데이터로 Map과 같은 구조로 작성할 수 있다. MDC의 고주논 ThreadLocal을 사용하여 실행 중인 스레드에 내부적으로 연결된다. 아래 사진과 같이 MDC 클래스 내에는 MDCAdapter 라는 인터페이스의 static 필드를 가지고 있다....

2025-02-20 · 1 min · 184 words

maven.test.skip vs skipTests

목표 jar 빌드할 때 테스트를 제외하는 옵션인 -Dmaven.test.skip=true와 -DskipTests의 차이를 이해한다. 차이점 -Dmaven.test.skip=true: 테스트 코드를 컴파일하지 않고, 테스트를 실행하지도 않는다. -DskipTests: 테스트 코드를 컴파일하지만 실행하지는 않는다. 참고 자료 https://stackoverflow.com/questions/21933895/what-is-the-difference-between-dmaven-test-skip-exec-vs-dmaven-test-skip-tr

2025-02-20 · 1 min · 29 words

8-경계 간 매핑하기

각 계층의 모델을 매핑 두 계층 간에 매핑을 하지 않으면 양 계층에서 같은 모델을 사용해야 하는데 이렇게 하면 두 계층이 강하게 결합된다. 각 계층의 모델을 매핑하지 않음 두 계층 간에 매핑을 하게 되면 보일러플레이트 코드를 너무 많이 만들게 된다. 많은 유스케이스들이 오직 CRUD만 수행하고 계층에 걸쳐 같은 모델을 사용하기 때문에 계층 사이의 매핑은 과하다. ‘매핑하지 않기’ 전략 웹 계층, 애플리케이션 계층, 영속성 계층 모두 같은 Account 모델을 사용한다. 장점: 매핑할 필요가 전혀 없어서 단순하다....

2025-02-17 · 3 min · 567 words

1-코드 정리법

보호 구문 아래와 같은 코드를 본다면 if (조건) ...코드... if (조건) if (다른 조건 부정) ...코드... 아래와 같이 정리할 수 있다. if (조건 부정) return if (다른 조건) return ...코드... 안 쓰는 코드 일단 지워라. 리플렉션을 사용한 코드일수도 있지 않은가? 로그를 활용해 지우고 나서 다시 실행해서 확인 해본다. 확신이 된다면 지울 수 있다. 지웠다가 나중에 필요할 경우는? 형상 관리 도구가 이를 해결해준다. 정리 과정에는 코드를 조금만 삭제해라. 그렇게 하면 잘못 고친 것으로 밝혀져도 비교적 쉽게 복구할 수 있다....

2025-02-17 · 4 min · 746 words

3-ElasticSearch 모니터링

Head를 이용해서 모니터링하기 Head는 클러스터의 상태를 한눈에 살펴볼 수 있는 모니터링 도구 중 하나이다. Head는 클러스터의 여러 정보를 웹 UI를 통해 확인할 수 있도록 해준다. 특히 Head의 가장 큰 장점 중 하나는 샤드 배치 정보를 시각적으로 확인할 수 있다는 것이다. 프로메테우스를 활용한 클러스터 모니터링 프로메테우스는 데이터를 시간의 흐름대로 저장할 수 있는 시계열 데이터베이스의 일종이며, 수집된 데이터를 바탕으로 임게치를 설정하고 경고 메시지를 받을 수 있는 오픈소스 모니터링 시스템이다. 각종 메트릭을 저장하는 TSDB(Time Series Data Base)의 역할을 하는 Prometheus Server가 중앙에 있다....

2025-02-11 · 2 min · 277 words

2-ElasticSearch 기본 동작

문서 색인과 조회 색인 API 4가지 API PUT /<target>/_doc/<_id> POST /<target>/_doc/ PUT /<target>/_create/<_id> POST /<target>/_create/<_id> 문서 ID를 지정해서 새 문서를 추가하려면 PUT /<target>/_create/<_id> 형식을 사용해야 된다. <target>: 인덱스 이름 대상이 존재하지 않고 데이터 <_id>: 문서 식별자 예시 색인 API 호출시 flow 기존에 숫자 형태로 정의된 필드에 문자 형태의 값이 들어오면 스키마 충돌이라고 판단하고 에러를 출력한다. 에러가 출력되면 해당 문서는 기본적으로는 색인되지 않는다. 기존 문서를 업데이트하면 문서의 _version 값이 올라간다. 문서 색인 없이 인덱스만 색인할 수도 있다....

2025-02-10 · 2 min · 269 words

9-값 타입

값 타입 3가지 기본값 타입 자바 기본 타입(int, double) 래퍼 클래스(Integer) String 임베디드 타입 컬렉션 값 타입 기본값 타입 값 타입은 다른 엔티티와 공유하면 안 된다. 임베디드 타입(복합 값 타입) 임베디드 타입을 사용하려면 다음 2가지 어노테이션이 필요하다. 참고로 둘 중 하나는 생략해도 된다. @Embeddable: 값 타입을 정의하는 곳에 표시 @Embedded: 값 타입을 사용하는 곳에 표시 임베디드 타입은 기본 생성자가 필수다. 임베디드 타입과 테이블 매핑 잘 설계한 ORM 애프리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많다....

2025-02-10 · 3 min · 485 words

11-쿼리 작성 및 최적화

쿼리 작성과 연관된 시스템 변수 SQL 모드 MySQL 서버의 sql_mode 라는 시스템 설정에는 여러 개의 값이 동시에 설정될 수 있다. sql_mode를 설정할 때는 구분자(,)를 이용해 키워드를 동시에 여러 개 설정할 수 있다. MySQL 서버의 sql_mode 시스템 변수에 설정된 값들은 SQL 문장 작성 규칙뿐만 아니라 MySQL 서버 내부적으로 자동 실행되는 데이터 타입 변환 및 기본값 제어 등과 관련된 옵션도 가지고 있다. 그래서 일단 MySQL 서버에 사용자 테이블을 생성하고 데이터를 저장하기 시작했담녀 가능한 한 sql_mode 시스템 변수의 내용은 변경하지 않는 것이 좋다....

2025-02-10 · 34 min · 7184 words

멀티 모듈 사용시 JaCoCo 구성

배경 멀티 모듈을 사용하는 maven 프로젝트가 있다. A, B 모듈이 존재하고, B 모듈이 A 모듈을 의존하고 있다. B 모듈에서 실행한 테스트들이 A 모듈 코드의 테스트 커버리지를 채우지 못하는 문제가 SonarQube에서 발생했다. 싱글 모듈에서 SonarQube가 테스트 커버리지를 측정하는 방법 SonarQube는 직접 테스트 커버리지 측정을 지원하지 않는다. 다른 툴을 이용해서 테스트 커버리지 분석 보고서를 생성하고, SonarQube에게 보고서의 위치를 알려줘서 커버리지를 출력하도록 한다. Java 프로젝트는 일반적으로 JaCoCo를 사용해서 보고서를 생성한다. maven의 JaCoCo 플러그인을 이용해서 보고서를 생성한다....

2025-02-04 · 2 min · 357 words

Spring log4j2 적용기

log4j vs logback vs log4j2 를 비교 해보고 log4j2를 사용해보기로 결정했다. Spring Framwork에 log4j2를 적용한 과정을 정리해본다. 의존 중복 처음에 log4j2 의존을 아래와 같이 추가해서 실행하니 에러가 발생했다. SLF4J가 여러 개 바인딩 되어서 발생한 문제였다. implementation 'org.springframework.boot:spring-boot-starter-log4j2:2.6.3' Spring Boot에 로깅 모듈을 제외 시켜서 해결할 수 있다. implementation('org.springframework.boot:spring-boot-starter-data-jpa:2.6.2') { exclude module: "spring-boot-starter-logging" } 멀티 프로필 Spring Boot에서는 Logback처럼 프로필 별 xml 자동 감지가 안된다. properties 파일을 통해서 사용할 로깅 xml파일을 지정해줘야 된다....

2025-02-01 · 1 min · 184 words

Logging

System.out.println("*********제발 나와라*********"); 위 코드 한 줄은 아마 개발을 해본 대부분은 시도 해본 디버깅 방법일 것이다. 필자도 한 때 많이 이용한 방법이다. 특별한 기술이 없어도 내가 작성한 코드가 어떻게 흘러가는지, 어디까지 동작하는지 확인할 수 있다. 점차 IDE 사용법에 익숙해지면 알게 되는 좀 더 쉬운 디버깅 방법으로는 디버거가 있다. 디버거를 사용하면 특정 코드 라인에 도달했을 때, 각 변수의 주소, 값 등을 확인할 수 있어 디버깅할 때 용이하다. 하지만 이런 방법들은 한계가 있다....

2025-02-01 · 5 min · 917 words

Docker 네트워크

목표 도커 네트워크가 무엇인지 이해한다. 도커 네트워크 타입에 무엇이 있는지 이해한다. Docker Network Docker는 컨테이너 간, 호스트, 외부 네트워크와 통신을 하기위한 네트워크 시스템을 포함하고 있다. Docker Network 타입 bridge 컨테이너 끼리 서로 연결하고 외부 네트워크와 분리하는 네트워크 동일한 bridge 네트워크 내의 컨테이너는 IP 주소 또는 컨테이너 이름을 사용해서 통신할 수 있다. 컨테이너와 호스트 사이에 소프트웨어 기반의 bridge를 만들어준다. 기본적으로 아웃바운드 트래픽은 허용하지만, 인바운드 트래픽은 허용하지 않는다. port publish 를 통해서 특정 포트로의 인바운드 트래픽을 허용해준다....

2025-02-01 · 2 min · 394 words

Docker Stack 알아보기

목표 Docker Stack이 무엇인지 이해한다. Docker Stack의 사용법을 이해한다. Docker Stack 이란 Docker Swarm 은 Docker 컨테이너를 클러스터링하고 스케줄링하기 위한 컨테이너 오케스트레이션 툴이다. Docker Stack 은 기본적으로 Docker Swarm을 통해 실행된다. Docker Stack을 사용하면 Swarm에 분산된 컨테이너인 여러 서비스를 논리적으로 배포하고 그룹화할 수 있다. vs Docker Compose Docker Compose는 단일 노드에서 실행되는 컨테이너를 관리하기 위한 용도이고, Docker Stack은 Docker Swarm 모드로 실행되는 멀티 노드 환경에서 컨테이너를 관리하긴 위한 용도이다. 공통점 docker-compose....

2025-02-01 · 1 min · 158 words

SSO 이해하기

목표 SSO(Single sign-on)가 무엇인지 이해한다. SSO와 OAuth, SAML의 관계를 이해한다. SSO란 SSO: 하나의 자격 증명으로 여러 애플리케이션과 웹사이트에 인증할 수 있는 인증 방법이다. 예시: 구글 로그인으로 Gmail, YouTube 등 인증 가능 일반적인 SSO 흐름 사용자가 접근하려는 애플리케이션 또는 웹사이트(SP)를 접속한다. SP는 사용자 인증 요청의 일부로 사용자에 대한 일부 정보(이메일 등)가 포함된 토큰을 SSO 시스템과 같은 IdP에 보낸다. IdP는 사용자가 이미 인증되었는지 확인하며, 인증된 경우 사용자에게 SP 애플리케이션에 대한 액세스 권한을 부여하고 5단계로 건너뛴다....

2025-01-25 · 1 min · 179 words

8-프록시와 연관관계 관리

프록시 지연 로딩: 엔티티가 실제 사용될 때까지 데이터베이스 조회를 지연하는 방법 지연 로딩 기능을 사용하려면 실제 엔티티 객체 대신 데이터베이스 조회를 지연할 수 있는 가짜 객체가 필요한데 이것을 프록시 객체라 한다. JPA 표준 명세는 지연로딩의 구현 방법을 JPA 구현체에 위임했다. 하이버네이트는 지연 로딩을 지원하기 위해 프록시를 사용하는 방법과 바이트코드를 수정하는 두 가지 방법을 제공한다. 프록시 기초 엔티티를 직접 조회하면 조회한 엔티티를 실제 사용하든 사용하지 않든 데이터베이스를 조회하게 된다. Member member = em....

2025-01-24 · 4 min · 821 words