JPA 17

[JPA] JPQL 기본

서론 JPA에서는 여러가지 쿼리방법을 지원하는데 그 중 대표적으로 JPQL과 JPA Criteria가 있다. JPQL의 경우에는 엔티티 객체를 대상으로 쿼리를 작성하고 SQL 문법과 매우 유사하다. List result = em.createQuery("select m From Member m where m.name like ‘%hello%'", Member.class) .getResultList(); 하지만 String 형태로 작성되기 때문에 동적인 쿼리는 작성하기 어렵다. 이를 위해서 JPA 표준스펙으로 JPA Criteria가 존재한다. 하지만 JPA Criteria 같은 경우, 코드를 자바 코드로 작성할 수 있다는 장점이 존재한다. CriteriaBuilder cb = em.getCriteriaBu..

JPA 2020.10.27

[JPA] 값 타입 Collections

데이터베이스에는 자바의 컬렉션을 저장할 수 있는 메커니즘이 아니다. 자바의 컬렉션 데이터를 저장하려면 별도의 테이블에 하나하나 저장해야한다. 사용 방법 예시 코드 Address 임베디드 값 타입 : @Embeddable public class Address { private String city; private String street; private String zipcode; public Address() { } public Address(String city, String street, String zipcode) { this.city = city; this.street = street; this.zipcode = zipcode; } public String getCity() { return cit..

JPA 2020.10.24

[JPA] 임베디드 타입

자바에는 기본값 타입이라는 것이 존재하는데, 먼저 int, double 같은 것과, Integer Long 과 같은 Wrapper 클래스, String 같은 것이 존재한다. String name; int age; 와 같은 것이 그 예이다. 참고로 int, double같은 기본 타입은 절대 공유할 수 없다. C언어야 메모리 접근이 가능하기 때문에 가능하지만, 자바는 그렇지 않다. int a = 10; int b = a; b = 20; b = a 과정에서는 값이 복사되는 것이지 공유되는 것이 아니다. 또한 Wrapper 클래스나 String 같은 특수한 클래스는 공유 가능한 객체긴 하지만 변경할 수가 없다. 이 녀석들은 기본 값 타입이기 때문에 생명주기 자체는 엔티티가 제거 되면 당연히 같이 제거가 된다. ..

JPA 2020.10.23

[JPA] orphanRemoval

부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제해주는 기능이다. @Entity public class Parent { @Id @GeneratedValue private Long id; private String username; @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true) private List childList = new ArrayList(); } orphanRemoval을 true로 하면 , Parent parent1 = em.find(Parent.class, parent.getId()); parent1.getChildList().remove(0); // delete 쿼리나간다. 자동으로 ..

JPA 2020.10.22

[JPA] CASCADE

특정 엔티티를 영속 상태로 만들 때, 연관된 엔티티도 함께 영속 상태로 만들도 싶을 때 사용한다. 예를 들어, 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장할때 사용한다. 원래 기본은 Child child1 = new Child(); Child child2 = new Child(); Parent parent = new Parent(); parent.addChild(child1); parent.addChild(child2); em.persist(parent); em.persist(child1); em.persist(child2); 이렇게 child1, 2를 다 저장해야한다. 근데, @Entity public class Parent { @Id @GeneratedValue private Long id; p..

JPA 2020.10.22

[JPA] 지연로딩

참조가 있는 엔티티를 조회할때는 그 참조를 한번에 같이 즉시 조회할지 아니면 사용할때 조회할지에 대한 정의를 내려줘야한다. 즉시 로딩은 엔티티 객체 조회시에 한번에 다 가져오는 것이고, 지연 로딩은 참조의 메서드를 호출 했을 때, 초기화했을 때 그때 불러오는 것이다. @ManyToOne과 @OneToMany의 fetch 전략은 기본이 즉시로딩이다. 이것을 지연로딩으로 바꾸려면 아래 코드와 같다. @Entity public class Member extends BaseEntity { @Id @GeneratedValue @Column(name = "MEMBER_ID") private Long id; @Column(name = "USERNAME") private String username; @ManyToOn..

JPA 2020.10.22

[JPA] 프록시

엔티티 객체를 조회할때는 사용범위를 고려해야한다. 어떤 엔티티 객체가 FK 컬럼으로 다른 엔티티를 참조하고 있다면 이 참조는 즉시 불러와질까, 아니면 어떻게 될까? 앞서 흔하게 사용한 em.find()는 즉시 모든걸 가져온다. 데이터베이스를 통해서 실제 엔티티 객체를 가져온다는 뜻이다. 반면에 EntityManager에는 .getReference()라는 것이 존재하는데, 이는 데이터베이스에서 조회하는 쿼리를 날리지 않고 가짜 엔티티 객체를 가져오는 메서드이다. 간단하게 말하면 가져왔다고 가정은 되어 있지만 실제로 쿼리를 날려서 가져온 것이 아니고 쉽게 말해 null이 들어가 있는 상태이다. 프록시는 실제 클래스를 상속 받아서 만들어진 존재이고 실제 클래스와 겉모양이 같다. 이 프록시는 프록시 객체, 즉 ..

JPA 2020.10.22

[JPA] @MappedSuperclass

이 어노테이션은 데이터베이스 객체지향과 설계상의 상속관계가 아니고, 그냥 단순하게 공통 매핑 정보가 필요할때 사용한다. 예를 들어 id나 name들은 자주 반복되므로 abstract 클래스를 따로 두고 필요할때 상속해서 사용하는 방법이다. 따라서 정리하자면 상속관계 매핑이 아니고, 엔티티 테이블 매핑도 아니고 그저 부모 클래스를 상속 받는 자식 클래스에 매핑 정보만 제공하는 방식이다. 당연히 엔티티가 아니기 때문에 조회나 검색이 불가능하다. 주로 등록수정일 등록자나 수정자 같은 전체 엔티티에서 공통으로 적용하는 정보를 모을때 사용한다. 즉, 직접 사용할 일이 없기 때문에 추상 클래스 (abstract) 클래스로 만들어 사용한다. ※ @Entity 클래스는 @Entity나 @MappedSuperclass ..

JPA 2020.10.20

[JPA] 상속관계 매핑

먼저 객체지향에는 상속이라는 것이 있다. 하지만 관계형 데이터베이스에는 상속이라는 관계가 주어지지 않는다. 하지만 조금 비슷한 것을 보자면, 슈퍼타입과 서브타입이라는 것이 존재한다. 만약 Item이라는 테이블이 존재할때, 키나 DTYPE을 통해서 Album인지 Movie인지 Book인지 등등 어떤 종류인지 구분해내는 것이다. 이런 구현 전략을 위해서 JPA는 3가지의 어노테이션을 제공한다. 1. @Inheritance(strategy = InheritanceType.JOINED) 2. @Inheritance(strategy = InheritanceType.SINGLE_TABLE) 3. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 1. 조인 전략 먼..

JPA 2020.10.20

[JPA] 여러가지 연관관계 매핑

연관관계를 매핑할 때는 1. 다중성과 2. 단방향인지 양방향인지, 양방향일때 3. 연관관계의 주인은 누구로 설정할지가 중요하다. 1. 다중성 여기서 다중성은 4가지가 존재한다. 1) 다대일 N:1 @ManyToOne 2) 일대다 1:N @ OneToMany 3) 일대일 1:1 @OneToOne 4) 다대다 N:M @ManyToMany 2. 단방향, 양방향 앞서 많이 이야기 했지만 테이블은 외래 키 하나만 정해져있어도 어느 방향으로든 데이터를 불러올 수 있다(조인) 방향이라는 개념 자체가 없다. 근데 객체는 아니다. 참조하는 필드가 있는 쪽으로만 방향이 정해져있고 한쪽만 참조하면 단방향, 양쪽이 서로 참조하면 양방향이다. 근데 사실 양방향이라는 용어는 억지로 만들어낸 것이고 단방향 두개라고 생각하면 된다...

JPA 2020.10.16