스프링 부트 JPA 모범 사례 - 에이콘 오픈소스 프로그래밍 시리즈

스프링 부트 JPA 모범 사례 - 에이콘 오픈소스 프로그래밍 시리즈

$57.17
Description
최근 클라우드 네이티브(cloud-native) 애플리케이션 구축에 많이 활용되는 스프링 부트(Spring Boot) 기반에서, 데이터 액세스 기술로 인기를 끌고 있는 것이 바로 JPA(Java Persistence API)다. 그러나 JPA는 익숙하던 기존의 방식과는 달리 내부적인 처리 메커니즘을 어느 정도 이해해야 어려움 없이 활용할 수 있다. 특히, 잘못 설계된 연관관계(association) 등은 성능에 많은 영향을 주기도 한다.
이 책은 JPA의 다양한 측면, 특히 성능과 관련된 이슈와 이를 해결하는 120개 이상의 모범 사례를 다룬다. 실용적인 레시피를 중심으로 구성되고, 각 레시피는 성능 관련 사례를 중점적으로 다루고 있으며, 여러 스타일(순수 하이버네이트 사용, 스프링 데이터 JPA 등)로 작성된 온전한 많은 예제를 제공하고 있다.

◆ 스프링, 스프링 부트, 하이버네이트를 사용해 자바에서 데이터 유지하는 방법
◆ 더티 트래킹 활성화 방법
◆ 다대다 연관관계를 효율적으로 구성하고 List와 Set 선택을 결정하는 방법
◆ MySQL을 통한 데이터 스트리밍 방법
◆ 단일 SELECT로 부모 측과 연관관계를 효율적으로 가져오는 방법
◆ 포크(fork)/조인(join) 프레임워크를 통한 배치 파일 처리 방법
◆ 컬렉션 및 커넥션 작업 방법
◆ 쿼리, 잠금, 스키마, 하이버네이트 타입에 대한 처리 방법
저자

안겔레오나르드

저자:안겔레오나르드(AnghelLeonard)

자바생태계에서20년이상의경험을가진수석기술전략가(ChiefTechnologyStrategist)이자독립컨설턴트다.일상업무에서강력한아키텍처,클린코드,고성능을지원하는자바분산애플리케이션을설계하고개발하는데중점을둔다.또한코칭,멘토링,기술리더십에도열정을쏟고있으며,여러권의도서와비디오,자바기술과관련된수십개의기사를저술했다.



역자:한성곤

다년간SW엔지니어링,개발,아키텍처수립뿐만아니라프로젝트관리및코드품질개선활동등다양한경험과역할을수행했다.현재삼성SDS에서로우코드플랫폼(LowCodePlatform)개발과관련된업무를수행중이며,전자정부표준프레임워크오픈커뮤니티커미터활동등을통해얕은지식이나마공유하기위해노력하고있다.

목차

