springdatajpa - 스프링 캠프
DESCRIPTION
스프링 캠프 발표자료 - SpringDataJPATRANSCRIPT
Spring Data JPA
발표자 소개
• 이름 : 김영한
• 소속 : SK Planet
목차
•이야기
•Spring Data 빨리 소개
•Spring Data JPA 소개
•사용 경험
•주의 사항
옛날 옛적에...
자바당 정파의 무술
Enterprise Java Beans
EJB 참 쉽죠잉~
낚시 전문 나영업
EJB 지옥
EJB 지옥
스프링
•현재 EJB 컨테이너 대체
•단순함의 승리
하이버네이트
•EJB 엔티티빈 기술을 대체
•JPA(Java Persistence API)라는 새로운 표준 정의
EJB 엔티티빈 JPA하이버네이트
표준정의등장
JPA
하이버네이트 EclipseLink OpenJPA
표준 인터페이스
JPA 구현체들
통계
잠깐만요! 제 주위에는 하이버네이트
안쓰는데요?
ZEROTURNAROUND 통계
•JRebel 만든 곳
•서버를 중단하지 않고 클래스 파일 대체, 프레임워크에 따라 수정이 많음
•전 세계 자바 사용자들이 어떤 프레임워크를 사용하는지 가장 민감한 회사
2011
2012
2012
De facto사실상 표준
SpringJPA
Hibernate
Spring Data
관계형 데이터베이스 세상
신흥 세력의 등장
Spring Data
Spring Data
단순한 통합 그 이상
•CRUD + 쿼리
•동일한 인터페이스
•페이징 처리
•메서드 이름으로 쿼리 생성
•스프링 MVC 에서 id 값만 넘겨도 도메인 클래스로 바인딩
잠깐만요!Spring Data 만 알면 다 된
다는 이야기?
이거면 다 되나요?
•이건 자바를 모르고 스프링을 사용하는 것과 같음
•해당 기술을 아는 사람이 편하게 사용하려고 쓰는 것
Spring Data JPA오늘의 주제
혹시 JPA 처음이신 분을 위해
순수 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); } }
Spring JdbcTemplate
Spring Spring-Jdbc
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; }
Spring + JPA
Spring JPA
Spring + JPA@Repositorypublic class MemberRepository {
@PersistenceContext EntityManager em; //컨테이너 주입
public Long save(Member member) { em.persist(member); return member.getId(); }
...
Spring + JPA
Spring JPA
Spring Data JPA
Spring JPASpring Data
JPA
Spring Data JPApublic interface MemberRepository extends JpaRepository<Member,Long> { //실제 아무것도 없음.}
JpaRepository 인터페이스
•<S extends T> S save(S entity)
•void delete(ID id)
•T findOne(ID id)
•Iterable<T> findAll()
•long count()
•기타 등등...
잠깐만요!인터페이스를 구현한 클래스
가 없는데요?
Spring Data JPA 원리<Interface>
MemberRepository
MemberRepository구현클래스구현 클래스 생성
Spring Data JPA 기능
메서드 이름으로 쿼리생성
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
메서드 이름으로 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);}
@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);}
@Modifying
[수정 쿼리도 직접 정의 가능]
@Modifying(clearAutomatically = true)@Query("update User u set u.firstname = ?1 where u.lastname = ?2")int setFixedFirstnameFor(String firstname, String lastname);
Specification 지원
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);
그냥 API 보세요!
http://docs.spring.io/spring-data/jpa/docs/1.4.1.RELEASE/reference/html/jpa.repositories.html
Spring Data JPA 경험
컴퓨터가 할일은컴퓨터가 하도록
무림 지존요다 스님
팀 프로젝트
작은 거 중간 거 큰 거
스프링MVC
하이버네이트
JPA
SpringDataJPA
팀 주요 프레임워크
스프링
QueryDSLThymeleaf
데이터 저장 레이어
도입시 경력별 반응
10년~신입 2년~
장점
•코딩량
•도메인 클래스를 중요하게 다룸
•비지니스 로직 이해 쉬움
•더 많은 테스트 케이스 작성 가능
장점
•진짜 진짜 편함. 과거로 돌아가라면 ...
•너무 복잡할 땐 SQL 사용
•비지니스 로직에 집중
Spring Data JPA 주의
p
SpringDataJPA무조껀 사용
만병통치약임
실제 사용해보면
ORM 기술다시는 안쓴다!
JPA
JDBC
HIBERNATE
DB
Spring Data
취급 주의!
•JPA(하이버네이트) 모르면 절대 쓰지마세요.
•본인 먼저 JPA 마스터
•데이터베이스 설계 마스터
•Spring Data JPA 는 단지 거들 뿐.
•대부분의 문제는 JPA 를 모르고 사용해서 발생
JPA 학습곡선은 아주 높다.
우리팀 사례
•오픈전 성능검수
•단순한 기능인데 성능이 너무 안나옴 (30TPS)
•신입의 JPQL 막쿼리 (지못미 ㅠㅠ)
•잘못된 로딩 전략 설정
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]
JPA 기본 로딩 전략
•@OneToMany : 기본값=지연로딩(LAZY)
•@ManyToOne : 기본값=즉시로딩(EAGER)
A B즉시로딩
사용
N:1 기본값 즉시로딩
C즉시로딩
JPQL D
즉시로딩
A B즉시로딩
사용
N:1 기본값 즉시로딩
C즉시로딩
JPQL D
즉시로딩
A B지연로딩
사용
지연로딩 설정
C지연로딩
JPQL D
지연로딩
최적화
•JPQL 수정
•로딩전략 LAZY 로 수정
•최적화 필요시 FETCH JOIN 사용
우리도 Spring Data JPA 사용하고 싶어요
본인이 이정도 이해하면 JPA 도입해보세요.
•본인이 작성한 JPQL 이 어떤 쿼리로 생성 될지 이해 해야 함.
•즉시, 지연 로딩 전략 이해
•영속성 컨텍스트 이해
•자동 변경 감지
•언제 영속성 컨텍스트가 플러시 되는가
•연관관계 매핑중에 mappedBy(inverse) 이해
•JPQL 한계 인식
여기서 한 두게 빼고 나머지 다 이해되면 그때 도입하세요.
가장 중요한 것
같이 달릴 수 있는 팀
가장 많이 받는 질문
Q : 제 선임이 새로운 기술은 안 받아 들여요.
A : 저도 잘...
마무리
JPA 추천 자료
영어 --;(번역본 없음)
진짜 어려움(원서는 더 어려움)
커밍순... JPA 책
•함 도와 줍쇼 ㅠㅠ
자료 출처
• http://zeroturnaround.com/rebellabs/java-ee-productivity-report-2011/
• http://zeroturnaround.com/rebellabs/developer-productivity-report-2012-java-tools-tech-devs-and-data/5/
• http://steveswinsburg.wordpress.com/2012/08/09/java-industry-review-2012/
감사합니다