Programming/Spring Boot

스프링 데이터 - 2 (스프링 부트 활용 - 8)

흠냐아뤼 2020. 3. 12. 01:37
728x90

 

1. ORM, JPA, 스프링 데이터 JPA 개요

 

- ORM (Object - Reltional - Mapping) 와 JPA (Java Persistence API)

객체와 릴레이션을 맵핑(ORM)할 때 발생하는 개념적 불일치를 해결하는 프레임워크(JPA) 

 

- 스프링 데이터 JPA

JPA 표준 스펙을 아주 쉽게 사용할 수 있게 스프링 데이터로 추상화 시켜 놓은 것

Spring Data JPA -> JPA -> Hibernate -> DataSource

 

 

2. Spring-Data-JPA 연동

 

1) JPA, PostgreSql 의존성 추가

 

1-1) 프로퍼티에 디비 연결 설정

 

2) @Entity 클래스 만들기

getter, setter, equals, hashCode 오버라이드

@Id : 아이디로 사용

@GeneratedValue : 자동으로 값이 만들어지게 설정

@Entity
public class Account {

    @Id @GeneratedValue
    private Long id;

    private String username;

    private String password;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Account account = (Account) o;
        return Objects.equals(id, account.id) &&
                Objects.equals(username, account.username) &&
                Objects.equals(password, account.password);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, username, password);
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

 

3) Repository 인터페이스 만들기

실제 구현체를 만들고 빈으로 만드는 것은 스프링 JPA가 알아서 해줌

따라서, JDBC를 쓰는 경우는 거의 없고 JPA를 주로 사용함

쿼리를 사용해야 하는 경우에도 JPA에서 사용 가능 (@Query)

예) @Query(nativeQuery = true, value = "select * from account where username = '{0}'")

public interface AccountRepository extends JpaRepository<Account, Long> {
    Account findByUsername(String username);
    
    // 반드시 있어야 하는 경우라면 그냥 엔티티 타입을 리턴받고 없는 경우에 예외를 던집니다.
	// 그런데 있을 수도 있고 없을 수도 있는 경우에 대한 메소드라면 Optional로 받아옵니다.
}

 

4) 테스트 만들기

- H2 DB를 테스트 의존성에 추가하기

- @DataJpaTest (슬라이스 테스트) 작성

 

Repostitory와 관련된 빈들만 등록해서 테스트

통합 테스트를 한다면 느리고, 테스트용 DB가 필요하다. (그렇게 하지 않으면 테스트 코드로 인해 디비 변경될 수 있음)

따라서 슬라이싱 테스트(인 메모리 데이터베이스로 테스트)를 권장

 

@RunWith(SpringRunner.class)
@DataJpaTest()
public class AccountRepositoryTest {

    @Autowired
    DataSource dataSource;

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    AccountRepository accountRepository;

    @Test
    public void di() throws SQLException {
        Account account = new Account();
        account.setUsername("hongchan");
        account.setPassword("pass");

        Account newAccount = accountRepository.save(account);

        assertThat(newAccount).isNotNull();

        Account existingAccount = accountRepository.findByUsername(newAccount.getUsername());
        assertThat(existingAccount).isNotNull();

        Account nonExistingAccount = accountRepository.findByUsername("jiyun");
        assertThat(nonExistingAccount).isNull();
    }
}

 

 

3. 데이터베이스 초기화

 

- JPA를 사용한 데이터베이스 초기화

create, create-drop, update

주로 update를 사용함(변경된 스키마를 자동으로 생성), create-drop은 데이터가 지워지기 때문

운영 DB의 경우 vaildate를 사용하고, false를 줌 (훨씬 안정적인 옵션임)

spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true

 

- SQL 스크립트를 사용한 데이터베이스 초기화

schema.sql, data.sql 을 리소스 디렉토리에 두면 해당 sql문이 순서대로 실행됨

 

처음에 개발할 때는 update 사용

나중에 어느정도 베포할 때 쯤 되면, create로 두고 테스트 코드에서 깔끔한 스키마를 생성하도록 한 다음에,

이를 복사해서 schema.sql로 사용

update를 계속 쓰면 스키마가 굉장히 지저분해짐

ex) update로 두고 email -> emailAddr 로 컬럼을 변경하면, 컬럼을 추가할 뿐, 기존 컬럼은 남아있음

 

 

4. 데이터베이스 마이그레이션 툴

스키마 변경, 데이터 변경을 버전 관리처럼 관리할 수 있음

 

1) flyway 의존성 추가

2) 마이그레이션 디렉토리 및 파일 추가

디렉토리 경로 : db/migration

파일 이름 : V숫자__이름.sql

 

flyway가 관리하는 테이블

 

인프런 백기선님 '스프링 부트’ 강의를 듣고 정리한 내용입니다.
728x90