과정명

Similar documents
- JPA를사용하는경우의스프링설정파일에다음을기술한다. <bean id="entitymanagerfactory" class="org.springframework.orm.jpa.localentitymanagerfactorybean" p:persistenceunitname=

Spring Data JPA Many To Many 양방향 관계 예제

* Factory class for query and DML clause creation * tiwe * */ public class JPAQueryFactory implements JPQLQueryFactory private f

PowerPoint Presentation

JUNIT 실습및발표

@OneToOne(cascade = = "addr_id") private Addr addr; public Emp(String ename, Addr addr) { this.ename = ename; this.a

Spring Boot/JDBC JdbcTemplate/CRUD 예제

Microsoft PowerPoint 자바-기본문법(Ch2).pptx

5장 SQL 언어 Part II

PowerPoint Presentation

어댑터뷰

C# Programming Guide - Types

q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2

gnu-lee-oop-kor-lec06-3-chap7

PowerPoint 프레젠테이션

파워포인트 템플릿

PowerPoint Presentation

JAVA PROGRAMMING 실습 08.다형성

쉽게 풀어쓴 C 프로그래밊

제11장 프로세스와 쓰레드

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

PowerPoint Presentation

PowerPoint 프레젠테이션

PowerPoint Presentation

Microsoft PowerPoint - C++ 5 .pptx

Microsoft PowerPoint - 2강

슬라이드 1

1. 객체의생성과대입 int 형변수 : 선언과동시에초기화하는방법 (C++) int a = 3; int a(3); // 기본타입역시클래스와같이처리가능 객체의생성 ( 복습 ) class CPoint private : int x, y; public : CPoint(int a

PowerPoint 프레젠테이션

Design Issues

제8장 자바 GUI 프로그래밍 II

Microsoft PowerPoint - CSharp-10-예외처리

예제 2) Test.java class A intvar= 10; void method() class B extends A intvar= 20; 1"); void method() 2"); void method1() public class Test 3"); args) A