1장.연관관계
__항목1:@OneToMany연관관계를효과적으로구성하는방법
____항상부모측에서자식측으로전이를사용
____부모측에mappedBy지정
____부모측에orphanRemoval지정
____연관관계의양측을동기화상태로유지
____equals()와hashCode()오버라이딩
____연관관계양측에서지연로딩사용
____toString()오버라이딩방법에주의
____@JoinColumn을사용해조인칼럼지정
____Author및Book샘플코드
__항목2:단방향@OneToMany연관관계를피해야하는이유
____일반적인단방향@OneToMany
____@OrderColumn사용
____@JoinColumn사용
__항목3:단방향@ManyToOne의효율성
____특정저자에게새도서추가
____저자의모든도서가져오기
____저자의도서페이징처리
____저자의모든도서가져오기와새로운도서추가
____저자의모든도서가져오기와도서삭제
__항목4:@ManyToMany연관관계를효과적으로구성하는방법
____관계의오너선택
____항상List가아닌Set사용
____연관관계의양측동기화상태유지
____CascadeType.ALL및CascadeType.REMOVE사용하지않기
____조인테이블설정
____연관관계양측에서지연로딩사용
____equals()및hashCode()오버라이딩
____toString()오버라이딩방법에주의
____Author및Book샘플코드
__항목5:@ManyToMany에서Set이List보다나은이유
____List사용
____Set사용
__항목6:CascadeType.REMOVE및orphanRemoval=true를사용해하위엔터티제거를피해야하는이유와시기
____영속성콘텍스트에이미로드된저자삭제
____하나의저자만영속성콘텍스트에로드된경우
____여러저자가영속성콘텍스트에로드된경우
____한저자와관련도서들이영속성콘텍스트에로드된경우
____삭제해야할저자와도서가영속성콘텍스트에로드되지않은경우삭제
__항목7:JPA엔터티그래프를통해연관관계를가져오는방법
____NamedEntityGraph로엔터티그래프정의
____쿼리메서드오버라이딩
____쿼리빌더메커니즘사용
____Specification사용
____@Query및JPQL사용
____애드혹엔터티그래프
____EntityManager를통한엔터티그래프정의
__항목8:JPA엔터티서브그래프를통해연관관계를가져오는방법
____@NamedEntityGraph및@NamedSubgraph사용
____애드혹엔터티그래프에서점노테이션(.)사용
____EntityManager를통한엔터티서브그래프정의
__항목9:엔터티그래프및기본속성처리방법
__항목10:하이버네이트@Where어노테이션을통한연관관계필터링처리
__항목11:@MapsId를통한단방향/양방향@OneToOne최적화방법
____일반적인단방향@OneToOne
____일반적인양방향@OneToOne
____@OneToOne을구원하는@MapsId
__항목12:단하나의연관관계만Null이아닌지확인하는방법
____테스트확인

2장.엔터티
__항목13:엔터티의플루언트API스타일적용방법
____엔터티세터를통한플루언트스타일
____별도메서드를통한플루언트스타일
__항목14:하이버네이트프록시를통한자식측에서부모연관관계채우기
____findById()사용
____getOne()사용
__항목15:영속성레이어에서자바8Optional사용방법
____엔터티에서의Optional
____리포지터리에서의Optional
__항목16:불변엔터티작성방법
__항목17:엔터티복제방법
____부모복제와도서에대한연관관계지정
____부모및도서복제
____하나로처리
__항목18:더티트래킹을활성화하는이유와방법
__항목19:불리언을Yes/No로매핑하는방법
__항목20:애그리거트루트로부터최적의도메인이벤트발행
____동기식실행
____비동기식실행

