Post

Spring 스프링 DB 2편 - 데이터 접근 활용 기술 - 1. 데이터 접근 기술 - 시작

1. 데이터 접근 기술 - 시작


데이터 접근 기술 진행 방식 소개

적용 데이터 접근 기술

  • JdbcTemplate
  • MyBatis
  • JPA, Hibernate
  • 스프링 데이터 JPA
  • Querydsl

여기에는 크게 2가지 분류가 있다.

SQLMapper

  • JdbcTemplate
  • MyBatis

ORM 관련 기술

  • JPA, Hibernate
  • 스프링 데이터 JPA
  • Querydsl

SQL Mapper 주요기능

  • 개발자는 SQL만 작성하면 해당 SQL의 결과를 객체로 편리하게 매핑해준다.
  • JDBC를 직접 사용할 때 발생하는 여러가지 중복을 제거해주고, 기타 개발자에게 여러가지 편리한 기능을 제공한다.

ORM 주요 기능

  • JdbcTemplate이나 MyBatis 같은 SQL 매퍼 기술은 SQL을 개발자가 직접 작성해야 하지만, JPA를 사용하면 기본적인 SQL은 JPA가 대신 작성하고 처리해준다. 개발자는 저장하고 싶은 객체를 마치 자바 컬렉션에 저장하고 조회하듯이 사용하면 ORM 기술이 데이터베이스에 해당 객체를 저장하고 조회해준다.
  • JPA는 자바 진영의 ORM 표준이고, Hibernate(하이버네이트)는 JPA에서 가장 많이 사용하는 구현체이다. 자바에서 ORM을 사용할 때는 JPA 인터페이스를 사용하고, 그 구현체로 하이버네이트를 사용한다고 생각하면 된다.
  • 스프링 데이터 JPA, Querydsl은 JPA를 더 편리하게 사용할 수 있게 도와주는 프로젝트이다.

DTO(data transfer object)

  • 데이터 전송 객체
  • DTO는 기능은 없고 데이터를 전달만 하는 용도로 사용되는 객체를 뜻한다.
    • 참고로 DTO에 기능이 있으면 안되는가? 그것은 아니다. 객체의 주 목적이 데이터를 전송하는 것이라면 DTO라 할 수 있다.
  • 객체 이름에 DTO를 꼭 붙여야 하는 것은 아니다. 대신 붙여두면 용도를 알 수 있다는 장점은 있다.
1
2
3
4
5
6
7
8
9
/**
* 확인용 초기 데이터 추가
*/
@EventListener(ApplicationReadyEvent.class)
public void initData() {
    log.info("test data init");
    itemRepository.save(new Item("itemA", 10000, 10));
    itemRepository.save(new Item("itemB", 20000, 20));
}
  • @EventListener(ApplicationReadyEvent.class) : 스프링 컨테이너가 완전히 초기화를 다 끝내고, 실행 준비가 되었을 때 발생하는 이벤트이다. 스프링이 이 시점에 해당 애노테이션이 붙은 initData() 메서드를 호출해준다.
    • 참고로 이 기능 대신 @PostConstruct 를 사용할 경우 AOP 같은 부분이 아직 다 처리되지 않은 시점에 호출될 수 있기 때문에, 간혹 문제가 발생할 수 있다. 예를 들어서 @Transactional 과 관련된 AOP가 적용되지 않은 상태로 호출될 수 있다.
    • @EventListener(ApplicationReadyEvent.class) 는 AOP를 포함한 스프링 컨테이너가 완전히 초기화 된 이후에 호출되기 때문에 이런 문제가 발생하지 않는다.

프로필

  • 스프링은 로딩 시점에 application.propertiesspring.profiles.active 속성을 읽어서 프로필로 사용한다.
  • 이 프로필은 로컬(나의 PC), 운영 환경, 테스트 실행 등등 다양한 환경에 따라서 다른 설정을 할 때 사용하는 정보이다.
  • 예를 들어서 로컬PC에서는 로컬 PC에 설치된 데이터베이스에 접근해야 하고, 운영 환경에서는 운영데이터베이스에 접근해야 한다면 서로 설정 정보가 달라야 한다. 심지어 환경에 따라서 다른 스프링 빈을 등록해야 할 수 도 있다. 프로필을 사용하면 이런 문제를 깔끔하게 해결할 수 있다.

데이터베이스 테이블 생성

1
2
3
4
5
6
7
8
9
drop table if exists item CASCADE;
create table item
(
    id bigint generated by default as identity,
    item_name varchar(10),
    price integer,
    quantity integer,
    primary key (id)
);
  • generated by default as identity
    • identity 전략이고 하는데, 기본 키 생성을 데이터베이스에 위임하는 방법이다. MySQL의 Auto Increment와 같은 방법이다.
    • 여기서 PK로 사용되는 id 는 개발자가 직접 지정하는 것이 아니라 비워두고 저장하면 된다. 그러면 데이터베이스가 순서대로 증가하는 값을 사용해서 넣어준다.

참고 - 권장하는 식별자 선택 전략

  • 데이터베이스 기본 키는 다음 3가지 조건을 모두 만족해야 한다.
    1. null 값은 허용하지 않는다.
    2. 유일해야 한다.
    3. 변해선 안 된다.
  • 테이블의 기본 키를 선택하는 전략은 크게 2가지가 있다.
    • 자연 키(natural key)
      • 비즈니스에 의미가 있는 키
      • 예: 주민등록번호, 이메일, 전화번호
    • 대리 키(surrogate key)
      • 비즈니스와 관련 없는 임의로 만들어진 키, 대체 키로도 불린다.
      • 예: 오라클 시퀀스, auto_increment, identity, 키생성 테이블 사용

자연 키보다는 대리 키를 권장한다

  • 자연 키와 대리 키는 일장 일단이 있지만 될 수 있으면 대리 키의 사용을 권장한다. 예를 들어 자연 키인 전화번호를 기본 키로 선택한다면 그 번호가 유일할 수는 있지만, 전화번호가 없을 수도 있고 전화번호가 변경될 수도 있다. 따라서 기본 키로 적당하지 않다. 문제는 주민등록번호처럼 그럴듯하게 보이는 값이다.
  • 이 값은 null 이 아니고 유일하며 변하지 않는다는 3가지 조건을 모두 만족하는 것 같다. 하지만 현실과 비즈니스 규칙은 생각보다 쉽게 변한다. 주민등록번호 조차도 여러 가지 이유로 변경될 수 있다.

References: 김영한 - [스프링 DB 2편 - 데이터 접근 활용 기술]
This post is licensed under CC BY 4.0 by the author.