Spring boot JPA

강정우·2022년 10월 27일
0

spring

목록 보기
20/27
post-thumbnail

3. JPA

  • 객체는 ORM이라는 기술이다.
    Object Relation Mapping : 객체와 관계형 DB를 Mapping 하겠다. 라는 뜻이다.

🤷왜 JPA를 하는가?

  • 전 세계적으로 JPA가 압도적으로 많이 쓰인다. mybatis를 사용하는 곳을 우리나라와 중국 뿐이고 우리나라도 최근에 굉장히 많은 관심도를 보이고 있다.
  • 또한 JPA는 sql조차도 개발자들이 직접 안 짜고 얘가 DB에 등록, 수정, 삭제 이런 query들을 직접 만들어서 다 날려준다.
    즉, 객체를 바로 DB에 query없이 저장할 수 있다.
  • JPS를 사용하면, SQL과 데이터 중심의 설계에서 객체 중심의 설계로 패러다임을 전환을 할 수 있다.
  • JPA를 사용하면 개발 생산성을 크게 높일 수 있다.

JPA 환경설정

1. build.gradle

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
  • 이때 spring-boot-starter-data-jpa 는 jdbc library를 포함하기 때문에 제거해도 된다.

  • hibernate library가 있어야 한다. JPA는 interface이고 여기 안에 있는 hibernate 만 거의 쓴다.

2. application properties

spring.jpa.show-sql=true : JPA가 날리는 SQL을 볼 수 있다.
spring.jpa.hibernate.ddl-auto=none : JPS는 회원 객체를 보고 table도 지가 다 만들어버린다. 그래서 auto로 table 생성기능을 끈 것이다. 이를 만약에 create로 하면 알아서 자동으로 다 만들어준다.

3. Entity 설정

PK 설정

  • VO에 @Entity 를 추가하고 PK인 @Id를 설정해준다.
  • DB에서 Id를 자동으로 생성해주는 것을 identity 전략이라고 하는데 이를 @GeneratedValue안에 넣을 수 있다.

column 설정

  • @Column(필드 명 = "컬럼 명")

4. Repository 생성 및 설정

  • 우선 class파일 생성 후 implements를 한다.
  • JPA는 사실 EntityManager 가 모든일을 다 한다.
  • build.gradle에서 jpa library를 추가하면 spring boot가 알아서 application.properties의 정도를 다 조합해서 EntityManager를 생성을 해준다. 이때 현재 DB랑 다 연결해서 만들어준다.
    우리는 이 만들어진것을 injection 받으면 된다.

query 작성

  • jpQL 이라는 객체지향 query문을 작성해야한다.
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() {
    List<Member> result = em.createQuery("select m from Member m", Member.class)
            .getResultList();
    return result;
}

ctrl + alt + n : 인라인
shift + ctrl + alt + t : refactoring

@Override
public List<Member> findAll() {
    return em.createQuery("select m from Member m", Member.class)
            .getResultList();
}
  • 자 위 코드를 보면 원래는 table에 query를 날리는데 객체에 query를 날린다. 그럼 이게 알아서 SQL로 번역이 된다.
    그런데 자세히 보면 select문에 column이 아니라 객체의 alias가 들어가는데 이렇게 그냥 쓰면 알아서 객체자체를 select해서 가져온다.

이 JPA 객체를 쓰려면 항상 transaction이 있어야 한다. Data를 저장하거나 변경하려면 항상 있어야 한다.

Assembly(Config) 작성 후 test 진행

  • 테스트 결과

  • 또한 Hibername 단에 보면 queyr문이 작성되는 것을 볼 수 있다.

5. service단에 transaction추가

  • 스프링은 해당 클래스의 메서드를 실행할 때 트랜잭션을 시작하고, 메서드가 정상 종료되면 트랜잭션을
    커밋한다. 만약 런타임 예외가 발생하면 롤백한다.

    JPA를 통한 모든 데이터 변경은 트랜잭션 안에서 실행해야 한다

4. Spring data JPA

  • 그런데 사실 JPA도 Spring만큼 오래된 기술이다. 그래서 Spring에서 JPA를 굉장히 편리하게 쓸 수 있도록 한번 감싼 기술이다.

1. Repository interface 작성

  • interface는 extends로 상속받고 또 여러가지를 상속받을 수 있다.
  • T와 Id를 설정해주어야 하는데 T는 entity(VO), Id는 entity(VO)의 식별자(PK) 참고로 여기서는 type으로 작성함
  • Spring Boot가 지가 알아서 만들어냄
  • 그리고 추가로 findByName의 methdo만 구현하면 됨. 그럼 끝남 -> 아니 쉬벌 이게 어캐 끝?

    얘가 SpringDataRepository를 상속받고 있다면 구현체를 자동으로 만들어준다. 그래서 Spring Bean에 자동으로 등록한다.
    그래서 우리는 그냥 Config에서 assembly만 하면 된다.

  • 위 설명을 추가하자면 저기 JpaRepository에 들어가보면 약 15개의 기본 CRUD SQL method들이 구현되어있는데 회사별로 다른 특이한 SQL들을 모두 구현할 수 없으니 그런것들만 구현해주면 되는것이다.

2. Config 작성

private final MemberRepository memberRepository;

@Autowired
public SpringConfig(MemberRepository memberRepository) {
	this.memberRepository = memberRepository;
}
  • 즉, 요거 하나가 @Bean과 같음 어떻게? 앞서 말했든 interface에 JpaRepository라는 것을 상속받으면 proxy라는 기술을 이용하여 요 구현체를 @Bean에 등록한다.
    그래서 Config에서 inject이 가능하다.

JPA의 힘

  • 위와같이 작성해도 알아서 SQL문을 짜준다.
  • 즉, 대부분(80%)의 sql을 interface의 이름(method name, return type, parameter)으로 query문 작성이 가능하다.
profile
智(지)! 德(덕)! 體(체)!

0개의 댓글