WY J
학습 공간
WY J
  • 분류 전체보기 (95)
    • Java (38)
      • 알고리즘 (5)
      • 자료구조 (4)
      • 기초 (9)
      • OOP (10)
      • Collection (3)
      • Effective (5)
      • reator (2)
    • HTML&CSS (5)
    • macOS (3)
    • Git (5)
    • Network (5)
    • MySQL (2)
    • Spring Boot (31)
      • Core (5)
      • MVC (15)
      • Security (10)
    • 알고리즘 (1)
    • Cloud (3)
      • AWS (3)
    • Docker (1)
    • Project (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

최근 글

hELLO · Designed By 정상우.
WY J

학습 공간

Spring Boot/MVC

[Spring MVC] Spring Data JPA 데이터 액세스 계층 구현

2022. 9. 3. 10:48

Spring Data JPA란?

Spring Data JDBC와 Spring Data JPA는 Spring Data라는 패밀리 그룹에 포함되어 있다.

Spring Data라는 추상화 된 데이터 액세스 접근 방식으로 구성이 되어 있기 때문에 Spring Data JDBC와 Spring Data JPA라는 기술은 사용하는 방식이 거의 유사하다.

 

JPA vs Hibernate ORM vs Spring Data JPA 용어 정리

JPA(Jakarta Persistence API)

  • 엔터프라이즈 Java 애플리케이션에서 관계형 데이터베이스를 사용하기 위해 정해놓은 표준 스펙이다.

Hibernate ORM

  • JPA라는 표준 스펙을 구현한 구현체이다. 실제 사용하는 API라고 볼 수 있다.

Spring Data JPA

  • JPA 스펙을 구현한 구현체의 API(Hibernate ORM)을 더 쉽게 사용할 수 있도록 해주는 모듈이다.

 

JDBC와 비교 코드

Entity 클래스 정의

Spring Data JDBC에서 사용한 애너테이션을 제거하고 JPA에 맞는 애너테이션을 새로 추가해야 한다.

@NoArgsConstructor
@Getter
@Setter
@Entity
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long memberId;

    @Column(nullable = false, updatable = false, unique = true)
    private String email;

    @Column(length = 100, nullable = false)
    private String name;

    @Column(length = 13, nullable = false, unique = true)
    private String phone;

    // (1) 추가된 부분
    @Enumerated(value = EnumType.STRING)
    @Column(length = 20, nullable = false)
    private MemberStatus memberStatus = MemberStatus.MEMBER_ACTIVE;

    @Column(nullable = false)
    private LocalDateTime createdAt = LocalDateTime.now();

    @Column(nullable = false, name = "LAST_MODIFIED_AT")
    private LocalDateTime modifiedAt = LocalDateTime.now();

    @OneToMany(mappedBy = "member")
    private List<Order> orders = new ArrayList<>();

    public Member(String email) {
        this.email = email;
    }

    public Member(String email, String name, String phone) {
        this.email = email;
        this.name = name;
        this.phone = phone;
    }

    public void addOrder(Order order) {
        orders.add(order);
    }

    // (2) 추가 된 부분
    public enum MemberStatus {
        MEMBER_ACTIVE("활동중"),
        MEMBER_SLEEP("휴면 상태"),
        MEMBER_QUIT("탈퇴 상태");

        @Getter
        private String status;

        MemberStatus(String status) {
           this.status = status;
        }
    }
}

 

Repository 인터페이스 구현

CrudRepository를 상속하는 대신 JpaRepository를 상속해야 한다.

CrudRepository를 상속해도 되지만, JpaRepository가 JPA에 특화된 더 많은 기능들을 포함하고 있다.

public interface CoffeeRepository extends JpaRepository<Coffee, Long> { // Jpa 상속
    Optional<Coffee> findByCoffeeCode(String coffeeCode);

//    @Query 수정
//    @Query(value = "FROM Coffee c WHERE c.coffeeId = :coffeeId")  // (1)
//    @Query(value = "SELECT * FROM COFFEE WHERE coffee_Id = :coffeeId", nativeQuery = true) // (2)	
	@Query(value = "SELECT c FROM Coffee c WHERE c.coffeeId = :coffeeId")  // (3)
    Optional<Coffee> findByCoffee(long coffeeId);
}

