분류 전체보기
-
Bulk Insert MySQL을 사용하면서 Batch Insert를 수행하기 위해서는 2가지 방법이 있습니다. JPA Batch Insert + Table 전략 JDBC Batch Insert IDENTITY 전략으로 Batch INSERT가 불가능한 이유 JPA + Batch Insert를 MySQL에서 사용하기 위해서는 ID 전략을 Table 전략으로 수정해야 합니다. 하지만 MySQL은 Sequence 전략이 없습니다. 일반적으로 MySQL에서 사용하는 IDENTITY 전략은 auto_increment으로 PK 값을 자동으로 증분합니다. 즉, Insert를 실행하기 전까지는 ID에 할당된 값을 알 수 없기 때문에 Transactional Write Behind를 할 수 없고 결과적으로 Batch ..
JPA Batch Insert와 JDBC Batch InsertBulk Insert MySQL을 사용하면서 Batch Insert를 수행하기 위해서는 2가지 방법이 있습니다. JPA Batch Insert + Table 전략 JDBC Batch Insert IDENTITY 전략으로 Batch INSERT가 불가능한 이유 JPA + Batch Insert를 MySQL에서 사용하기 위해서는 ID 전략을 Table 전략으로 수정해야 합니다. 하지만 MySQL은 Sequence 전략이 없습니다. 일반적으로 MySQL에서 사용하는 IDENTITY 전략은 auto_increment으로 PK 값을 자동으로 증분합니다. 즉, Insert를 실행하기 전까지는 ID에 할당된 값을 알 수 없기 때문에 Transactional Write Behind를 할 수 없고 결과적으로 Batch ..
2023.12.30 -
애그리거트와 트랜잭션 한 주문 애그리거트에 대해 운영자는 배송 상태로 변경할 때 사용자는 배송지 주소를 변경하면 어떻게 될까요? 위 그림은 운영자와 고객이 동시에 한 주문 애그리거트를 수정하는 과정을 보여줍니다. 트랜잭션마다 리포지토리는 새로운 애그리거트 객체를 생성하므로 운영자 스레드가 고객 스레드는 같은 주문 애그리거트를 나타내는 다른 객체를 구하게 됩니다. 운영자 스레드가 고객 스레드는 개념적으로 동일한 애그리거트지만 물리적으로 서로 다른 애그리거트 객체를 사용합니다. 때문에 운영자 스레드가 주문 애그리거트 객체를 배송 상태로 변경하더라도 고객 스레드가 사용하는 주문 애그리거트 객체에는 영향을 주지 않습니다. 고객 스레드 입장에서 주문 애그리거트 객체는 아직 배송 상태 전이므로 배송지 정보를 변경할..
JPA - LOCK애그리거트와 트랜잭션 한 주문 애그리거트에 대해 운영자는 배송 상태로 변경할 때 사용자는 배송지 주소를 변경하면 어떻게 될까요? 위 그림은 운영자와 고객이 동시에 한 주문 애그리거트를 수정하는 과정을 보여줍니다. 트랜잭션마다 리포지토리는 새로운 애그리거트 객체를 생성하므로 운영자 스레드가 고객 스레드는 같은 주문 애그리거트를 나타내는 다른 객체를 구하게 됩니다. 운영자 스레드가 고객 스레드는 개념적으로 동일한 애그리거트지만 물리적으로 서로 다른 애그리거트 객체를 사용합니다. 때문에 운영자 스레드가 주문 애그리거트 객체를 배송 상태로 변경하더라도 고객 스레드가 사용하는 주문 애그리거트 객체에는 영향을 주지 않습니다. 고객 스레드 입장에서 주문 애그리거트 객체는 아직 배송 상태 전이므로 배송지 정보를 변경할..
2023.12.30 -
OSIV란? OSIV(Open Session In View)는 영속성 컨텍스트를 뷰까지 열어준다는 뜻입니다. 영속성 컨텍스트가 살아있으면 엔티티는 영속 상태로 유지됩니다. 따라서 뷰에서도 지연 로딩을 할 수 있습니다. 참고로 OSIV는 하이버네이트에서 사용하는 용어이고, JPA에서는 OEIV(Open EntityManager In View)라고 하지만 관계상 모두 OSIV라고 부릅니다. 과거 OSIV: 요청 당 트랜잭션 OSIV의 핵심은 뷰에서도 지연로딩이 가능하도록 하는 것입니다. 가장 단순한 구현 방법은 클라이언트의 요청이 들어오자마자 서블릿 필터나 스프링 인터셉터에서 트랜잭션을 시작하고 요청이 끝날 때 트랜잭션도 끝내는 것입니다. 이것을 요청 당 트랜잭션 방식의 OSIV라고 합니다. 이렇게 하면 영..
JPA - OSIVOSIV란? OSIV(Open Session In View)는 영속성 컨텍스트를 뷰까지 열어준다는 뜻입니다. 영속성 컨텍스트가 살아있으면 엔티티는 영속 상태로 유지됩니다. 따라서 뷰에서도 지연 로딩을 할 수 있습니다. 참고로 OSIV는 하이버네이트에서 사용하는 용어이고, JPA에서는 OEIV(Open EntityManager In View)라고 하지만 관계상 모두 OSIV라고 부릅니다. 과거 OSIV: 요청 당 트랜잭션 OSIV의 핵심은 뷰에서도 지연로딩이 가능하도록 하는 것입니다. 가장 단순한 구현 방법은 클라이언트의 요청이 들어오자마자 서블릿 필터나 스프링 인터셉터에서 트랜잭션을 시작하고 요청이 끝날 때 트랜잭션도 끝내는 것입니다. 이것을 요청 당 트랜잭션 방식의 OSIV라고 합니다. 이렇게 하면 영..
2023.12.30 -
상속관계 매핑 관계형 데이터베이스는 상속 관계 개념은 없고 슈퍼타입 서브타입 관계라는 모델링 기법이 객체의 상속과 유사합니다. 그래서 상속 관계 매핑을 객체의 상속 구조와 DB의 슈퍼타입 서브타입 관계를 매핑하는 형식으로 진행합니다. 이에 대해 슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 3가지 전력이 있습니다. 객체 관점에서 Item은 혼자 사용되는 경우가 없는 추상 클래스이고, album, movie, book이 이를 상속받아서 사용하는 것이라고 가정합시다. 조인 전략 일반적으로 가장 많이 채택되는 전략입니다. 조회 시에 join으로 인한 성능 저하가 있다. 추상 클래스와 구현 클래스 모두 별도의 테이블이 만들어집니다. 운영을 위해서 @DiscriminatorColumn으로 DTYPE열을..
JPA - 상속 관계와 값타입상속관계 매핑 관계형 데이터베이스는 상속 관계 개념은 없고 슈퍼타입 서브타입 관계라는 모델링 기법이 객체의 상속과 유사합니다. 그래서 상속 관계 매핑을 객체의 상속 구조와 DB의 슈퍼타입 서브타입 관계를 매핑하는 형식으로 진행합니다. 이에 대해 슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 3가지 전력이 있습니다. 객체 관점에서 Item은 혼자 사용되는 경우가 없는 추상 클래스이고, album, movie, book이 이를 상속받아서 사용하는 것이라고 가정합시다. 조인 전략 일반적으로 가장 많이 채택되는 전략입니다. 조회 시에 join으로 인한 성능 저하가 있다. 추상 클래스와 구현 클래스 모두 별도의 테이블이 만들어집니다. 운영을 위해서 @DiscriminatorColumn으로 DTYPE열을..
2023.12.30 -
다양한 연관관계 다대일 단방향 가장 많이 사용하는 연관관계 다대일 중 다에 @ManyToOne 붙여서 다대일을 명시 다대일 중 다에 @JoinColumn 으로 FK 명시 @Entity class Member( name: String, team: Team, ) : BaseEntity() { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "member_id") var id: Long? = null protected set var name: String = name @ManyToOne @JoinColumn(name = "team_id") var team: Team = team } @Entity class Team( name: St..
JPA - 연관관계 매핑과 프록시다양한 연관관계 다대일 단방향 가장 많이 사용하는 연관관계 다대일 중 다에 @ManyToOne 붙여서 다대일을 명시 다대일 중 다에 @JoinColumn 으로 FK 명시 @Entity class Member( name: String, team: Team, ) : BaseEntity() { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "member_id") var id: Long? = null protected set var name: String = name @ManyToOne @JoinColumn(name = "team_id") var team: Team = team } @Entity class Team( name: St..
2023.12.30 -
출시 순서도 JDBC JDBC API는 JAVA 진영의 Database 연결 표준 인터페이스 입니다. 위 그림을 보시면 JDBC API 명세를 JDBC DriverManager가 구현하고, JDBC API에 맞게 동작할 수 있게 각 제품군에 따른 Driver가 만들어져 있습니다. 따라서, 사용하는 API를 변경하지 않고 Driver만 변경해주면 어떤 제품이든 사용이 가능해집니다. 하지만 JDBC만을 이용하여 코딩하게 되면 위와 같은 작업을 직접 해주어야 하기 때문에 중복된 코드, 예외 처리 등 불편한 점이 많습니다. SQL MAPPER Java Persistence Framwork중 하나인 SQL Mapper의 컨셉은 객체의 필드와 SQL문을 매핑하여 데이터를 객체화 하는 것인데 여기서 객체와 관계를 매..
JPA 탄생 배경출시 순서도 JDBC JDBC API는 JAVA 진영의 Database 연결 표준 인터페이스 입니다. 위 그림을 보시면 JDBC API 명세를 JDBC DriverManager가 구현하고, JDBC API에 맞게 동작할 수 있게 각 제품군에 따른 Driver가 만들어져 있습니다. 따라서, 사용하는 API를 변경하지 않고 Driver만 변경해주면 어떤 제품이든 사용이 가능해집니다. 하지만 JDBC만을 이용하여 코딩하게 되면 위와 같은 작업을 직접 해주어야 하기 때문에 중복된 코드, 예외 처리 등 불편한 점이 많습니다. SQL MAPPER Java Persistence Framwork중 하나인 SQL Mapper의 컨셉은 객체의 필드와 SQL문을 매핑하여 데이터를 객체화 하는 것인데 여기서 객체와 관계를 매..
2023.12.29 -
공부한 내용을 정리하는 블로그와 관련 코드를 공유하는 Github이 있습니다. 멀티 모듈이 필요한 이유 프로젝트가 커지다 보면 여러 개의 서버를 만들어야 할 때가 있습니다. 간단한 예시로 위 그림과 같이, WEB 서버와 Batch 서버가 있을 수 있습니다. 만약 WEB 서버를 만들다가 Batch 서버를 추가해야 하는 시점에 WEB 서버에 있는 Member 엔티티를 Batch 서버에서도 사용해야 한다면 어떻게 사용할 것인가에 대해 고민해야 하는 시점이 옵니다. 가장 쉽고 간단한 방법은 Member 클래스 파일을 그대로 복사해서 만들고 사용하는 방식입니다. 하지만 이럴 경우 연동되는 프로젝트가 늘어날 경우, Member 클래스 코드에 수정이 필요한 경우 곳곳에 퍼져있는 코드를 수정해야 하기 때문에 실수할 여..
Spring - Gradle 멀티 모듈 프로젝트공부한 내용을 정리하는 블로그와 관련 코드를 공유하는 Github이 있습니다. 멀티 모듈이 필요한 이유 프로젝트가 커지다 보면 여러 개의 서버를 만들어야 할 때가 있습니다. 간단한 예시로 위 그림과 같이, WEB 서버와 Batch 서버가 있을 수 있습니다. 만약 WEB 서버를 만들다가 Batch 서버를 추가해야 하는 시점에 WEB 서버에 있는 Member 엔티티를 Batch 서버에서도 사용해야 한다면 어떻게 사용할 것인가에 대해 고민해야 하는 시점이 옵니다. 가장 쉽고 간단한 방법은 Member 클래스 파일을 그대로 복사해서 만들고 사용하는 방식입니다. 하지만 이럴 경우 연동되는 프로젝트가 늘어날 경우, Member 클래스 코드에 수정이 필요한 경우 곳곳에 퍼져있는 코드를 수정해야 하기 때문에 실수할 여..
2023.12.29 -
공부한 내용을 정리하는 블로그와 관련 코드를 공유하는 Github이 있습니다. 코드 커버리지 코드 커버리지는 소프트웨어의 테스트 케이스가 얼마나 충족되었는지를 나타내는 지표 중 하나입니다. 테스트를 진행하였을 때 '코드 자체가 얼마나 실행되었느냐'는 것이고, 이는 수치를 통해 확인할 수 있습니다. 코드 커버리지의 측정 기준은 크게 구문, 조건, 결정 3가지로 나뉩니다. 가장 대표적으로 많이 사용되고 있는 측정 기준은 구문 입니다. 구문(Statement) = 라인(Line) 커버리지 코드 한 줄이 한 번이상 실행된다면 충족한다는 것을 기준으로 측정됩니다. void foo (int x) { system.out("start line"); // 1번 if (x > 0) { // 2번 system.out("mi..
Spring - Jacoco 적용하기공부한 내용을 정리하는 블로그와 관련 코드를 공유하는 Github이 있습니다. 코드 커버리지 코드 커버리지는 소프트웨어의 테스트 케이스가 얼마나 충족되었는지를 나타내는 지표 중 하나입니다. 테스트를 진행하였을 때 '코드 자체가 얼마나 실행되었느냐'는 것이고, 이는 수치를 통해 확인할 수 있습니다. 코드 커버리지의 측정 기준은 크게 구문, 조건, 결정 3가지로 나뉩니다. 가장 대표적으로 많이 사용되고 있는 측정 기준은 구문 입니다. 구문(Statement) = 라인(Line) 커버리지 코드 한 줄이 한 번이상 실행된다면 충족한다는 것을 기준으로 측정됩니다. void foo (int x) { system.out("start line"); // 1번 if (x > 0) { // 2번 system.out("mi..
2023.12.29 -
공부한 내용을 정리하는 블로그와 관련 코드를 공유하는 Github이 있습니다. REST Docs 란? 테스트 코드 기반으로 Restful API 문서를 돕는 도구입니다. Asciidoctor를 이용해서 HTML 등등 다양한 포맷으로 문서를 자동으로 출력할 수 있습니다. RestDocs의 가장 큰 장점은 테스트 코드 기반으로 문서를 작성한다는 점입니다. API Spec과 문서화를 위한 테스트 코드가 일치하지 않으면 테스트 빌드를 실패하게 되어 테스트 코드로 검증된 문서를 보장할 수 있습니다. Swagger VS REST Docs 보통 Spring 에서 문서화를 할 때, Swagger과 Restdocs를 사용하게 됩니다. Swagger는 마치 Postman처럼(직접 요청하듯이) API를 테스트해 볼 수 있는..
Spring - REST Docs 적용 및 최적화하기공부한 내용을 정리하는 블로그와 관련 코드를 공유하는 Github이 있습니다. REST Docs 란? 테스트 코드 기반으로 Restful API 문서를 돕는 도구입니다. Asciidoctor를 이용해서 HTML 등등 다양한 포맷으로 문서를 자동으로 출력할 수 있습니다. RestDocs의 가장 큰 장점은 테스트 코드 기반으로 문서를 작성한다는 점입니다. API Spec과 문서화를 위한 테스트 코드가 일치하지 않으면 테스트 빌드를 실패하게 되어 테스트 코드로 검증된 문서를 보장할 수 있습니다. Swagger VS REST Docs 보통 Spring 에서 문서화를 할 때, Swagger과 Restdocs를 사용하게 됩니다. Swagger는 마치 Postman처럼(직접 요청하듯이) API를 테스트해 볼 수 있는..
2023.12.29 -
DB 트랜잭션 이해하기 트랜잭션이란? 트랜잭션이란 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산들 을 의미합니다. 하나의 트랜잭션이 모두 실행되었을 때를 Commit 이라고 합니다. 일종의 확인 도장으로 트랜잭션에 묶인 모든 쿼리가 성공되어 결과가 실제 DB에 반영하는 것입니다. 하나의 트랜잭션이 모두 실행되지 않도록 하는 RollBack 이라고 합니다. 쿼리 실행결과를 취소하고 DB를 트랜잭션 이전 상태로 되돌리는 것입니다. 트랜잭션의 특징 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질을 ACID 라고 합니다. A : Atomicity(원자성) 트랜잭션은 DB에 모두 반영되거나, 전혀 반영되지 않아야 한다. 완료되..
Spring - Transaction 총정리DB 트랜잭션 이해하기 트랜잭션이란? 트랜잭션이란 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산들 을 의미합니다. 하나의 트랜잭션이 모두 실행되었을 때를 Commit 이라고 합니다. 일종의 확인 도장으로 트랜잭션에 묶인 모든 쿼리가 성공되어 결과가 실제 DB에 반영하는 것입니다. 하나의 트랜잭션이 모두 실행되지 않도록 하는 RollBack 이라고 합니다. 쿼리 실행결과를 취소하고 DB를 트랜잭션 이전 상태로 되돌리는 것입니다. 트랜잭션의 특징 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질을 ACID 라고 합니다. A : Atomicity(원자성) 트랜잭션은 DB에 모두 반영되거나, 전혀 반영되지 않아야 한다. 완료되..
2023.12.29 -
DB Replication 이란? 데이터베이스 이중화 방식 중 하나로 하나의 Master DB와 여러 대의 Slave DB를 구성하는 방식을 의미합니다. 사용하는 이유 부하 분산 서비스에 사용자가 많아져 트래픽이 늘어날 경우, DB에 쿼리를 날리는 일이 빈번하게 일어납니다. DB에서는 쿼리를 모두 처리하기 힘들어지게 되고 이에 따라 부하를 줄이기 위해 DB를 이중화하여 Master에서는 쓰기/수정/삭제 연산을 처리하고 Slave에서는 읽기 연산만을 처리하여 병목 현상을 줄일 수 있습니다. 데이터 백업 Master의 데이터가 날아가더라도 Slave에 데이터가 저장되어 있으므로 어느 정도 복구할 수 있습니다. MySQL Replication은 비동기 방식이기 때문에 100% 정합성을 보장할 수 없습니다. M..
Spring - MySQL Replication 적용하기(with AWS RDS 다중 AZ)DB Replication 이란? 데이터베이스 이중화 방식 중 하나로 하나의 Master DB와 여러 대의 Slave DB를 구성하는 방식을 의미합니다. 사용하는 이유 부하 분산 서비스에 사용자가 많아져 트래픽이 늘어날 경우, DB에 쿼리를 날리는 일이 빈번하게 일어납니다. DB에서는 쿼리를 모두 처리하기 힘들어지게 되고 이에 따라 부하를 줄이기 위해 DB를 이중화하여 Master에서는 쓰기/수정/삭제 연산을 처리하고 Slave에서는 읽기 연산만을 처리하여 병목 현상을 줄일 수 있습니다. 데이터 백업 Master의 데이터가 날아가더라도 Slave에 데이터가 저장되어 있으므로 어느 정도 복구할 수 있습니다. MySQL Replication은 비동기 방식이기 때문에 100% 정합성을 보장할 수 없습니다. M..
2023.12.28 -
p6spy란? p6spy란 쿼리 파라미터를 로그에 남겨주고 추가적인 기능을 제공하는 외부 라이브러리입니다. 사실 이 외부 라이브러리 없이도 application.yml에 다음과 같은 설정을 통해 쿼리 파라미터의 값들을 찍을 수 있습니다. # application.yml logging: level: org.hibernate.SQL: debug org.hibernate.type: trace # for native query org.springframework.jdbc.core.JdbcTemplate: DEBUG org.springframework.jdbc.core.StatementCreatorUtils: TRACE 이렇게 값을 찍게 될 경우 아래 그림과 같이 ?가 찍히고 그 아래 실제 들어간 파라미터 값을 ..
Spring - p6spy 적용하기p6spy란? p6spy란 쿼리 파라미터를 로그에 남겨주고 추가적인 기능을 제공하는 외부 라이브러리입니다. 사실 이 외부 라이브러리 없이도 application.yml에 다음과 같은 설정을 통해 쿼리 파라미터의 값들을 찍을 수 있습니다. # application.yml logging: level: org.hibernate.SQL: debug org.hibernate.type: trace # for native query org.springframework.jdbc.core.JdbcTemplate: DEBUG org.springframework.jdbc.core.StatementCreatorUtils: TRACE 이렇게 값을 찍게 될 경우 아래 그림과 같이 ?가 찍히고 그 아래 실제 들어간 파라미터 값을 ..
2023.12.28