다가오는 다음을 향해
[SpringBoot JPA] JPA 구현하기(기초) 본문
SpringBoot JPA 구현(기초)
참고 : https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/unit/49597?category=questionDetail
📌 JPA
- JPA는 기존의 반복 코드는 물론이고, 기본적인 SQL도 JPA가 직접 만들어서 실행해준다.
- JPA를 사용하면, SQL과 데이터 중심의 설계에서 객체 중심의 설계로 패러다임을 전환을 할 수 있다.
- JPA를 사용하면 개발 생산성을 크게 높일 수 있다.
☘️ build.gradle 파일에 JPA, h2 데이터베이스 관련 라이브러리 추가
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
☘️ application.properties 에 JPA 설정 추가
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
#JPA가 생성하는 SQL을 출력
spring.jpa.show-sql=true
#JPA가 자동으로 테이블을 생성해주는 기능 (사용: create , 미사용: none)
Spring.jpa.hibernate.ddl-auto=none
☘️ JPA 엔티티 매핑
package hello.hellospring.domain;
import org.hibernate.annotations.AttributeAccessor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- @Entity : 객체와 테이블을 매핑
- @Id : 기본키 매핑
- @GeneratedValue(strategy = GenerationType.IDENTITY) : 기본키 생성을 데이터베이스에 위임
☘️ JPA 회원 리포지토리
public class JpaMemberRepository implements MemberRepository{
private final EntityManager em;
public JpaMemberRepository(EntityManager em) {
this.em = em;
}
@Override
public Member save(Member member) {
em.persist(member);
return member;
}
@Override
public Optional<Member> findById(Long id) {
Member member = em.find(Member.class, id);
return Optional.ofNullable(member);
}
@Override
public Optional<Member> findByName(String name) {
List<Member> result = em.createQuery("select m from Member m where m.name =:name ", Member.class)
.setParameter("name", name)
.getResultList();
return result.stream().findAny();
}
@Override
public List<Member> findAll() {
return em.createQuery("SELECT m from Member m", Member.class)
.getResultList();
}
}
- EntityManager : 엔티티를 관리하는 역할. 엔티티 매니저 내부에 영속성 컨텍스트가 있으며, 이를 통해 엔티티를 관리 합니다.
- 영속성 컨텍스트 : 엔티티를 영구적으로 저장하는 공간 입니다.
createQuery("select m from Member m where m.name =:name ", Member.class)
- JPQL : 엔티티(객체)를 대상으로 쿼리를 날립니다. 객체자체를 SELECT 합니다.
☘️ 서비스 계층에 트랜잭션 추가
@Transactional
public class MemberService {}
- @Transactional : 클래스 위에 추가 될 경우 해당 클래스의 메서드를 실행할 때 트랜젝션을 시작하고, 정상일 경우 Commit, 예외 발생 시 Rollback합니다.
☘️ 스프링 설정 변경
@Configuration
public class SpringConfig {
private EntityManager em;
public SpringConfig(EntityManager em) {
this.em = em;
}
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new JpaMemberRepository(em);
}
}
☘️ 스프링 통합 테스트
- 회원 가입 테스트 : JPA에서 생성하는 SQL을 확인 할 수 있습니다.
- 실제로 DB에 등록되는지 테스트
1. 테스트 메소드 위에 @Commit 애노테이션을 추가하면 실제로 DB에 저장 됩니다.
@Test
@Commit
public void 회원가입() {}
2. 스프링 통합 테스트 - 회원가입
3. 스프링 통합테스트 - 전체
1) @Commit 애노테이션 삭제 및 H2 콘솔에서 DB를 삭제 합니다. (SQL: DELETE FROM member)
2) 스프링 통합테스트를 해봅니다.
'JPA' 카테고리의 다른 글
[JPA] 영속성 관리 - 내부 동작 방식 (0) | 2022.12.29 |
---|---|
[JPA] JPA 구현하기(기초) (0) | 2022.12.29 |