JPA 40

JPQL 기본 문법

TypedQuery : 리턴 타입이 확실한 경우 사용 TypedQuery query1 = em.createQuery("select m from Member m", Member.class); TypedQuery query2 = em.createQuery("select m.username from Member m", String.class); Query : 리턴 타입이 정확하지 않을 경우 사용 Query query3 = em.createQuery("select m.username, m.age from Member m"); 단순 값을 DTO로 조회 : 패키지 명을 전부 적어야함 List resultList = em.createQuery("select new jpql.MemberDTO(m.username, m...

JPA/JPQL 2020.06.09

JPQL 특징

JPQL은 SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다. 엔티티와 속성은 대소문자 구분 - 엔티티 : 대문자 (Member) - 속성 : 소문자 (age) JPQL 키워드는 대소문자 구분 X(SELECT, FROM , where) 엔티티 이름 사용, 테이블 이름이 아님 별칭은 필수(as 생략 가능) ANSI 규약의 쿼리문은 모두 지원함 - COUNT, SUM, AVG ... - GROUP BY, HAVING, ORDER BY ... TypeQuery : 반환 타입이 명확할 때 사용 - Query 반환 타입이 명확하지 않을 때 사용

JPA/JPQL 2020.06.09

SAVE 메서드 주의 사항

새로운 엔티티인 경우 저장 새로운 엔티티가 아닌 경우 MERGE 함 *** @GeneratedValue 인 경우 식별자가 없을 경우 SAVE 가 호출되나 @Id 만 사용한 경우 식별자가 있는 것으로 간주하여 SELECT SAVE가 호출된다. 매우 비효율적이므로 implements Persistable의 isNew를 구현하여 직접 SAVE가 호출되도록 할 수 있다. @Entity @Getter @EntityListeners(AuditingEntityListener.class) @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Item implements Persistable { @Id private String id; @CreatedDate ..

JPA/JPA 2020.06.09

사용자 정의 리포지토리 구현

화면 조회시 사용되는 복잡한 쿼리들은 기존 리포지토리를 사용하지 말고, 새로운 리포지토리를 생성하여 사용 권장 // 기능 인터페이스 생성 public interface MemberRepositoryCustom { List findMemberCustom(); } // 인터페이스 구현 @RequiredArgsConstructor public class MemberRepositoryImpl implements MemberRepositoryCustom { // 이름을 맞춰야함 class명 + impl private final EntityManager em; // 주입 권장방식 @Override public List findMemberCustom() { return em.createQuery("select m f..

JPA/JPA 2020.06.09

페이징 처리

**페이지수는 0부터 시작한다 public interface MemberRepository extends JpaRepository { // 기본 페이징 처리(totalcnt 조회 가능) Page findByAge(int age, Pageable pageable); // 가져오려는 수보다 +1 더 가져와 구현 가능(totalcnt 없음), 모바일 device에서 구현할때 사용함.(미리 로딩 가능) Slice findByAge(int age, Pageable pageable); // 카운트 쿼리를 분리해서 사용이 가능하다. @Query(countQuery = "") ... } // 구현부 int page = 0; int limit = 3; PageRequest pageRequest = PageRequest...

JPA/JPA 2020.06.09

Auditing

엔티티 생성, 변경할 때 변경한 사람과 시간을 알고 싶은 경우 Main class에 @EnableJpaAuditing 추가 등록일 수정일 등록자 수정자 @EntityListeners(AuditingEntityListener.class) @MappedSuperclass public class JpaBaseEntity { @CreatedDate @Column(updatable = false) private LocalDateTime createdDate; @LastModifiedDate private LocalDateTime lastModifiedDated; @CreatedBy @Column(updatable = false) private String createdBy; @LastModifiedBy priva..

JPA/JPA 2020.06.09

컬렉션 조회(OneToMany)

Fetch 조인 사용시 페이징 처리는 하지 말것. 모든 데이터 조회 이후 메모리에서 페이징 처리하므로 큰 장애가 발생할 수 있음. Fetch 조인 페이징 처리 방법 XtoOne 관계는 모두 Fetch 조인 컬렉션은 지연 로딩으로 조회 fetch 조인 로딩값 개수 설정 spring: jpa: properties: hibernate: default_batch_fetch_size: 100 // in 쿼리 갯수 lazy 로딩 값 한번에 호출 복합키는 복합키 클래스를 생성해서 처리해야함.

JPA/JPA 2020.06.09

OneToOne Entity

부모 Entity 조회 // OneToOne 관계의 경우 Lazy 로딩이 정상 동작하지 않는 경우가 많다. // lazy 로딩이 정상동작하기 위해선 특정 조건을 충족해야한다. // lazy 로딩 발생 jpaUserRepository.findAll() .stream() .map(user -> // Model 데이터 매핑 User.builder() .userId(user.getId()) .name(user.getName()) .build(); ).forEach(user -> System.out.println(user.toString())); // Lazy 로딩이 발생하지 않는다.(JPQL 사용) em.createQuery( "select new com.test.react.Model.User(u.id, u.n..

JPA/JPA 2020.06.09

변경 감지와 병합(merge)

준영속 엔티티 영속성 컨텍스트가 관리하지 않는 엔티티로 update해도 데이터는 변경되지 않음. 임의로 만들어낸 엔티티 Book book = new Book(); book.setId(form.getId()); book.setName(form.getName()); 준영속 엔티티 수정하는 방법(병합 사용은 추천하지 않음) 변경 감지 기능 사용(Dirty Checking), setter 대신 함수를 이용해서 변경하도록 하라 tem findItem = itemRepository.findOne(itemId); findItem.setPrice(bookParam.getPrice()); findItem.setName(bookParam.getName()); findItem.setStockQuantity(bookParam..

JPA/JPA 2020.06.09