본문 바로가기

SpringFramework

(36)
JPA - 트랜잭션과 락 (+격리수준) 트랜잭션과 격리레벨 트랜잭션은 아래 4가지 성질을 보장해야 한다. - 원자성(Atomicity) : 트랜잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공하던지, 실패하던지 해야한다. 부분적 성공, 실패는 없다. - 일관성(Consistency) : 모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야 한다. 만약 게시판 제목의 컬럼타입이 VARCHAR(255) 라면, 이 조건에 맞아야한다. - 격리성(Isolation) : 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다. 동시에 같은 데이터가 수정되면 안된다. 트랜잭션끼리 서로 간섭할 수 없다. - 지속성(Durability) : 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 한다. 중간에 시스템에 문제가..
JPA - N+1 문제 N+1 문제는 JPA를 사용하면서 성능상 가장 조심해야 하는 문제중 하나로 꼽히고 있다. N+1 문제란 무엇인가? @Entity public class Order { // 주문정보 @Id @GeneratedValue private Long id; @ManyToOne(fetch = FetchType.EAGER) // 즉시로딩 전략 private Member members; // 주문한 회원 } // ========================================== public class OrderService { // ... EntityManager 생략 Order order = em.find(Order.class, "1"); /* SELECT o.*, m.* FROM Order o LEFT O..
JPA - 스프링 데이터 JPA 스프링 데이터 JPA란? 스프링 프레임워크에서 JPA를 편리하게 사용할 수 있도록 지원하는 프로젝트. 데이터 접근 계층을 개발할 때 지루하게 반복되는 CRUD 문제를 더 깔끔한 방법으로 해결한다. CRUD를 처리하기 위한 공통 인터페이스를 제공하고 리포지토리를 개발할 때 인터페이스만 작성하면, 실행 시점에 스프링 데이터 JPA가 구현 객체를 동적으로 생성하여 주입한다. 데이터 접근 계층을 개발할 때 구현 클래스 없이 인터페이스만 작성하여 사용이 가능하다. - 스프링 데이터 JPA 라이브러리 추가 dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' // ... } 공통 인터페이스 - 스프링 데이터 JPA ..
JPA - QueryDSL Spring Boot 2.5.5 + QueryDSL 5.0.0 세팅 및 사용법 관련 설명 참고 => https://xggames.tistory.com/57 (본문은 김영한님의 자바 ORM 표준 JPA 프로그래밍 서적을 참고하여 정리한 내용이며, QueryDSL의 상위 버전의 경우에는 적용되지 않을 수 있습니다) QueryDSL은 JPA의 표준이 아닌 오픈소스 프로젝트이다. 따라서 Spring-Data-JPA에는 포함이 되어있지않고, 별도의 라이브러리 DI를 추가해줘야 한다. Criteria처럼 코드기반이면서도 단순하고 사용하기가 쉽다. Criteria는 너무 복잡하고 어렵다는 단점이 있지만 QueryDSL은 쉽고 간결하며, 모양도 쿼리와 비슷하게 개발할 수 있어서 가독성을 높여주는 효과는 덤. gradl..
JPA - Criteria Criteria는 JPQL을 생성하는 빌더 클래스다. Criteria는 문자가 아닌 query.select(arg).where(..) 이런 모양으로 프로그래밍 코드로 JPQL을 작성할 수 있는 특징이 있다. 문자열 기반 쿼리는 컴파일시점에서는 오류가 나지 않지만, Criteria는 코드로 JPQL을 작성하기때문에 컴파일 시점에 오류를 잡아낼 수 있다. 하지만, 장점이 많은 만큼 복잡하고 장황한 문제가 있다. 그래서 사용하기 불편하고, 복잡한 코드때문에 가독성이 떨어지는 단점이 있다. 아래의 Criteria 사용 기본예제를 살펴보자. Spring-Data-JPA의 EntityManager를 사용한다. EntityManagerFactory emf = Persistence.createEntityManagerF..
JPA - 객체지향 쿼리 언어, JPQL JPQL(JavaPersistence Query Language)은 가장 중요한 객체지향 쿼리 언어이다. Criteria나 QueryDSL은 이 JPQL을 편리하게 사용하도록 도와주는 기술이며, JPQL에서 시작한다. JPQL의 특징 - 테이블이 아닌 객체를 대상으로 검색하는 객체지향 쿼리 - SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않도록 함 - SQL이 데이터베이스 테이블이 대상인 데이터 중심의 쿼리라면, JPQL은 엔티티 객체를 대상으로 하는 객체지향 쿼리이다. - JPQL을 사용하면 JPA가 이를 분석하여 적절한 SQL을 만들어서 DB를 조회한다. 그리고 조회 결과를 엔티티 객체를 생성하여 반환한다. - 엔티티 직접 조회, 묵시적 조인, 다형성 등을 지원하여 SQL보다 코드가 간결하..
JPA - 값타입 엔티티 타입(Entity Type)과 값 타입(Value Type)의 특징 - 엔티티 타입(Entity Type) - 식별자(@Id)가 있다. 그리고 식별자로 구별할 수 있다 - 생명 주기가 있다. (생성 - 영속 - 소멸) - 공유할 수 있다. 다른 엔티티에서 얼마든지 해당 엔티티를 참조할 수 있다. - 값 타입(Value Type) - 임베디드 타입 - 식별자가 없다. - 생명주기를 엔티티에 의존한다. 즉 의존하는 엔티티가 제거되면 같이 제거된다. - 공유하지 않는 것이 안전하다. 오직 하나의 주인만이 관리해야하며, 불변객체로 만드는 것이 안전하다. 임베디드 타입(복합 값 타입) @Entity public class Member { @Id @GeneratedValue private Long id; p..
JPA - 연관관계 고급매핑 상속 관계 매핑 조인전략 : 엔티티 각각을 모두 테이블로 만들고 자식 테이블이 부모 테이블의 기본 키를 받아서 기본키+외래키로 사용하는 전략 - 객체는 타입으로 구분이 가능하지만, 테이블은 타입의 개념이 없기때문에 구분하는 컬럼을 추가해야한다. @Entity @Inheritance(strategy = InheritanceType.JOINED) // 상속 매핑 @DiscriminatorColumn(name = "DTYPE") // 구분 컬럼을 지정 public abstract class Item { @Id @GeneratedValue private Long id; private String name; private int price; } @Entity @DiscriminatorValue("Album") /..
JPA - 연관관계 엔티티들은 대부분 다른 엔티티와 연관관계를 가진다. 예를들면 회원과 주문이 있다고한다면, 회원은 회원 관련한 정보를 담고있고, 주문은 상품의 구매와 같은 정보를 담고 있을 것이다. 둘은 완전히 다른 특성을 가지고있는데, 서로다른 특성을 지닌 정보들끼리 관계를 맺게 해줄 수 있다. 상품구매를 누가했을까? 이렇듯 회원과 주문을 연결하여 관계를 맺는 것을 연관관계라고 한다. 연관관계 개념 및 이해 핵심 키워드 - Direction (방향) 단방향(둘 중 한쪽만 참조) 양방향(양쪽 모두 참조)이 있다. 방향은 객체관계에만 존재한다 - Multiplicity (다중성) 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M) - owner (연관관계의 주인) 객체를 양방향 연관관계로 만들게 되면 연관..
JPA - 엔티티 매핑 - 객체와 테이블 매핑: @Entity, @Table - 기본 키 매핑: @Id - 필드와 컬럼 매핑: @Column - 연관관계 매핑: @ManyToOne, @JoinColumn @Entity 속성 기능 기본값 name JPA에서 사용할 Entity 이름을 지정. 설정하지 않으면 Class명을 그대로 사용한다 (ex) User class -> "User") @Entity 사용시 주의사항 - 기본 생성자는 필수 (파라미터가 없는 public 혹은 protected) => 실제로 Entity Class에서 생성자를 생략해도 Java에서는 기본생성자를 만들어주기 때문에 오류가 발생하지는 않음. => JPA가 객체 생성시에 기본 생성자를 사용하기 때문 - final, enum, interface, inner ..