3장.페치
__항목21:다이렉트페치사용방법
____스프링데이터를통한다이렉트페치
____EntityManager를통한다이렉트페치
____하이버네이트Session을통한다이렉트페치
____다이렉트페치및세션수준반복읽기
____ID로여러엔터티다이렉트페치
__항목22:미래영속성콘텍스트에서데이터베이스변경사항전파를위한읽기전용엔터티의사용이유
____읽기-쓰기모드로Author로드
____읽기전용모드로Author로드
____Author수정
__항목23:하이버네이트BytecodeEnhancement를통한엔터티속성지연로딩방법
____속성에대한지연로딩활성화
____속성지연로딩과N+1
____속성지연로딩과지연초기화예외
____지연로드속성에대한명시적기본값지정
____커스텀Jackson필터제공
__항목24:서브엔터티를통한엔터티속성지연로딩방법
__항목25:스프링프로젝션을통한DTO가져오기
____JPA네임드(네이티브)쿼리및스프링프로젝션결합사용
____클래스기반프로젝션
____스프링프로젝션재사용방법
____동적스프링프로젝션사용방법
__항목26:스프링프로젝션에서엔터티를추가하는방법
____구체화된연관관계
____구체화되지않은연관관계
__항목27:엔터티의일부또는외부가상속성을통한스프링프로젝션보완방법
__항목28:*-to-One연관관계를포함하는스프링프로젝션의효율적로딩방법
____중첩된닫힌프로젝션사용
____단순닫힌프로젝션사용
____단순열린프로젝션사용
__항목29:연관된컬렉션을포함하는스프링프로젝션주의사항
____중첩된닫힌프로젝션사용
____단순닫힌프로젝션사용
____DTO에서List변환
__항목30:스프링프로젝션을통한모든속성가져오는방법
____쿼리빌더메커니즘사용
____JPQL및@Query사용
____명시적칼럼목록및@Query와함께JPQL사용
____네이티브쿼리와@Query사용
__항목31:생성자표현식을통해DTO를가져오는방법
__항목32:생성자표현식을통해DTO에서엔터티를가져오지말아야하는이유
__항목33:JPATuple을통해DTO를가져오는방법
__항목34:@SqlResultSetMapping및@NamedNativeQuery를통해DTO를가져오는방법
____스칼라매핑
____생성자매핑
____엔터티매핑
__항목35:ResultTransformer를통해DTO를가져오는방법
__항목36:커스텀ResultTransformer를통해DTO를가져오는방법
__항목37:@Subselect를통해엔터티를쿼리에매핑하는방법
__항목38:Blaze-Persistence엔터티뷰를통해DTO를가져오는방법
__항목39:단일SELECT로부모와연관관계를효율적으로가져오는방법
__항목40:JOIN과JOINFETCH결정방법
____주어진가격보다비싼저서를저술한모든저자가져오기
____모든저서와저자가져오기
__항목41:모든왼쪽엔터티를가져오는방법
__항목42:관련없는엔터티로부터DTO를가져오는방법
__항목43:JOIN문작성방법
____INNERJOIN
____LEFTJOIN
____RIGHTJOIN
____CROSSJOIN
____FULLJOIN
____MySQL에서FULLJOIN시뮬레이션
__항목44:JOIN페이지네이션방법
____DENSE_RANK()윈도우함수해결방안
____항목45:결과세트를스트림하는방법(MySQL)및Streamable유틸리티의사용방법
____결과세트스트리밍(MySQL)
____Streamable유틸리티와스트링혼동하지않기
____필요보다더많은열을가져와map()을통해일부삭제하지않기
____필요보다더많은행을가져와filter()을통해일부삭제하지않기
____and()를통한Streamable결합에주의
____커스텀Streamable래퍼타입을반환하는방법

4장.배치처리
__항목46:스프링부트스타일배치등록방법
____배치처리활성화및JDBCURL설정
____배치등록을위한엔터티준비
____내장saveAll(Iterableentities)단점확인및방지
____올바른방법의커스텀구현
____테스트확인
__항목47:부모-자식관계배치등록최적화방법
____배치순서지정
____항목48:세션수준에서배치크기제어방법
____항목49:포크/조인JDBC배치처리방법
____포크/조인배처처리
__항목50:CompletableFuture를통한엔터티배치처리
__항목51:배치업데이트에대한효율적인처리방법
____버전이지정된엔터티
____부모-자식관계의배치업데이트
____벌크업데이트
__항목52:효율적으로배치삭제하는방법(연관관계없이)
____deleteAllInBatch()내장메서드를통한삭제
____deleteInBatch(Iterableentities)내장메서드를통한삭제
____deleteAll()내장메서드를통한삭제
____delete(Tentity)내장메서드를통한삭제
__항목53:효율적으로배치삭제하는방법(연관관계와함께)
____orphanRemoval=true사용
____deleteAllInBatch()내장메서드를통한삭제
____deleteInBatch(Iterableentities)내장메서드를통한삭제
____deleteAll(Iterableentities)와delete(Tentity)내장메서드를통한삭제
____SQL,ONDELETECASCADE사용
____deleteAllInBatch()내장메서드를통한삭제
____deleteInBatch(Iterableentities)내장메서드를통한삭제
____deleteAll(Iterableentities)와delete(Tentity)내장메서드를통한삭제
__항목54:배치로연관관계가져오는방법
____컬렉션수준에서의@BatchSize
____클래스/엔터티수준에서의@BatchSize
__항목55:배치등록에서PostgreSQL(BIG)SERIAL을피해야하는이유
____식별자가져오기프로세스최적화
____reWriteBatchedInserts를통한배치최적화

