ORM 이란 Object-Relational Mapping 의 약자로, 이름 그대로 객체(Object)와 관계형 데이터(Relational data) 를 매핑하기 위한 기술이다. 객체와 테이블 관계를 바탕으로 SQL문장을 자동으로 생성하여 객체로 DB를 조작하게 하는 기술.
객체 지향 프로그래밍과 관계형 데이터베이스 사이의 목표와 동작 방식이 다르다 보니 데이터 표현 방식이 달라서 패러다임 불일치가 일어나는데, 이 때문에 개발자는 더 많은 코드를 작성해야하고 실수하기 쉬운 것은 ORM이 해결해준다.
JPA
JPA는 Java Persistence API의 약자로, 자바 ORM 기술에 대한 API 표준 명세이다. ORM을 사용하는 방식을 정의한 인터페이스를 모아둔 것. JPA는 특정 기능을 하는 라이브러리가 아니며, 말그대로 인터페이스이다. 따라서 사용방식에 대해서만 정의했을 뿐 구현이 없다.
Hibernate
JPA라는 명세의 구현체. 즉, JPA 인터페이스를 구현한 라이브러리 중 하나로 현 프레임워크 중 가장 주도 하고 있다.
Spring Data JPA
Spring Data JPA는 JPA를 쓰기 편하게 만들어놓은 모듈이다. JPA를 한 단계 추상화시킨 Repository라는 인터페이스를 제공함으로써 JPA를 사용할 때 예상가능하고 반복적인 코드들을 대신 작성해주어 코드를 줄일 수 있도록 해준다.
@Getter
@Entity
@NoArgsConstructor
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String memberName;
// One이 Member, Many가 Orders 멤버는 여러 주문을 할 수 있기 때문
//
@OneToMany(mappedBy = "member", fetch = FetchType.EAGER)
private List<Orders> orders = new ArrayList<>();
public Member(String memberName) {
this.memberName = memberName;
}
}
연관관계 주인에 값을 입력하지 않고, 주인이 아닌 entity에 값을 입력하면 문제가 생길 수 있다.
Order order = new Order ("order", "order”);
em.persist(order);
Order order2 = new Order (”order2", "order2”);
em.persist(order2);
Member member = new Member("member", ”member”);
//여기가 실수 포인트!!!
member.getOrders().add(order);
member.getOrders().add(order2);
em.persist(member);
member.order에만 값을 저장하고 order.member에 아무 값도 입력하지 않았다면 외래키 값도 null로 저장되는 상태가 된다.
이런 문제를 해결하는 방법은 객체 관점에서는 양쪽 방향에서 모두 값을 입력해주는 것이 가장 안전하다.
하지만 매번 양쪽으로 값을 넣는 건 깜빡할 여지가 많아 이런 식으로 메소드를 만들어 양쪽에 저장해 주는 방식도 있다.
private Order order;
public void setMember(Member member) {
this.member = member; // order.member에 저장
member.getOrders().add(this); // member.order에 저장
}
...
}
build.gradle 파일에서 사용 중인 플러그인, dependencies 등을 확인할 수 있다.
위의 dependencies 리스트와 실제로 사용중인 라이브러리의 리스트가 일치하지 않는다.
왜냐하면 우리가 Spring Web이 필요해서 이것만 끌어온다고 선택했지만 Spring Web이 또 의존하고 있는 라이브러리들을 존재한다. 결국 Spring Web을 사용하려면 이런저런 라이브러리들을 더 끌고 와야해서 실제적으로는 아래처럼 수많은 라이브러리들을 끌고 오게 되고 마지막엔 spring-core까지 끌고 오게 된다.
라이브러리의 관계성을 보고자 하면,
하늘 색으로 표시되는, 창을 둘러싼 메뉴들 중 오른쪽 메뉴 들 중에서 Gradle을 찾아 눌러 라이브러리를 확인할 수 있는데
펼쳐보면 수많은 라이브러리들에 의존하고 있는 걸 볼 수 있다. 이게 전부 끌려온 것이다.
+ 참고로 (*)가 붙은건 이미 다른 라이브러리에서 이와 같은 걸 의존하고 있어 중복되어 있으므로 생략했다는 뜻이다.
이번 강의 라이브러리 관련 Tip
+ 현업에서는 System.out.print를 사용안하고 로그로 확인하며 에러를 관리한다. 로깅에 관련한 라이브러리가 궁금하다면, logback과 slf4j에 대해 검색해보자. + 자바 진영에서는 테스트 프레임워크로 junit을 사용