[북스터디] 스프링 부트 핵심 가이드(ch6)를 공부해 보았다.(4편)ch6

Wang_Seok_Hyeon·2023년 3월 25일
0
post-thumbnail

주저리

이번 장의 주제는 데이터베이스 연동이었다.

잠깐 주저리를 하자면,
백엔드 개발자가 되기 위해서는 아래와 같은 로드맵을 따른다.

정말 많은 것들이 있는데 이중에
관계형 데이터베이스 중에 하나가 MariaDB이다.
백엔드 개발자가 되기 위해서 필수적으로 거쳐야 하는 과정인 것!

게다가 현재 스터디하고 있는 책의 경우,
API에 대해서 배우기 부분과 아래의 있는 내용을 꽤 많이 포함하는 경우기 때문에
해당 부분은 꽤 필수라고 할 수 있다.

특히 이 책은 ORM부터 시작해서 JPA, 하이버네이트, Entity의 설계, 나아가 lombok 어노테이션까지 소개하는 형태로 꼼꼼하게 정리 되어 있다 :)

관련해서 상세하게 기술하고 정리할 수 있도록 노력해 보겠다!

ORM

ORM은 Object Relational Mapping의 줄임말로 객체 관계 매핑이라고 한다.(무슨 말이지? 싶지만, 결과적으로 보면 Java(객체)랑 DB(관계)를 연결하는 '중간 과정'(매핑) 하는 걸 일반적인 용어로 써 둔 걸 말한다.
하지만 완벽하게 모든 기능을 관리할 수는 없다.(객체 <==> 관계)
(제한된 일부 기능을 활용)

먼저 장단점 부터 짚고 넘어가자.

ORM의 장점
1. ORM을 사용하면 데이터베이스 쿼리를 객체지향적으로 조작 가능
2. 재사용 및 유지보수가 편리
3. 데이터베이스에 대한 종속성이 줄어든다.

ORM의 단점
1.ORM만으로 온전한 서비스 구현 X(근데 이거 너무 당연한 거 아닌가..?)
2.애플리케이션의 객체 관점과 데이터베이스의 관계 관점의 불일치
위에 처음 개념을 상술한 것의 연장이다.
이 부분은 구체적으로 알 필요도 있지만 앞으로 나올 내용을 통해 자세하게 알아보는 쪽으로 하겠다.

자, 이제 ORM이 객체 관계 매핑 방식이라는 걸 알았으니 구체적으로 Java와 DB를 연결해 주는 ORM이 무엇인지 알 필요가 있다. 그것이 'JPA'다.

JPA

JPA(Java Persistence API)는 앞서 말했듯 Java에서 표준으로 쓰이는 ORM 방식이다.
Java언어를 활용해, DB로 자동으로 매핑해주는 어노테이션들이 존재하며 이를 활용하여, DB에 대한 부분을 좀 더 손쉽게 구현이 가능하다.

다만 계속 말해 왔듯이, 결국 객체 언어이기 때문에, 완벽하게 모든 DB 기능을 쓸 수는 없다.(서브쿼리를 활용한다던지의 기능)

그럼 JPA는 어떻게 DB와 자동으로 연결되는 걸까?
그 메커니즘은 자연스럽게 JDBC를 사용하면 된다는 걸 알 수 있다.
JPA는 이러한 JDBC를 통해 SQL 쿼리를 개발자가 직접 만드는 게 아닌,
자동으로 작동할 수 있게 해준다.

그렇다면 JDBC를 사용하는 구체적인 구현체에는 어떤 게 있는가?
여기에는 대표적인 것이 3가지가 있다고 한다.
하이버네이트(Hibernate),이클립스 링크(EclipseLink),데이터 뉴클리어스(Data Nucleus)

하지만 나도 하이버네이트는 log에서 보았고, 다른 블로그나 글들에서 접했지만 다른 것들은 해당 서적에서 처음 접했다.

즉, 하이버네이트가 가장 많이 사용되는 것이며
이에 관해 자세히 알 필요가 있는 셈이다.

하이버네이트(Hibernate)

위에 언급한 대로, 하이버네이트는
JPA가 정의하는 인터페이스 구현체 중 하나인데, 해당 서적은 더 편하게 사용할 수 있게 Hibernate 기능을 모듈화한 Spring Data JPA를 사용해
JPA 자체를 사용할 일은 거의 없다고 한다.
참고로, 여러 프로젝트를 하며, 전부 Spring Data JPA를 쓰는 기본적인 부분을 사용해 왔다. 즉, 기본은 Spring Data JPA를 활용할 수 있지만

추가로 더 많은 기능과 관련한 추가사항이 필요하다면 추후에 JPA를 뜯어 보는 것도 좋은 방향일 것이다.

서적은 Spring Data JPA의 구체적인 설명으로
Hibernate를 대신한다. 다만 이 경우, 어노테이션 부분이 추후에 설명된다.

이전에 어노테이션의 설명을 보기 전에 조금 더 ORM에 존재하는 관련한 내용들을 조금 더 깊게 알 필요가 있습니다. 관련한 내용이 조금 크지만 제가 이해한 내용으로 간단하게 정리하면 아래와 같습니다.

엔티티 매니저 팩토리로 생성된 엔티티 매니저는 엔티티를 영속성 컨텍스트에 추가해서 영속 객체로 만드는 작업을 수행하고, 영속성 컨텍스트와 데이터베이스를 비교하면서 실제 데이터베이스를 대상으로 작업을 수행

다만 여기서 엔티티 매니저 팩토리는 무엇인지 엔티티 매니저가 무엇인지 알 필요가 있습니다.

  1. 엔티티 매니저
    말 그대로 엔티티 매니저는 DB의 엔티티를 관리하는 객체를 뜻하며 DB에 접근해 CRUD 작업을 수행합니다. 실제로 SimpleJpaRepository에서 엔티티 매니저 사용을 확인할 수 있습니다.
  2. 엔티티 매니저 팩토리
    이러한 엔티티 매니저는 엔티티 매니저 팩토리에 의해서 만들어집니다.
    엔티티 매니저 팩토리란 데이터베이스에 대응하는 객체로서 스프링 부트의 자동 설정 기능으로 최소한의 설정만으로 작동할 수 있지만, JPA의 구현체 중 하나인 하이버네이트에서는 persitence.xml이라는 설정 파일을 구성하고 사용할 수 있습니다.

위의 두 가지에 관한 구체적인 설명이라기 보단 개념적이고 관계적인 설명이지만, 해당 개념들을 바탕으로 영속성 컨텍스트 즉, DB와 JAVA를 실질적으로 연결할 수 있다는 걸 개념적으로 이해하멷 됩니다.

이제 어노테이션의 전반적인 소개와 정리를 하고자 합니다. 이 부분은 별도의 큰 타이틀로 소개하는 것이 좋을 것 같습니다.

어노테이션& JPA 사용법

많은 어노테이션을 설명하고 어노테이션 안에서 사용되는 관련 메소드도 소개할 것이기에 위와 같이 가장 큰 타이틀을 붙이게 되었습니다.
그럼 먼저 엔티티 관련 기본 어노테이션입니다.

엔티티 관련 기본 어노테이션

  1. @Entity : 해당 클래스가 엔티티임을 명시해줌
  2. @Table : 엔티티 클래스랑 매핑이 되서 안 써줘도 되지만 불일치 하는 경우 Table(name = "Table이름") 으로 명시해준다.
  3. @Id : PrimaryKey로 사용할 Column의 위에 붙이는 어노테이션
  4. @GeneratedValue() : @Id와 함께 사용(PK값 설정) 아래 내용 참고
    위 어노테이션이 사용하는 명령어
  • AUTO(기본 설정값, 안 쓰면 해당 값이 됨)
  • IDENTITY(AUTO_INCRESEMENT)
  • SEQUENCE (@SequenceGenerator 식별자 생성기 설정,
    이를 통해 값 자동 주입)
  • TABLE
    - 어떤 DBMS를 쓰더라도 동일하게 동작하기 원할 때 사용(범용성)
    - 식별자로 사용할 숫자의 보관 테이블을 별도로 생성,
    엔티티 생성할 때마다 값 갱신해 사용
    - @TableDenerateor 어노테이션으로 테이블 정보를 설정
    5.@Column() -- 잘 사용하지 않지만 같이 쓰는 값 소개를 위해 기입
  • name : 데이터베이스의 칼럼명을 설정(명시하지 않으면 필드명이 지정됨)
  • nullable : 레코드 생성시, 칼럼 값이 null이 가능해짐
  • length : db 칼럼의 길이를 지정할 수 있음
  • unique: 해당 칼럼을 unique로 설정이 가능
    6.@Transient 엔티티 클래스에 선언돼 있는 값이지만 DB에서는 필요 없는 경우 사용하는 어노테이션

위와 같은 어노테이션을 사용했다면 이는 DB를 설정하게 된 것이다.
그렇다면 이제 JPA == Repository를 만들어 이를 활용할 수 있게 해주어야 한다.
이 Repository의 경우 일정한 규칙으로 만들어지며 이는 다음과 같다.

리포지토리 인터페이스 설계

아래와 같이 작성해서 개인적으로 사용할 repository를 만들 수 있다.
책에서는 Product라는 테이블을 만들었고, 이를 활용하기 위해
ProductRepositoy 를 만든다.

public interface ProductRepository extends JpaRepository<Product, Long>{}

위와 같이 인터페이스를 구현하면 된다. JpaRepository를 상속받고,
Product 엔티티가 있는 클래스를 값으로 받고(보통 Entity라고 명시하는데 책에서는 명시하지 않았다.) Id 고유번호(PK)를 뒤에 값으로 해서 생성한다.

이제 메서드를 불러오는 규칙에 대해 알 필요가 있다. 이 메서드를 불러오는 정리가 개인적으로 이 서적에서 크게 도움이 되었던 요소였다.

주요 메서드 소개 및 정리

  • findBy/getBy* : where절의 역할 뒤에 엔티티 필드값 입력해 사용

  • save* : 값의 저장 및 수정에 사용(SimpleJpaRepositoty에 존재)

  • delete* : 값의 삭제에 사용(SimpleJpaRepositoty에 존재)

  • And, Or : '조건을 추가'할 때 사용

  • Like/NotLike : like 기능, 비슷한 키워드 Containing/Contains,isContaing

  • StartWith/StartingWith : 특정 키워드로 시작하는 문자열 '조건'

  • EndsWith/EndingWith : 특정 키워드로 끝나는 문자열 '조건'

  • IsNull/IsNotNull : 기록된 값이 null이거나 null아닌 값 '검색'

  • True/False : Boolean의 해당 타입 레코드 '검색'

  • Before/After : 시간 기준으로 값 '검색'

  • LessThen/GreaterThan : 특정 값 기준으로 대소 비교에 사용

  • Between : 두 값 사이의 데이터 '조회(검색)'

  • OrderBy : 순서를 지정해 주어 검색

  • CountBy : 결과값의 개수를 반환(int)

    위의 내용을 기반으로 책에서는 DTO 를 이용해 Getter Setter를 만들고 그 예제를 소개하는데,

    중간에 필요한 개념은 스프링 부트 애플리케이션 구조라는 파트 하나여서 해당 부분만 정리하고 넘어간다.

결과적으로 lombok을 사용하기 때문에 소개하지 않고 바로 lombok으로 넘어간다.
다만 lombok의 경우도 간단하게 주요 어노테이션만 소개하겠다. 의존성 주입 등 실질적인 설정이 어렵지도 사용법이 어렵지도 않기 때문이다.

주요 lombok 어노테이션 소개

@Getter : Getter 자동 생성
@Setter : Setter 자동 생성
@ToString : ToString 자동 생성
@EqulasAndHashCode : 객체의 동등성과 동일성을 비교하는데 사용
@AllArgsConstructor : AllArgsConstructor 자동 생성
- 모든 값을 가지는 생성자를 만든다는 뜻
@RequiredArgsConstructor : RequiredArgsConstructor 자동 생성
- 적절한 값(final값)을 가지는 생성자를 만든다는 뜻
@NoArgsConstructor : AllArgsConstructor 자동 생성
- 기본 생성자를 만든다는 뜻
@Data
(
@Getter
@Setter
@ToString
@EqulasAndHashCode
@RequiredArgsConstructor
)
위의 어노테이션을 다 가진다.
하지만 실제 서비스에서는 위와 같이 여러가지 기본 기능이 제공되는게
오히려 독이 될 수 있기에 개별적으로 사용하는게 더 많다.

아래는 현재 서적에는 없지만 자주 사용한 lombok 어노테이션으로 간단하게 만 소개하겠다.
@Slf4j : log 남기는데 사용
@Builder : 생성자를 만들 때 사용되는데 .builde()'.V'.build()의 형태를 띄며 '.V'에 해당하는 부분에 값을 지정해 넣는 방식을 사용

위와 같이 정리하면, 6장의 내용을 전체적으로 정리한 셈이 된다!

이걸로 오늘의 정리는 끝!

profile
하루 하루 즐겁게

0개의 댓글