5장.컬렉션
__항목56:@ElementCollection컬렉션JOINFETCH방법
__항목57:@ElementCollection에대한DTO방법
__항목58:@ElementCollection과@OrderColumn을함께사용해야하는이유와시기
____@OrderColumn을통한@ElementCollection최적화
__항목59:엔터티컬렉션병합방법
____Detached컬렉션병합
____테스트확인

6장.커넥션과트랜잭션
__항목60:실제필요시점까지커넥션획득지연방법
__항목61:@Transactional(readOnly=true)의실제작동방식
__항목62:스프링이@Transactional을무시하는이유
__항목63:트랜잭션타임아웃설정및롤백이예상대로작동하는지확인하는방법
____트랜잭션및쿼리타임아웃설정
____트랜잭션이롤백됐는지확인
__항목64:리포지터리인터페이스에서@Transactional을사용하는이유와방법
____인터페이스리포지터리의쿼리메서드는기본적으로트랜잭션콘텍스트에서실행되는가?
____그럼해야할일은서비스메서드수준에서@Transactional을추가하는것뿐인가?
____그럼일반적해당방법으로항상충분한가?
____알았다.리포지터리인터페이스로@Transactional을이동하자
____그러나서비스메서드에서더많은쿼리메서드를호출하려면어떻게해야할까?ACID를잃게될까?
____그럼커넥션획득을지연하면리포지터리인터페이스에@Transactional을사용하지않아도되는가?
____간단하고일반적인3가지시나리오

7장.식별자
__항목65:MySQL에서하이버네이트5AUTO생성자타입을피해야하는이유
__항목66:hi/lo알고리듬을통한시퀀스식별자생성최적화방법
____외부시스템처리
__항목67:Pooled(-lo)알고리듬을통한시퀀스식별자생성최적화방법
____Pooled알고리듬
____Pooled-Lo알고리듬
__항목68:equals()및hashCode()를올바로오버라이드하는방법
____단위테스트구성
____equals()및hashCode()오버라이딩을위한최적의접근방법
____피해야할equals()및hashCode()오버라이딩방법
__항목69:스프링스타일로하이버네이트@NaturalId를사용하는방법
____테스트확인
____복합자연ID
__항목70:하이버네이트@NaturalId사용및엔터티식별자조회생략방법
____@NaturalIdCache단독으로사용
____@NaturalIdCache및@Cache사용
__항목71:@NaturalId칼럼참조연관관계정의방법
____테스트확인
__항목72:자동생성키를얻는방법
____getId()를통한자동생성키가져오기
____JdbcTemplate을통한자동생성키가져오기
____SimpleJdbcInsert를통한자동생성키가져오기
__항목73:커스텀시퀀스ID를생성하는방법
__항목74:복합기본키를효율적으로구현하는방법
____@Embeddable및@EmbeddedId를사용한복합키
____@IdClass를사용한복합키
____UUID는어떨까?
____GenerationType.AUTO를통한UUID생성
____직접할당되는UUID
____하이버네이트uuid2
__항목75:복합키에서관계를정의하는방법
____테스트확인
____Publisher저장
____2명의Author저장
____이름으로Author조회
____Author의Book삭제
____Author삭제
__항목76:연결테이블에대한엔터티사용방법
____연결테이블에대한복합기본키정의
____연결테이블에대한엔터티정의
____Author와Book연결

