본문 바로가기

SPRING/Spring 활용

[스프링부트| 스프링부트와 JPA 활용 1 | 웹 애플리케이션 개발 | 회원 도메인 개발] 회원 리포지토리 개발

  • 회원 기능
    -회원 등록
    -회원 조회
  • 상품 기능
    -상품 등록
    -상품 수정
    -상품 조회
  • 주문 기능
    -상품 주문
    -주문 내역 조회
    -주문 취소

개발 순서: 서비스, 리포지토리 계층을 개발하고, 테스트 케이스를 작성해서 검증, 마지막에 웹 계층 적용

@Repository // 스프링 컨테이너에 이 클래스가 데이터 리포지토리 역할을 한다고 표시
public class MemberRepository {

    @PersistenceContext // JPA 엔티티 매니저를 자동으로 주입받기 위한 어노테이션
    private EntityManager em; // 엔티티 매니저 객체 선언, 데이터베이스 조작을 담당

    public void save(Member member) {
        em.persist(member); // 멤버 객체를 데이터베이스에 저장
    }

    public Member findOne(Long id) {
        return em.find(Member.class, id); // id를 기반으로 한 멤버 객체를 데이터베이스에서 조회
    }

    public List<Member> findAll() {
        return em.createQuery("select m from Member m", Member.class)
                .getResultList(); // 모든 멤버 객체를 조회하여 리스트로 반환
    }

    public List<Member> fingByName(String name) {
        return em.createQuery("select m from Member m where m.name = :name", Member.class)
                .setParameter("name", name)
                .getResultList(); // 이름을 기준으로 멤버 객체를 조회하여 리스트로 반환
    }
}

@PersistenceContext

@PersistenceContext 어노테이션은 Java Persistence API(JPA)의 일부로, 애플리케이션에서 엔티티 매니저(EntityManager)를 자동으로 주입받기 위해 사용됩니다. 엔티티 매니저는 JPA를 통해 데이터베이스와의 상호작용을 관리하며, 엔티티들의 생명주기를 관리하는 주요 인터페이스입니다.

주요 특징 및 사용법

  1. 자동 주입: @PersistenceContext를 사용하면 스프링 프레임워크가 실행 중인 영속성 컨텍스트에서 EntityManager 인스턴스를 자동으로 찾아 해당 필드나 메소드에 주입합니다. 이 과정은 개발자가 직접 EntityManagerFactory를 사용하여 EntityManager를 생성하고 관리할 필요가 없게 해 줍니다.
  2. 연관된 EntityManagerFactory: @PersistenceContext는 특정 EntityManagerFactory에 연결될 수 있습니다. 만약 애플리케이션에서 여러 데이터베이스 또는 영속성 유닛을 사용하는 경우, unitName 속성을 통해 특정 영속성 유닛을 지정할 수 있습니다.
  3. 컨테이너 관리 트랜잭션: EntityManager는 일반적으로 컨테이너(예: 스프링 컨테이너)에 의해 관리되는 트랜잭션과 연동됩니다. 이는 EntityManager가 현재 진행 중인 트랜잭션과 자동으로 연결되어, 트랜잭션이 커밋되거나 롤백될 때 데이터베이스와의 동기화를 자동으로 처리한다는 것을 의미합니다.
  4. 프록시 및 실제 사용: 스프링은 @PersistenceContext를 통해 주입된 EntityManager를 프록시 객체로 제공합니다. 이 프록시는 실제 EntityManager의 메소드 호출을 처리하기 전에 필요한 초기화와 트랜잭션 관련 작업을 수행합니다.

persist()

em.persist(member);에서 persist 메소드는 Java Persistence API (JPA)에서 사용되는 메소드로, 주어진 엔티티 객체를 영속성 컨텍스트에 관리되도록 하는 역할을 합니다. 여기서 '영속성 컨텍스트'란 엔티티를 영구 저장하는 환경을 말하며, JPA의 핵심 구성 요소 중 하나입니다.

