데이터접근프레임워크 (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 상속매핑 Entity Manager 질의 API JPQL - 1 -
4 일차 JPA 4.1 도메인모델과 JPA 4.2 JPA이용도메인객체구현 4.3 엔티티관계 4.4 엔티티매핑 4.5 엔티티관계매핑 도메인모델소개 문제도메인 도메인모델의액터 EJB3 자바지속성 API 자바클래스로서의도메인객체
도메인모델소개 도메인모델 시스템을통해해결하려고하는문제의개념적인이미지 객체와객체들의연관관계 (association) 로구성함 도메인모델의객체는물리적인객체가아니라시스템에서사용하는개념임 비즈니스룰과비즈니스로직은도메인모델위에서실행됨 (act on the domain model) Martin Fowler 가도메인모델의개념을처음사용 - 3 -
문제도메인 (1/3) 분석방향 JPA 를설명하는꼭필요한도메인부분만포함 온라인옥션에서품목을사고파는데직접관련된기능만대상으로함 현실적인예와는약간의거리를두고핵심개념은정확히반영 도메인내용 판매자 (Seller) 는품목 (item) 을 ActionBazaar 사이트에올린다. 품목은검색가능 (searchable) 카테고리와항해가능 (navigable) 카테고리로구성된다. 경매참여자 (Bidder) 는품목에입찰 (bid) 한다. 가장높은금액을써낸사람이이긴다. - 4 -
문제도메인 (2/3) 핵심기능 - 판매자는품목을검색가능한카테고리로등록하고, 입찰자는품목에입찰하고, 가장높은입찰금액을쓴입찰자가이긴다. 도메인객체들 Seller Item Category Bidder Bid Order - 5 -
문제도메인 (3/3) 엔티티와관계로구성된도메인모델 - 6 -
도메인모델의액터 (1/2) 관계를통해파악할수있는정보들 품목은판매자에의해판매되고, 판매자는여러품목을팔수있다. 품목은하나이상의카테고리에속하고, 각카테고리는한부모카테고리를가진다. 입찰자는품목에입찰한다. 도메인모델은, 객체가다루어지는방식을서술하지는않음 주문이하나이상의품목으로구성되며, 입찰자가주문한다는사실은알수있지만, 언제어떻게이관계가형성되는지알수없다. 비즈니스로직과비즈니스규칙에의해밝혀진다. - 7 -
도메인모델의액터 (2/2) 객체 (object) 도메인객체는자바의클래스와동일한개념 도메인객체 Category의인스턴스는수백개가될수있음 관계 (relationship) 한도메인객체가다른도메인객체를참조하고있음 관계의방향은일방향이거나양방향임 개수 (multiplicity, or cardinality) 1:1, 1:N, N:N 등의개수가존재함 선택사항 (optionality) cardinality가 0..1, 0..n, 0..2 등으로관계의대상이존재하지않을수도있음 예, 사용자 (User) 는청구정보 (BillingInfo) 를가질수도있고없을수도있음 - 8 -
EJB 3 자바지속성 API JPA(Java Persistence API) 메타데이터 기반 POJO 기술임, 따라서 Java 객체저장을위해특정인터페이스구현, 클래스상속, 프레임워크패턴준수등을하지않음 저장되는객체는 JPA 관련코드를한줄도가지지않음 POJO 로구성한도메인모델과 annotation 또는 Xml 만있으면됨 Annotation/Xml 포함정보 도메인객체가무엇인가? (, @Embeded) 도메인객체를어떻게식별하는가? () 객체들간의관계유형은무엇인가? (@OneToOne, @OneToMany, @ManyToMany) 도메인객체가어떻게 DB 에매핑되는가? (@Table, @Column, @JoinColumn) JPA 를사용한 O/R 매핑이 EJB2 의엔티티나 JDBC 에비해많이개선된것이긴하지만여전히매핑관련복잡한작업을해야함 - 9 -
자바클래스로서의도메인객체 POJO 구성요소 id 객체식별자 name,modificationdate 객체속성 items, parentcategory,subcategories 관계를위한객체속성 객체속성을위한 getter/setter 관계객체속성을위한 getter/setter public class Category { protected Long id; protected String name; protected Date modificationdate; protected Set<Item> items; protected Category parentcategory; protected Set<Category> subcategories; public Category() { public Long getid() { return this.id; public void setid(long id) { this.id = id; public String getname() { return this.name; public Category getparentcategory() { return this.parentcategory; public void setparentcategory(category parentcategory) { this.parentcategory = parentcategory; - 10 -
4 일차 JPA 4.1 도메인모델과 JPA 4.2 JPA이용도메인객체구현 4.3 엔티티관계 4.4 엔티티매핑 4.5 엔티티관계매핑 테스트프로젝트생성 annotation 엔티티데이터저장 엔티티식별자 (identity) 명세 @Embeddable annotation
테스트프로젝트생성 (1/3) Maven Project Group Id: kr.nextree.edu.jpa Artifact Id: nexbay-entity Version: 1.0.0-SNAPSHOT Packaging: jar Name: Nexbay Entity 과정명 : SQL 기초와 MyBatis SQL/MyBatis - 12 -
테스트프로젝트생성 (2/3) 의존관계생성 <dependencies>.. <dependency> <groupid>org.hibernate</groupid> <artifactid>hibernate-annotations</artifactid> <version>3.5.5-final</version> </dependency> <dependency> <groupid>org.hibernate</groupid> <artifactid>hibernate-entitymanager</artifactid> <version>4.3.3.final</version> </dependency> <dependency> <groupid>org.slf4j</groupid> <artifactid>slf4j-api</artifactid> <version>1.7.7</version> <scope>test</scope> </dependency>.. <dependency> <groupid>org.slf4j</groupid> <artifactid>slf4j-log4j12</artifactid> <version>1.7.7</version> <scope>test</scope> </dependency> <dependency> <groupid>org.hsqldb</groupid> <artifactid>hsqldb</artifactid> <version>2.3.2</version> </dependency>.. </dependencies> 과정명 : SQL 기초와 MyBatis SQL/MyBatis - 13 -
테스트프로젝트생성 (3/3) HSQLDB Server Mode 참고 : http://hsqldb.org/doc/guide/ch01.html hsqldb-server-run.cmd 파일생성 java -cp./lib/hsqldb-2.3.2.jar org.hsqldb.server -database.0 file:./z-nexbay-data/nexbaydb -dbname.0 nexbaydb hsqldb-manager-run.cmd 파일생성 java -cp./lib/hsqldb-2.3.2.jar org.hsqldb.util.databasemanager jdbc 연결정보 jdbc:hsqldb:hsql://localhost:9001/nexbaydb 과정명 : SQL 기초와 MyBatis SQL/MyBatis - 14 -
주석 (annotation) (1/2) 는 POJO 가고유하게식별되는도메인객체임을알림 public class Category { public Category() { public Category(String name) { 엔티티는완전한 POJO 이므로객체지향특성을 100% 활용할수있음 다형성 (polymorphism) 상속 (inheritance) User Bidder Seller SomeUser - 15 -
주석 (annotation) (2/2) 상속과지속성 (persistence) User 가엔티티이므로 User 의모든속성 (userid, username, email, ) 은 Seller 나 Bidder 가저장될때함께저장됨 User 자체가직접인스턴스가되거나저장되어서는안될경우, abstract class 로선언함 public class User { String userid; String username; String email; public class Seller extends User { public class Bidder extends User { - 16 -
엔티티데이터저장 (1/3) 접근방식정의 필드-기반접근 : 필드나인스턴스변수를이용하여 O/R 매핑을정의 속성-기반접근 : 속성 (property) 을사용하여 O/R 매핑을정의 (getter/setter 사용 ) 필드기반접근 POJO의저장대상데이터필드를 public이나 protected로선언 Persistence Provider에게 getter/setter를무시하도록함 인스턴스변수에 @XXX annotation을사용 public class Category { public Long id; public String name; public Date modificationdate; public Category() { - 17 -
엔티티데이터저장 (2/3) @Transient annotation 해당필드는저장하지않음 주로실행시점에사용하는정보이거나, 파생속성 (derived attribute) 임 public class Category { @Transient protected Long activeusercount; transient public String generatedname; public Category() { 속성 (property) 기반접근일경우, @Transient 태그를 getter 에붙임 transient 키워드는 @Transient 태그와동일한효과를가짐 - 18 -
엔티티데이터저장 (3/3) 데이터타입의상이함 POJO의인스턴스변수타입과테이블의타입이일치하지않음 따라서, 둘간에약간의제약조건이있음 Persitence 필드 / 속성이가능한데이터타입 Java 원시타입 : int, double, long 등 Java 원시타입래퍼 : Integer, Double String 타입 : String Java API Serializable 타입 : BigInteger, Date 사용자정의 Serializable 타입 : Serializable 배열타입 : byte[], char[] 열거타입 : {SELLER, bidder, CSR, ADMIN 엔티티의집합 : Set<Category> 임베디드클래스 : @Embeddable 태그를붙여정의한클래스 - 19 -
엔티티식별자 (identity) 명세 (1/4) 모든엔티티는유일하게식별이되어야함 (uniquely identifiable) 어느시점에엔티티는유일하게식별되는테이블의 row로저장되어야하기때문 테이블은일차키 (primary key) 로유일하게식별함 객체구분 서로다른객체 : 객체의식별자 (identity) 가다름 서로같은객체 : 객체의식별자 (identity) 가같음 객체비교 Object 클래스의 equals 메소드이용 예, name 이유일성식별자인경우, public boolean equals (Object other) { if (other instanceof Category) { return this.name.equals(((category)other).name) else { return false; 식별자로는 Long id 와같이 Long 타입이더경제적임 - 20 -
엔티티식별자 (identity) 명세 (2/4) Persistence Provider 에게 identity 가저장된위치를알려주는방법 (javax.persistence.id) Class (javax.persistence.idclass) @EmbeddedId (javax.persistence.embeddedid) annotation 필드나속성에지정하고이는테이블의일차키 (primary key) 가됨 속성 (property) 기반접근의예 public class Category { protected Long id; public Long getid() { return this.id; public void setid(long id) { this.id = id; ** 피해야할타입 float, Float, double 등을피해야함 TimeStamp 타입을피해야함 - 21 -
엔티티식별자 (identity) 명세 (3/4) Class 하나이상의 를사용할경우 Class 를사용 즉, 복합 (composite) 키가필요할경우사용 public class CategoryPK implements Serializable { String name; Date createdate; public CategoryPK() { public boolean equals(object other) { if (other instanceof CategoryPK) { final CategoryPK othercategorypk = (CategoryPK)other; return (othercategory.name.equals(name) && othercategorypk.createdate.equals(createdate)); return false; public int hashcode() { return super.hashcode(); Class(CategoryPK.class) public class Category { public Category() { protected String name; protected Date createdate; - 22 -
엔티티식별자 (identity) 명세 (4/4) @EmbeddedId IdClass 를엔티티안으로가져와서내포된유일성필드를사용하는것과같음 @Embeddedable public class CategoryPK implements Serializable { String name; Date createdate; public CategoryPK() { public boolean equals(object other) { if (other instanceof CategoryPK) { final CategoryPK othercategorypk = (CategoryPK)other; return (othercategory.name.equals(name) && othercategorypk.createdate.equals(createdate)); return false; public int hashcode() { return super.hashcode(); public class Category { public Category() { @EmbeddedId protected CategoryPK categorypk; - 23 -
@Embeddable 주석 (annotation) Embeddable 자체 identity는필요없고다른엔티티에포함되는객체 자체로저장되거나접근되지않음 @Embeddable 객체는 identity를가질수없음 @Embeddable 객체는엔티티객체와같은테이블에저장됨 @Embeddedable public class Address { protected String streetline1; protected String streetline2; protected String city; protected String state; protected String zipcode; protected String country; public class User { protected Long id; protected String username; protected String firstname; protected String lastname; @Embedded protected Address address; protected String email; protected String phone; - 24 -
4 일차 JPA 4.1 도메인모델과 JPA 4.2 JPA이용도메인객체구현 4.3 엔티티관계 4.4 엔티티매핑 4.5 엔티티관계매핑 @OneToOne @OneToMany, @ManyToOne @ManyToMany
@OneToOne (1/3) @OneToOne 단방향일대일 양방향일대일 단방향 예, 사용자는청구정보를가질수있다. 필드기반접근 public class User { protected String userid; protected String email; @OneToOne protected BillingInfo billinginfo; User 1 0..1 BillingInfo public class BillingInfo { protected Long billingid; protected String creditcardtype; protected String creditcardnumber; protected String nameoncreditcard; protected Date creditcardexpiration; protected String bankaccountnumber; protected String bankname; protected String routingnumber; - 26 -
@OneToOne (2/3) 속성기반접근단방향관계 public class User { protected String userid; protected String email; protected BillingInfo billing; @OneToOne public BillingInfo getbilling() { this.billing; public void setbilling(billinginfo billing) { this.billing = billing; public class BillingInfo { protected Long billingid; protected String creditcardtype; protected String creditcardnumber; protected String nameoncreditcard; protected Date creditcardexpiration; protected String bankaccountnumber; protected String bankname; protected String routingnumber; - 27 -
@OneToOne (3/3) 양방향일대일 두개의 @OneToOne 태그를사용함 public class User { protected String userid; protected String email; @OneToOne protected BillingInfo billinginfo; public class BillingInfo { protected Long billingid; protected String creditcardtype; protected String routingnumber; @OneToOne(mappedBy="billingInfo", optional="false"); protected User user; mappedby= billinginfo 의의미 관계소유자가 User 임 User 클래스안의 billinginfo 인스턴스변수로매핑됨 optional= false 의의미 BillingInfo 객체는 User 객체없이단독으로저장될수없음 - 28 -
@OneToMany, @ManyToOne @OneToMany, @ManyToOne 가장흔한관계임 Set 이나 List 를사용 Item 1 has 0..* placed on Bid OneToMany ManyToOne public class Item { protected Long itemid; protected String title; protected String description; protected Date postdate; @OneToMany(mappedBy="item") protected Set<Bid> bids; public class Bid { protected Long bidid; protected Double amount; protected Date timestamp; @ManyToOne protected Item item; - 29 -
@ManyToMany @ManyToMany 흔하지않고가끔씩나타나는관계유형으로기본적으로양방향임 양쪽모두관련엔티티다수를참조하는관계 Item 0..* belongs to 1..* contains Category Category 는여러개의 Item 을포함하고있음, Item 은여러 Category 에속함 public class Category { protected Long categoryid; protected String name; @ManyToMany protected Set<Item> items; public class Item { protected Long itemid; protected String title; @ManyToMany(mappedBy="items") protected Set<Category> categories; - 30 -
4 일차 JPA 4.1 도메인모델과 JPA 4.2 JPA이용도메인객체구현 4.3 엔티티관계 4.4 엔티티매핑 4.5 엔티티관계매핑 개요 테이블지정 컬럼매핑 @Enumerated 사용 CLOB와 BLOB 매핑 날짜타입매핑 단일엔티티복수테이블매핑 일차키생성 내장가능클래스매핑
개요 다양한 annotation 을이용한매핑 @Table(name="USERS") @SecondaryTable(name="USER_PICTURES", pkjoincolumns=@primarykeyjoincolumn(name="user_id")) public class User implements Serializable { @Column(name="USER_ID", nullable=false) protected Long userid; @Column(name="USER_NAME", nullable=false) protected String username; @Column(name="FIRST_NAME", nullable=false, length=1) protected String firstname; @Column(name="LAST_NAME", nullable=false) protected String lastname; @Enumerated(EnumType.ORDINAL) @Column(name="USER_TYPE", nullable=false) protected UserType usertype; @Column(name="PICTURE", table="user_pictures") @Lob @Basic(fetch=FetchType.LAZY) protected byte[] picture; @Column(name="CREATION_DATE", nullable=false) @Temporal(TemporalType.DATE) protected Date creationdate; @Embedded protected Address address; public User() { @Embeddable public class Address implements Serializable { @Column(name="STREET", nullable=false) protected String street; @Column(name="CITY", nullable=false) protected String city; @Column(name="STATE", nullable=false) protected String state; @Column(name="ZIP_CODE", nullable=false) protected String zipcode; @Column(name="COUNTRY", nullable=false) protected String country; - 32 -
테이블지정 @Table 주석 엔티티가매핑될테이블을지정하는주석 (annotation) name, catalog, schema 등의파라미터를가짐 (catalog,schema 는거의사용하지않음 ) @Table 은선택사항임, 지정되지않을경우클래스과같은이름의테이블로매핑 대부분의 Persistence 제공자들은스키마자동생성기능을제공함, 하지만단순한스키마에만적용해야함 User 클래스를 USERS 테이블로매핑하는예 @Table(name="USERS", schema="actionbazaar") public class User uniqueconstraints 파라미터사용예 @Table(name="CATEGORIES", uniqueconstraints= {@UniqueConstraint(columnNames={"CATEGORY_ID")) - 33 -
컬럼매핑 @Column 주석 저장될필드나속성을테이블의컬럼으로매핑 userid 속성을 USER_ID 컬럼으로매핑하고자할경우, @Column(name="USER_ID") protected Long userid; 한엔티티를여러테이블에분산하여저장할경우, @Column(name="PICTURE", table="user_pictures") protected byte[] picture; 파라미터 : insertable, updatable @Column(name="USER_ID", insertable=false, updatable=false) protected Long userid; @Column은선택사항임, 지정되지않을경우속성과같은이름의컬럼으로매핑됨 - 34 -
@Enumerated 사용 @Enumerated - 열거형데이터매핑 열거형 UserType 정의 public enum UserType {SELLER, BIDDER, SCR, ADMIN; 배열과마찬가지로, 위네값은 ordinal 이라부르는인덱스값과연관지어짐 사용예 1, UserType.SELLER 의경우 0 이저장됨 @Enumerated(EnumType.ORDINAL) default 값임 UserType usertype; 사용예 2, UserType.SELLER 의경우 SELLER 가저장됨 @Enumerated(EnumType.STRING) UserType usertype; - 35 -
CLOB 과 BLOB 매핑 RDBMS 에서대규모데이터를저장하는방법 BLOB - Binary Large Object 타입 CLOB Character Large Object 타입 @Lob BLOB이나 CLOB 필드를매핑함 매핑예, @Lob @Basic(fetch=FetchType.LAZY) 필드로직접매핑 ( 처음접근할때로드됨 ) protected byte[] picture; CLOB/BLOB 여부는타입에의해결정됨 char[], String CLOB 컬럼에저장 지연 (lazy) 로딩은선택사항이며 EJB 벤더별로차이가있음 - 36 -
날짜 (temporal) 타입매핑 날짜 (temporal) 데이터타입 대부분 DBMS 벤더가서로다른입자 (granularity) 를가진날짜데이터타입을지원 DATE(day, month, year 저장 ) TIME(time만저장, day, month, year는저장하지않음 ) TIMESTAMP(time, day, month, year 저장 ) 사용예, @Temporal(TemporalType.DATE) protected Date creationdate; @Temporal로지정하지않을경우, TIMESTAMP가기본값 ( 가장작은입도 ) - 37 -
단일엔티티복수테이블매핑 @SecondaryTable: 복수테이블매핑 흔히사용되지않지만, 특정상황에서매우유용한방법 예, User 도메인객체는 User 의대용량이미지정보를가지고있다. 이경우, USERS 테이블에대용량이미지를저장하면수행성능을현저하게떨어뜨린다. 이경우, 대용량이미지를별도의 USER_PICTURES 란테이블에저장을하면효율적이다. @Table(name="USERS") @SecondaryTable(name="USER_PICTURES", pkjoincolumns=@primarykeyjoincolumn(name="user_id")) public class User implements Serializable {.. 위에서, USER_ID 가 USER_PICTURES 테이블의일차키이면서동시에외부키임. - 38 -
일차키생성 (1/4) 대행키 (Surrogate key) 권장 CATEGORY_ID, EMPLOYEE_ID 등은대행키 대행키는일차키로사용하기위해만듬 복합키보다는대행키사용을권장함 @GeneratedValue : 일차키생성 Identity Sqeuence 테이블 Identity 컬럼이용 MS-SQL 서버처럼여러 DBMS 가지원함 예, @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="USER_ID") protected Long userid; - 39 -
일차키생성 (2/4) 데이터베이스시퀀스사용절차 데이터베이스안에시퀀스정의 CREATE SEQUENCE USER_SEQUENCE START WITH 1 INCREMENT BY 10; SequenceGenerator 생성 @SequenceGenerator(name="USER_SEQUENCE_GENERATOR", sequencename="user_sequence", initialvalue=1, allocationsize=10) @GeneratedValue 태크지정 @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="user_sequence_generator") @Column(name="USER_ID") protected Long userid; - 40 -
일차키생성 (3/4) 시퀀스테이블사용절차 한테이블로여러시퀀스값을사용할수있음 시퀀스테이블정의 ( 오라클의예 ) CREATE TABLE SEQUENCE_GENERATOR_TABLE (SEQUENCE_NAME VARCHAR2(80) NOT NULL, SEQUENCE_VALUE NUMBER(15) NOT NULL, PRIMARY KEY (SEQUENCE_NAME)); 시퀀스테이블초기화 INSERT INTO SEQUENCE_GENERATOR_TABLE (SEQUENCE_NAME, SEQUENCE_VALUE) VALUES ('USER_SEQUENCE', 1); TableGenerator 생성 @TableGenerator (name="user_table_generator", table="sequence_generator_table", pkcolumnname="sequence_name", valuecolumnname="sequence_value", pkcolumnvalue="user_sequence") @GeneratedValue 사용 @GeneratedValue(strategy=GenerationType.TABLE, generator="user_table_generator") @Column(name="USER_ID") protected Long userid; - 41 -
일차키생성 (4/4) 기본일차키생성전략 자동선택 @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="USER_ID") protected Long userid; JPA 공급자에따라기본값이다름 Oracle 데이터베이스를사용할경우, SEQUENCE가기본전략 SQL Server 데이터베이스를사용할경우, IDENTITY가기본전략 - 42 -
내장가능 (embeddable) 클래스매핑 내장가능객체는엔티티를위한편리한데이터저장공간이며 identity 가없음 @Table(name="USERS") public class User implements Serializable { @Column(name="USER_ID", nullable=false) protected Long userid; @Embedded protected Address address; @Embeddable public class Address implements Serializable { @Column(name="STREET", nullable=false) protected String street; @Column(name="ZIP_CODE", nullable=false) protected String zipcode; Address 의 street 는 USERS.STREET 컬럼으로매핑됨 Address 의 zipcode 는 USERS.ZIP_CODE 컬럼으로매핑됨 - 43 -
4 일차 JPA 4.1 도메인모델과 JPA 4.2 JPA이용도메인객체구현 4.3 엔티티관계 4.4 엔티티매핑 4.5 엔티티관계매핑 일대일관계매핑 일대다, 다대일관계매핑 다대다관계매핑
일대일관계매핑 (1/2) @JoinColumn 을이용한매핑 @Table(name="USERS") public class User { @Column(name="USER_ID") protected String userid; @OneToOne @JoinColumn(name="USER_BILLING_ID", referencedcolumnname="billing_id", updatable=false) protected BillingInfo billinginfo; @Table(name="BILLING_INFO") public class BillingInfo { @Column(name="BILLING_ID") protected Long billingid; - 45 -
일대일관계매핑 (2/2) @PrimaryKeyJoinColumn 을이용한매핑 Parent 측 ( 여기서는 User) 의일차키가복합키일경우, @PrimaryKeyJoinColumn 을사용한다. @Table(name="USERS") public class User { @Column(name="USER_ID") protected Long userid; @OneToOne @PrimaryKeyJoinColumn(name="USER_ID", referencedcolumnname="billing_user_id") protected BillingInfo billinginfo; @Table(name="BILLING_INFO") public class BillingInfo { @Column(name="BILLING_USER_ID") protected Long userid; - 46 -
일대다, 다대일관계매핑 Item-Bid 관계 @Table(name="ITEMS") public class Item { @Column(name="ITEM_ID") protected Long itemid; @OneToMany(mappedBy="item") protected Set<Bid> bids; @Table(name="BIDS") public class Bid { @Column(name="BID_ID") protected Long bidid; @ManyToOne @JoinColumn(name="BID_ITEM_ID", referencedcolumnname="item_id") protected Item item; - 47 -
다대다관계매핑 (1/2) 다대다관계 두개의일대다관계로나눌수있음 조인테이블이필요함 - 48 -
다대다관계매핑 (2/2) 다대다관계 ( 계속 ) 소유다대다 : 1 번 종속다대다 : 2 번 @Table(name="CATEGORIES") public class Category implements Serializable { @Column(name="CATEGORY_ID") protected Long categoryid; 1 @ManyToMany @JoinTable(name="CATEGORIES_ITEMS", joincolumns= @JoinColumn(name="CI_CATEGORY_ID", referencedcolumnname="category_id"), inversejoincolumns= @JoinColumn(name="CI_ITEM_ID", referencedcolumnname="item_id")) protected Set<Item> items; @Table(name="ITEMS") public class Item implements Serializable { @Column(name="ITEM_ID") protected Long itemid; 2 @ManyToMany(mappedBy="items") protected Set<Category> categories; - 49 -
넥스트리소프트 ( 주 ) 박석재수석 (demonpark@nextree.co.kr) 임병인수석 (byleem@nextree.co.kr) 과정명 : SQL 기초와 MyBatis SQL/MyBatis - 50 -