8장.산출속성
__항목77:산출된비영속속성매핑방법
____JPA빠른접근
____JPA@PostLoad
____하이버네이트@Formula
__항목78:@Generated를통한산출된영속속성매핑방법
____하이버네이트@Generated
____columnDefinition항목을통한공식
____CREATETABLE을통한공식
____테스트확인
__항목79:JPQL쿼리에서여러파라미터와함께SQL함수사용방법
____SELECT부분의함수
____WHERE부분의함수
__항목80:@JoinFormula를통해@ManyToOne관계를SQL쿼리에매핑하는방법


9장.모니터링
__항목81:SQL문카운트및어설션사용이유와방법
__항목82:프리페어드스테이트먼트바인딩및추출파라미터로깅방법
____TRACE
____Log4j2
____MySQL과profileSQL=true
__항목83:쿼리상세정보로깅방법
____DataSource-Proxy사용
____log4jdbc사용
____P6spy사용
__항목84:임계치를사용한느린쿼리로그방법
__항목85:트랜잭션및쿼리메서드상세로깅
____트랜잭션상세로깅
____트랜잭션콜백을통한제어권확보
____쿼리메서드실행시간로깅

10장.DataSource및커넥션풀설정
__항목86:HikariCP설정커스터마이징방법
____application.properties를통한HikariCP파리미터최적화
____application.properties및DataSourceBuilder를통한HikariCP파리미터최적화
____DataSourceBuilder를통한HikariCP파라미터최적화
____다른커넥션풀최적화
__항목87:2개의커넥션풀을갖는2개의데이터소스구성방법
____테스트확인

11장.감사
__항목88:생성및수정시간과엔터티사용자추적방법
____스프링데이터감사기능활용
____하이버네이트지원기능활용
____테스트확인
__항목89:하이버네이트Envers감사활성화방법
____엔터티감사
____스키마생성
____엔터티스냅숏쿼리
____ValidityAuditStrategy감사로깅전략
__항목90:영속성콘텍스트를확인하는방법
__항목91:테이블메타데이터추출방법

12장.스키마
__항목92:스프링부트에서Flyway설정방법
____신속한Flyway설정(MySQL및PostgreSQL)
____Flyway를통한데이터베이스생성
____@FlywayDataSource를통한Flyway설정
____Flyway와다중스키마
__항목93:schema-*.sql을통한두데이터베이스생성과엔터티매칭방법

13장.페이지네이션
__항목94:오프셋페이지네이션성능저하발생시기와이유
____오프셋및키세트인덱스스캔
____오프셋페이지네이션장단점
____스프링부트오프셋페이지네이션
__항목95:COUNT(*)OVER및Page를사용한오프셋페이지네이션최적화방법
____COUNT(*)OVER()윈도우집계
__항목96:SELECTCOUNT서브쿼리및Page를사용한오프셋페이지네이션최적화방법
____SELECTCOUNT서브쿼리
__항목97:JOINFETCH및Pageable사용방법
__항목98:HHH000104조치방법
____관리되는엔터티가져오기
__항목99:SlicefindAll()구현방법
____신속한구현
____SlicefindAll(Pageablepageable)구현
__항목100:키세트페이지네이션구현방법
__항목101:키세트페이지네이션에다음페이지버튼추가방법
__항목102:ROW_NUMBER()을통한페이지네이션구현방법

