Database
Database 에 관한 내용을 공유합니다.
-
설정하기 build.gradle.kts import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("org.springframework.boot") version "3.0.4" id("io.spring.dependency-management") version "1.1.0" kotlin("jvm") version "1.7.22" kotlin("plugin.spring") version "1.7.22" kotlin("plugin.jpa") version "1.7.22" kotlin("kapt") version "1.7.22" } group = "com.example" version = "0.0.1-SNAPSHOT" java.sourceCompat..
Spring Data JPA - QueryDSL 사용하기설정하기 build.gradle.kts import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("org.springframework.boot") version "3.0.4" id("io.spring.dependency-management") version "1.1.0" kotlin("jvm") version "1.7.22" kotlin("plugin.spring") version "1.7.22" kotlin("plugin.jpa") version "1.7.22" kotlin("kapt") version "1.7.22" } group = "com.example" version = "0.0.1-SNAPSHOT" java.sourceCompat..
2023.12.30 -
@Transactional(readOnly = true) service layer에서 @Transactional을 대부분 사용합니다. 데이터 변경이 있는 경우 @Transactional을 붙이고 데이터 조회만 하는 경우라면 @Transactional(readOnly = true)를 명시합니다. readOnly가 true로 붙은 조회용의 경우 스냅샷이 생기지 않습니다. 즉, 영속성 컨텍스트에서 관리는 하고 있지만 dirty checking을 안하기 때문에 수정해도 DB에 결과가 반영되지 않습니다. N+1 N+1 은 엔티티를 조회할 때, 해당 엔티티에 연관관계를 갖는 다른 엔티티를 프록시로 가져오면서(LazyLoading) 실제 데이터에 접근하는 시점에 해당 엔티티를 가져오기 위해 또 다른 조회 쿼리를 보내..
Spring Data JPA - 성능 최적화@Transactional(readOnly = true) service layer에서 @Transactional을 대부분 사용합니다. 데이터 변경이 있는 경우 @Transactional을 붙이고 데이터 조회만 하는 경우라면 @Transactional(readOnly = true)를 명시합니다. readOnly가 true로 붙은 조회용의 경우 스냅샷이 생기지 않습니다. 즉, 영속성 컨텍스트에서 관리는 하고 있지만 dirty checking을 안하기 때문에 수정해도 DB에 결과가 반영되지 않습니다. N+1 N+1 은 엔티티를 조회할 때, 해당 엔티티에 연관관계를 갖는 다른 엔티티를 프록시로 가져오면서(LazyLoading) 실제 데이터에 접근하는 시점에 해당 엔티티를 가져오기 위해 또 다른 조회 쿼리를 보내..
2023.12.30 -
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