🤍 전 강의 25% 할인 중 🤍

2024년 상반기를 돌아보고 하반기에도 함께 성장해요!
인프런이 준비한 25% 할인 받으러 가기 >>

[인프런 워밍업 클럽 Study] 백엔드 3주차 발자국

[인프런 워밍업 클럽 Study] 백엔드 3주차 발자국


학습 내용 요약

 

<SQL을 직접 작성하는 것에 대한 문제점>

  1. 실수할 여지가 많으며, 실수 시 인지하는 시점이 느리다

    • SQL 작성 시 오타가 발생할 경우 IDE에서 자체적으로 확인해주는 것이 아니라면 보통은 런타임 에러로 처리가 되어서 실제로 서버가 가동될 때 에러가 발생하여 문제가 더 커질 가능성이 있음.

  2. 특정 데이터베이스에 종속적이게 된다.

    • 데이터베이스마다 SQL 문법이 조금씩 다르기 때문에 데이터베이스를 바꾸게 되면 이미 작성한 SQL문도 잘못된 부분이 있으면 하나하나 다 바꿔줘야 함.

  3. 반복작업이 많아진다.

    • 테이블을 하나 만들 때마다 기본적인 INSERT / SELECT / UPDATE / DELETE 쿼리는 필요하며, SELECT 쿼리를 할 때마다 필드 하나하나를 매핑해주는 것이 번거롭다.

  4. 데이터베이스와 객체는 패러다임이 다르다.

    • 대표적으로 연관관계와 상속에서 이러한 차이점이 두드러진다.

     

<JPA의 정의>

  • ORM (Object-Relational Mapping) : 관계형 데이터베이스와 객체 지향 프로그래밍 언어 간의 호환되지 않는 데이터를 자동으로 매핑(연결)해주는 프로그래밍 기법

  • JPA : 객체와 관계형 데이터베이스의 테이블을 짝지어 데이터를 영구적으로 저장할 수 있도록 정해진 Java 진영의 규칙

  • Hibernate : JPA를 구현한 구현체.

 

<JPA 어노테이션>

  • @Entity : 특정 객체에 붙여, 해당 객체를 DB 테이블로 인식하게 해주는 어노테이션.

  • @Id : 객체 필드에 붙여 그 객체 필드를 primary key로 간주하게 하는 어노테이션.

  • @GeneratedValue : 기본키의 생성 전략을 정의하기 위한 어노테이션.

    • 생성 전략으로는 Table, Sequence, Identity, Auto가 있으며, 기본값은 Auto임.

  • @Column : 객체 필드를 테이블 컬럼에 매핑하는 어노테이션.

    • nullable : null 값의 허용 여부를 설정

    • unique : 유일성 조건 여부를 설정

    • length : 문자 길이 제약조건을 설정

     

<application.yml>

  • spring.jpa.hibernate.ddl-auto

    • 스프링이 시작할 때 DB에 있는 테이블을 어떻게 처리할지에 대한 옵션

    • create : 기존 테이블이 있다면 삭제 후 다시 생성

    • create-drop : 스프링이 종료될 때 테이블을 삭제

    • update : 객체와 테이블이 다른 부분만 변경

    • validate : 객체와 테이블이 동일한지 확인

    • none : 별다른 조치를 하지 않음

  • spring.jpa.properties.hibernate.show_sql

    • JPA를 사용해 DB에 SQL을 날릴 때 SQL 쿼리문을 보여주는 것에 대한 설정

  • spring.jpa.properties.hibernate.format_sql

    • JPA를 사용해 DB에 SQL을 날릴 때 SQL을 예쁘게 포맷팅하는 것에 대한 설정

  • spring.jpa.properties.hibernate.dialect

    • 데이터베이스의 종류를 설정해주기 위한 방언 설정

     

<자동으로 쿼리문 날리기>

Repository

public interface UserRepository extends JpaRepository<User, Long> {
}
  • Repository에서 JpaRepository를 상속받도록 설정하고, 테이블의 매핑 객체인 User 와 유저 테이블의 id인 Long 타입을 각각 적어주어야 한다.

 

간단하게 사용할 수 있는 JPA 명령어

  • userRepository.XXX()

    • save : 주어진 객체를 저장하거나 업데이트 한다.

    • findAll : 주어지는 객체가 매핑된 테이블의 모든 데이터를 가져온다.

    • __By__ : id를 기준으로 특정한 1개의 데이터를 가져온다. By 앞과 뒤에 어떤 단어가 들어가는지에 따라 쿼리를 마음껏 만들어낼 수 있다

      • By 앞에는 find, findAll, exists, count 등이 들어갈 수 있다.

      • By 뒤에는 필드 이름이 들어가며, and나 or 로 조합될 수 있다.

      • ex) findAllByNameAndAge = select * from user name = ? and age = ?

      • ex) findAllByNameOrAge = select * from user name = ? or age = ?

    • 동등 조건 외에 다양한 조건을 활용할 수도 있다.

      • GreaterThan, GreaterThanEqual, LessThan, LessThanEqual, Between, StartsWith , EndsWith 등…

     

<트랜잭션과 영속성 컨텍스트>

  • 트랜잭션 : 쪼갤 수 없는 업무의 최소 단위

    • commit : 트랜잭션 시작 후 실행된 SQL 명령을 DB에 반영

    • rollback : 트랜잭션 시작 후 실행된 SQL 명령을 반영하지 않고 취소

  • 대상 메소드에 @Transactional 어노테이션을 붙여 트랜잭션을 적용할 수 있다.

  • 트랜잭션 실행 로직은 다음과 같다.

    1. 서비스 메소드가 시작할 때 트랜잭션과 영속성 컨텍스트가 시작돈다.

    2. 서비스 메소드 로직이 모두 정상적으로 성공하면 commit 된다.

    3. 서비스 메소드 로직 실행 도중 문제가 생기면 rollback 된다.

    4. 트랜잭션이 종료될 때 영속성 컨텍스트도 종료된다.

  • 영속성 컨텍스트의 특징

    • 변경 감지 (Dirty Check) : 영속성 컨텍스트 안에서 불러온 Entity는 명시적으로 save 를 해주지 않더라도 알아서 변경을 감지하여 저장된다.

    • 쓰기 지연 : 여러 SQL 문을 실행시켜도 이 쿼리문들을 모아 commit 되는 시점에 한번에 DB에 적용시켜준다.

    • 1차 캐싱 : ID를 기준으로 Entity를 기억하는 기능으로, SELECT 문을 사용하여 특정 엔티티를 불러올 경우 쿼리문이 한 번만 발생하며, 이후 같은 엔티티를 불러올 경우 영속성 컨텍스에 저장된 엔티티를 불러오게 된다.

     


회고

저번 주에 클린 코드에 대한 강의를 듣고 이번 주에 과제를 진행하면서 클린 코드를 적용해보기로 했지만 생각보다 쉽지 않아 아쉬웠던 것 같습니다. 이번 주 금요일에 진행했었던 QNA 코드리뷰 시간에서는 throw new를 적용할 때 발생하는 동시성 이슈, N+1 문제, @Transactional 어노테이션의 readonly 옵션, enum 클래스의 활용, ApiUrlConstants로 API 주소를 관리하는 기법 등이 기억에 남았습니다. 이제 마지막으로 최종 과제만 남았는데, 남은 시간동안 테스트 코드를 이용하여 최종 과제를 해결하는 것은 어려워도 지금까지 배운 클린 코드에 대한 지식으로 최대한 깔끔한 코드를 작성해보도록 노력할 것입니다.

 


댓글을 작성해보세요.

채널톡 아이콘