14장.쿼리
__항목103:하이버네이트HINT_PASS_DISTINCT_THROUGH를통한SELECTDISTINCT최적화방법
__항목104:JPA콜백설정방법
____@EntityListeners를통한분리된리스너클래스
__항목105:스프링데이터쿼리빌더를통한결과세트크기제한과카운트및삭제파생쿼리사용방법
____결과세트크기제한
____카운트및삭제파생쿼리
__항목106:포스트커밋에서시간소요가많은작업을피해야하는이유
__항목107:중복된save()호출을피하는방법
__항목108:N+1문제방지이유와방법
____하이버네이트@Fetch(FetchMode.JOIN)과N+1
____FetchMode.JOIN대신JOINFETCH사용
____FetchMode.JOIN대신엔터티그래프사용
__항목109:하이버네이트기반소프트삭제지원사용방법
____하이버네이트소프트삭제
____테스트확인
____유용한쿼리
____현재영속성콘텍스트에서Deleted속성업데이트
__항목110:OSIV안티패턴회피이유와방법
____Hibernate5Module
____로드되지않은속성에대한명시적(수동)초기화
____하이버네이트의hibernate.enable_lazy_load_no_trans에대해
__항목111:UTC시간대로날짜/시간저장방법(MySQL)
__항목112:ORDERBYRAND()를통해작은결과세트를뒤섞는방법
__항목113:WHERE/HAVING절에서서브쿼리를사용하는방법
__항목114:저장프로시저호출방법
____값(스칼라데이터타입)을반환하는저장프로시저호출
____결과세트를반환하는저장프로시저호출
____항목115:프록시를언프록시하는방법
____프록시객체란?
____엔터티객체와프록시객체는동일하지않음
____프록시에대한언프록시
____엔터티객체와언프록시객체는동일함
__항목116:데이터베이스뷰매핑방법
__항목117:데이터베이스뷰수정방법
____UPDATE문트리거
____INSERT문트리거
____DELETE문트리거
__항목118:WITHCHECKOPTION을사용하는이유와방법
__항목119:데이터베이스임시순위를행에효율적으로할당하는방법
____쿼리와OVER절에ORDERBY절사용
____OVER절에여러칼럼사용
__항목120:모든그룹의상위N개행을효율적으로찾는방법
__항목121:SpecificationAPI를통한고급검색구현방법
____테스트확인
____장르Anthology의40세이상저자모두가져오기
____가격이60미만인도서에대한페이지가져오기
____다음단계
__항목122:IN절파라미터패딩을통한SQL캐싱향상방법
__항목123:Specification쿼리페치조인생성방법
____메모리기반조인페치및페이지네이션
____데이터베이스에서조인페치및페이지네이션
__항목124:하이버네이트쿼리실행계획캐시사용방법
__항목125:스프링QBE(QueryByExample)를통한비영속엔터티의데이터베이스존재여부확인방법
____모든속성의일대일비교
____일부속성의일대일비교
____하위속성집합에대한Or결합적용
__항목126:하이버네이트@DynamicUpdate를통해수정된칼럼만UPDATE문에포함하는방법
__항목127:스프링에서네임드(네이티브)쿼리를사용하는방법
____네임드(네이티브)쿼리참조
____@NamedQuery및@NamedNativeQuery사용
____속성파일(jpa-named-queries.properties)사용
__항목128:다른쿼리/요청에서부모와자식을가져오는가장좋은방법
__항목129:업데이트를사용한병합작업최적화방법
__항목130:SKIPLOCKED옵션을통한동시테이블기반큐구현방법
____SKIPLOCKED설정
____테스트확인
__항목131:버전기반(@Version)OptimisticLockException발생후트랜잭션재시도방법
____버전기반낙관적잠금예외
____낙관적잠금예외시뮬레이션
____트랜잭션재시도
____테스트시나리오
__항목132:버전없는OptimisticLockException의트랜잭션재시도방법
____버전없는낙관적잠금예외
____낙관적잠금예외시뮬레이션
____트랜잭션재시도
____테스트시나리오
__항목133:버전기반낙관적잠금및분리된엔터티를처리하는방법
__항목134:장기HTTP통신에서의낙관적잠금메커니즘및분리된엔터티사용방법
____테스트확인
__항목135:엔터티가수정되지않은경우에도잠긴엔터티버전을증가시키는방법
____OPTIMISTIC_FORCE_INCREMENT
____PESSIMISTIC_FORCE_INCREMENT
__항목136:PESSIMISTIC_READ/WRITE작동방식
____PESSIMISTIC_READ
____PESSIMISTIC_WRITE
__항목137:PESSIMISTIC_WRITE가UPDATE/INSERT및DELETE에서작동하는방식
____UPDATE트리거
____DELETE트리거
____INSERT트리거

