본문 바로가기

IT/JPA

(16)
JPA Kotlin으로 Entity설계시 고려할 부분을 알아보자 오늘은 요즘 스프링 프로젝트 개발시에 많이들 JPA+ Kotlin조합으로 개발을 하시는데 이 때 Entity를 만들때 고려할 만한 것들에 대해 알아보고자 합니다. 프로젝트 환경 SpringBoot 2.7.5 Kotlin 1.7.20 JPA Entity noArgs constructor JPA Entity는 기본적으로 인자가 없는 생성자가 필요합니다. 하지만 코틀린에서는 주생성자 사용시 기본생성자를 가지고 있지 않아 디폴트 파라미터로 직접만들어야 합니다. 부 생성자로만 사용할 경우에도 생성자 위임을 통해 모든 필드를 초기화해야 합니다. 이런 초기화해주는 문제는 Kotlin에서 제공하는 플러그인을 통해 해결 가능합니다. plugins { kotlin("plugin.noarg") version "1.7.20"..
Spring Data JPA Pageable Paging 하기 오늘은 게시판에 필수인 Pagination 페이징처리를 Spring Data Jpa에서 어떻게 하는지와 관련 클래스를 알아보고 간단하게 만들어도 볼까합니다. Pagination 데이터베이스에서 데이터를 가져올 때 한번에 전부 가져오는 것이 아니라 정해진 Size만큼 페이징해서 가져오면서 서버의 부화를 줄여주는 기술 다른 언어들의 일반적인 페이징로직에 비해 Spring Data JPA를 쓰면 동적 페이징 쿼리가 쉽습니다. 순수 JPA에서의 Pagination 먼저 간략히 순수 JPA에서의 Pagination에 대해 알아보시죠 데이터베이스에 따라 Pagination처리를 하는 방법은 다양합니다. Mysql은 좀 간단한 편이고, Oracle은 좀 복잡합니다. JPA는 이런 여러 DB 방언(dialect)을 추..
JPA BatchSize에 대해 알아보자 오늘은 JPA BatchSize에 대해 간단히 알아 보겠습니다. Jpa BatchSize란 BatchSize 는 JPA 의 성능 개선을 위한 옵션 중 하나입니다. 데이터의 전체 row를 예상할 수 있는 범위에서는 좋은 방안이긴 하나 정확한 Size를 알수 없을때는 적정값을 설정해 주긴 어렵습니다. 그리고 연관관계의 있는 엔티티의 1+N 이슈의 한 해결 방법이기도 합니다. 다수의 프록시 객체를 조회할 때 WHERE 절이 같은 여러 개의 SELECT 쿼리들을 하나의 IN 쿼리로 만들어줍니다. - Entity Team 엔티티 Member 엔티티를 1:N의 연관관계를 맺어 보겠습니다. - BatchSize @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @..
JPA의 낙관적 락과 비관적 락을 통해 엔티티에 대한 동시성 제어에 대해 알아보자 오늘은 Transaction isolation level에 대해 알아보겠습니다. 트랜잭션 격리수준이란 동시에 여러 트랜잭션을 처리할 때 트랜잭션이 얼마나 서로 고립되어 있는지를 의미합니다. 즉 해당 트랜잭션이 다른 트랜잭션에서 변경한 데이터를 볼 수 있는 기준을 결정하는 것입니다. - 트랜잭션 레벨에서의 격리 READ UNCOMMITED READ_UNCOMMITTED 는 가장 낮은 격리 수준이며 가장 많은 동시 액세스를 허용합니다. 커밋되지 않은 데이터 읽기 가능 반복 불가능한 읽기와 팬텀 읽기가 모두 발생할 수 있습니다. 따라서 행을 다시 읽거나 범위 쿼리를 다시 실행할 때 다른 결과를 얻을 수 있습니다. READ COMMITTED 커밋된 데이터만 읽기 가능 Oracle DBMS에서 표준으로 사용합니다..
JPA EntityManager 라이프사이클에 대해 알아보자 이번 시간에는 JPA Lifecycle에 대해 간단히 알아보고자 합니다. 저 같은 경우는 설정파일로 만들어 사용하고 있는데 오늘 그 개념을 정리하고자 글을 적습니다. 예전 강의를 들을때를 기억하며 정리하도록 하겠습니다. - JPA 코드 Spring Data Jpa가 아닌 JPA에서의 코드를 먼저 한번 보겠습니다. emf: EntityManagerFactory = Persistence.createEntityManagerFactory("master") entityManager: EntityManager = emf.createEntityManager() transaction: EntityTransaction = entityManager.getTransaction() try { transaction.begin(..
JPA EntityGraph에 대해 알아보자 이번 시간에는 JPA EntityGraph에 대해 간단히 알아보고자 합니다. JPA 2.0까지는 엔터티 연결을 로드하기 위해 일반적으로 FetchType을 사용했습니다. LAZY 및 FetchType Lazy 또는 EAGER를 통해서 JPA 제공자에게 관련 연관을 추가로 로딩합니다. 그러나 FetchType은 정적이며 런타임에 이 두 전략 사이를 전환할 수 없습니다. JPA 엔터티 그래프의 주요 목표는 엔터티의 관련 연결 및 기본 필드를 로드할 때 런타임 성능을 개선하는 것입니다. 간단히 말해서 JPA는 하나의 선택 쿼리에서 모든 그래프를 로드한 다음 더 많은 SELECT 쿼리와의 연결 가져오기를 방지합니다. 이것은 응용 프로그램 성능을 향상시키기 위한 좋은 접근 방식입니다. EntityGraph를 코드..
JPA 상속 전략에 대해 알아보자 이번 시간에는 JPA 객체간 상속관계 대해 알아보고자 합니다. ​ 관계형 데이터베이스에는 클래스 계층을 데이터베이스 테이블에 매핑하는 간단한 방법이 없습니다. 굳이 따지면 (슈퍼타입 서브타입 관계)있긴 하지만 잘 사용되진 않습니다. 이를 해결하기 위해 JPA는 다음과 같은 몇가지 상속전략을 제공합니다. Joined Table Single Table Table per Class - Joined Strategy 조인테이블 전략을 사용하면 계층 구조의 각 클래스가 해당 테이블에 매핑됩니다. 모든 테이블에 반복적으로 나타나는 유일한 열은 필요할 때 결합하는 데 사용되는 식별자입니다. @DiscrimanatorColumn으로 부모 클래스의 구분컬럼을 지정한니다. 기본 값은 DTYPE입니다. 부모테이블 클래스 En..
JPA Entity Manager를 알아보자 이번 시간에는 JPA EntityManager에 대해 알아보고자 합니다. 지난번에 알아보았던 JPA영속성 컨텍스트 글에서도 잠깐 등장한 녀석입니다. EntityManager는 Java Persistence API의 일부이며 JPA 2.0 사양에 정의된 프로그래밍 인터페이스와 수명 주기 규칙을 구현합니다. 또한 EntityManager 의 API를 사용하여 영속성 컨텍스트에 액세스할 수 있습니다 . 이글에서는 EntityManager 의 구성, 유형 및 다양한 API를 살펴보겠습니다 .- Gradle 종속성 Gradle에 아래와 같이 종속성을 추가해 줍니다. implementation("org.springframework.boot:spring-boot-starter-data-jpa") //hibernate..
JPA 영속성 컨텍스트를 알아보자 이번 시간에는 JPA 영속성 컨텍스트에 대해 알아보고자 합니다. Hibernate와 같은 영속성 공급자는 영속성 컨텍스트를 사용하여 애플리케이션의 엔티티 수명 주기를 관리합니다. 이글에서는 영속성 컨텍스트의 소개부터 왜 중요한 지를 알아보겠습니다. 영속성 컨텍스트에 종류와 그 차이점을 예제와 함께 살펴보겠습니다.- 영속성 컨텍스트 (Persistence context) 먼저 영속성 컨텍스트의 공식 정의에 대해 알아 보겠습니다. EntityManager인스턴스는 영속성 컨텍스트와 연결됩니다. 영속성 컨텍스트는 영구 엔티티ID에 대해 고유한 엔티티 인스턴스가 있는 엔티티 인스턴스 집합입니다. 영속성 컨텍스트 내에서 엔티티 인스턴스와 해당 수명 주기가 관리됩니다. EntityManager API는 영구 엔티티..
JPQL – JPA 및 Hibernate에서 쿼리를 정의하는 방법 이번 시간에는 JPA 쿼리언어인 JPQL사용법에 대해서 알아보겠습니다. JPQL은 엔터티 모델을 기반으로 데이터베이스 쿼리를 정의할 수 있는 강력한 쿼리 언어입니다. 구조와 구문은 SQL과 매우 유사합니다. 그러나 JPQL 쿼리의 다른 부분을 살펴보기 전에 지적하고 싶은 중요한 차이점이 있습니다. JPQL은 데이터베이스 테이블 대신 엔터티 개체 모델을 사용하여 쿼리를 정의합니다. 이는 Java 개발자에게 매우 편리하지만 데이터베이스가 여전히 SQL을 사용한다는 점을 염두에 두어야 합니다. 최대 절전 모드 또는 기타 JPA 구현은 JPQL 쿼리를 SQL로 변환해야 합니다. 따라서 생성된 SQL 문을 확인하기 위해 개발 중에 SQL 문의 로깅을 활성화하는 것이 좋습니다 .- Select - From절 Fro..
JPA @Embedded 및 @Embeddable에 대해 알아보자 이번 시간에는 JPA 값타입에 하나인 임베디드 타입에 대해서 알아보겠습니다. @Embeddable, @Embedded 어노테이션을 사용해서 구현합니다.- @Embeddale // writer.kt @Embeddable class Writer( @Enumerated(EnumType.STRING) var writerType: UserType, @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "writer_seller_id") var writerSeller: Seller? = null, @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "writer_staff_id") var writerStaff: Staff? = ..
JPA 연관관계 방향성 (이론편) Spring boot로 프로젝트를 할때 비즈니스에 따른 객체와 관계형 데이터베이스의 연관관계 설계는 까다롭고 매우 중요하다는것을 다들 아실겁니다. 오늘은 그 연관관계에 대해서 이론적으로 정리해 보고자 합니다.- 연관관계의 정의 연관관계의 방향 : 단방향, 양방향 연관관계의 주체 : 양방향일때 관리 주체 연관관계의 종류 : N+1, 1+N, 1:1, N+M 연관관계 방향 데이터베이스의 테이블은 Foreign key로 테이블의 조인이 가능합니다. 그러므로 테이블은 방향성을 논할 필요가 없겠죠 그에 반해 객체는 참조할 수 있는 필드에 따라서 다른 객체를 참조할 수 있습니다. 그말의 즉슨 한쪽에만 참조용 필드가 있으면 단방향, 양쪽 모두에 참조용 필드가 있으면 양방향 관계가 됩니다. 말이 양방향이지 서로 방향을..
JPA Entity 애노테이션 알아보기 JPA Entity 애노테이션 알아보기 지난 시간에 상품을 주문하고 결제하는 데 필요한 대략적인 Entity를 만들어 보았다 오늘은 Entity에 사용된 애노테이션에 대해 알아보고자 한다 @Entity - Jpa Entity를 만들기 위해 사용되며 데이터베이스 테이블과 1:1로 매칭되는 객체단위이다 - 테이블에서 하나의 레코드 값을 의미한다. @Id, @GeneratedValue - @Id는 테이블에서 Primary key와 같은 개념이며 객체의 유일한 키값을 의미한다. = @GeneratedValue는 유일한 키값에 대한 전략이다. @JsonIgnore - 직렬화 역직렬화에 사용되는 논리적 프로퍼티(속성..) 값을 무시할때 사용됩니다. @JsonIgnore var password: String, 위의 ..
JPA Entity를 만들어 보자 JPA Entity 만들기 스프링으로 프로젝트를 진행할때 ORM으로 진행한다. 그때 Entity를 만들어 DB와 매핑을 하는데 오늘은 Entity작성법을 알아보고 다음편에는 관련 속성에 관하여 정리를 해보고자 한다. - 이글의 목적은 Entity를 만들때마다 생각이 가물가물한 경우가 많아서 대략적인 구조를 정리하는 차원이다. - 참고로 작성된 언어는 KOTLIN으로 작성되었다.시나리오 1. 고객정보를 담은 Customer Entity 작성 2. 상품을 판매하는 판매자 Entity작성 3. 판매자가 운영하는 가게 정보를 담은 Entity작성 4. 판매하는 상품의 정보를 담은 Entity 작성 5. 판매하는 상품의 옵션 정볼를 담은 Entity 작성 6. 주문 정보를 담은 Entity 작성 7. 주문한 가게..
[ JPA ] 프록시와 연관관계 정리 프록시와 연관관계 관리 프록시 2개의 테이블 Shop, Product가 있다. 두 테이블은 OneToMany , ManyToOne으로 연관되어 있다. 이 경우 Product를 조회할 때 Shop이 함께 출력되는 경우와 Product만 출력되는 경우를 보자 # 상품과 상점이 함께 출력되는 경우 fun pringProductAndShop(productId: String) { val product = em.find(Product::class.java, productId) val shop = product.shop println("상점 이름 : ${shop.name}") println("상품 이름 : ${product.name}") } # 상점만 출력되는 경우 fun printShop(shopId: String..