김쥬르에 개발일지
SpringBoot ORM 본문
ORM이란?
자바의 객체와 데이터베이스를 연결하는 프로그래밍 기법입니다.
예를 들어 데이터베이스에 age,name 컬럼에 20, 홍길동이라는 값이 들어있다고 생각해봅시다.
이것을 자바에서 사용하려면 보통은 SQL이라는 언어로 데이터를 사용하니 SQL도 학습해야합니다.
하지만 ORM이 있다면 데이터베이스의 값을 마치 객체처럼 사용할수있습니다.
객체와 데이터베이스를 연결해 자바 언어로만 데이터베이스를 다룰수 있게 해주는
도구를 ORM(object-relational mapping)이라고 합니다.
ORM 장단점
장점 1. SQL을 직접 작성하지 않고 사용하는 언어로 DB에 접근 가능
장점 2. 객체지향적으로 코드를 작성할 수 있기 때문에 비즈니스 로직에 집중
장점 3 . 데이터베이스 시스템에 대한 종속성이 줄어듦
장점 4. 매핑하는 정보가 명확하기 때문에 ERD에 대한 의존도를 낮추고 유지보수 유리
단점 1. 프로젝트의 복잡성이 커질수록 사용 난이도 상승
단점 2. 복잡하고 무거운 쿼리는 ORM으로 해결이 불가한 경우 생김
그렇다고 해서 SQL문을 뒤로 하시면안됩니다.
토비라는 강사님의 말을 인용해서 말씀드리면
현재 기업 90%는 관계형 데이터베이스를 사용하고
언어에 경우 시대의 흐름에 따라 (JAVA,Python ...) 유행이 급격하게 바뀌지만
데이터베이스의 경우 향후 10년 이상은 큰틀에서 벗어나지 않는다.
즉 백엔드 개발자로서의 길을 걷고 계신다면
SQL 학습은 필수와도 같다고 생각하고
JPA 와 SQL 둘다 능숙하다면 기업에서도 좋아할거같습니다.
현재 저는 SQLD 자격증 공부도 계획중이기에
SQL에 관한 포스팅도 추후 올리도록하겠습니다!
서론이 길었네요 ㅎ..
이어서 하이버네이트 라는 친구도 알아보겠습니다.
JPA와 하이버네이트?
DBMS에도 여러종류가 있는것처럼 ORM에도 여러 종류가 있습니다.
자바에서는 JPA를 표준으로 사용하고 JPA는 자바에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스입니다.
인터페이스이기에 실제 사용을 위해서는 ORM 프레임워크를 추가로 선택해야합니다.
대표적으로 하이버네이트를 많이 사용하죠
하이버네이트는 JPA 인터페이스를 구현한 구현체이자 자바용 ORM 프레임워크입니다.
내부적으로는 JDBC API를 사용합니다.
하이버네이트의 목표는 자바 객체를 통해 데이터베이스 종류와 관계없이 자유자재로 사용하는데 있습니다.

이번엔 JPA의 중요한 컨셉중 하나인 엔티티 매니저와 영속성 컨텍스트을 알아보겠습니다.
엔티티?
포스팅을 처음부터 보신분이라면 Entity라는 단어가 익숙하실텐데요엔티티는 데이터베이스의 테이블과 매핑되는 객체를 의미합니다.엔티티는 본질적으로 자바 객체이므로 일반 객체와 다르지 않지만데이터베이스의 테이블과 직접 연결된다는 아주 강력한 특징이 있어 구분지어 부릅니다.엔티티는 객체이긴 하지만 데이터베이스에 영향을 미치는 쿼리를 실행하는 객체인셈이죠
엔티티 매니저?
이름 그대로 엔티티를 관리해 데이터베이스와 어플리케이션 사이에서 객체를
생성,수정,삭제 하는 등의 역할을 합니다. 이런 엔티티 매니저를 만드는곳이 엔티티 팩토리입니다.
예를 들어 회원 2명이 동시의 회원가입을 하려는 경우 엔티티 매니저는 다음과 같이 업무를 처리합니다.
회원 1의 요청에 대해서 가입처리를 할 엔티티 매니저를 엔티티 매니저 팩토리가 생성하면
이를 통해 가입 처리해 데이터베이스에 회원 정보를 저장하는것이죠
회원 2도 마찬가지이며 회원 1,2를 위해 생성된 엔티티 매니저는 필요한 시점에 데이터베이스와 연결하여 쿼리합니다.