15장.상속
__항목138:단일테이블상속을효율적으로사용하는방법
____데이터저장
____쿼리및단일테이블상속
____하위클래스속성Non-Nullability이슈
____구분자칼럼의메모리사용량최적화
__항목139:SINGLE_TABLE상속계층구조에서특정하위클래스가져오기
__항목140:조인테이블상속의효율적사용방법
____데이터저장
____쿼리및조인테이블상속
____JPAJOINED상속전략및전략디자인패턴사용방법
__항목141:클래스별테이블상속의효율적사용방법
____데이터저장
____쿼리및클래스별테이블상속
__항목142:@MappedSuperclass효율적사용방법
____데이터저장

16장.일반타입과하이버네이트타입
__항목143:하이버네이트타입라이브러리를통한하이버네이트및미지원타입처리방법
__항목144:CLOB및BLOB매핑방법
____사용용이성(성능에대한트레이드오프)
____성능저하방지(트레이드오프는사용용이성)
__항목145:자바열거형을데이터베이스에효율적으로매핑하는방법
____EnumType.STRING을통한매핑
____EnumType.ORDINAL을통한매핑
____열거형을커스텀표현방식으로매핑
____열거형을데이터베이스Enum타입에매핑(PostgreSQL)
__항목146:JSON자바객체를MySQLJSON칼럼에효율적으로매핑하는방법
____Author저장
____Author가져오기/수정하기
____JSON쿼리를통한Author가져오기
__항목147:JSON자바Object를PostgreSQLJSON칼럼에효율적으로매핑하는방법
____Author저장
____Author가져오기/수정하기
____JSON쿼리를통한Author가져오기

부록A.(하이버네이트)JPA기본사항
__영속성유닛이란?
__EntityManagerFactory란?
__EntityManager란?
__엔터티상태전이

부록B.연관관계효율성

부록C.하루를절약할수있는5가지SQL성능팁
__WHERE절에서의SQL함수사용
__인덱스칼럼순서의중요성
__기본키와고유키
__LIKE와동등(=)
__UNION과UNIONALL및JOIN형태

부록D.유용한데이터베이스인덱스를만드는방법
__JPA2.1@Index
__인덱스를추측하지말자
__인덱싱을위해가장많이사용되는SQL쿼리우선순위지정
__인덱스가필요한중요한SQL쿼리
__GROUPBY및ORDERBY인덱싱을통한정렬작업방지
__고유성을위한인덱스사용
__외래키에대한인덱스사용
__인덱스전용액세스를위한칼럼추가
__나쁜표준을피하자

부록E.SQLPhenomena
__DirtyWrites
__DirtyReads
__Non-RepeatableReads
__PhantomReads
__ReadSkews
__WriteSkews
__LostUpdates


부록F.스프링트랜잭션격리수준
__@Transactional(isolation=Isolation.READ_UNCOMMITTED)
__@Transactional(isolation=Isolation.READ_COMMITTED)
__@Transactional(isolation=Isolation.REPEATABLE_READ)
__@Transactional(isolation=Isolation.SERIALIZABLE)

부록G.스프링트랜잭션전파
__Propagation.REQUIRED
__Propagation.REQUIRES_NEW
__Propagation.NESTED
__Propagation.MANDATORY
__Propagation.NEVER
__Propagation.NOT_SUPPORTED
__Propagation.SUPPORTS

부록H.플러싱메커니즘
__엄격한플러시작업순서
__데이터질의어(DQL)실행전플러시:SELECT쿼리
__트랜잭션커밋전플러시
__자동플러시모드
__코드이야기
__글로벌플러시모드
__서비스수준플러시모드
__쿼리수준플러시모드

부록I.2차캐시
__NONSTRICT_READ_WRITE
__READ_ONLY
__READ_WRITE
__TRANSACTIONAL
__쿼리캐시

부록J.도구

부록K.하이버네이트6

출판사 서평

이책에서다루는내용