InsertColumnNonNullableError(#colName) 에해당하는메시지출력 존재하지않는컬럼에값을삽입하려고할경우, InsertColumnExistenceError(#colName) 에해당하는메시지출력 실행결과가 primary key 제약에위배된다면, Ins

쉽게 풀어쓴 C 프로그래밍

C++ Programming

강의 개요

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

chap x: G입력

SQL

슬라이드 1

문서 템플릿

유니티 변수-함수.key

OCW_C언어 기초

JAVA PROGRAMMING 실습 02. 표준 입출력

PowerPoint 프레젠테이션

adfasdfasfdasfasfadf

슬라이드 1


PowerPoint 프레젠테이션

Microsoft PowerPoint - additional01.ppt [호환 모드]

17장 클래스와 메소드

목차 BUG 문법에맞지않는질의문수행시, 에러메시지에질의문의일부만보여주는문제를수정합니다... 3 BUG ROUND, TRUNC 함수에서 DATE 포맷 IW 를추가지원합니다... 5 BUG ROLLUP/CUBE 절을포함하는질의는 SUBQUE

chap 5: Trees

MySQL-.. 1

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

빅데이터분산컴퓨팅-5-수정

C++ Programming

13주-14주proc.PDF

PowerPoint 프레젠테이션

8 장데이터베이스 8.1 기본개념 - 데이터베이스 : 데이터를조직적으로구조화한집합 (cf. 엑셀파일 ) - 테이블 : 데이터의기록형식 (cf. 엑셀시트의첫줄 ) - 필드 : 같은종류의데이터 (cf. 엑셀시트의각칸 ) - 레코드 : 데이터내용 (cf. 엑셀시트의한줄 )

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

5장. JSP와 Servlet 프로그래밍을 위한 기본 문법(완성-0421).hwp

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

Microsoft PowerPoint - Java7.pptx

JDBC 소개및설치 Database Laboratory

ThisJava ..

슬라이드 제목 없음

API 매뉴얼

Microsoft PowerPoint - e pptx

쉽게 풀어쓴 C 프로그래밍

Microsoft PowerPoint - ch07 - 포인터 pm0415

과정명

WINDOW FUNCTION 의이해와활용방법 엑셈컨설팅본부 / DB 컨설팅팀정동기 개요 Window Function 이란행과행간의관계를쉽게정의할수있도록만든함수이다. 윈도우함수를활용하면복잡한 SQL 들을하나의 SQL 문장으로변경할수있으며반복적으로 ACCESS 하는비효율역

<4D F736F F F696E74202D203137C0E55FBFACBDC0B9AEC1A6BCD6B7E7BCC72E707074>

TITLE

슬라이드 제목 없음

Spring Boot

Microsoft PowerPoint - 04-UDP Programming.ppt

Connection 8 22 UniSQLConnection / / 9 3 UniSQL OID SET

윈도우시스템프로그래밍

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

<4D F736F F F696E74202D20C1A63034B0AD202D20C7C1B7B9C0D3B8AEBDBAB3CABFCD20B9ABB9F6C6DBC0D4B7C2>

Microsoft PowerPoint - chap04-연산자.pptx

Microsoft PowerPoint 웹 연동 기술.pptx

JAVA PROGRAMMING 실습 05. 객체의 활용

PowerPoint 프레젠테이션

3 S Q L A n t i p a t t e r n s Trees/intro/parent.sql CREATE TABLE Comments ( comment_id SERIAL PRIMARY KEY, parent_id BIGINT UNSIGNED, comment TEXT

09-interface.key

쉽게

(Microsoft PowerPoint - java1-lecture11.ppt [\310\243\310\257 \270\360\265\345])

PowerPoint Presentation

Microsoft PowerPoint - chap11-포인터의활용.pptx

2 Cover Story POJO 로돌아온 EJB 3.0 과자바퍼시스턴스 API 이번특집에서는자바EE 5의변화중가장눈에띄는 EJB 3.0과자바퍼시스턴스 (Java Persistence) API 기술을소개하고자한다. 이기술들은기존 EJB 2.1에비해서많은부분이달라졌다.

thesis

rmi_박준용_final.PDF

Microsoft PowerPoint - Chap12-OOP.ppt

PowerPoint Presentation

JVM 메모리구조

슬라이드 1

Transcription:

데이터접근프레임워크 (JPA 와 Hibernate) 교육기간 : 2014.05.26 ~ 05.30 강사 : 박석재, 임병인 넥스트리소프트 demonpark@nextree.co.kr byleem@nextree.co.kr

교육일정표 교육은매회 3 시간씩총 5 회에걸쳐진행합니다. 1 일차 2 일차 3 일차 4 일차 5 일차 5 월 26 일 ( 월 ) 5 월 27 일 ( 화 ) 5 월 28 일 ( 수 ) 5 월 29 일 ( 목 ) 5 월 30 일 ( 금 ) ORM 이해하기 영속성 패러다임불일치 계층형아키텍처 객체 / 관계형매핑 Quick Start - Hibernate Hibernate 개요 Hibernate 기본 OR Mapping I - Hibernate Spring 과 Hibernate 통합 OR Mapping II 트랜잭션관리 Hibernate 와 EJB - JPA 도메인모델과 JPA JPA 이용도메인객체구현 엔티티관계 엔티티매핑 엔티티관계매핑 - JPA 상속매핑 EntityManager 질의 API JPQL - 1 -

5 일차 JPA 5.1 상속매핑 5.2 EntityManager 5.3 질의 API 와 JPQL 단일테이블전략 조인테이블전략 클래스별테이블전략 다형성관계매핑

단일테이블전략 상속계층의모든클래스를한테이블로매핑함 식별자 (discriminator) 컬럼으로계층상의객체를구분함 식별자컬럼은객체의타입값을가짐 식별자컬럼 매핑 annotation @Entity @Table(name="USERS") @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="USER_TYPE", discriminatortype=discriminatortype.string, length=1) public abstract class User... @Entity @DiscriminatorValue(value="S") public class Seller extends User... @Entity @DiscriminatorValue(value="B") public class Bidder extends User - 3 -

조인테이블전략 일대일관계를이용하여상속을표현 각엔티티별로테이블을나누며, 상속관계는일대일관계로표현 부모클래스에해당하는테이블은자식클래스들의공통인컬럼을가짐 매핑 annotation @Entity @Table(name="USERS") @Inheritance(strategy=InheritanceType.JOINED) @DiscriminatorColumn(name="USER_TYPE", discriminatortype=string, length=1) public abstract class User... @Entity @Table(name="SELLERS") @DiscriminatorValue(value="S") @PrimaryKeyJoinColumn(name="USER_ID") public class Seller extends User... @Entity @Table(name="BIDDERS") @DiscriminatorValue(value="B") @PrimaryKeyJoinColumn(name="USER_ID") public class Seller extends User... - 4 -

클래스별테이블전략 상속계층상의모든클래스가각각테이블로매핑되며테이블은관계가없음 OO / Relational 관점에서모두바람직하지않음 @Entity @Table(name="USERS") @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) public class User {... @Entity @Table(name="SELLERS") public class Seller extends User {... @Entity @Table(name="BIDDERS") public class Bidder extends User { 엔티티검색시 SQL UNION 을사용하거나각엔티티를별도의 SQL 로검색해야함 - 5 -

상속매핑전략비교 상속매핑전략선택은많은고민을필요로함 특성단일테이블조인테이블클래스별테이블 테이블지원 모든클래스를한테이블에 컬럼이널가능 하위클래스추가시테이블이확장됨 부모클래스, 자식클래스가별도의테이블로매핑되고조인으로서로묶음매핑된테이블은정규화됨 식별자컬럼사용예예아니오 각클래스별한테이블이며조인관계없음 엔티티계층검색 SQL 생성 단순 SELECT 조인을포함한 SELECT 각클래스별하나의 SELECT 또는 SELECT의 UNION 사용 삽입 / 갱신을위한 SQL 하나의 INSERT/UPDATE 여러 INSERT/SELECT, 부모클 래스와각하위클래스용 다형성관계좋음좋음나쁨 다형성질의좋음좋음나쁨 EJB3 JPA 지원필수필수선택사항 각클래스별하나의 INSERT/UPDATE - 6 -

5 일차 JPA 5.1 상속매핑 5.2 EntityManager 5.3 질의 API 와 JPQL EntityManager소개 EntityManager 인스턴스생성 지속성오퍼레이션관리 엔티티라이프사이클리스너 엔티티운영가이드

EntityManager 소개 : EntityManager 인터페이스 (1/2) EntityManager 객체지향과관계형간의다리역할 도메인객체를테이블로변환 엔티티저장요청시 : 엔티티객체를생성하여, 데이터베이스저장한다음객체지향세계로리턴하여줌 SQL 과같은 CRUD 오퍼레이션제공 강력한기능에비해상대적으로작고단순하며직관적인인터페이스를가짐 - 8 -

EntityManager 소개 : EntityManager 인터페이스 (2/2) 메소드시그너처 public void persist(object entity); public <T> T merge(t entity); public void remove(object entity); public <T> T find(class<t> entityclass, Object primarykey); public void flush(); public void setflushmode(flushmodetype flushmode); public FlushModeType getflushmode(); public void refresh(object entity); public Query createquery(string jpqlstring); public Query createnamedquery(string name); public Query createnativequery(string sqlstring); public Query createnativequery(string sqlstring, Class result Class); public Query createnativequery(string sqlstring, String resultsetmapping); public void close(); public boolean isopen(); public EntityTransaction gettransaction(); public void jointransaction(); 엔티티를 DB 로저장 설명 EntityManager 의지속성컨텍스트로엔티티를병합 DB 로부터엔티티삭제 일차키로엔티티인스턴스를찾음 EntityManager 의지속성컨텍스트안의엔티티를 DB 와동기화함 EntityManager 의지속성컨텍스트의 flush 모드를변경함 (AUTO 또는 COMMIT) 현재플러시모드검색 DB 의엔티티를리셋함 JPQL 문을이요하여동적질의생성 질의인스턴스생성 원시 SQL 문을이용하여동적질의생성 EntityManager 를종료함 EntityManager 실행상태확인 트랜잭션객체검색 기존 JTA 트랜잭션조인을요청함 - 9 -

EntityManager 소개 : 엔티티라이프사이클 엔티티는아주단순한라이프사이클을가짐 SessionBean이나 MDB는애플리케이션시작과함께컨테이너로로드됨 반면, EntityManager 는 JPA 엔티티로인식하기전에는 POJO 를알지못함 SessionBean 이나 MDB 는처음부터끝까지컨테이너가인식함 반면, EntityManager 는가능한짧은시간동안엔티티를인식하고다루어야함 관리되는엔티티 (managed entity) - 10 -

EntityManager 소개 : 지속성컨텍스트, 범위, EntityManager (1/2) 지속성컨텍스트 (persistence context) 주어진지속성범위내에서 EntityManager 에의해관리되는엔티티컨테이너의집합 지속성범위는엔티티를관리하고있는기간임, 다음두가지유형이있음 트랜잭션 (transaction) 확장 (extended) EntityManager 의내부기능에가장중요한역할을수행함 EntityManager 는엔티티의상태관리를현재가용한지속성컨텍스트로위임함 트랜잭션 - 범위 EntittyManager 트랜잭션기간동안엔티티는 attach 상태이고, 종료후자동으로 detach 상태가됨 - 11 -

EntityManager 소개 : 지속성컨텍스트, 범위, EntityManager (2/2) 확장 - 범위 EntityManager 여러트랜잭션을걸쳐서라이프사이클이지속됨 유상태세션빈과함께사용하고빈인스턴스가살아있는동안계속됨 엔티티의관리대상여부는트랜잭션과관계없음 빈자체가제거되든지 EntityManager가종료되어야범위가끝남 - 12 -

EntityManager 소개 : ActionBazaar 에서 EntityManager 사용 @Stateless public class ItemManagerBean implements ItemManager { @PersistenceContext(unitName="actionBazaar") private EntityManager entitymanager; public ItemManagerBean() {} public Item additem(string title, String description, byte[] picture, double initialprice, long sellerid) { Item item = new Item(); item.settitle(title); item.setdescription(description); item.setpicture(picture); item.setinitialprice(initialprice); Seller seller = entitymanager.find(seller.class, sellerid); item.setseller(seller); entitymanager.persist(item); return item; } public Item updateitem(item item) { entitymanager.merge(item); return item; } public Item undoitemchanges(item item) { entitymanager.refresh(entitymanager.merge(item)); return item; } public void deleteitem(item item) { entitymanager.remove(entitymanager.merge(item)); } } - 13 -

EntityManger 인스턴스생성 : 컨테이너 - 관리 EntityManager Container-managed EntityManager @PersistenceContext annotation을이용주입됨 지속성유닛은소스코드로설정할수없으므로 persistence.xml에설정함 admin 유닛을위한 EntityManager 얻기 @PersistenceContext(unitName="admin") EntityManager entitymanager; 일반적으로 Java EE 모듈은하나의지속성유닛을가짐 EntityManager 범위설정 범위는엔티티의타입에따라결정됨 (transaction or extended) @PersistenceContext(type=PersistenceContextType.EXTENDED) EntityManager entitymanager; 무상태세션빈이나 MDB는확장-지속성범위를가질수없음 유상태세션빈은확장-지속성범위를가질수있음 - 14 -

EntityManger 인스턴스생성 : 애플리케이션 - 관리 EntityManager 애플리케이션 - 관리 EntityManager Java-EE 컨테이너로부터아무것도원하지않음 즉, EntityManager 의라이프사이클을위한모든코드를직접작성해야함 Java SE 나 Tomcat 과같은경량급웹컨테이너만있는곳에서사용 Java EE 컨테이너내에서도 EntityManager 에대한세심한통제가필요한곳에사용가능 @Stateless public class ItemManagerBean implements ItemManager { @PersistenceUnit private EntityManagerFactory entitymanagerfactory; private EntityManager entitymanager; public ItemManagerBean() {} @PostConstruct public void initialize() { entitymanager = entitymanagerfactory.createentitymanager(); } public Item updateitem(item item) { entitymanager.jointransaction(); entitymanager.merge(item); return item; } } @PreDestroy public void cleanup() { if (entitymanager.isopen()) { entitymanager.close(); } }... - 15 -

지속성오퍼레이션관리 : 엔티티저장 EntityManager.persist() 인터페이스 Item은 Seller와다대일관계를가지고있음 persist() 는새로생성하는것이지갱신 (update) 하는것이아님 따라서, persist() 대상객체의일차키나 identity가 DB에존재하지않아야함 public Item additem(string title, String description, byte[] picture, double initialprice, long sellerid) { Item item = new Item(); item.settitle(title); item.setdescription(description); item.setpicture(picture); item.setinitialprice(initialprice); Seller seller = entitymanager.find(seller.class, sellerid); item.setseller(seller); entitymanager.persist(item); return item; } - 16 -

지속성오퍼레이션관리 : 일차키로엔티티검색 EntityManager.find() 인터페이스 일차키로엔티티인스턴스검색 Seller seller = entitymanager.find(seller.class, sellerid); 첫번째파라미터 : 엔티티의자바타입 두번째파라미터 : 엔티티인스턴스의 identity 값 identity는 @Id, @IdClass, @EmbeddableId를이용하여지정 복합키사용 SellerPK sellerkey = new SellerPK(); sellerkey.setfirstname(firstname); sellerkey.setlastname(lastname); Seller seller = entitymanager.find(seller.class, sellerkey); 검색결과가없을경우 null이나빈객체를리턴함 내부캐시를활용함으로써성능을높임 데이터로드시두가지모드 (lazy / eager) 를사용함 @Column(name="PICTURE") @Lob @Basic(fetch=FetchType.LAZY) public byte[] getpicture() { - 17 -

지속성오퍼레이션관리 : 엔티티갱신 (1/2) 갱신 (update) EntityManager는엔티티의모든변경을 DB에반영함 따라서, 애플리케이션은갱신에대해신경쓸필요없음 아래예제에서 seller는관리상태이므로 DB와데이터동기화를뒤에서처리하여줌 public void calculatecreditworthiness (Long sellerid) { PowerSeller seller = entitymanager.find (PowerSeller.class, sellerid); } seller.setcreditworth(seller.getcreditworth() * CREDIT_FACTOR * getratingfromcreditbureaurobberbarons(seller)); seller.setcreditworth(seller.getcreditworth() + (seller.getcreditworth() * FEEDBACK_FACTOR * seller.getbuyerfeedbackrating())); seller.setcreditworth(seller.getcreditworth() + (seller.getcreditworth() * SELLING_FACTOR * gettotalhistoricalsales(seller))); - 18 -

지속성오퍼레이션관리 : 엔티티갱신 (2/2) detach/attach 오퍼레이션 EntityManager가트랜잭션범위에서사용될때, 트랜잭션이종료되면 detach됨 따라서, 세션빈이리턴하는모든엔티티는 detach 상태임 예, 엔티티저장 에서 additem() 메소드가리턴하는 Item은 detach 상태임 엔티티갱신을위해서는 reattacht(== merge) 함 public Item updateitem(item item) { entitymanager.merge(item); return item; } - 19 -

지속성오퍼레이션관리 : 엔티티삭제 엔티티삭제 우선 EntityManager 에 merge() 한후 remove() 함 public void deleteitem(item item) { entitymanager.remove(entitymanager.merge(item)); } 현재 attach 상태에있는엔티티만삭제할수있기때문임 Bidder 엔티티가삭제될때 BillingInfo 객체를함께삭제 @Entity public class Bidder { @OneToOne(cascade=CascadeType.REMOVE) public BillingInfo setbillinginfo() { 일대다관계에서다 (many) 측의객체를삭제할때, 일 (one) 측의객체를함께삭제할때주의를요함 - 20 -

지속성오퍼레이션관리 : flush() 로갱신제어 EntityManager.flush() flush() 를모를경우불리할수있음 persist(), merge(), remove() 오퍼레이션결과가바로 DB에반영되지않음 flush() 가호출될때까지반영은늦추어짐 이러한메커니즘은불필요한 DB 접근을막아서수행성능을높이기위한것임 flush 모드 AUTO/COMMIT 디폴트 DB flush 모드는 AUTO 임, EntityManager가필요할때자동으로 flush() 호출 트랜잭션범위 EntityManager의경우, 트랜잭션종료시점에 flush() 호출 확장범위 EntityManager의경우, 지속성컨텍스트가닫히는시점에 flush() 호출 반영되지않은변경은다음질의어수행전에 flush() 호출 COMMIT 모드 커밋시에만 flush() 호출 entitymanager.setflushmode(flushmodetype.commit); 모드변경은매우비용이많이드는오퍼레이션임 entitymanager.flush(); - 21 -

지속성오퍼레이션관리 : 엔티티리프레시 EntityManager.refresh() DB 로부터관리중인모든엔티티를다시읽어옴 (repopulate) undo 오퍼레이션후에 refresh() 호출은매우유익함 public Item undoitemchanges(item item) { entitymanager.refresh(entitymanager.merge(item)); return item; } refresh() 전에항상 merge() 함 persist() 오퍼레이션호출후바로 DB 에반영되지않는상황에서사용할수있음 public Item additem(string title, String description, byte[] picture, double initialprice, long sellerid) { Item item = new Item(); item.settitle(title);... entitymanager.persist(item); entitymanager.flush(); entitymanager.refresh(item); return item; } - 22 -

엔티티라이프사이클리스너 : 엔티티리스너사용 엔티티상태모니터링 Callback 엔티티는무상태임 예, Item 의입찰금액이지정한값을넘었을때, 통지하는경우 public class ItemMonitor {... public ItemMonitor() {} @PrePersist @PreUpdate Callback 지정 public void monitoritem(item item) { if (item.getinitialbidamount() > ItemMonitor.MONITORING_THRESHOLD) { notificationmanager.senditempriceemailalert(item); } } } @Entity @EntityListeners(actionbazaar.persistence.ItemMonitor.class) public class Item implements Serializable { 리스너등록 리스너클래스는 DI 를지원하지않음, 엔티티가 DI 컨테이너밖에서존재할수있음 - 23 -

엔티티라이프사이클리스너 : 기본리스너클래스 감사또는트랜잭션로그 모든엔티티에대한변화를기록함 이경우기본리스너를활용할수있음, 모든엔티티의모든지속성오퍼레이션을로깅 annotation 을이용하여지정할법이없음 public class ActionBazaarAuditor {... @PrePersist @PostPersist... @PostRemove public void logoperation(object object) { Logger.log("Performing Persistence Operation on: + object.getname()); persistence.xml 을이용하여기본리스너지정 <persistence-unit name="actionbazaar">... <default-entity-listeners> actionbazaar.persistence.actionbazaarauditor.class </default-entity-listeners>... - 24 -

엔티티라이프사이클리스너 : 리스너클래스실행순서 실행순서 기본리스너, 엔티티클래스특정리스너, 부모클래스리스너등이존재함 기본리스너가가장먼저실행됨, 다음으로부모클래스리스너,... 동일한유형의리스너가여러개일경우나열된순서대로실행 EntityListeners({actionbazaar.persistence. ItemMonitor.class, actionbazaar.persistence. ItemMonitor2.class}) 실행순서는프로그램으로제어할수없지만, 기본리스너와부모리스너를제외가능 @Entity @ExcludeDefaultListeners @ExcludeSuperClassListeners @EntityListeners(actionbazaar.persistence.SellerMonitor.class) public class Seller extends User { - 25 -

엔티티운영가이드 컨테이너-관리엔티티관리자를사용할것 EntityManager를웹-티어로주입 (injecting) 하지말것엔티티접근객체패턴을사용할것콜백을외부리스너와분리할것 - 26 -

5 일차 JPA 5.1 상속매핑 5.2 EntityManager 5.3 질의API 5.4 JPQL 질의 API 소개 질의실행

질의 API 소개 : 개요 지금까지 EntityManager.find 를이용하여엔터티를검색하였으며, 이는 ID 나일차키로엔터티를검색하는것임 질의 API 는최적화된질의어를작성할수있게해줌 EntityManager 의인터페이스와 java.persistence.query 인터페이스를이용하여질의어정의, 파라미터바인딩, 실행, 페이지처리등을수행함 JPA 질의 API 는 JPQL 이나 SQL 모두를사용하여질의를작성할수있음 SQL 보다는 JPQL 에집중할예정임 SQL 은레코드를리턴하지만, JPQL 은엔티티를리턴함 질의 API JDBC 질의단계 (SQL) JPA 질의단계 (JPQL) EntityManager query methods 1. DB 커넥션획득 1. EntityManager 인스턴스획득 JPQL 2. 질의문생성 2. 질의인스턴스생성 Query interface 3. 질의문실행 3. 질의실행 4. 결과검색 (DB 레코드 ) 4. 결과엔터티검색 - 28 -

질의 API 소개 : 질의 (query) 분석 질의 (query) 타입 지명 (named) 질의 : 저장한후재사용함 동적 (dynamic, or ad hoc) 질의 : 실행시점에다양한환경에맞추어생성됨 동적질의예 모든카테고리를검색하고자함, JPQL 이용 @PersistenceContext em; EntityManager 주입... public List findallcategories() { Query query = em.createquery("select c FROM Category c");... return query.getresultlist(); } 지명질의일경우 : em.createnamedquery() 호출 - 29 -

질의 API 소개 : 지명 (named) 질의 (1/2) 개요 사용하기전에미리정의해야함 annotation을이용하거나 Xml 메타데이터를이용하여정의할수있음 지명질의는인스턴스를만들때이름을이용하여접근함 지명질의의장점 질의의재사용을높임 코드의유지보수를용이하게함, 질의가비즈니스로직에흩어지지않음 수행성능을높임, 한번준비되면효율적으로재사용됨 annotation 을사용한지명질의의예 @Entity @NamedQuery( name = "findallcategories", query = "SELECT c FROM Category c WHERE c.categoryname LIKE :categoryname ") public class Category implements Serializable {... } - 30 -

질의 API 소개 : 지명 (named) 질의 (2/2) 여러개의지명질의 javax.persistence.namedqueries 주석 (annotation) 사용 @Entity @NamedQueries({ @NamedQuery( name = "findcategorybyname", query = "SELECT c FROM Category c WHERE c.categoryname LIKE :categoryname order by c.categoryid" ), @NamedQuery( name = "findcategorybyuser", query = "SELECT c FROM Category c JOIN c.user u WHERE u.userid =?1" )}) @Table(name = "CATEGORIES") public class Category implements Serializable { } 지속성유닛범위이므로범위내에서질의이름이유일해야함 - 31 -

질의실행 : 질의인스턴스생성 (1/2) EntityManager 인터페이스 질의인스턴스를생성하기위한메소드제공 원시 SQL 질의생성을위한메소드도제공 메소드시그너처 public Query createquery(string jpqlstring); public Query createnamedquery(string name); public Query createnativequery(string sqlstring); public Query createnativequery(string sqlstring, Class result Class); public Query createnativequery(string sqlstring, String resultsetmapping); 설명 JPQL 문을이요하여동적질의생성질의인스턴스생성원시 SQL문을이용하여동적질의생성 지명질의인스턴스생성 엔티티가속한지속성유닛에접근하는모든컴포넌트로부터지명질의인스턴스생성 오픈상태의 EntityManager 인스턴스가있어야함 사용하려면 EntityManager.createNamedQuery() 메소드를호출함 Query queyr = em.createnamedquery( findallcategories ); - 32 -

질의실행 : 질의인스턴스생성 (2/2) 동적질의인스턴스생성 EntityManager가가용한곳어디서든지동적질의생성가능함 세션빈, MDB, 웹애플리케이션, 컨테이너외부 EJB 2 에서는동적질의를지원하지않음 질의생성 : EntityManager.createQuery() 타당한 JPQL 문을파라미터로전달 EntityManager가컨테이너-관리든애플리케이션-관리든상관없음 질의생성예 Query query = em.createquery( SELECT i FROM Item i ); JPQL은 SQL과유사하지만 JPQL 사용를권장함 - 33 -

질의실행 : 질의인터페이스사용 (1/5) 질의인터페이스 질의실행을위한메소드정의 질의인스턴스를위한파라미터설정메소드정의 페이지처리, 플러시모드제어등을위한메소드정의 SQL과 JPQL은동일한인터페이스사용 메소드시그너처 설명 public List getresultlist() public Object getsingleresult() public int executeupdate() public Query setmaxresults(int maxresult) public Query setfirstresult(int startposition) public Query sethint(string hintname, Object value) public Query setparameter(string name, Object value) public Query setparameter(string name, Date value, TemporalType temporaltype) 질의결과세트검색단일결과나객체검색 JPQL UPDATE나 DELETE 문실행검색할객체의최대갯수첫번째질의결과의첫번째위치질의를위한벤더특정힌트설정지명파라미터를위한값설정파라미터가 Date 타입일경우, 지면파라미터값설정...... - 34 -

질의실행 : 질의인터페이스사용 (2/5) 질의인터페이스사용예, 미리정의한지명질의로부터질의인스턴스생성함 query = em.createnamedquery("findcategorybyname"); query.setparameter("categoryname", categoryname); query.setmaxresults(10); query.setfirstresult(3); List categories = query.getresultlist(); 파라미터설정 특정가격을가진모든 Item 엔티티의인스턴스검색 SELECT i FROM Item i WHERE i.initialprice =?1 파라미터는이름이나숫자로지정이가능함 query.setparameter(1, 100.0); 여러파라미터설정 SELECT i FROM Item i WHERE i.initialprice >?1 AND i.initialprice <?2 query.setparameter(1, 100.0); query.setparameter(2, 200.0); - 35 -

질의실행 : 질의인터페이스사용 (3/5) 지면파라미터설정 - 코드가독성을높여줌 SELECT i FROM Item i WHERE i.initialprice = :price query.setparameter( price, 100.0); 단일엔터티검색 하나의엔티티만검색 query.setparameter(1, Recycle from Mr. Dumpster ); Category cat = (Category)query.getSingleResult(); 결과가없을경우, NoResultException 결과가여러개일경우, NonUniqueResultException try {... query.setparameter(1, "Recycle from Mr. Dumpster"); Category cat = (Category)query.getSingleResult();... }catch (NonUniqueResultException ex) { handleexception(ex); } catch (NoResultException ex) { handleexception(ex); } - 36 -

질의실행 : 질의인터페이스사용 (4/5) 여러엔티티검색 대부분의질의는결과집합 (set) 이나결과리스트를리턴함 100 과 200 사이의결과를검색하는질의 query.setparameter("lowprice", lowpricevalue) 지명파라미터 lowprice query.setparameter("highprice", highpricevalue) List items = query.getresultlist(); 결과리스트가없을경우빈리스트를리턴함, 예외를던지지않음 결과리스트의페이지처리 수천또는수만건의검색결과를효율적으로처리하는방법이필요함 JPA 는페이지처리인터페이스를제공함 query.setmaxresults(50); query.setfirstresult(0); 시작오프셋값 List items = query.getresultlist(); 다음 50 건을가져오려면, query.setmaxresults(50); query.setfirstresult(50); - 37 -

질의실행 : 질의인터페이스사용 (5/5) 오프셋과페이지사이즈를동적으로처리 public List getpageditems(int pageindex, int pagesize) {... query.setmaxresults(pagesize) ; query.setfirstresult(pageindex) ; return query.getresultlist(); } 질의 flush 모드통제 flush 모드를통해 EntityManager가 DB에쓰는방식을결정 AUTO 모드 ( 기본 ): 지속성컨텍스트안의엔티티갱신을지속성공급자가책임짐 COMMIT 모드 : 지속성컨텍스트안의엔티티에대한갱신을정의하지않음 대부분의경우 AUTO 모드사용을권장함 - 38 -

질의실행 : 질의힌트지정 벤더고유의확장 질의실행중에사용할수있는벤더고유의확장기능이있음 확장기능의예, 성능최적화, 질의힌트전달 질의힌트 질의힌트는지속성제공자가질의수행중에사용할팁 예, 질의사용중에캐시를사용할것을지정함 TopLink 사용시타임아웃시간을 10 초로설정함 query.sethint( toplink.jdbc.timeout, new Integer(10000)); Hibernate 사용시동일한동작 query.sethime( org.hibernate.timeout, new Integer(10)); 공급자의파라미터지정방식에따름, 다음은자주쓰이는예 로우패치크기, 캐시모드, 캐시리프레시, 타임아웃 @NamedQuery( name = "finduserwithnoitems", query = "SELECT DISTINCT u FROM User u WHERE u.items is EMPTY", hints = { @QueryHint(name = "org.hibernate.timeout", value = "10") } ) - 39 -

5 일차 JPA 5.1 상속매핑 5.2 EntityManager 5.3 질의API 5.4 JPQL 개요 문 (statement) 유형정의 FROM절사용 조건식과연산자 JPQL 함수사용 SELECT절사용 조합 (aggregation) 사용 질의결과정렬 하위-질의사용 엔티티조인 대량갱신과삭제

개요 JPQL(Java Persistence Query Language) Hibernate는 HSQL 제공 Kodo는 JDO QL 제공 JPQL은 EJB 2의 EJB QL의확장판임 JPQL은자바영역안에서클래스와객체를다룸 SQL은 DB 영역에서테이블, 컬럼, 로우를다룸 둘은외관상비슷하지만완전히서로다른두영역에서실행됨 JPQL이변환을통해 SQL로변경되는절차 - 41 -

문 (statement) 유형정의 (1/3) JPQL 은세가지문 (statement) 을제공함 SELECT: 엔티티와엔티티관련데이터를검색함 UPDATE: 하나또는그이상의엔티티를갱신함 DELETE: 하나또는그이사의엔티티를삭제함 SELECT 정의및사용 JPQL 의예, SELECT c FROM Category c WHERE c.categoryname LIKE :categoryname ORDER BY c.categoryid SELECT 절 : 검색할객체타입, 엔티티, 값등을지정함 FROM 절 : 다른절에서사용할엔티티선언 [ 옵션 ] WHERE 절 : 질의결과를필터링함 [ 옵션 ] ORDER BY 절 : 질의결과순서를정함 [ 옵션 ] GROUP BY 절 : 조합 (aggregation) 수행 [ 옵션 ] HAVING 절 : 조합과결합 (conjunction) 안에서필터링수행 - 42 -

문 (statement) 유형정의 (2/3) UPDATE 와 DELETE 정의 WHERE 절에조건을지정함으로써대규모갱신및삭제가가능함 SQL 문과매우유사함 UPDATE 사용 한가지엔티티유형만지정할수있음 엔티티개수를제한하기위해 WHERE 절을사용함 UPDATE 문의구문, UPDATE entityname indentifiervariable SET single_value_path_expression1 = value1,... single_value_path_expressionn = valuen WHERE where_clause 성이 Packrat 인판매자의상태를 G(Gold) 로하고커미션비율을 10 퍼센트로함 UPDATE Seller s SET s.status = 'G', s.commissionrate = 10 WHERE s.lastname like 'PackRat%' - 43 -

문 (statement) 유형정의 (3/3) DELETE 사용 SQL 문과매우비슷함 하나의엔티티유형만지정할수있음 WHERE 절에서문의영향을받는대상을제한함 DELETE 문의구문 DELETE entityname indentifiervariable WHERE where_clause Silver 상태의판매자를모두삭제함 DELETE Seller s WHERE s.status= Silver - 44 -

FROM 절사용 (1/4) FROM 절 가장중요한절로질의를위한도메인 ( 질의대상엔티티 ) 을결정함 FROM Category c Category는도메인이며, c는 Category 타입에대한식별자 (identifier) 로지정함 질의도메인지정 : 엔티티지명 @Entity 주석에서 name 요소를사용하여엔티티의이름을정의할수있음 name을지정하지않을경우, 엔티티클래스의이름이엔티티이름이됨 지속성유닛안에서이름은유일해야함 Category 클래스에서엔티티이름정의예, @Entity(name = "CategoryEntity") public class Category 이경우, FROM 절은 FROM CategoryEntity c - 45 -

FROM 절사용 (2/4) 식별자 (identifier) 변수 (SELECT c )FROM Category c 에서정의된식별자 c 는다른절에서도사용함 구문 FROM entityname [AS] identificationvariable identificationvariable 는자바에서타당한변수여야하며, JPQL 의예약어가아니어야함 다음은 JPQL의예약어들임유형 예약어 문 (statement) 과절 (clause) 조인조건과연산함수 (function) SELECT, UPDATE, DELETE, FROM, WHERE, GROUP, HAVING, ORDER, BY, ASC, DESC JOIN, OUTER, INNER, LEFT, FETCH DISTINCT, OBJECT, NULL, TRUE, FALSE, NOT, AND, OR, BETWEEN, LIKE, IN, AS, UNKNOWN, EMPTY, MEMBER, OF, IS, NEW, EXISTS, ALL, ANY, SOME AVG, MAX, MIN, SUM, COUNT, MOD, UPPER, LOWER, TRIM, POSITION, CHARACTER_LENGTH, CHAR_LENGTH, BIT_LENGTH, CURRENT_TIME, CURRENT_DATE, CURRENT_TIMESTAMP - 46 -

FROM 절사용 (3/4) 경로표현식 (path expression) 이란? 표현식 c.categoryname, c.categoryid 등을경로표현식이라고함 (.) 은항해연산자 WHERE 절이나 ORDER BY 절에서사용함 연관관계필드는단일값객체거나집합객체일수있음 컬렉션값표현식의예, SELECT distinct c FROM Category c WHERE c.items is NOT EMPTY 컬렉션값표현식을이용한지속성필드항해예, c.items.user.firstname c.items.user.contactdetails.email c.items.itemname (== category.getitems().getitemname() 와동일함 ) - 47 -

FROM 절사용 (4/4) WHERE 를이용한필터링 WHERE 절은질의결과를필터링함 WHERE 절이없을경우, 모두를대상으로함 SELECT c FROM Category c 조건을지정함 SELECT c FROM Category c WHERE c.categoryid > 500 WHERE 절에는자바상수의거의모든타입사용, boolean, float, enum, String, int 등 octal, hexadecimal, byte[], char[] 등은사용하지못함 - 48 -

조건식과연산자 (1/5) 개요 WHERE 절의조건은조건표현식또는조건식 (conditional expression) 이라고함 JPQL 은숫자, 문자열, 부울리언값, 경로표현식을관계형연산자를이용하여평가함 조건식의예, c.categoryname = Dumped Cars 연산자의유형들 연사자유형 항해 (navigational). 단항부호 (unary sign) +, - 수식 (arithmetic) *, /, +, - 연산자 관계 (relational) =, >, >=, <, <=, <>, [NOT] BETWEEN, [NOT] LIKE, [NOT] IN, IS [NOT] NULL, IS [NOT] EMPTY, [NOT] MEMBER [OF] 논리 (logical) NOT, AND, OR WHERE c.categoryname = 'Dumped Cars' OR c.categoryname = 'Furniture from Garbage' 조건식의예, - 49 -

조건식과연산자 (2/5) BETWEEN 을이용한범위비교 수식에서값의범위를비교하기위해 BETWEEN을사용함 BETWEEN 연산자구문 path_expression [NOT] BETWEEN lowerrange and upperrange 범위표현의예, WHERE c.categoryid BETWEEN :lowrange AND :highrange IN 연산자사용 경로표현식이리스트값안에있는지여부를판단하는조건식에 IN을사용함 IN 연산자구문, path_expression [NOT] IN (List_of_values) IN 연산자를사용한예 < WHERE u.userid IN ( viper, drdba, dumster ) WHERE u.userid NOT IN ( viper, drdba, dumster ) 하위질의와 IN의사용, ( 하위질의결과가복수일수있음 ) WHERE c.user IN (SELECT u FROM User u WHERE u.usertype = 'A') - 50 -

조건식과연산자 (3/5) LIKE 연산자사용 단일값경로표현식이문자열패턴과일치하는지확인할때 LIKE 연산자를사용함 LIKE 연산자구문 string_value_path_expression [NOT] LIKE pattern_value pattern_value 는상수이거나파라미터임 pattern_value 는 (_) 나 (%) 를포함할수있음, (_) 는단일문자, (%) 는여러문자를의미함 LIKE 연산자를사용한예, WHERE c.itemname LIKE _ike mike, bike 모두해당 (%) 를사용한예, WHERE c.categoryname LIKE Recycle% Recycle 로시작하는모든단어 (%) 를앞뒤로사용한예, WHERE c.categoryname NOT LIKE %Recycle% Recycle 이포함되지않음모든이름 파라미터를적용한예, WHERE c.categoryname NOT LIKE?1-51 -

조건식과연산자 (4/5) 널값과빈컬렉션다루기 널과빈문자열은서로다르고, JPQL은서로다른방식으로이들을다룸 널과빈문자열을동일한방식으로다루는 DB도있음 빈문자열과널을비교해서 true를리턴하는지확인해야함 널을포함한부울리언연산결과 표현식 1 값 부울리언연산자 표현식 2 값 결과 TRUE AND null UNKNOWN FALSE AND null FALSE Null AND null UNKNOWN TRUE OR null TRUE Null OR null UNKNOWN FALSE OR null UNKNOWN NOT null UNKNOWN NOT NULL 체크예, WHERE c.parentcategory IS NOT NULL - 52 -

조건식과연산자 (5/5) 컬렉션 컬렉션의 IS NOT NULL 체크가불가능하여, IS [NOT] EMPTY 를사용함 컬렉션 EMPTY 체크예, WHERE c.items IS EMPTY JPQL 에서의다음표현이, SELECT c FROM Category c WHERE c.items IS EMPTY SQL 의다음표현으로변환됨 SELECT c.category_id, c.category_name, c.create_date, c.created_by, c.parent_id FROM CATEGORIES c WHERE ( (SELECT COUNT(*) FROM CATEGORIES_ITEMS ci, ITEMS i WHERE ( (ci.category_id = c.category_id) AND (i.item_id = ci.item_id))) = 0) - 53 -

JPQL 함수사용 (1/2) 개요 JPQL은문자열과산술 (arithmetic) 연산을위한내장함수를제공함 이함수는 WHERE절이나 HAVING 절에서사용할수있음 문자열함수 질의결과필터링에사용함 문자열함수 CONCAT(string1, string2) SUBSTRING(string, position, length) TRIM([LEADING TRAILING BOTH] [trim_character] FROM] string_to_trimmed) LOWER(string) UPPER(string) LENGTH(string) LOCATE(searchString, sringtobesearched[initialposition]) 두문자열값을합쳐서리턴함 설명 position 부터 length 까지의부분문자열을리턴함 지정된문자열을새로운길이로정리함. 정리 (trimming) 은 LEADING, TRAILING, 또는 BOTH 끝단에서. 정리문자가없으면기본으로스페이스임 문자열을소문자로변환 문자열을대문자로변환 문자열의길이를리턴함 주어진문자열의위치를리턴함. initialposition 을주지않으면 1 로부검색을시작함 - 54 -

JPQL 함수사용 (2/2) 문자열함수 ( 계속 ) 합친문자열을비교하는예, WHERE CONCAT(u.firstName, u.lastname) = ViperAdmin 하위문자열을비교하는예, WHERE SUBSTRING(u.lastName, 1, 3) = VIP 산술함수 CRUD 오퍼레이션에계산은별로쓰이지않음 보고목적으로산술함수를사용하면매우유용함 다음함수는 WHERE 절이나 HAVING 절에서사용함 산술함수 설명 ABS(simple_arithmetic_expression) SQRT(simple_arithmetic_expression) MOD(num, div) SIZE(collection_value_path_expression) 절대값을리턴함제곱근을리턴함정수값리턴컬렉션의항목개수를리턴함 SIZE 의예, WHERE SIZE(c.items) = 5-55 -

SELECT 절사용 개요 SELECT 절은질의결과를나타냄 SELECT 절의구문 SELECT [DISTINCT] expression1, expression2,... expressionn expression 은단일값임, 컬렉션값경로표현식은불가능함 SELECT 절의예, SELECT c.categoryname, c.createdby FROM Category c 중복데이터를허용하지않는예, SELECT DISTINCT c.categoryname, c.createdby FROM Category c 생성자표현식사용 하나이상의자바인스턴스를리턴하기위해생성자사용이가능함 SELECT NEW actionbazaar.persistence.itemreport (c.categoryid, c.createdby) FROM Category WHERE categoryid.createdby = :username - 56 -

조합 (Aggregation) 사용 (1/2) 조합은엔티티컬렉션을다루는보고서질의를작성할때유용함 조합함수 JPQL 은조합함수를제공함, AVG, COUNT, MAX, MIN, SUM 조합함수의리턴타입 AVG() 리턴타입은 Double COUNT() 리턴타입은 Long MAX() 리턴타입은지속성필드에따라다름 MIN() 리턴타입은지속성필드에따라다름 SUM() 리턴타입은 Long 이나 Double 가격이가장높은값을찾는예, SELECT MAX(i.itemPrice) FROM Item i 질의결과개수를세는예, SELECT COUNT(c) FROM Category c - 57 -

조합 (Aggregation) 사용 (2/2) GROUP BY 와 HAVING 으로묶음짓기 특정필드를기준으로데이터를묶음지을필요가있음 User 와 Category 간에일대다관계가있을때, Category 인스턴스를 user 기준으로묶음 SELECT c.user, COUNT(c.categoryId) FROM Category c GROUP BY c.user 위의예에서, Category 엔티티를다섯개이상가진사용자만으로제한한예, SELECT c.user, COUNT(c.categoryId) FROM Category c GROUP BY c.user HAVING COUNT(c.categoryId) > 5 WHERE 절추가한예, SELECT c.user, COUNT(c.categoryId) FROM Category c WHERE c.createdate is BETWEEN :date1 and :date2 GROUP BY c.user HAVING COUNT(c.categoryId) > 5-58 -

질의결과정렬 ORDER BY 절 검색결과값이나객체를정렬할때사용함 ORDER BY 절구문, ASC 이기본값임 ORDER BY path_expression1 [ASC DESC],... path_expressionn [ASC DESC] 카테고리이름으로오름차순으로정렬한예, SELECT c FROM Category c ORDER BY c.categoryname ASC 오름차순과내림차순을각각지정한예, SELECT c.categoryname, c.createdate FROM Category c ORDER BY c.categoryname ASC, c.createdate DESC WHERE 절이있을경우, 먼저 WHERE 절에의해필터링된다음, 정렬함 - 59 -

하위 - 질의사용 (1/3) 하위 - 질의 (subquery) 하위 - 질의는질의속의질의임 WHERE 절이나 HAVING 절에서하위 - 질의를사용할수있음 JPQL 에서는 SQL 과는달리 FROM 절에서는하위 - 질의를사용할수없음 하위 - 질의가먼저실행되고본질의가다음으로실행됨 하위 - 질의구문 [NOT] IN / [NOT] EXISTS / ALL / ANY / SOME ( 하위 - 질의 ) IN 에서하위 - 질의 IN 절은리스트값에서하나의값이포함되어있는지를평가함 IN 에서하위 - 질의예, SELECT i FROM Item i WHERE i.user IN (SELECT c.user FROM Category c WHERE c.categoryname LIKE :name) - 60 -

하위 - 질의사용 (2/3) EXISTS 하위 - 질의가어떤결과세트를포함하는지확인함 EXISTS 절의예, SELECT i FROM Item i WHERE EXISTS (SELECT c FROM Category c WHERE c.user = i.user) EXISTS 절은 IN 연산자와동일함 테이블이대용량데이터를가지고있을경우, IN 보다는 EXISTS 사용을권장함 DB는 EXISTS를사용할때더효율적으로처리함 ANY, ALL, SOME IN 연산자사용과유사함 산술연산자와함께사용할수있음, =, >, >=, <, <=, <> - 61 -

하위 - 질의사용 (3/3) ANY, ALL, SOME ( 계속 ) 하위 - 질의와 ALL 연산자의예, SELECT c FROM Category c WHERE c.createdate >= ALL (SELECT i.createdate FROM Item i WHERE i.user = c.user) 하위 - 질의와 ANY 연산자의예, SELECT c FROM Category c WHERE c.createdate >= ANY (SELECT i.createdate FROM Item i WHERE i.seller = c.user) SOME 은 ANY 의다른이름 - 62 -

엔티티조인 (1/3) JOIN 연산자 FROM 절에엔티티지정함 WHERE 절에조인조건을지정함 두엔티티는관계나임의의지속성필드를기반으로연결 (join) 함 내부조인 : 관계를이용하여 Category 와 Item 을조인하고조인조건에일치하는엔티티만을검색함 외부조인 : 조인조건에일치하는결과뿐아니라다른쪽의엔티티에일치하지않는엔티티역시검색함, 즉 Item 과일치하지않더라도 Category 의모든인스턴스를검색함 쎄타 (Theta) 조인 관계보다는임의의지속성이나관계필드를기반으로연결함 Category 의 rating 필드가 DELUXE, GOLD, STANDARD, PREMIUM 값을가짐 Item 의 star 필드역시 DELUXE, GOLD, STANDARD, PREMIUM 값을가짐 SELECT i FROM Item i, Category c WHERE i.star = c.rating 이두엔티티를쎄타조인을걸면, - 63 -

엔티티조인 (2/3) 관계조인 가장흔한형태의조인임 관계를바탕으로둘또는그이상의엔티티를연결함 Category 와 User 는다대일관계를가짐, 특정범주에속하는모든사용자검색예, SELECT u FROM User u INNER JOIN u.category c INNER 절은선택사항임 WHERE u.userid LIKE?1 외부조인 엔티티간의연관관계가선택적일때, 조인조건에맞지않는추가엔티티를검색할수있음 보고서작성에매우유용함 Category 를가지지않는 User 도있을경우의예, SELECT u FROM User u LEFT OUTER JOIN u.category c WHERE u.userid like?1-64 -

엔티티조인 (3/3) 페치 (fetch) 조인 특정엔티티를위한질의를하면서, 동시에연관엔티티도동시에검색할수있음 Bid 를검색할때, 연관된 Bidder 의인스턴스를로드하고초기화하는예, SELECT b FROM Bid b FETCH JOIN b.bidder WHERE b.biddate >= :biddate 관계에대해지연로드로설정된상황, 특정질의에서연관엔티티를즉시로드할때 페치조인은외부, 내부조인과함께사용할수있음 - 65 -

대량갱신과삭제 개요 연말에사용자의상태값을모두 G(old) 로변경하는예, UPDATE User u SET u.status = 'G' WHERE u.numtrades >=?1 특정조건에맞는사용자를모두삭제하는예, @PersistenceContext em;... // start transaction Query query = em.createquery("delete USER u WHERE u.status = :status "); query.setparameter("status", 'GOLD'); int results = query.executeupdate(); //end transaction 대량갱신과삭제는여러함정이있으므로반드시별도의트랜잭션으로실행해야함 DB 오퍼레이션으로바로변환되므로관리엔티티와 DB 간불일치발생가능함 - 66 -

넥스트리소프트 ( 주 ) 박석재수석 (demonpark@nextree.co.kr) 임병인수석 (byleem@nextree.co.kr) 과정명 : SQL 기초와 MyBatis SQL/MyBatis - 67 -