스프링부트는 내부에서 엔티티 매니저 팩토리를 하나만 생성해서 관리하고
@PersistenceContext 또는 @Autowired 어노테이션을 사용해서 엔티티 매니저를 사용합니다.
스프링부트가 엔티티 매니저를 사용하는 방법 예
@PersistenceContext
EntityManager em; //프록시 엔티티 매니저. 필요시 진짜 엔티티 매니저 호출
스프링부트는 기본적으로 빈은 하나만 생성해서 공유하므로 동시성 문제가 발생할 수 있습니다.
그래서 실제로는 엔티티 매니저가 아닌 실제 엔티티 매니저와 연결하는 프록시(가짜) 매니저를 사용합니다.
필요할 때 데이터베이스 트랜잭션과 관련된 실제 엔티티 매니저를 호출 하는거죠
말이 어려웠는데요
쉽게 말해 엔티티 매니저는 JPA에서 관리하므로 직접 생성하거나 관리할 필요가 없습니다.
개념을 알고 넘어가는것이 중요합니다.!
영속성 컨텍스트?
엔티티 매니저는 영속성 컨텍스트에 저장한다는 특징이 있습니다.
영속성 컨텍스트는 JPA의 중요한 특징 중 하나로, 엔티티를 관리하는 가상의 공간입니다.
영속성 컨텍스트가 있기에 효과적으로 데이터를 가져올수있고, 엔티티를 편하게 사용하는것이죠
영속성 컨텍스트에는 1차 캐시 , 쓰기 지연 , 변경 감지 , 지연 로딩 이라는 특징이 있습니다.
1차 캐시
영속성 컨텍스트는 내부에 1차 캐시를 가지고있습니다.
캐시의 키는 엔티티의 @Id 어노테이션이 달린 기본키 역할을 하는 식별자이며 값은 엔티티입니다.
엔티티를 조회하면 1차 캐시에서 데이터를 조회하고 값이 있으면 반환합니다.
값이 없으면 데이터베이스에서 조회해 1차 캐시에 저장한 다음 반환합니다.
이를 통해 캐시된 데이터를 조회할 때에는 데이터베이스를 거치지 않아도 되므로
매우 빠르게 데이터를 조회할 수 있습니다.
쓰기 지연
쓰기 지연은 트랜잭션을 커밋하기 전까지는 데이터베이스에 실제로 질의문을 보내지 않고 쿼리를 모았다가
트랜잭션을 커밋하면 모았던 쿼리를 한번에 실행하는 것을 의미합니다.
예를 들어 데이터 추가 쿼리가 3개라면 영속성 컨텍스트는 트랜잭션을 커밋하는 시점에
3개의 쿼리를 한꺼번에 쿼리를 전송합니다.
이를 통해 적당한 묶음으로 쿼리를 요청할 수 있어 데이터베이스 시스템의 부담을 줄일 수 있습니다.
변경감지
트랜잭션을 커밋하면 1차 캐시에 저장되어 있는 엔티티의 값과 현재 엔티티의 값을 비교해서 변경 된 값이 있다면
변경 사항을 감지해 변경된 값을 데이터베이스에 자동으로 반영합니다.
이를 통해 쓰기 지연과 마찬가지로 적당한 묶음으로 쿼리를 요청할 수 있고, 데이터베이스 시스템의 분담을 줄일 수 있습니다.
지연 로딩
지연 로딩은 쿼리로 요청한 데이터를 애플리케이션에 바로 로딩하는 것이 아니라
필요할 때 쿼리를 날려 데이터를 조회하는 것을 의미합니다.
이 특징들의 갖는 공통점은 모두 데이터베이스의 접근을 최소화해 성능을 높일 수 있다는 겁니다.
캐시를 하거나, 자주 쓰지 않게 하거나, 변화를 자동 감지해서 미리 준비하거나 하는 등의 방법을 통해 말이죠
이런 특징을 잘 이해하고 JPA를 사용한다면 문제 상황을 조금 더 잘 이해할수 있을거같습니다.
'Spring boot' 카테고리의 다른 글
| Spring Boot 블로그 글 추가하기 (1) | 2023.12.27 |
|---|---|
| Spring Boot REST API (2) | 2023.12.26 |
| SpringBoot 테스트 코드 (0) | 2023.12.25 |
| Spring Boot 어노테이션 모음 (0) | 2023.12.25 |
| SpringBoot 구조 이해하기 (0) | 2023.12.23 |