본문 바로가기
Spring/DB 2편

데이터 접근 기술 - 시작

by JHyun0302 2023. 8. 10.
728x90

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를 더 편리하게 사용할 수 있게 도와주는 프로젝트이다.

 

 

 

 


프로젝트 구조

 

TestDataInit

@Slf4j
@RequiredArgsConstructor
public class TestDataInit {
    private final ItemRepository itemRepository;
    
    /**
    * 확인용 초기 데이터 추가
    */
    @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) : 스프링 컨테이너가 완전히 초기화를 다 끝내고,  실행 준비가 되었을 때 발생

 

  • @PostConstruct 를 사용할 경우 AOP 같은 부분이 아직 다 처리되지 않은 시점에 호출될 수 있어 간혹 문제가 발생
        ex) @Transactional 과 관련된 AOP가 적용되지 않은 상태로 호출될 수 있다.
  • @EventListener(ApplicationReadyEvent.class) 는 AOP를 포함한 스프링 컨테이너가 완전히 초기화 된 이후에 호출

 

 

ItemServiceApplication

@Import(MemoryConfig.class)
@SpringBootApplication(scanBasePackages = "hello.itemservice.web")
public class ItemServiceApplication {

    public static void main(String[] args) {
    	SpringApplication.run(ItemServiceApplication.class, args);
    }
    
    @Bean
    @Profile("local")
    public TestDataInit testDataInit(ItemRepository itemRepository) {
    	return new TestDataInit(itemRepository);
    }
}

 

  • @Import(MemoryConfig.class) : 앞서 설정한 MemoryConfig 를 설정 파일로 사용
  • scanBasePackages = "hello.itemservice.web" : 컴포넌트 스캔 경로 → hello.itemservice.web 하위로 지정했다.
  • @Profile("local") : 특정 프로필의 경우에만 해당 스프링 빈을 등록한다. 

 

 

프로필(@profile)

  • 스프링은 로딩 시점에 application.properties 의 spring.profiles.active 속성을 읽어서 프로필로 사용한다.
        ex) 로컬PC에서는 로컬 PC에 설치된 데이터베이스에 접근해야 하고,
              운영 환경에서는 운영 데이터베이스에 접근해야 한다면 서로 설정 정보가 달라야 한다.
              환경에 따라서 다른 스프링 빈을 등록해야 할 수 도 있다. 

 

// src/main/resources/application.properties
spring.profiles.active=local

// src/test/resources/application.properties
spring.profiles.active=test

 

 

 

참고

프로필에 대한 스프링 부트 공식 메뉴얼
https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.profiles

 

 

 

 

 

 


프로젝트 구조 - 테스트

 

 

 

@AfterEach
void afterEach() {
    //MemoryItemRepository 의 경우 제한적으로 사용
    if (itemRepository instanceof MemoryItemRepository) {
    	((MemoryItemRepository) itemRepository).clearStore();
    }
}

 

@AfterEach

  • 테스트는 서로 영향을 주면 안된다. 따라서 각각의 테스트가 끝나고 나면 저장한 데이터를 제거해야 한다.
  • @AfterEach 는 각각의 테스트의 실행이 끝나는 시점에 호출된다.

 

 

 

 

 

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

  1. null 값은 허용하지 않는다.
  2. 유일해야 한다.
  3. 변해선안된다.

 

테이블의 기본 키를 선택하는 전략

  • 자연 키(natural key) : 비즈니스에 의미가 있는 키
        ex) 주민등록번호, 이메일, 전화번호
  • 대리 키(surrogate key) : 비즈니스와 관련 없는 임의로 만들어진 키, 대체 키로도 불린다.
        ex) 오라클 시퀀스, auto_increment, identity, 키생성

 

 

 

자연키 보다 대리키 선택!!

 

 

반응형