persist 메소드의 주요 기능

  1. 엔티티의 영속화: persist 메소드는 새로 생성된 엔티티 객체를 영속성 컨텍스트에 추가합니다. 이 객체는 이후 엔티티 매니저(EntityManager)에 의해 관리되며, 영속성 컨텍스트의 일부가 됩니다.
  2. 데이터베이스에 저장: 영속 상태가 된 엔티티는 트랜잭션이 커밋되는 시점에 데이터베이스에 저장됩니다. persist를 호출하는 순간 데이터베이스에 즉시 반영되지 않고, 트랜잭션의 일부로서 관리되어, 트랜잭션이 성공적으로 완료되면 함께 데이터베이스에 반영됩니다.
  3. 엔티티 식별자: JPA가 엔티티를 영속화할 때, 엔티티에 정의된 식별자(주로 @Id 어노테이션으로 표시된 필드)가 중요한 역할을 합니다. 만약 엔티티의 식별자가 자동 생성되는 경우(@GeneratedValue 등), persist 호출 시점에 식별자가 생성될 수 있습니다.
  4. 영속성 컨텍스트와의 일치: persist 메소드를 사용하면 해당 엔티티는 영속성 컨텍스트 내에서 "영속 상태"가 되며, 이 상태의 엔티티는 JPA가 관리하는 생명주기를 갖게 됩니다. 이로 인해 엔티티의 변경 사항이 자동으로 추적되고, 데이터베이스와의 동기화가 이루어집니다.

findByName(String name)

findByName(String name) 메서드는 주어진 이름에 해당하는 모든 Member 엔티티를 데이터베이스에서 검색하여 리스트로 반환하는 기능을 합니다. 이 메서드는 Java Persistence API (JPA)의 기능을 활용하여 JPQL(JPA Query Language) 쿼리를 실행합니다.

  • 쿼리 생성: EntityManager의 createQuery 메소드를 사용하여 JPQL 쿼리를 생성합니다. 이 쿼리는 Member 엔티티에서 name 필드가 주어진 파라미터 name과 일치하는 모든 엔티티를 선택합니다.
  • 파라미터 설정: setParameter 메소드를 통해 쿼리의 :name 파라미터에 실제 검색할 이름 값을 바인딩합니다. 이 방법은 쿼리를 안전하게 실행하도록 하며 SQL 인젝션 공격을 방지합니다.
  • 결과 반환: getResultList 메소드는 쿼리의 결과로 얻어진 Member 객체들의 리스트를 반환합니다. 이 메소드는 일치하는 결과가 없을 경우 빈 리스트를 반환하고, 예외를 발생시키지 않습니다.

JPQL (Java Persistence Query Language) 설명

JPQL은 데이터베이스 테이블이 아닌 엔티티 객체 모델을 대상으로 쿼리를 작성하는 객체 지향 쿼리 언어입니다. SQL과 유사하지만, 테이블, 컬럼, 조인 대신 엔티티, 속성, 관계를 사용하여 쿼리를 구성합니다.

  • 객체 지향 쿼리: JPQL은 엔티티 클래스와 그 필드를 사용하여 쿼리를 작성합니다. 예를 들어, 데이터베이스의 members 테이블 대신 Member 엔티티를 사용합니다.
  • 데이터베이스 중립성: JPQL 쿼리는 특정 데이터베이스 SQL 문법에 의존하지 않으므로, 다양한 데이터베이스 제품에서 동일하게 작동합니다. 이는 애플리케이션의 이식성을 향상시킵니다.
  • 통합 및 성능 최적화: JPA 구현체는 JPQL을 분석하여 최적의 SQL 쿼리로 변환하고 실행합니다. 이 과정에서 쿼리 플랜 최적화, 캐싱 등 다양한 성능 최적화 기법이 적용될 수 있습니다.