벌크성 수정 쿼리
2022. 7. 21. 03:02
JPA/JPA-Spring Data
JPA를 사용한 벌크성 수정 쿼리 public int bulkAgePlus(int age) { int resultCount = em.createQuery( "update Member m set m.age = m.age + 1" + "where m.age >= :age") .setParameter("age", age) .executeUpdate(); return resultCount; } JPA를 사용한 벌크성 수정 쿼리 테스트 @Test public void bulkUpdate() throws Exception { //given memberJpaRepository.save(new Member("member1", 10)); memberJpaRepository.save(new Member("member2",..
스프링 데이터 JPA 페이징과 정렬
2022. 7. 20. 20:45
JPA/JPA-Spring Data
페이징과 정렬 파라미터 org.springframework.data.domain.Sort : 정렬 기능 org.springframework.data.domain.Pageable : 페이징 기능 (내부에 Sort 포함) 특별한 반환 타입 org.springframework.data.domain.Page : 추가 count 쿼리 결과를 포함하는 페이징 org.springframework.data.domain.Slice : 추가 count 쿼리 없이 다음 페이지만 확인 가능(내부적으로 limit + 1조회) List (자바 컬렉션): 추가 count 쿼리 없이 결과만 반 Page 인터페이스 public interface Page extends Slice { int getTotalPages(); //전체 페이지..
순수 JPA 페이징과 정렬
2022. 7. 20. 18:15
JPA/JPA-Spring Data
public List findByPage(int age, int offset, int limit) { return em.createQuery("select m from Member m where m.age = :age order by m.username desc") .setParameter("age", age) .setFirstResult(offset) .setMaxResults(limit) .getResultList(); } public long totalCount(int age) { return em.createQuery("select count(m) from Member m where m.age = :age", Long.class) .setParameter("age", age) .getSingleR..
파라미터 바인딩
2022. 7. 20. 13:15
JPA/JPA-Spring Data
select m from Member m where m.username = ?0 //위치 기반 select m from Member m where m.username = :name //이름 기반 import org.springframework.data.repository.query.Param public interface MemberRepository extends JpaRepository { @Query("select m from Member m where m.username = :name") Member findMembers(@Param("name") String username); } 컬렉션 파라미터 바인딩 Collection 타입으로 in절 지원 @Query("select m from Member..
@Query, 값, DTO 조회하기
2022. 7. 20. 12:46
JPA/JPA-Spring Data
@Query("select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) " + "from Member m join m.team t") List findMemberDto(); package study.datajpa.repository; import lombok.Data; @Data public class MemberDto { private Long id; private String username; private String teamName; public MemberDto(Long id, String username, String teamName) { this.id = id; this.username = username; this.teamName ..
@Query, 리포지토리 메소드에 쿼리 정의하기
2022. 7. 20. 12:31
JPA/JPA-Spring Data
public interface MemberRepository extends JpaRepository { @Query("select m from Member m where m.username= :username and m.age = :age") List findUser(@Param("username") String username, @Param("age") int age); } 출처 : 김영한 JPA 스프링 데이터 강의
JPA NamedQuery
2022. 7. 19. 21:02
JPA/JPA-Spring Data
* @NamedQuery 어노테이션으로 Named 쿼리 정의* @Entity @NamedQuery( name="Member.findByUsername", query="select m from Member m where m.username = :username") public class Member { ... } JPA를 직접 사용해서 Named 쿼리 호출 public class MemberRepository { public List findByUsername(String username) { ... List resultList = em.createNamedQuery("Member.findByUsername", Member.class) .setParameter("username", username) .ge..
메소드 이름으로 쿼리 생성
2022. 7. 19. 18:17
JPA/JPA-Spring Data
public interface MemberRepository extends JpaRepository { List findByUsernameAndAge(String username, int age); } 순수 JPA 리포지토리 public List findByUsernameAndAge(String username, int age) { return em.createQuery("select m from Member m where m.username = :username and m.age > :age") .setParameter("username", username) .setParameter("age", age) .getResultList(); } 순수 JPA 테스트 코드 @Test public void fin..
공통 인터페이스 설정
2022. 7. 19. 17:38
JPA/JPA-Spring Data
1. 공통 인터페이스 설정 JavaConfig 설정- 스프링 부트 사용시 생략 가능 @Configuration @EnableJpaRepositories(basePackages = "jpabook.jpashop.repository") public class AppConfig {} 스프링 데이터 JPA가 구현 클래스 대신 생성 public interface MemberRepository extends JpaRepository { } JpaRepository 인터페이스: 공통 CRUD 제공 제네릭은 설정 주의 T findOne(ID) Optional findById(ID) 변경 제네릭 타입 T : 엔티티ID : 엔티티의 식별자 타입 S : 엔티티와 그 자식 타입 주요 메서드 save(S) : 새로운 엔티티는 ..
순수 JPA 기반 리포지토리 만들기
2022. 7. 19. 02:41
JPA/JPA-Spring Data
package study.datajpa.repository; import org.springframework.stereotype.Repository; import study.datajpa.entity.Member; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import java.util.List; import java.util.Optional; @Repository public class MemberJpaRepository { @PersistenceContext private EntityManager em; public Member save(Member member) { em.persist(mem..
예제 도메인 모델
2022. 7. 19. 00:10
JPA/JPA-Spring Data
package study.datajpa.entity; import lombok.*; import javax.persistence.*; @Entity @Getter @Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) @ToString(of = {"id", "username", "age"}) public class Member { @Id @GeneratedValue @Column(name = "member_id") private Long id; private String username; private int age; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "team_id") private Team..
@Enumerated
2022. 7. 11. 20:14
JPA/Annotation
1. @Enumerated @Enumerated 어노테이션은 java 의 enum 형태로 되어 있는 미리 정의되어 있는 코드 값이나 구분값을 데이타 타입으로 사용하고자 할때 사용됩니다. 속성으로 EnumType.ORDINAL, EnumType.STRING 이 있는데 ORDINAL 은 enum 객체에 정의된 순서가 컬럼의 값으로 사용되고 STRING 은 enum 의 문자열 자체가 컬럼의 값으로 사용이 됩니다.
@GeneratedValue
2022. 7. 11. 20:13
JPA/Annotation
1. @GeneratedValue : PK 컬럼의 데이타 형식은 정해져 있지는 않으나 구분이 가능한 유일한 값을 가지고 있어야 하고 데이타 경합으로 인해 발생되는 데드락 같은 현상을 방지 하기 위해 대부분 BigInterger 즉 Java 의 Long 을 주로 사용합니다. 물론 String 형태의 고정된 키값을 직접 생성해서 관리하기도 합니다. 중요한 것은 대량의 요청이 유입 되더라도 중복과 deadlock 데드락이 발생 되지 않을 만큼 키값이 빨리 생성이 되고 안전하게 관리 되어야 한다는 점입니다. - deadlock 동일한 시점에 요청이 유입 되었을때 데이타베이스는 테이블 혹은 레코드를 lock 을 걸어 데이타가 변경되지 않도록 막아 놓고 다른 작업을 진행합니다. 이때 1번째 요청이 A 테이블의 값을..
@Id 어노테이션
2022. 7. 11. 20:07
JPA/Annotation
1. @Id 어노테이션 : JPA 에서도 Entity 클래스 상에 해당 PK 를 명시적으로 표시를 해야 되는데 그것을 @Id 어노테이션을 이용해 이것이 PK 임을 지정 합니다. 만약 Spring Boot 의 spring.jpa.hibernate.ddl-auto 속성이 create 로 되어 있고 아직 해당 테이블이 데이타베이스상에 존재하지 않는다면 EntityManager 가 DDL 을 통해 테이블을 생성하면서 PK 를 같이 생성해 줍니다.
JPQL - 벌크 연산
2022. 7. 10. 14:21
JPA
1. 벌크 연산 • 재고가 10개 미만인 모든 상품의 가격을 10% 상승하려면? • JPA 변경 감지 기능으로 실행하려면 너무 많은 SQL 실행 • 1. 재고가 10개 미만인 상품을 리스트로 조회한다. • 2. 상품 엔티티의 가격을 10% 증가한다. • 3. 트랜잭션 커밋 시점에 변경감지가 동작한다. • 변경된 데이터가 100건이라면 100번의 UPDATE SQL 실행 2. 벌크 연산 예제 • 쿼리 한 번으로 여러 테이블 로우 변경(엔티티) • executeUpdate()의 결과는 영향받은 엔티티 수 반환 • UPDATE, DELETE 지원 • INSERT(insert into .. select, 하이버네이트 지원) 3. 벌크 연산 주의 • 벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리..
JPQL - Named 쿼리
2022. 7. 10. 14:04
JPA
1. Named 쿼리 - 정적 쿼리 • 미리 정의해서 이름을 부여해두고 사용하는 JPQL • 정적 쿼리 • 어노테이션, XML에 정의 • 애플리케이션 로딩 시점에 초기화 후 재사용 • 애플리케이션 로딩 시점에 쿼리를 검증 2. Named 쿼리 - 어노테이션 3. Named 쿼리 - XML에 정의 • XML이 항상 우선권을 가진다. • 애플리케이션 운영 환경에 따라 다른 XML을 배포할 수 있다. 출처 : 김영한, 자바 ORM 표준 JPA 프로그래밍 - 기본편
JPQL - 엔티티 직접 사용
2022. 7. 10. 13:47
JPA
1. 엔티티 직접 사용 - 기본 키 값 • JPQL에서 엔티티를 직접 사용하면 SQL에서 해당 엔티티의 기 본 키 값을 사용 • [JPQL] select count(m.id) from Member m //엔티티의 아이디를 사용 select count(m) from Member m //엔티티를 직접 사용 • [SQL](JPQL 둘다 같은 다음 SQL 실행) select count(m.id) as cnt from Member m 2. 엔티티 직접 사용 - 외래 키 값 출처 : 김영한, 자바 ORM 표준 JPA 프로그래밍 - 기본편
JPQL - 다형성 쿼리
2022. 7. 10. 13:24
JPA
1. TYPE • 조회 대상을 특정 자식으로 한정 • 예) Item 중에 Book, Movie를 조회해라 • [JPQL] select i from Item i where type(i) IN (Book, Movie) • [SQL] select i from i where i.DTYPE in (‘B’, ‘M’) 2. TREAT(JPA 2.1) • 자바의 타입 캐스팅과 유사 • 상속 구조에서 부모 타입을 특정 자식 타입으로 다룰 때 사용 • FROM, WHERE, SELECT(하이버네이트 지원) 사용 예) 부모인 Item과 자식 Book이 있다. • [JPQL] select i from Item i where treat(i as Book).auther = ‘kim’ • [SQL] select i.* from I..
JPQL - 페치 조인(fetch join)
2022. 7. 10. 01:58
JPA
1. 페치 조인(fetch join) • SQL 조인 종류X • JPQL에서 성능 최적화를 위해 제공하는 기능 • 연관된 엔티티나 컬렉션을 SQL 한 번에 함께 조회하는 기능 • join fetch 명령어 사용 • 페치 조인 ::= [ LEFT [OUTER] | INNER ] JOIN FETCH 조인경로 2. 엔티티 페치 조인 • 회원을 조회하면서 연관된 팀도 함께 조회(SQL 한 번에) • SQL을 보면 회원 뿐만 아니라 팀(T.*)도 함께 SELECT • [JPQL] select m from Member m join fetch m.team • [SQL] SELECT M.*, T.* FROM MEMBER M INNER JOIN TEAM T ON M.TEAM_ID=T.ID //회원1, 팀A(SQL) //..
JPQL - 경로 표현식
2022. 7. 8. 22:26
JPA
1. JPQL - 경로 표현식 • .(점)을 찍어 객체 그래프를 탐색하는 것 2. 경로 표현식 용어 정리 • 상태 필드(state field): 단순히 값을 저장하기 위한 필드 (ex: m.username) • 연관 필드(association field): 연관관계를 위한 필드 • 단일 값 연관 필드: @ManyToOne, @OneToOne, 대상이 엔티티(ex: m.team) • 컬렉션 값 연관 필드: @OneToMany, @ManyToMany, 대상이 컬렉션(ex: m.orders) 2. 경로 표현식 특징 • 상태 필드(state field): 경로 탐색의 끝, 탐색X JPQL: select m.username, m.age from Member m SQL: select m.username, m.age..