부트 개념과 활용-25.스프링 데이터 JPA(스프링 데이터)
스프링 데이터 5부: 스프링 데이터 JPA 소개
ORM(Object-Relational Mapping)과 JPA(Java Persistence API)
ORM(Object-Relational Mapping)
- 객체와 릴레이션을 맵핑할 때 발생하는 개념적 불일치를 해결하는(솔루션을 제공하는) 프레임워크
객체지향에서는 클래스, 여러가지 프로퍼티 등..
테이블은 테이블과 칼럼이 전부. 테이블은 상속도 없다.
객체는 크기가 다양하고, 클래스간의 상속 등..
이런 복잡한 객체관계를 테이블로 어떻게 풀 수 있을까? - http://hibernate.org/orm/what-is-an-orm/
JPA (Java Persistence API)
- ORM을 위한 자바 (EE) 표준 (대부분의 스펙이 하이버네이트를 기준)
스프링 데이터 JPA
- JPA를 아주 사용하기 쉽게 추상화
- Repository 빈 자동 생성
- 쿼리 메소드 자동 구현
- @EnableJpaRepositories (스프링 부트가 자동으로 설정 해줌.)
- SDJ -> JPA -> Hibernate -> Datasource
스프링 데이터 6부: 스프링 데이터 JPA 연동
- 스프링 데이터 JPA 의존성 추가
- @Entity 클래스 만들기
- Repository 만들기
- 스프링 데이터 리파지토리 테스트 만들기
- H2 DB를 테스트 의존성에 추가하기
- @DataJpaTest (슬라이스 테스트) 작성
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
@Entity
public class Account {
@Id @GeneratedValue // 자동으로 생성되는 값, 리포지터리 통해 저장할때 자동으로 생성된 값을 씀
private Long id;
private String username;
private String password;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
...
}
@ExtendWith(SpringExtension.class) // junit 5
@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("jaeuk");
account.setPassword("pass");
Account newAccount = accountRepository.save(account);
// junit 5
assertNotNull(newAccount, "newAccount is not null");
Account existingAccount = accountRepository.findByUsername(newAccount.getUsername());
assertNotNull(existingAccount, "existingAccount is not null");
Account noeExistingAccount = accountRepository.findByUsername("hunuk");
assertNull(noeExistingAccount, "noeExistingAccount is null");
}
}
}
public interface AccountRepository extends JpaRepository<Account, Long> {
// jpql 문법
Account findByUsername(String username);
// Optional<Account> findByUsername(String username); // 이렇게도 사용 가능
// 네이티브 쿼리도 사용 가능
// @Query(nativeQuery = true, value ="select * from account where username = '{0}'")
// Account findByUsername(String username);
}
더 자세한 내용은 스프링 데이터 JPA 강좌 들으며 다시 정리
참고사항
- 테스트용 db는 h2를 사용하는게 더 좋다. 더 빠르고 안정적이다. 보통은 테스트 리소스에 다 넣어놓고 테스트.
- @SpringBootTest 를 사용하면 모든 빈들이 다 생성되기 때문에, 상관은 없으나 슬라이싱 테스트를 하는 방법을 더 추천.