JPQL을 통한 객체 지향 쿼리 사용

  • JPA에서는 JPQL이라는 객체 지향 쿼리를 통해 데이터베이스 테이블을 조회할 수 있다.
  • JPQL은 데이터베이스 테이블을 대상으로 조회하는 것이 아닌, Entity 클래스의 객체를 대상으로 객체를 조회하는 방법이다.
  • JPQL 문법을 사용하여 객체를 조회하면 JPA가 내부적으로 JPQL을 분석하여 SQL을 만든 후, 데이터베이스를 조회하고 결과를 Entity 객체로 매핑한 뒤 반환한다.
  • (3) JPQL은 객체를 대상으로 한 조회이기 때문에 Coffee 클래스의 coffeeId 필드를 지정하였다. c는 Coffee 클래스의 별칭이며 모든 필드를 조회한다.
  • (1)과 같이 SELECT c를 생략한 형태로 사용 가능하다.
  • (2)와 같이 nativeQuery 애트리뷰트 값을 true로 지정하면 SQL 쿼리가 적용된다.

 

Service 클래스 구현

Spring Data JDBC에서 Spring Data JPA으로 바뀌었다고 해도 Service 클래스의 코드는 크게 변경되지 않았다.

@Service
public class MemberService {
    private final MemberRepository memberRepository;

    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    public Member createMember(Member member) {
        verifyExistsEmail(member.getEmail());

        return memberRepository.save(member);
    }

    public Member updateMember(Member member) {
        Member findMember = findVerifiedMember(member.getMemberId());

        Optional.ofNullable(member.getName())
                .ifPresent(name -> findMember.setName(name));
        Optional.ofNullable(member.getPhone())
                .ifPresent(phone -> findMember.setPhone(phone));
        // 멤버 상태 업데이트
        Optional.ofNullable(member.getMemberStatus())
                .ifPresent(memberStatus -> findMember.setMemberStatus(memberStatus));

        // 수정 시간 업데이트
        findMember.setModifiedAt(LocalDateTime.now());

        return memberRepository.save(findMember);
    }

    public Member findMember(long memberId) {
        return findVerifiedMember(memberId);
    }

    public Page<Member> findMembers(int page, int size) {
        return memberRepository.findAll(PageRequest.of(page, size,
                Sort.by("memberId").descending()));
    }

    public void deleteMember(long memberId) {
        Member findMember = findVerifiedMember(memberId);

        memberRepository.delete(findMember);
    }

    public Member findVerifiedMember(long memberId) {
        Optional<Member> optionalMember =
                memberRepository.findById(memberId);
        Member findMember =
                optionalMember.orElseThrow(() ->
                        new BusinessLogicException(ExceptionCode.MEMBER_NOT_FOUND));
        return findMember;
    }

    private void verifyExistsEmail(String email) {
        Optional<Member> member = memberRepository.findByEmail(email);
        if (member.isPresent())
            throw new BusinessLogicException(ExceptionCode.MEMBER_EXISTS);
    }
}

 

'Spring Boot > MVC' 카테고리의 다른 글

[Spring MVC] 테스팅(Testing)  (0) 2022.09.08
[Spring MVC] 트랜잭션(Transaction)  (0) 2022.09.06
[Spring MVC] JPA Entity 매핑과 연관 관계 매핑  (0) 2022.09.01
[Spring MVC] JPA(Java Persistence API) 개요  (0) 2022.08.31
[Spring MVC] JDBC 기반 DB 계층  (0) 2022.08.29
    'Spring Boot/MVC' 카테고리의 다른 글
    • [Spring MVC] 테스팅(Testing)
    • [Spring MVC] 트랜잭션(Transaction)
    • [Spring MVC] JPA Entity 매핑과 연관 관계 매핑
    • [Spring MVC] JPA(Java Persistence API) 개요
    WY J
    WY J

    티스토리툴바