스프링,스프링부트,하이버네이트를사용해자바에서데이터유지하는방법
더티트래킹활성화방법
다대다연관관계를효율적으로구성하고List와Set선택을결정하는방법
MySQL을통한데이터스트리밍방법
단일SELECT로부모측과연관관계를효율적으로가져오는방법
포크(fork)/조인(join)프레임워크를통한배치파일처리방법
컬렉션및커넥션작업방법
쿼리,잠금,스키마,하이버네이트타입에대한처리방법

지은이의말

간단히말해이책은스프링부트애플리케이션의자바영속성(Persistence)성능에대한모범사례모음집이다.모범사례는120개이상의항목을통해제공되며,다음과같이3가지범주로분류된다.

첫째,엔터티정의,관계매핑,쿼리작성,데이터가져오기,식별자(identifier)생성기(generator)선택등에대한모범사례를다룬다.주로스프링부트기본제공아티팩트(artifact)로도움을받을수없는영역과수정이어렵고도메인모델에상당한변경을필요로하는심각한성능저하방지를다룬다.

둘째,스프링부트지원기능(더정확하게는스프링데이터)사용을위한모범사례를다룬다.기본지원기능의묘책을활용하다보면성능이저하될수있다.예를들어OSIV(OpenSessioninView),오프셋페이지네이션(offsetpagination),커밋후후크(post-commitshook),@Transactional에대한오해는다루는주제중일부에불과하다.여러분은이범위항목들에뛰어들준비가돼있고흥미를느낄것이라확신한다.

셋째,애플리케이션의성능을유지할수있는몇가지하이버네이트기능을자세히알아본다.기본적으로스프링데이터는영속성공급자로,하이버네이트를사용하기에스프링데이터를통해하이버네이트를활용할수있을뿐만아니라하이버네이트자체로도활용할수있다.하이버네이트프록시(proxy)를통한자식측부모연관관계채우기(populating),더티트래킹(DirtyTracking),커넥션(connection)획득지연,지연로딩(lazyloading)속성,자연키(naturalkey)사용과같은좋은기능은다루는항목중일부에불과하다.

이책의전제조건은매우명확하다.IDE(예:NetBeans,Eclipse,IntelliJIDEA,VisualStudio등),MySQL및PostgreSQL이필요하다.선택적으로다른데이터베이스벤더(예:오라클,SQL서버등)를설치하거나사용할수있다.

옮긴이의말

스프링프레임워크,특히최근클라우드네이티브(cloud-native)기반애플리케이션구축에많이사용되는스프링부트기반에서데이터액세스기술로인기를끌고있는것이바로JPA(JavaPersistenceAPI)다.개별데이터베이스시스템마다네이티브(native)쿼리를작성해야하는MyBatis나코드에직접쿼리를작성하는JDBC기반개발은DBMS대상을확대하기가쉽지않지만,JPA의경우간단한설정변경만으로여러DBMS와버전을손쉽게지원하는특징을갖는다.무엇보다도SQL중심이아닌객체지향적설계및개발방식을지원한다.

그러나JPA는기존에익숙하던방식이나직관적인다른데이터액세스기술과는달리내부적인처리메커니즘을어느정도알고동작방식을이해해야어려움없이활용할수있다.즉,학습곡선(learningcurve)이가파르다.특히잘못설계된엔터티(entity)는성능에많은영향을주기도하고,정확하게설정되지않은연관관계(association)는예외가발생하는등의난항을겪는경우가많다.

이책은JPA에대한다양한측면,특히성능과관련된이슈와이에대한해결방법을다룬다.다만JPA의기초를다루지않고JPA사용에대한기본지식을갖고있어야볼수있는수준으로,JPA를이미사용하고있는개발자를위한레시피(recipe)와모범사례(bestpractices)를모았다.실용적인레시피를중심으로구성되고,각레시피는성능사례또는성능관련사례를중점적으로다루고있으며여러스타일(순수하이버네이트사용,스프링데이터JPA등)로작성된온전한많은예제를포함하고있다.