Association Mapping

두 클래스 사이의 Association 유형별 매핑 방법에 대해서 살펴보고자 한다. 그리고 다양한 Collection의 매핑 방법 및 Collection의 주요속성인 inverse,cascade에 대해서 샘플코드를 중심으로 살펴본다.

One To One Mapping

테이블간 1:1 매핑이 있을 경우에 각각의 Entity 클래스를 정의하고 클래스간 관계를 OneToOne 매핑으로 처리한다.

Sample Source
@Entity
public class Employee {
   @OneToOne
   private TravelProfile profile;
}
 
@Entity
public class TravelProfile {
   @OneToOne
   private Employee employee;
}

위의 예를 보면 Employee 와 TravelProfile가 각각 OneToOne이라는 Annotation을 기재하여 매핑처리한 것을 알수 있다.

One To Many Mapping

테이블간 1:N 매핑이 있을 경우에 각각의 Entity 클래스를 정의하고 한쪽에는 OneToMany, 다른쪽에는 ManyToOne 이라는 Annotation을 기재하여 관계를 나타낸다.

Sample Source
@Entity
public class Department{
   @OneToMany(targetEntity=User.class)
   private Set<User> users = new HashSet(0);
}
 
@Entity
public class User{
   @ManyToOne
   private Department department;
}

위의 예를 보면 Department:User = 1:N 의 관계가 있으며 그 관계에 대해서 Department 클래스에서 OneToMany로 표시하고 User 클래스에서 ManyToOne으로 표시하여 관계를 나타냈다.

Collection Type

Collection은 위의 예에서 사용된 Set 이외에도 List,Map를 사용할 수 있는데 각각의 사용법은 다음과 같다

Set

java.util.Set 타입으로 <set>을 이용하여 정의한다. 객체의 저장 순서를 알 수 없으며, 동일 객체의 중복 저장을 허용하지 않는다. (HashSet 이용) 다음은 set 태그를 이용하여 Collection 객체를 정의한 소스 코드의 예이다

Sample Source
@Entity
public class Department{
   @OneToMany(targetEntity=User.class)
   private Set<User> users = new HashSet(0);
}

List

java.util.List 타입으로 <list>를 이용하여 정의한다. List 타입의 경우 저장된 객체의 순서를 알 수 있으며, 저장 순서를 테이블에 보관하기 위해서 별도 인덱스 컬럼 정의가 필요하다. (ArrayList 이용) 다음은 list 태그를 이용하여 Collection 객체를 정의한 소스 코드의 예이다

Sample Source
@Entity
public class Department{
   @OneToMany(targetEntity=User.class ) 
   private List<User> users = new ArrayList(0);
}

Map

java.util.map 타입으로 <map>을 이용하여 (키,값)을 쌍으로 정의한다. (HashMap 이용) 다음은 map 태그를 이용하여 Collection 객체를 정의한 소스 코드의 예이다. Key 설정을 위해 MapKey라는 Annotation을 추가적으로 정의해야 한다.

Sample Source
@Entity
public class Department{
   @OneToMany(targetEntity=User.class)
   @MapKey(name="userId")
   private Map<String,User> users ;
}

단방향/양방향 관계 속성

1:N(부모:자식)관계 지정에 있어서 자식쪽에서 부모에 대한 참조 관계를 가지고 있느냐 없느냐에 따라서 참조관계가 있으면 양방향 관계, 없으면 단방향 관계로 정의된다.

단방향

자식 Entity에 부모 Entity에 대한 참조정보 없이 정의한다.

Sample Source
@Entity
public class Department{
   @OneToMany(targetEntity=User.class)
   private Set<User> users = new HashSet(0);
}
 
@Entity
public class User{
   @Column(name="DEPT_ID")
   private String deptId;
}

위의 예에서 보면 User 클래스에서 Department 클래스에 대한 참조관계를 지정하지 않고 단순하게 테이블의 컬럼 DEPT_ID와의 매핑으로 deptId를 지정한 것을 알 수 있다.

양방향

자식 Entity에 부모 Entity에 대한 참조정보를 지정하여 정의한다.

Sample Source
@Entity
public class Department{
   @OneToMany(targetEntity=User.class)
   private Set<User> users = new HashSet(0);
}
 
@Entity
public class User{
   @ManyToOne
   private Department department;
}

위의 예에서 보면 User 클래스에서 Department 클래스에 대한 ManyToOne Annotation을 통해 매핑관계를 지정한 것을 알 수 있다.

mappedBy,Cascade 속성

mappedBy와 cascade는 Collection 정의시 중요한 의미를 가지는 속성 중의 하나로, 다음과 같은 의미를 지닌다.

  • mappedBy: 객체간 관계 연결을 어느 Entity에서 할 것인지에 대한 옵션을 정의하기 위한 속성이다.
  • cascade : 부모 객체에 대한 CUD를 자식 객체에도 전이할지에 대한 옵션을 정의하기 위한 속성이다.

