84
Spring Data JPA

SpringDataJPA - 스프링 캠프

Embed Size (px)

DESCRIPTION

스프링 캠프 발표자료 - SpringDataJPA

Citation preview

Page 1: SpringDataJPA - 스프링 캠프

Spring Data JPA

Page 2: SpringDataJPA - 스프링 캠프

발표자 소개

• 이름 : 김영한

• 소속 : SK Planet

Page 3: SpringDataJPA - 스프링 캠프

목차

•이야기

•Spring Data 빨리 소개

•Spring Data JPA 소개

•사용 경험

•주의 사항

Page 4: SpringDataJPA - 스프링 캠프

옛날 옛적에...

Page 5: SpringDataJPA - 스프링 캠프

자바당 정파의 무술

Enterprise Java Beans

Page 6: SpringDataJPA - 스프링 캠프

EJB 참 쉽죠잉~

낚시 전문 나영업

Page 7: SpringDataJPA - 스프링 캠프

EJB 지옥

Page 8: SpringDataJPA - 스프링 캠프

EJB 지옥

Page 9: SpringDataJPA - 스프링 캠프

스프링

•현재 EJB 컨테이너 대체

•단순함의 승리

Page 10: SpringDataJPA - 스프링 캠프

하이버네이트

•EJB 엔티티빈 기술을 대체

•JPA(Java Persistence API)라는 새로운 표준 정의

Page 11: SpringDataJPA - 스프링 캠프

EJB 엔티티빈 JPA하이버네이트

표준정의등장

Page 12: SpringDataJPA - 스프링 캠프

JPA

하이버네이트 EclipseLink OpenJPA

표준 인터페이스

JPA 구현체들

Page 13: SpringDataJPA - 스프링 캠프

통계

Page 14: SpringDataJPA - 스프링 캠프

잠깐만요! 제 주위에는 하이버네이트

안쓰는데요?

Page 15: SpringDataJPA - 스프링 캠프

ZEROTURNAROUND 통계

•JRebel 만든 곳

•서버를 중단하지 않고 클래스 파일 대체, 프레임워크에 따라 수정이 많음

•전 세계 자바 사용자들이 어떤 프레임워크를 사용하는지 가장 민감한 회사

Page 16: SpringDataJPA - 스프링 캠프

2011

Page 17: SpringDataJPA - 스프링 캠프

2012

Page 18: SpringDataJPA - 스프링 캠프

2012

Page 19: SpringDataJPA - 스프링 캠프

De facto사실상 표준

SpringJPA

Hibernate

Page 20: SpringDataJPA - 스프링 캠프

Spring Data

Page 21: SpringDataJPA - 스프링 캠프

관계형 데이터베이스 세상

Page 22: SpringDataJPA - 스프링 캠프

신흥 세력의 등장

Page 23: SpringDataJPA - 스프링 캠프

Spring Data

Page 24: SpringDataJPA - 스프링 캠프

Spring Data

Page 25: SpringDataJPA - 스프링 캠프

단순한 통합 그 이상

•CRUD + 쿼리

•동일한 인터페이스

•페이징 처리

•메서드 이름으로 쿼리 생성

•스프링 MVC 에서 id 값만 넘겨도 도메인 클래스로 바인딩

Page 26: SpringDataJPA - 스프링 캠프

잠깐만요!Spring Data 만 알면 다 된

다는 이야기?

Page 27: SpringDataJPA - 스프링 캠프

이거면 다 되나요?

•이건 자바를 모르고 스프링을 사용하는 것과 같음

•해당 기술을 아는 사람이 편하게 사용하려고 쓰는 것

Page 28: SpringDataJPA - 스프링 캠프

Spring Data JPA오늘의 주제

Page 29: SpringDataJPA - 스프링 캠프

혹시 JPA 처음이신 분을 위해

Page 30: SpringDataJPA - 스프링 캠프

순수 JDBC public Long save(Connection conn, Member member) {

PreparedStatement pstmt = null;

String sql = "INSERT INTO MEMBER(USERNAME, PHONE_NUMBER) VALUES (?, ?)";

try {

pstmt = conn.prepareStatement(sql); pstmt.setString(1, member.getUsername()); pstmt.setString(2, member.getPhoneNumber());

pstmt.executeUpdate();

ResultSet generatedKeys = pstmt.getGeneratedKeys(); if (generatedKeys.next()) { long memberId = generatedKeys.getLong(1); return memberId; }

return null;

} catch (Exception e) { throw new RuntimeException(e); } finally { close(pstmt); } }

Page 31: SpringDataJPA - 스프링 캠프
Page 32: SpringDataJPA - 스프링 캠프

Spring JdbcTemplate

Spring Spring-Jdbc

Page 33: SpringDataJPA - 스프링 캠프

