티스토리 뷰

ORM을 사용하는 이유

데이터베이스는 객체와 다르다.

데이터베이스는 데이터가 중복되지 않는 것이 중요하고, 영속적인 데이터의 보존과 무결성, 여러 명이 동시에 접속한 상황에 대한 제어가 필요하다.

반면 객체도 모듈처럼 활용할 수 있도록 중복되지 않아야겠지만, 여러 개의 객체가 생성될 수도, DTO처럼 데이터를 나르는 데 필요한 객체를 별도 정의할 수도 있으므로 데이터베이스의 특징과는 다르다.

또한 객체의 데이터는 수시로 바뀔 수 있고, 따라서 트랜잭션이라는 개념이 없다.

하지만 그렇다고 데이터베이스의 테이블과 객체의 데이터가 서로 다르다면, 프로그래밍을 할 때 헷갈리게 되고, 테이블에 맞추자니 객체의 장점을 상쇄하게 된다.

ORM은, 객체는 객체대로, (관계형)데이터베이스는 데이터베이스대로 설계하자는 것이다. 테이블과 매핑될 객체를 설계하되, 객체가 가진 특징을 살리자는 것이다.

예를 들어 테이블 A, B가 있고, B가 A의 아이디를 FK한다고 해보자.

이 경우, 클래스 A, B가 있고, B는 A의 아이디 대신 객체를 가지도록 설계할 수 있다. 그러면 DB입장에서는 조인하는 것은 같겠지만, 코드 상에서는 ORM 기술로 인해 쿼리를 날릴 필요도 없이 B만 가지고도 컨트롤할 수 있는 것이다! 만약 ORM을 사용하지 않았다면, 쿼리를 날리는 것에 더불어 A-B가 합쳐진 별개의 객체나 A, B 객체를 모두 컨트롤해야 하지 않았을까 한다.

이런 식으로 DB와 객체의 연관관계를 맺는 것을 ORM이라고 할 수 있는데, 이 연관관계를 맺는 방법은 세 가지가 있다.

일대다, 다대일, 다대다이다. 이때는 객체가 다른 객체를 참조할 수 있도록 방향성 설계가 중요하다.

 

연관관계 매핑의 방법: 일대다, 다대일, 다대다

테이블은 외래 키를 가지고 두 테이블의 연관관계를 맺는다.

객체는 어노테이션을 가지고 연관관계를 맺을 수 있으며, 단방향, 양방향이라는 방향성을 가지게 된다.

단방향은, 하나의 객체가 다른 객체를 참조하는 것을 말하며, 양방향은 서로 참조하는 것을 말한다.

양방향 관계에서 주의해야 할 것은 양방향이라고는 하지만, 사실은 똑같은 객체를 서로 바라보는 것이 아니라, A - B & B - A’ 처럼 바라보게 된다는 것이다. 따라서 양방향 관계를 맺었을 때, 데이터의 통제는 양쪽에서 해주어야 맞다.

 

일대다-다대일, 단방향-양방향

Food 테이블이 있고 Restaurant 테이블이 있다고 하자.

Restaurant 하나에 Food는 여러 개가 될 수 있다. 이 경우를 일대다라고 한다.

테이블에서는 아래와 같이 Food에 대한 정보가 없다. Food에서 Restaurant ID를 FK하고 있기 때문이다.

Food에서는 Restaurant의 ID 하나에 여러 개의 Food ID가 달린 걸 볼 수 있다.

 

객체에서 이러한 관계를 설정하려면, Food에서 아래와 같이 작성한다.

@ManyToOne
@JoinColumn(name="RESTAURANT_ID")
private Restaurant restaurant;

@ManyToOne 으로 관계를 설정하고, 어떤 테이블이 FK할 것인지 @JoinColumn으로 지정한다(디폴트로 ID를 FK함_. 여기까지만 작성해도, 관계 설정은 된다.

하지만 이 경우, Food에서만 관계를 지정했으므로, Restaurant에서는 Food를 알 수 없게된다. Restaurant의 Food를 보고 싶을 때는 Food에서 특정 RestaurantID를 가진 로우를 뒤져야 할 것이다.

이를 위해 다대일 쪽 Restaurant에서도 매핑을 해준다.

@OneToMany(mappedBy = "restaurant")
private final List<Food> menu = new ArrayList<Food>();

이 설정을 mappedBy로 하는데, 주인의 졸(?)에서 어떤 객체를 참조할 것인지 지정해주면 된다.

이때 작성한 menu 리스트는, 조인 테이블에서 restaurant ID와 같은 Food의 데이터를 저장해준 것으로, menu에서 수정해봤자 Food 테이블은 수정되지 않는다. 한 번 조회한 데이터를 리스트로 저장해준 것뿐이기 때문이다.

사실 mappedBy는 주인 쪽, 그러니까 FK를 지정한 쪽에서 써줘도 되긴 하지만 헷갈리니까 여기다 쓰라고 한다.

 

다대다

데이터베이스는 다대다 관계를 가질 수 없다. 하지만 도서관-저자 간의 관계라면 다대다 관계가 발생할 수 있다. 이런 경우 다대다 관계를 가지려면 중간 다리 테이블을 둬야 한다.

만약 코드 상에서 다대다를 구현하고 싶다면, @ManyToMany를 쓰면 되지만, 데이터베이스에서는 중간 다리 테이블이 탄생되어 버린다.

보기에도 싫을 뿐더러, 실무에서는 개발자도 모르는 복잡한 조인의 쿼리가 발생할 수도 있고, 중간 다리 테이블에서는 추가 컬럼을 사용할 수 없기 때문에 사용을 지양한다고 한다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/05   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함