< ORM란? >

ORM이란, Object-Relational Mapping의 약자로, 객체 지향 프로그래밍 언어를 사용하여 호환되지 않는 유형 시스템 간에 데이터를 변환하는 프로그래밍 기법을 말한다. 즉, 프로그래밍 언어의 객체와 데이터베이스의 데이터를 자동으로 연결해주는 역할을 한다.
< JPA란? >
Java에서는 JPA(Java Persistence API)를 ORM 표준으로 사용하며. JPA는 자바에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스이다. 이 JPA를 사용하면 개발자는 데이터베이스의 데이터를 마치 자바의 객체처럼 쉽게 다룰 수 있게 된다.

 

위의 두 가지 개념을 잘 모를 시 아래 링크를 통해 학습을 하고 읽는 걸 추천 한다.

https://taeyoungcoding.tistory.com/300

 

DBMS와 ORM

🌳🌳 데이터베이스는 효율적으로 데이터를 저장하고 검색할 수 있는 시스템이다. 데이터베이스의 주요 이점은 많은 사용자가 데이터를 안전하게 활용하고,관리 할 수 있다는 것이다. 💻💻

taeyoungcoding.tistory.com

 

하지만  JPA는 인터페이스이므로 실제 동작을 위해서는 이를 구현한 ORM 프레임워크를 추가로 선택해야 한다.

 < Hibernate란 ? >

ORM 프레임워크 중 하나인 Hibernate는 JPA 인터페이스를 구현한 구현체이자 자바용 ORM 프레임워크이다. 이는 내부적으로 JDBC API를 사용하며, Hibernate를 통해 개발자는 직접적인 SQL 쿼리문 없이도 데이터베이스와의 작업을 수행할 수 있다.

Hibernate의 가장 큰 장점은 데이터베이스의 종류에 상관없이 일관된 코드로 데이터베이스 작업을 처리할 수 있다는 점이다. 즉, MySQL, Oracle, PostgreSQL 등 어떤 데이터베이스를 사용하더라도, Hibernate를 통한 코드 작성 방식은 동일하다.

< 엔티티 매니저란? >

<엔티티>

엔티티(Entity)는 기본적으로 자바 객체이다. 하지만 이는 일반적으로 자바 객체와는 조금 특별한 성질을 가지고 있다.

바로 "데이터베이스 테이블과 매핑" 된다는 특성이다. 

<엔티티 매니저>

엔티티 매니저(entity manager)는 엔티티의 생성,수정,삭제 등의 작업을 수행한다. 이러한 엔티티 매니저는 '엔티티 매니저 팩토리(Entity Manager Factory)'에서 만들어진다. 

 

 

예를 들어, 두 명의 사용자가 동시에 회원 가입을 한다고 생각해보자. 이때 각 사용자의 회원 가입 요청에 대해 엔티티 매니저 팩토리는 독립적인 엔티티 매니저를 생성한다. 각 엔티티 매니저는 자신이 담당하는 사용자의 정보를 데이터베이스에 저장하게 된다. 이렇게 각각의 엔티티 매니저를 통해 회원 가입 처리가 완료되면, 사용자 정보는 데이터베이스에 안전하게 저장된다. 

스프링 부트에서는 직접 엔티티 매니저 팩토리를 생성,관리하지 않는다. 스프링 부트는 내부적으로 엔티티 매니저 팩토리를 하나만 생성하고 이를 공유한다. 이런 점이 바로 스프링 부트가 간편함과 효율성을 제공하는 비결 중 하나이다.

 

< Spring boot가 엔티티 매니저를 사용하는 방법 예시 >

스프링 부트에서는 @PersistenceContext 또는 @Autowired 어노테이션을 사용해서 엔티티 매니저를 사용한다.

이 Annotation을 사용하면 Spring boot가 관리하는 엔티티 매니저를 손쉽게 사용할 수 있다. 

@PersistenceContext
EntityManager em; // 프록시 엔티티 매니저. 필요할 때 진짜 엔티티 매니저 호출

여기서 중요한 점은 스프링 부트는 기본적으로 빈은 하나만 생성하여 공유한다는 점이다. 따라서 동시성 문제가 발생할 수 있다. 이 문제를 해결하기 위해 스프링 부트는 '프록시 엔티티 매니저'를 사용한다. 이는 실제 엔티티 매니저와 연결하는 가짜 엔티티 매니저로, 필요할 때 데이터베이스 트랜잭션과 관련된 실제 엔티티 매니저를 호출한다.


빈에 대해 궁금한 것은 더 보기 클릭 <

 

더보기

빈이라는 것은 Spring에서 빈은 우리가 생성한 클래스의 인스턴스를 의미한다. 이 빈은 스프링의 제어 역전(IoC,Inversion of Control)원칙에 따라 스프링 컨테이너가 관리한다. 즉, 빈의 생성과 생명주기를 스프링이 관리한다는 것이다.

 

스프링 부트는 기본적으로 빈을 하나만 생성하여 모든 클라이언트가 공유한다. 이는 싱글톤(Singleton)디자인 패턴이 적용된 것이다. 이 패턴은 애플리케이션 내에서 해당 빈의 인스턴스가 단 한 개만 존재하도록 보장한다.

 

