[스프링 부트 핵심 가이드] 정리 3주차

AmeriKano·2023년 6월 4일
0

책 링크

매주 스프링 부트 핵심 가이드 를 읽으며 이전에 궁금했거나, 새롭게 알게 된 내용들을 정리할 예정이다.
(이번 주는 6장을 읽었다.)


ORM과 JPA

ORM이란?

ORM은 Object Relational Mapping의 줄임말로, 자바와 같은 객체지향 언어에서의 객체와 RDB(Relational Database, 관계형 데이터베이스)의 테이블을 자동으로 매핑하는 방법이다.

ORM을 이용하면 쿼리문을 작성이 아닌 코드로 데이터를 조작할 수 있다.

ORM의 장점

  • 쿼리를 객체지향적으로 조작할 수 있다.
  • 쿼리문을 작성하는 양이 아주 많이 줄어든다.
  • 즉, 재사용 및 유지보수가 편리하다. (객체지향을 따르므로)
  • 데이터베이스에 대한 종속성이 줄어든다. (예를 들어, MySQL을 사용하던 데이터베이스를 MariaDB로 교체한다고 했을 때, 약간 바뀌는 모든 쿼리문을 교체할 필요도 없고 그만큼 에러가 발생할 위험도 줄어든다.)

ORM의 단점

  • 복잡한 쿼리를 요구하는 경우 코드로 구현하기 어려우며 성능 문제가 발생할 수 있다.
  • 객체의 관점과 데이터베이스의 관계의 관점에는 차이가 있어서 혼동이 발생할 수 있다.

JPA

JPA는 Java Persistence API를 의미하며, 자바의 ORM 기술 표준으로 채택된 인터페이스이다. ORM이 개념이라면 JPA는 조금 더 구체적인 명세라고 생각하면 되겠다.

JPA는 내부적으로 JDBC를 사용하는데, 개발자가 JDBC를 활용하여 구현하면 SQL에 의존하게 되어 효율이 떨어진다. JPA는 이 문제점을 보완하여 개발자 대신 요구하는 기능에 맞는 SQL을 생성하고 데이터베이스를 조작하여 객체와 데이터베이스를 이어준다. 이를 기반으로 구현한 것 중 가장 많이 사용되는 것이 하이버네이트(Hibernate) 이고, 스프링 부트에서는 이 하이버네이트의 기능을 더욱 편하게 사용하도록 구현된 Spring Data JPA를 활용할 수 있다.

엔티티

데이터베이스의 테이블에 대응하는 클래스이다. 데이터베이스의 테이블과 컬럼을 정의할 수 있으며, 어노테이션을 사용하여 다양한 관계를 정의할 수 있다.

엔티티 관련 어노테이션

  • @Entity
    해당 클래스가 엔티티임을 명시하기 위한 어노테이션이다.

  • @Table
    테이블 이름과 클래스 이름을 다르게 지정해야 할 때 사용한다. 명시하지 않으면 둘의 이름이 같다는 의미이며, 다른 이름을 쓰려면 @Table(name= 이름) 의 형태로 테이블명을 명시해야 한다.

  • @Id
    테이블의 기본 값으로 사용되며, 모든 엔티티는 이 @Id 어노테이션이 필요하다.

  • @GeneratedValue
    일반적으로 @Id 와 함께 사용되며, 어떤 방식으로 자동 생성할지를 결정한다. 흔히 데이터베이스에 위임하는 IDENTITY 를 많이 사용하며, 이 방식은 데이터베이스의 AUTO_INCREMENT 를 사용해 기본값을 생성한다.

  • @Column
    엔티티 클래스의 멤버는 자동으로 컬럼으로 매핑되지만, 몇 가지 설정이 필요한 경우 사용한다.(컬럼의 이름, 값이 null이 될 수 있는지, 데이터 길이, 유니크 컬럼 등)

레포지토리

레포지토리는 Spring Data JPA가 제공하는 인터페이스이다. JpaRepository 를 상속받는 인터페이스를 생성하여 엔티티가 생성한 데이터베이스에 접근하는 데 사용된다.

기본 예시

// 엔티티와 엔티티의 기본값(@id) 타입으로 지정
public interface PersonRepository extends JpaRepository<Person, Long> {
}

메소드 생성 규칙

기본적인 메소드는 생성이 되어있지만 규칙에 따라 커스텀 메서드도 생성할 수 있다. 이를 통해 CRUD(Create, Read, Update, Delete)를 모두 구현 가능하다.

  • findBy: 일치하는 값을 가지는 컬럼을 조회한다. SQL의 where의 역할을 한다.
  • StartsWith/StartingWith - EndsWith/EndingWith : 특정 키워드로 시작하거나 끝나는 조건을 설정한다.
  • Before/After: 시간을 기준으로 검색한다.
  • Between: 두 값 사이의 데이터를 검색한다.

컨트롤러와 서비스

컨트롤러 클래스에 API를 구현하고, 여기에서 어떠한 요청을 받으면 데이터베이스는 서비스 클래스에서 핵심 기능을 제공한다. 데이터베이스와 밀접한 관련이 있는 객체는 엔티티 또는 DAO(Data Access Object)를 사용하고, 클라이언트와 가까워지는 서비스 등의 레이어에서는 데이터를 주고받을 때 DTO(Data Transfer Object) 객체 를 사용하는 것이 일반적이다.

JPA 에서 값을 변경할 때

조회, 추가, 삭제 의 메소드와는 다른 점이 있다. update 라는 키워드를 따로 사용하지 않으며, 값을 find() 를 통해 가져오면 객체가 영속성 컨텍스트에 추가된다. 컨텍스트가 유지되는 상황에서 코드에서 객체의 값을 변경하고 다시 save() 를 실행하면 변경 감지를 수행하여 값을 변경해준다.

profile
똑똑한 사람이 되게 해주세요

0개의 댓글