ORM
(Object-Relational-Mapping)
객체와 데이터베이스 간의 데이터 매핑을 자동으로 처리해 주는 기술
객체 지향 프로그래밍에서는 클래스와 객체를 사용하여 데이터를 처리한다.
관계형 데이터베이스에서는 테이블과 레코드를 사용한다.
위 두가지 방식은 데이터를 저장하고 처리하는 방식이 다르다.
ORM은 이러한 객체지향 프로그래밍과 관계형 데이터베이스 간의 불일치를 해결하기 위해
개발된 기술이다.
ORM을 사용하면 데이터베이스와 상호작용할 때 객체를 사용하여 코드를 작성할 수 있다.
ORM은 객체와 데이터베이스 간의 매핑 정보를 가지고 있으며, 이 정보를 사용하여
객체를 데이터베이스에 저장하고 조회할 수 있다.
ORM을 사용하면 데이터베이스와의 작업을 수행하는 코드를 직접 작성할 필요가 없으며,
객체를 사용하여 데이터를 처리할 수 있어서 코드의 가독성과 유지보수성이 좋아진다.
대표적인 ORM 프레임워크로는 Hibernate, EclipseLink, DataNucleus, Ebean 등이 있다.
Hibernage ORM : 자바 언어를 위한 객체 관계 매핑 프레임워크
JPA : 자바에서의 ORM의 기술 표준으로 사용하는 인터페이스의 모음
-> JPA는 인터페이스이다. 인터페이스를 구현하는 실제 클래스가 필요한데
JPA를 구현한 대표적인 실제 클래스에는 하이버네이트(Hibernatem)가 있다.
Hibernate Architecture를 나타내는 그림
내용 참고 - 위키백과 -
내용 참고 - 점프 투 스프링 부트 -
객체지향 모델과 관계형 데이터베이스의 패러다임 불일치 발생
패러다임 불일치
객체 | 릴레이션 | |
밀도 문제 (Granularity) |
다양한 크기의 객체를 만들 수 있음, 커스텀한 타입 만들기 쉬움 |
테이블, 기본 데이터 타입 |
서브타입 문제 (Subtype) |
상속, 다형성 구현이 쉬움 | 상속 없음. 다형적인 관계 표현 불가 |
식별성 문제 (Identity) |
레퍼런스 동일성(==), 인스턴스 동일성(equals() 메서드) |
주키(primary key) |
관계 문제 (Association) |
서로간의 객체 참조를 통해 표현, 다대다 가능, 방향이 존재 |
다대다 불가, 다대다를 맺어주는 테이블로처리 외래키가 있어서 바로 조회 가능(방향이 없음) |
데이터 네비게이션 문제 (Navigation) |
어디든지 레퍼런스로 다른 객체 이동 가능 | 레퍼런스 방식이 배효율적 데이터베이스의 요청을 적게 할수록 성능이 좋은데 참조를 하기위해 JOIN을 많이쓰면 성능적으로 비효율적이다. 그렇다고 데이터를 JOIN을 하지 않고 lazy loading을 해도 N+1 문제가 발생한다. |
관계, 데이터 네비게이션 문제
class Member {
private int memberId;
private String mamberName;
private Team team;
}
class Team {
private int teamId;
private String teamName;
}
Member member = new Member();
Team team = new Team();
member.setTeam(team);
member.team(); //가능
team.member(); // 불가능
member는 team을 가지고 있어서
member.team이 가능하지만,
team은 그렇지 않으므로
team.member() 는 불가능하다.
Member Table
member_id | member_name | team_id |
1 | minsoo | 2 |
2 | minjung | 1 |
3 | minsuk | 1 |
4 | minsook | 3 |
5 | daehyun | 2 |
6 | songyi | 1 |
team_id | team_name |
1 | naver_team |
2 | kakao_team |
3 | line_team |
멤버 테이블에서 민수의 팀아이디와 일치하는 팀 이름을 팀 테이블에서 조회
>> kakao_team
네이버 팀의 팀아이디인 1을 외래키로 가지고 있는 애들을 멤버 테이블에서 조회
>> minjung, minsuk, songyi
-> 양방향이 가능하다.
내용 참고 - 아카이브 -
내용 참고 - 스파르타 코딩클럽 -
ORM, JPA의 등장
패러다임 불일치로 인해 발생하는 문제들과, 반복적이고 번거로운 애플리케이션 단에서의
쿼리 작업을 줄여주기 위해서 ORM(객체 관계 매핑) 기술들이 등장하게 된다.
JPA : Java Persistence API
자바 ORM 기술에 대한 표준 명세
1. 쿼리를 자동으로 만들어준다.
2. 어플리케이션 계층에서 SQL의 의존성을 줄여 번거로운 작업이 매우 단축된다.
3. 패러다임의불일치를 해결해 준다.
4. 성능 최적화를 위해 많은 노력 중에 있지만 성능도 좋다.
5. 방언도 지원해 준다.
h2 Dagabase, mySQL, Oracle 등 어떤 쿼리문을 사용하든 코드의 변경은 없다.
관계형 DB이자 표준을 준수한 SQL을 지원한다면, JPA가 방언들도 알아서 처리해 준다.
JPA 예시
Entity
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer age;
// getters, setters, constructors, 등의 메서드 생략
}
@Entity : 해당 클래스가 JPA 엔티티임을 나타낸다.
@Table : 해당 클래스가 매핑할 테이블명을 지정한다.
@Id : 해당 필드가 엔티티의 primary key 임을 나타낸다.
@GeneratedValue : primary key 값을 자동으로 생성함을 나타낸다.
Repository
@Repository
public class UserRepository {
@PersistenceContext
private EntityManager entityManager;
@Transactional
public void saveUser(User user) {
entityManager.persist(user);
}
}
@Repository : 해당 클래스가 데이터베이스와 상호작용하는 레포지토리임을 나타낸다.
@PersistenceContext : EntityManager를 주입하는 역할
-> EntityManager : JPA에서 엔티티의 영속성을 관리하는 주요 클래스
@Transactional : 해당 메서드가 트랜잭션으로 실행되어야 함을 나타냄
EntityManager의 데이터베이스 작업들은 트랜잭션 내에서 실행된다.
Service
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public void saveUser(User user) {
userRepository.saveUser(user);
}
}
@Service : 해당 클래스가 비즈니스 로직을 담당한다는 것을 명시
@Autowired : UserRepository를 주입하는 역할
UserService의 saveUser 메서드를 호출
-> UserRepository의 saveUser 메서드가 실행
-> 데이터베이스에 User 데이터가 저장
참고하면 좋은 링크 - ORM이란? -
'데이터베이스 탐구' 카테고리의 다른 글
프로그래머스) (mySQL) 가장 비싼 상품 구하기 (0) | 2023.04.30 |
---|---|
데이터베이스) SQL (0) | 2023.04.30 |
프로그래머스) (mySQL) 12세 이하인 여자 환자 목록 출력하기 (0) | 2023.04.25 |
프로그래머스) (mySQL) 흉부외과 또는 일반외과 의사 목록 출력하기 (0) | 2023.04.25 |
프로그래머스) (mySQL) 인기있는 아이스크림 (0) | 2023.04.16 |