Spring JdbcTemplate public Member findOne(Long id) {

String sql = "select MEMBER_ID as id, USERNAME, PHONE_NUMBER from MEMBER where id = ?";

Member member = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Member>(), id); return member; }

Page 34: SpringDataJPA - 스프링 캠프

Spring + JPA

Spring JPA

Page 35: SpringDataJPA - 스프링 캠프

Spring + JPA@Repositorypublic class MemberRepository {

@PersistenceContext EntityManager em; //컨테이너 주입

public Long save(Member member) { em.persist(member); return member.getId(); }

...

Page 36: SpringDataJPA - 스프링 캠프

Spring + JPA

Spring JPA

Page 37: SpringDataJPA - 스프링 캠프

Spring Data JPA

Spring JPASpring Data

JPA

Page 38: SpringDataJPA - 스프링 캠프

Spring Data JPApublic interface MemberRepository extends JpaRepository<Member,Long> { //실제 아무것도 없음.}

Page 39: SpringDataJPA - 스프링 캠프

JpaRepository 인터페이스

•<S extends T> S save(S entity)

•void delete(ID id)

•T findOne(ID id)

•Iterable<T> findAll()

•long count()

•기타 등등...

Page 40: SpringDataJPA - 스프링 캠프

잠깐만요!인터페이스를 구현한 클래스

가 없는데요?

Page 41: SpringDataJPA - 스프링 캠프

Spring Data JPA 원리<Interface>

MemberRepository

MemberRepository구현클래스구현 클래스 생성

Page 42: SpringDataJPA - 스프링 캠프

Spring Data JPA 기능

Page 43: SpringDataJPA - 스프링 캠프

메서드 이름으로 쿼리생성

public interface MemberRepository extends Repository<Member, Long> {

List<User> findByEmailAndName(String email, String name);}

[생성된 JPQL]

select m from Member mwhere m.email = ?1 and m.name = ?2

Page 44: SpringDataJPA - 스프링 캠프

메서드 이름으로 NamedQuery 호출

[XML에 작성한 NamedQuery]<named-query name="User.findByLastname"> <query>select u from User u where u.lastname = ?1</query></named-query>

[어노테이션으로 작성한 NamedQuery]@Entity@NamedQuery(name = "User.findByEmailAddress", query = "select u from User u where u.emailAddress = ?1")public class User {}

public interface UserRepository extends JpaRepository<User, Long> {

List<User> findByLastname(String lastname); User findByEmailAddress(String emailAddress);}

Page 45: SpringDataJPA - 스프링 캠프

@Query

[인터페이스에 쿼리작성 가능]public interface UserRepository extends JpaRepository<User, Long> {

@Query("select u from User u where u.emailAddress = ?1") User findByEmailAddress(String emailAddress);}

[JPA 네이티브 쿼리 지원]public interface UserRepository extends JpaRepository<User, Long> {

@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?0", nativeQuery = true) User findByEmailAddress(String emailAddress);}

Page 46: SpringDataJPA - 스프링 캠프

@Modifying

[수정 쿼리도 직접 정의 가능]

@Modifying(clearAutomatically = true)@Query("update User u set u.firstname = ?1 where u.lastname = ?2")int setFixedFirstnameFor(String firstname, String lastname);

Page 47: SpringDataJPA - 스프링 캠프

Specification 지원

Page 48: SpringDataJPA - 스프링 캠프

Specfication(DDD)

Specification<Member>����������� ������������������  firstNameLike����������� ������������������  =����������� ������������������  MemberSpecs.isFirstName("김");����������� ������������������   Specification<Member>����������� ������������������  ageBetween����������� ������������������  =����������� ������������������  MemberSpecs.ageBetween(20,����������� ������������������  40);����������� ������������������  ����������� ������������������   Specifications<Member>����������� ������������������  specs����������� ������������������  =����������� ������������������  

Specifications.where(firstNameLike).and(ageBetween);����������� ������������������   ����������� ������������������   ����������� ������������������  ����������� ������������������   List<Member>����������� ������������������  list����������� ������������������  =����������� ������������������  memberRepository.findAll(specs);

Page 50: SpringDataJPA - 스프링 캠프

Spring Data JPA 경험

Page 51: SpringDataJPA - 스프링 캠프

컴퓨터가 할일은컴퓨터가 하도록

무림 지존요다 스님

Page 52: SpringDataJPA - 스프링 캠프

팀 프로젝트

작은 거 중간 거 큰 거

Page 53: SpringDataJPA - 스프링 캠프

스프링MVC

하이버네이트

JPA

SpringDataJPA

팀 주요 프레임워크

스프링

QueryDSLThymeleaf

데이터 저장 레이어

Page 54: SpringDataJPA - 스프링 캠프

도입시 경력별 반응

10년~신입 2년~

Page 55: SpringDataJPA - 스프링 캠프

장점

•코딩량

•도메인 클래스를 중요하게 다룸

•비지니스 로직 이해 쉬움

•더 많은 테스트 케이스 작성 가능

Page 56: SpringDataJPA - 스프링 캠프

장점

•진짜 진짜 편함. 과거로 돌아가라면 ...

•너무 복잡할 땐 SQL 사용

•비지니스 로직에 집중

Page 57: SpringDataJPA - 스프링 캠프

Spring Data JPA 주의

Page 58: SpringDataJPA - 스프링 캠프

p

SpringDataJPA무조껀 사용

만병통치약임

Page 59: SpringDataJPA - 스프링 캠프

실제 사용해보면

Page 60: SpringDataJPA - 스프링 캠프

ORM 기술다시는 안쓴다!

Page 61: SpringDataJPA - 스프링 캠프

JPA

JDBC

HIBERNATE

DB

Spring Data

Page 62: SpringDataJPA - 스프링 캠프

취급 주의!

•JPA(하이버네이트) 모르면 절대 쓰지마세요.

•본인 먼저 JPA 마스터

•데이터베이스 설계 마스터

•Spring Data JPA 는 단지 거들 뿐.

•대부분의 문제는 JPA 를 모르고 사용해서 발생

Page 63: SpringDataJPA - 스프링 캠프

JPA 학습곡선은 아주 높다.

Page 64: SpringDataJPA - 스프링 캠프

우리팀 사례

•오픈전 성능검수

•단순한 기능인데 성능이 너무 안나옴 (30TPS)

•신입의 JPQL 막쿼리 (지못미 ㅠㅠ)

•잘못된 로딩 전략 설정

Page 65: SpringDataJPA - 스프링 캠프

JPQL 묵시적 조인

select o.member.teamfrom Order owhere o.product.name = 'productA' and o.address.city = 'JINJU'

[JPQL]

select t.*from Orders oinner join Member m on o.member_id=m.id inner join Team t on m.team_id=t.idinner join Product p on o.product_id=p.id where p.name='productA' and o.city='JINJU'

[실행된 SQL]

Page 66: SpringDataJPA - 스프링 캠프

JPA 기본 로딩 전략

•@OneToMany : 기본값=지연로딩(LAZY)

•@ManyToOne : 기본값=즉시로딩(EAGER)

Page 67: SpringDataJPA - 스프링 캠프

A B즉시로딩

사용

N:1 기본값 즉시로딩

C즉시로딩

JPQL D

즉시로딩

Page 68: SpringDataJPA - 스프링 캠프

A B즉시로딩

사용

N:1 기본값 즉시로딩

C즉시로딩

JPQL D

즉시로딩

Page 69: SpringDataJPA - 스프링 캠프

A B지연로딩

사용

지연로딩 설정

C지연로딩

JPQL D

지연로딩

Page 70: SpringDataJPA - 스프링 캠프

최적화

•JPQL 수정

•로딩전략 LAZY 로 수정

•최적화 필요시 FETCH JOIN 사용

Page 71: SpringDataJPA - 스프링 캠프

우리도 Spring Data JPA 사용하고 싶어요

Page 72: SpringDataJPA - 스프링 캠프

본인이 이정도 이해하면 JPA 도입해보세요.

•본인이 작성한 JPQL 이 어떤 쿼리로 생성 될지 이해 해야 함.

•즉시, 지연 로딩 전략 이해

Page 73: SpringDataJPA - 스프링 캠프

•영속성 컨텍스트 이해

•자동 변경 감지

•언제 영속성 컨텍스트가 플러시 되는가

•연관관계 매핑중에 mappedBy(inverse) 이해

•JPQL 한계 인식

Page 74: SpringDataJPA - 스프링 캠프

여기서 한 두게 빼고 나머지 다 이해되면 그때 도입하세요.

Page 75: SpringDataJPA - 스프링 캠프

가장 중요한 것

Page 76: SpringDataJPA - 스프링 캠프
Page 77: SpringDataJPA - 스프링 캠프

같이 달릴 수 있는 팀

Page 78: SpringDataJPA - 스프링 캠프

가장 많이 받는 질문

Q : 제 선임이 새로운 기술은 안 받아 들여요.

A : 저도 잘...

Page 79: SpringDataJPA - 스프링 캠프

마무리

Page 80: SpringDataJPA - 스프링 캠프

JPA 추천 자료

영어 --;(번역본 없음)

진짜 어려움(원서는 더 어려움)

Page 81: SpringDataJPA - 스프링 캠프

커밍순... JPA 책

•함 도와 줍쇼 ㅠㅠ

Page 82: SpringDataJPA - 스프링 캠프
Page 84: SpringDataJPA - 스프링 캠프

감사합니다