반응형
Spring Data JPA 게시글은 대부분 인프런의 김영한님의 강의인 '실전! 스프링 데이터 JPA' 기반으로 내용을 정리했습니다.
프로젝트 환경 설정
- https://start.spring.io/
- Project : Gradle Project
- Language : Java
- Spring Boot : (22.07.24 기준) 2.7.2
- Group : study
- Artifact : data-jpa
- Java : 11 (강의에서는 딱히 선택하는 부분이 나오지 않았지만 일단 나는 11을 선택했다.)
- Dependencies
- Spring Web
- Spring Data JPA
- H2 Database
- Lombok
HelloController
- 테스트로 컨트롤러를 하나 만들어서 잘 매핑되는지 확인
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
RUN 설정
- 지금 테스트를 실행해보면 느린 경향이 좀 있다. 왜냐하면 인텔리제이가 Gradle을 통해서 실행되기 때문에 바로 JAVA을 띄우는 것보다 느리다. 그래서 따로 설정해주어야 한다.
- Preferences > gradle 검색 > Build and run 모두 IntelliJ IDEA로 변경
Lombok 초기설정
- Preferences > plugin 검색 > plugins에서 lombok 검색 후 install
- 나의 경우는 전 강의를 들으면서 설치가 되어있음.
- preferences > annotation 검색 > Annotation Processors에서 Enable annotation processing 체크
라이브러리 살펴보기
- build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
- testImplementation : 테스트 할 때만 해당 라이브러리를 적용한다.
- spring-boot-starter-data-jpa
- aop, jdbc, hibernate 등 연관 된 라이브러리를 모두 가져온다
- spring-boot-starter-web
- tomcat, spring-webmvc 등
- spring-boot-starter(공통) : 스프링 부트 + 스프링 코어 + 로깅
- spring-boot-starter-test
- junit : 테스트 프레임워크, 스프링 부트 2.2부터 junit5(jupiter) 사용
- 과거 버전은 vintage였다.
- mockito : 목(mock) 라이브러리
- assertj : 테스트 코드를 좀 더 편하게 작성하게 도와주는 라이브러리
- spring-test : 스프링 통합 테스트 지원
- junit : 테스트 프레임워크, 스프링 부트 2.2부터 junit5(jupiter) 사용
- 핵심 라이브러리
- 스프링 MVC
- 스프링 ORM
- JPA, 하이버네이트
- 스프링 데이터 JPA
- 기타 라이브러리
- H2 데이터베이스 클라이언트
- 커넥션 풀 : 부트 기본은 HikariCP
- 로깅 SLF4J & LogBack
- 테스트
H2 데이터베이스 설치
- 버전은 클라이언트 버전(springboor)과 맞춰줘야한다.
- Mac이므로 All Platforms를 눌러 zip 파일을 다운한다.
- 참고로 springboot 버전이 올라갈 때마다 h2 데이터베이스 라이브러리의 버전이 궁금하다면 spring.io에 접속 > Projects > Spring Boot > Learn 탭 > 버전 옆 Reference Doc. > Dependency Version > 컨트롤+F로 h2 검색하면 찾을 수 있다.
- h2.sh 실행
cd h2 설치 경로/bin
./h2.sh
위 명령어를 입력하면 h2 database 웹 페이지가 하나 자동으로 뜬다.
- JDBC url : jdbc:h2:~/datajpa
- DB를 원격으로 접속하는 것이 아니라 파일을 생성하게 된다.
- 이 과정을 해주지 않으면 DB를 찾을 수 없다는 식의 에러가 발생해 접근하지 못한다.
- JDBC url : jdbc:h2:tcp://localhost/~/datajpa
- 처음 url로 한 번 접속 후 연결을 끊고 이 url로 접속한다. 이제 계속 이 url로 접속하면 된다.
스프링 데이터 JPA와 DB 설정, 동작 확인
application.yml
- resources/application.properties 삭제 후 같은 위치에 application.yml 파일을 생성
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/datajpa
username: sa
password:
driver-class-name: org.h2.Driver
jpa:
hibernate:
ddl-auto: create
properties:
hibernate:
format_sql: true
# show_sql: true
logging.level:
org.hibernate.SQL: debug
# org.hibernate.type: trace
- spring.jpa.hibernate.ddl-auto: create는 애플리케이션 실행 시점에 테이블을 drop하고 다시 생성한다.
- 모든 로그 출력은 가급적 로거를 통해서 남겨야 한다.
- show_sql : System.out에 하이버네이트 실행 SQL을 남긴다.
- org.hibernate.SQL : logger를 통해 실행 SQL을 남긴다.
동작 확인
- Member.class
@Entity
@Getter @Setter
public class Member {
@Id @GeneratedValue
private Long id;
private String username;
public Member() {
}
public Member(String username) {
this.username = username;
}
}
- MemberJpaRepository.class
@Repository
public class MemberJpaRepository {
@PersistenceContext
private EntityManager em;
public Member save(Member member) {
em.persist(member);
return member;
}
public Member find(Long id) {
return em.find(Member.class, id);
}
}
- MemberJpaRepository.class
@SpringBootTest
@Transactional // 이 애노테이션이 없으면 컴파일 시점에 에러 터짐
class MemberJpaRepositoryTest {
@Autowired MemberJpaRepository memberJpaRepository;
@Test
public void testMember() {
Member member = new Member("memberA");
Member savedMember = memberJpaRepository.save(member);
Member findMember = memberJpaRepository.find(savedMember.getId())
assertThat(findMember.getId()).isEqualTo(member.getId());
assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
assertThat(findMember).isEqualTo(member);
}
}
스프링 데이터 JPA
- MemberRepository.class
public interface MemberRepository extends JpaRepository<Member, Long> {
}
- MemberResoitoryTest.class
@SpringBootTest
@Transactional
@Rollback(false)
class MemberRepositoryTest {
@Autowired MemberRepository memberRepository;
@Test
public void testMember() {
Member member = new Member("memberA");
Member savedMember = memberRepository.save(member);
Member findMember = memberRepository.findById(savedMember.getId()).get();
Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
Assertions.assertThat(findMember).isEqualTo(member);
}
}
반응형