ORM(Object-Relational Mapping)은 객체지향 프로그래밍에서 사용되는 객체들과 관계형 데이터베이스의 테이블을 매핑(mapping)하는 기술을 말한다.
JPA를 사용해서 엔티티 클래스를 만들고, 이 엔티티 클래스를 기반으로 Hibernate가 ORM을 수행한다.
1차 캐시 (First-Level Cache)
1차 캐시는 Hibernate의 세션(Session) 내에 존재하는 캐시로, 동일한 세션 내에서 반복적으로 조회되는 엔티티 객체를 데이터베이스에 재차 쿼리를 날리지 않고, 세션 내에 저장된 엔티티를 재사용하는 메커니즘입니다. 이 덕분에 성능이 향상되고, 불필요한 데이터베이스 쿼리 호출을 줄일 수 있습니다.
System.out.println("username : " + boardList.get(0).getUser().getUsername()); //같은 USER_ID System.out.println("username : " + boardList.get(1).getUser().getUsername()); //같은 USER_ID System.out.println("username : " + boardList.get(4).getUser().getUsername());

@ManyToOne(fetch = FetchType.LAZY) private User user;
위처럼 get(0)과 get(1)은 동일한 user_id를 가지고 왔다
그렇기에 두번째 sysout인 get(1)을 호출시에는 db로 가지않고 하이버네이트의 1차캐시에서 user테이블의 정보를 가지고 와서 빠르다.
get(4)의 경우는 참조한적 없는 user라 db에서 다시 참조해야한다.
데이터베이스 스키마 자동 생성
- ORM은 엔티티 클래스를 기반으로 데이터베이스의 테이블을 자동으로 생성할 수 있습니다. 개발자가 데이터베이스 스키마를 직접 작성할 필요 없이, ORM이 엔티티 정의를 바탕으로 테이블, 칼럼, 인덱스 등을 자동으로 생성해줍니다. 이 기능은 초기 개발 단계에서 매우 유용합니다.
insert into user_tb(username, password, email, created_at) values ('ssar', '1234', 'ssar@nate.com', now()); insert into user_tb(username, password, email, created_at) values ('cos', '1234', 'cos@nate.com', now()); insert into user_tb(username, password, email, created_at) values ('love', '1234', 'love@nate.com', now()); insert into board_tb(title, content, created_at, user_id) values ('제목1', '내용1', now(), 1); insert into board_tb(title, content, created_at, user_id) values ('제목2', '내용2', now(), 1); insert into board_tb(title, content, created_at, user_id) values ('제목3', '내용3', now(), 2); insert into board_tb(title, content, created_at, user_id) values ('제목4', '내용4', now(), 2); insert into board_tb(title, content, created_at, user_id) values ('제목5', '내용5', now(), 2);
연관 관계 매핑
- ORM은 엔티티 간의 다양한 관계를 매핑할 수 있습니다. 예를 들어, 일대일(One-to-One), 일대다(One-to-Many), 다대일(Many-to-One), 다대다(Many-to-Many) 관계를 설정하고 관리할 수 있습니다. 이러한 관계를 설정하면 ORM이 자동으로 필요한 조인(Join) 쿼리를 생성하고, 연관된 엔티티들을 적절히 로딩해줍니다.

지연 로딩(Lazy Loading)과 즉시 로딩(Eager Loading)
- 지연 로딩(Lazy Loading): 엔티티와 관련된 데이터를 실제로 필요할 때까지 로딩하지 않고 미뤄둡니다. 예를 들어,
Board
엔티티를 로딩할 때 관련된User
엔티티가 필요하지 않으면 데이터베이스에서 가져오지 않습니다. 필요할 때getUser()
를 호출하면 그제서야 데이터베이스에 쿼리를 날려 데이터를 가져옵니다.
- 즉시 로딩(Eager Loading): 엔티티를 로딩할 때 관련된 모든 데이터를 즉시 함께 로딩합니다. 따라서 연관된 데이터를 미리 준비해두어 필요한 순간에 바로 사용할 수 있습니다.
Share article