JPA

아래 세가지 지원 기능은 제약이 커서 복잡한 실무 환경에서의 사용은 선택적으로! 1. 인터페이스 지원 - QuerydslPredicateExecutor Pageable, Sort 지원 // 리포지토리에 적용 public interface MemberRepository extends JpaRepository, CustomMemberRepository, QuerydslPredicateExecutor { ... } // 서비스에서 사용 Iterable result = memberRepository.findAll( member.age.between(10, 40) .and(member.username.eq("1"))); 한계 외부 조인 불가능 (묵시적 조인 가능) 클라이언트가 Querydsl 구현기술에 의존 2...
스프링 데이터 JPA 리포지토리로 변경 public interface MemberRepository extends JpaRepository { List findByUsername(String username); } 테스트 @SpringBootTest @Transactional class MemberRepositoryTest { @Autowired EntityManager em; @Autowired MemberRepository memberRepository; @Test public void basicTest() { Member member = new Member("member1", 10); memberRepository.save(member); Member findMember = memberReposit..
순수 JPA 리포지토리와 Querydsl 스프링이 주입하는 em은 실제 동작 시점에 트랜잭션 단위로 진짜 엔티티 매니저를 찾아주는 프록시 엔티티 매니저임 JPAQueryFactory를 메인 어플리케이션 클래스에 Bean으로 등록하고, 리포지토리에서 주입받아도 됨 장점: @RequiredArgsConstructor 활용해 리포지토리 코드 짤 때 깔끔함 단점: 두 개를 주입받아야 하므로 테스트코드 짤 때 불편함 @Bean JPAQueryFactory jpaQueryFactory(EntityManager em) { return new JPAQueryFactory(em); } 리포지토리 @Repository public class MemberJpaRepository { private final EntityMan..
* F2: IntelliJ 오류난 곳으로 바로 이동 프로젝션과 결과 반환 - 기본 프로젝션: select 대상 지정 튜플은 querydsl 종속적인 자료형이기 때문에 repository 계층이 아닌 controller나 service 단에서는 사용 지양 다른 계층으로 넘길 때는 DTO 사용 권장 // 프로젝션 대상 하나 @Test public void simpleProjection() { List result = queryFactory .select(member.username) // 이름만 지정 .from(member) .fetch(); for (String s : result) { System.out.println("s = " + s); } } // 프로젝션 대상 여러개 @Test public voi..
기초 설정 스프링, Querydsl 버전에 따라 설정하는 법이 계속 바뀜 강의 수강 시점에서의 설정 방법: https://www.inflearn.com/chats/669477 Q파일은 gitignore Q타입 생성 확인 후 테스트 케이스로 실행 검증 h2 설치 및 설정 -> sql 로그 출력, 쿼리 파라미터 로그 출력(운영 단계에서는 성능 테스트하고 사용) # application.yml spring: profiles: active: local datasource: url: jdbc:h2:tcp://localhost/~/querydsl username: sa password: driver-class-name: org.h2.Driver jpa: hibernate: ddl-auto: create proper..
경로 표현식 .(점)을 찍어 객체 그래프 탐색 상태 필드: 단순히 값을 저장하기 위한 필드 예: m.username 연관 필드: 연관관계를 위한 필드 단일 값 연관 필드: 대상이 엔티티, @ManyToOne, @OneToOne 예: m.team 컬렉션 값 연관 필드: 대상이 컬렉션, @OneToMany, @ManyToMany 예: m.orders 특징 상태 필드: 경로 탐색의 끝, 더 이상 탐색 불가 예: select m.username, m.age from Member m 단일 값 연관 경로: 묵시적 내부 조인 발생, 더 탐색 가능 예: select o.member from Order o 탐색 시 자바로는 .(점)만 찍으면 되기 때문에 편하지만 db에서는 조인이 일어나므로 사용 지양 컬렉션 값 연관 경..
문법예) select m from Member as m where m.age > 18엔티티와 속성은 대소문자 구분 (Member, age)JPQL 키워드는 대소문자 구분 X (select, from, where)엔티티 이름 사용 (테이블명 X)별칭 필수 (m), as 생략 가능집합과 정렬TypeQuery, QueryTypeQuery: 반환 타입 명확할 때Query: 반환 타입 명확하지 않을 때 TypedQuery q1 = em.createQuery("select m from Member as m where m.age > 18", Member.class); Query q2 = em.createQuery("select m.username, m.age from Member as m where m.a..
JPQL SQL을 추상화한 객체 지향 쿼리 언어 SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원 엔티티 객체를 대상으로 쿼리 특정 DB SQL에 의존하지 않음 결국에는 SQL로 변환된다 오타에 취약하고, 동적 쿼리 생성에 어려움이 있다 (그냥 String이기 때문) Criteria(JPA 공식 기술): JPQL 빌더 (실무 사용 X) -> QueryDSL 사용 권장 em.createQuery("쿼리문", 반환 객체) QueryDSL(오픈 소스) 문자가 아닌 자바코드로 JPQL 작성 (JPQL 빌더 역할) 컴파일 시점에 문법 오류 발견 가능 동적 쿼리 작성 편리 공식 사이트에 친절하게 정리되어 있음 네이티브 SQL JPA가 제공하는 SQL을 직접 사용 JPQL로 해결할 ..
기본값 타입 JPA의 데이터 타입 분류 엔티티 타입: @Entity로 정의하는 객체 데이터가 변해도 식별자로 지속해서 추적 가능 예) 회원 엔티티의 키나 나이 값을 변경해도 식별자로 인식 가능 값 타입: int, Integer, String과 같이 단순히 값으로 사용하는 자바 기본 타입이나 객체 식별자가 없고 값만 있으므로 변경 시 추적 불가 예) 숫자 100을 200으로 변경하면 완전 대체 값 타입 분류 기본값 타입 임베디드 값 타입 컬렉션 값 타입 기본값 타입 예) String name, int age 생명주기가 엔티티에 의존 회원 엔티티 삭제 시 이름, 나이 필드 함께 삭제 값 타입은 공유하면 안됨 예) 회원 이름 변경 시 다른 회원의 이름도 변경되면 안됨 참고: int, double 같은 기본 타..
프록시 em.find(): DB에서 실제 엔티티 객체 조회 em.getReference(): DB 조회를 미루는 프록시 엔티티 객체 조회 Member member = new Member(); member.setUsername("a"); em.persist(member); em.flush(); // insert 문 실행 em.clear(); Member findMember = em.getReference(Member.class, member.getId()); // 프록시 Member class, select문 실행 X 프록시 특징 실제 엔티티를 상속받아 겉 모양이 같음 실제 객체의 참조를 보관 이론상 사용하는 입장에서 실제인지 프록시인지 구분 없이 사용하면 됨 프록시 객체 초기화 최초로 프록시 객체의 어떤..
hjkim0502
'JPA' 태그의 글 목록