예를 들어, UserService 라는 빈을 생성하면 스프링 부트는 이 'UserService' 빈을 하나만 생성한다. 


@Service
public class UserService {
    //...
}


그리고 이 빈을 필요로 하는 곳에서는 '@Autowired' 어노테이션을 주입받아 사용한다.


@Controller
public class UserController {
    
    @Autowired
    private UserService userService;
    
    //...
}


UserController에서 주입받은 userService는 스프링 부트가 생성된 단 하나의 UserService 빈이다. 이는 동일한 UserService 인스턴스가 애플리케이션의 모든 곳에서 공유되는 것을 의미한다.

이처럼 스프링 부트에서 빈은 기본적으로 싱글톤 스코프를 가지며, 이로 인해 메모리 사용량을 줄이고 효율성을 높일 수 있는 것이다.

 

Reference :

  1. Spring Beans and Dependency Injection 2.Spring Bean Scopes

🤔< 영속성 컨텍스트란? >🤔

영속성컨텍스는 JPA의 가장 중요한 개념 중 하나로, 단순히 이해 하자면 엔티티를 저장하고 관리하는 가상의 데이터베이스 공간이라고 볼 수 있다. 엔티티 매니저는 이 영속성 컨텍스트를 통해 엔티티를 관리하며, 데이터베이스와의 상호작용을 효과적으로 수행한다.

 

< 영속성 컨텍스트의 핵심 특징 > 

 

1차 캐시

영속성 컨텍스트는 내부에 1차 캐시라는 메모리 공간을 가지고 있다. 이 곳에는 데이터베이스에서 조회한 엔티티가 저장되면서, 이후 같은 엔티티를 조회하려 할 때 이 캐시를 먼저 확인하여 데이터베이스 접근을 줄이는 역할을 한다. 이렇게 함으로써 데이터 조회 속도를 크게 향상 시킬 수 있다.

 

쓰기 지연

쓰기 지연(transactional write-behind)는 엔티티에 대한 변경(추가,수정,삭제)이 일어났을 때, 즉시 데이터베이스에 반영하는 것이 아니라, 트랜잭션을 커밋하는 시점에 한꺼번에 반영하는 기능이다. 이를 통해 데이터베이스의 부담을 줄이면서, 성능을 향상시킬 수 있다.

 

변경 감지

영속성 컨텍스트는 트랜잭션 커밋 시점에 1차 캐시에 저장된 엔티티와 현재 엔티티의 상태를 비교한다. 이를 통해 변경된 내용이 있는지를 자동으로 감지하고, 이를 데이터베이스에 반영한다. 

 

지연 로딩 

지연 로딩(lazy loading)은 엔티티가 실제로 사용되는 시점에서 데이터베이스에서 데이터를 로딩하는 기능이다. 이를 통해 불필요한 데이터 로딩을 최소화하여 애플리케이션의 성능을 향상시킬 수 있다.

 

< 엔티티의 상태 > 

엔티티는 4가지의 상태를 가진다. 영속성 컨텍스트가 관리하고 있지 않는 분리(detached)상태, 영속성 컨텍스트가 관리하는 관리(managed)상태, 영속성 컨텍스트와 전혀 관계가 없는 비영속(transient)상태, 삭제된(removed)상태로 나뉜다.

이 상태는 특정 메서드를 호출해 변경할 수 있는데, 필요에 따라 엔터티의 상태를 조절해 데이터를 올바르게 유지하고 관리할 수 있다.

 

< 엔티티의 상태 변경 예시 코드 >

public class EntityManagerTest {

@Autowired
EntityManager em;

public void example() {
// 1. 엔티티 매니저가 엔티티를 관리하지 않는 상태(비영속 상태)
Member member = new MEmber(1L, "홍길동");

// 2. 엔티티가 관리 상태가 된다.(관리 상태)
em.persist(member);
// 3. 엔티티 객체가 분리된 상태가 된다.(분리 상태)
em.detach(member);
// 4. 엔티티 객체가 삭제된 상태가 된다.(삭제 상태)
em.remove(member);
 }
}

1.엔티티를 처음 만들면 엔티티는 비영속 상태가 된다.

2.persist() 메서드를 사용해 엔티티를 관리 상태로 만들 수 있으며, Member 객체는 영속성 컨텍스트에서 상태가 관리 된다.

3.만약 엔티티를 영속성 컨텍스트에서 관리하고 싶지 않다면 detach()메서드를 사용해 분리 상태로 만들 수 있다.

4. 또한 더 이상 객체가 필요 없다면 remove()메서드를 사용해서 엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제할 수 있다. 

 

 

 

Reference : Reference : 출처 : 스프링 부트 3 백엔드 개발자 되기 - 자바 편

http://www.yes24.com/Product/Goods/118625612

 

스프링 부트 3 백엔드 개발자 되기 - 자바 편 - YES24

- 자바 백엔드 개발자가 되고 싶다면- 자바 언어 입문 그다음에 꼭 보세요실력을 갖춘 개발자로 성장하려면 시작이 중요합니다. 그래서 이 책은 무엇부터 익혀야 하는지 막막한 입문자에게 백엔

www.yes24.com

 

+ Recent posts