mappedBy: ○, cascade: ○

mappedBy와 cascade를 모두 정의하여 사용할 경우에는 자식 Entity에서 관계연결 처리를하고 부모 Entity에서 CUD처리시 자식 Entity도 자동으로 처리된다.

Define Source
@Entity
public class Department{
   @OneToMany(targetEntity=User.class,mappedBy="deptId",cascade={CascadeType.PERSIST, CascadeType.MERGE})
   private Set<User> users = new HashSet(0);
}
 
@Entity
public class User{
   @ManyToOne(targetEntity=Department.class)
   private Department department;
}
Sample Source
// User(자식) Entity의 setDepartment 메소드를 통해서 관계설정
user.setDepartment(department);
 
// 부모 entity의 저장으로 자식까지 동시처리
em.persist(department);

mappedBy: ○, cascade: Ⅹ

mappedBy만 정의하여 사용할 경우에는 자식 Entity에서 관계연결 처리를하고 부모,자식 각자 CUD처리한다.

Define Source
@Entity
public class Department{
   @OneToMany(targetEntity=User.class,mappedBy="deptId")
   private Set<User> users = new HashSet(0);
}
 
@Entity
public class User{
   @ManyToOne(targetEntity=Department.class)
   private Department department;
}
Sample Source
// User(자식) Entity의 setDepartment 메소드를 통해서 관계설정
user.setDepartment(department);
 
// 부모/자식 entity의 각각 처리
em.persist(department);
em.persist(user);

mappedBy: Ⅹ, cascade: ○

cascade만 정의하여 사용할 경우에는 부모 Entity에서 관계연결 처리를 하고 부모 Entity에서 CUD처리시 자식 Entity도 자동으로 처리된다.

Define Source
@Entity
public class Department{
   @OneToMany(targetEntity=User.class,cascade={CascadeType.PERSIST, CascadeType.MERGE})
   private Set<User> users = new HashSet(0);
}
 
@Entity
public class User{
   @ManyToOne(targetEntity=Department.class)
   private Department department;
}
Sample Source
// Department(부모) Entity의 getUsers().add 메소드를 통해서 관계설정
department.getUsers().add(user);
 
// 부모 entity의 저장으로 자식까지 동시처리
em.persist(department);

mappedBy: Ⅹ, cascade: Ⅹ

모두 정의하지 않을때는 부모 Entity에서 관계 연결 처리를 하고 부모,자식 각자 CUD처리한다.

Define Source
@Entity
public class Department{
   @OneToMany(targetEntity=User.class)
   private Set<User> users = new HashSet(0);
}
 
@Entity
public class User{
   @ManyToOne(targetEntity=Department.class)
   private Department department;
}
Sample Source
// Department(부모) Entity의 getUsers().add 메소드를 통해서 관계설정
department.getUsers().add(user);
 
// 부모/자식 entity의 각각 처리
em.persist(department);
em.persist(user);

Many To Many Mapping

테이블간 M:N 매핑이 있을 경우에 각각의 Entity 클래스를 정의하고 양쪽에 ManyToMany이라는 Annotation을 기재하여 관계를 나타낸다.

Sample Source
@Entity
public class Role{
   @ManyToMany(targetEntity=User.class)
   private Set<User> users = new HashSet(0);
}
 
@Entity
public class User{
   @ManyToMany
   @JoinTable(name="AUTHORITY",
              joinColumns=@JoinColumn(name="USER_ID"),
              inverseJoinColumns=@JoinColumn(name="ROLE_ID"))
   private Set<Role> roles = new HashSet(0);	
}

위의 예를 보면 Role:User = M:N 의 관계가 있으며 그 관계에 대해서 Role클래스에서 ManyToMany로 표시하고 User 클래스에서 ManyToMany로 표시하여 관계를 나타내면서 User 클래스에서 관계를 위한 별도의 테이블에 대한 정의를 하고 있다. 이 경우에 ROLE과 USER를 연결하는 관계 테이블로 AUTHORITY가 사용된 것을 알 수 있다.

 
egovframework/rte2/psl/orm/association_mapping.txt · 마지막 수정: 2015/04/14 11:24 (외부 편집기)
 
이 위키의 내용은 다음의 라이센스에 따릅니다 :CC Attribution-Noncommercial-Share Alike 3.0 Unported
전자정부 표준프레임워크 라이센스(바로가기)

전자정부 표준프레임워크 활용의 안정성 보장을 위해 위험성을 지속적으로 모니터링하고 있으나, 오픈소스의 특성상 문제가 발생할 수 있습니다.
전자정부 표준프레임워크는 Apache 2.0 라이선스를 따르고 있는 오픈소스 프로그램입니다. Apache 2.0 라이선스에 따라 표준프레임워크를 활용하여 발생된 업무중단, 컴퓨터 고장 또는 오동작으로 인한 손해 등에 대해서 책임이 없습니다.
Recent changes RSS feed CC Attribution-Noncommercial-Share Alike 3.0 Unported Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki