Archive: 2022

0

QueryDSL - 동적 쿼리

목차 QueryDSL - QueryDsl 페이징 사용하기 QueryDSL - 사용자 정의 Repository QueryDSL - 동적 쿼리와 성능 최적화 조회 QueryDSL - 순수 JPA 리포지토리와 Querydsl QueryDSL - SQL Function 호출하기 QueryDSL - 수정, 삭제 벌크 연산 QueryDSL - 동적 쿼리 QueryDSL - 프로젝션과 결과 반환 QueryDSL - 조인 QueryDSL - 집계 QueryDSL - 결과 조회 QueryDSL - 검색 조건 쿼리 QueryDSL - Q-Type 활용 QueryDSL - JPA JPQL vs JPA QueryDSL QueryDSL 시작하기 동적 쿼리를 해결하는 두가지 방식 BooleanBuilder Where 다중 파라미터 사용 동적 쿼리 - BooleanBuilderBooleanBuilder 를 이용해 동적 쿼리를 작성할 수 있다. @Testpublic void dynamicQuery_BooleanBuilder(){ String usernameParam = "member1"; Integer ageParam = 10; List<Member> result = searchMember1(usernameParam, ageParam); assertThat(result.size()).isEqualTo(1);}private List<Member> searchMember1(String usernameCond, Integer ageCond){ BooleanBuilder builder = new BooleanBuilder(); if(usernameCond != null){ builder.and(member.username.eq(usernameCond)); } if(ageCond != null){ builder.and(member.age.eq(ageCond)); } return queryFactory .selectFrom(member) .where(builder) .fetch();} /* select member1 from Member member1 where member1.username = ?1 and member1.age = ?2 */ select member0_.member_id as member_i1_1_, member0_.age as age2_1_, member0_.team_id as team_id4_1_, member0_.username as username3_1_ from member member0_ where member0_.username=? and member0_.age=? 동적 쿼리 - Where 다중 파라미터 사용

0

QueryDSL - 프로젝션과 결과 반환

목차 QueryDSL - QueryDsl 페이징 사용하기 QueryDSL - 사용자 정의 Repository QueryDSL - 동적 쿼리와 성능 최적화 조회 QueryDSL - 순수 JPA 리포지토리와 Querydsl QueryDSL - SQL Function 호출하기 QueryDSL - 수정, 삭제 벌크 연산 QueryDSL - 동적 쿼리 QueryDSL - 프로젝션과 결과 반환 QueryDSL - 조인 QueryDSL - 집계 QueryDSL - 결과 조회 QueryDSL - 검색 조건 쿼리 QueryDSL - Q-Type 활용 QueryDSL - JPA JPQL vs JPA QueryDSL QueryDSL 시작하기 프로젝션과 결과 반환 프로젝션(Projection) 은 쿼리 결과를 가져올 때 반환할 필드를 지정하는 것 프로젝션 : select 대상 지정 프로젝션 대상이 하나면 타입을 명확하게 지정할 수 있다. 프로젝션 대상이 둘 이상이면 튜플 이나 DTO 로 조회한다. List<String> result = queryFactory .select(member.username.concat("_").concat(member.age.stringValue())) .from(member) .where(member.username.eq("member1")) .fetch(); 튜플 조회@Testpublic void tupleProjection(){ List<Tuple> result = queryFactory .select(member.username, member.age) .from(member) .fetch(); for (Tuple tuple : result){ String username = tuple.get(member.username); Integer age = tuple.get(member.age); System.out.println("username = " + username); System.out.println("age = " + age); }}

0

QueryDSL - 조인

목차 QueryDSL - QueryDsl 페이징 사용하기 QueryDSL - 사용자 정의 Repository QueryDSL - 동적 쿼리와 성능 최적화 조회 QueryDSL - 순수 JPA 리포지토리와 Querydsl QueryDSL - SQL Function 호출하기 QueryDSL - 수정, 삭제 벌크 연산 QueryDSL - 동적 쿼리 QueryDSL - 프로젝션과 결과 반환 QueryDSL - 조인 QueryDSL - 집계 QueryDSL - 결과 조회 QueryDSL - 검색 조건 쿼리 QueryDSL - Q-Type 활용 QueryDSL - JPA JPQL vs JPA QueryDSL QueryDSL 시작하기 기본 조인첫 번째 파라미터에 조인 대상을 지정하고, 두번째 파라미터에 별칭으로 사용할 Q 타입을 지정하면 된다. @Testpublic void join(){ List<Member> result = queryFactory.selectFrom(member) .join(member.team, team) .where(team.name.eq("teamA")) .fetch(); assertThat(result) .extracting("username") .containsExactly("member1", "member2");} /* select member1 from Member member1 inner join member1.team as team where team.name = ?1 */ select member0_.member_id as member_i1_1_, member0_.age as age2_1_, member0_.team_id as team_id4_1_, member0_.username as username3_1_ from member member0_ inner join team team1_ on member0_.team_id=team1_.team_id where team1_.name=? Seta Join From 절에 여러 엔티티를 선택해서 세타 조인이 가능하다. 외부 조인 불가능 조인 on 을 사용하면 외부 조인 가능 @Testpublic void setaJoin(){ em.persist(new Member("teamA")); em.persist(new Member("teamB")); List<Member> result = queryFactory.select(member) .from(member, team) .where(member.username.eq(team.name)) .fetch(); assertThat(result) .extracting("username") .containsExactly("teamA", "teamB");}

0

QueryDSL - 집계

목차 QueryDSL - QueryDsl 페이징 사용하기 QueryDSL - 사용자 정의 Repository QueryDSL - 동적 쿼리와 성능 최적화 조회 QueryDSL - 순수 JPA 리포지토리와 Querydsl QueryDSL - SQL Function 호출하기 QueryDSL - 수정, 삭제 벌크 연산 QueryDSL - 동적 쿼리 QueryDSL - 프로젝션과 결과 반환 QueryDSL - 조인 QueryDSL - 집계 QueryDSL - 결과 조회 QueryDSL - 검색 조건 쿼리 QueryDSL - Q-Type 활용 QueryDSL - JPA JPQL vs JPA QueryDSL QueryDSL 시작하기 집계 함수@Testpublic void aggregation(){ List<Tuple> result = queryFactory.select( member.count(), member.age.sum(), member.age.avg(), member.age.max(), member.age.min() ) .from(member) .fetch(); Tuple tuple = result.get(0); assertThat(tuple.get(member.count())).isEqualTo(4); assertThat(tuple.get(member.age.sum())).isEqualTo(100); assertThat(tuple.get(member.age.avg())).isEqualTo(25); assertThat(tuple.get(member.age.max())).isEqualTo(40); assertThat(tuple.get(member.age.min())).isEqualTo(10);} Group by@Testpublic void group() { List<Tuple> result = queryFactory.select(team.name, member.age.avg()) .from(member) .join(member.team, team) .groupBy(team.name) .fetch(); Tuple teamA = result.get(0); Tuple teamB = result.get(1); assertThat(teamA.get(team.name)).isEqualTo("teamA"); assertThat(teamA.get(member.age.avg())).isEqualTo(15); assertThat(teamB.get(team.name)).isEqualTo("teamB"); assertThat(teamB.get(member.age.avg())).isEqualTo(35);}

0

QueryDSL - 결과 조회

목차 QueryDSL - QueryDsl 페이징 사용하기 QueryDSL - 사용자 정의 Repository QueryDSL - 동적 쿼리와 성능 최적화 조회 QueryDSL - 순수 JPA 리포지토리와 Querydsl QueryDSL - SQL Function 호출하기 QueryDSL - 수정, 삭제 벌크 연산 QueryDSL - 동적 쿼리 QueryDSL - 프로젝션과 결과 반환 QueryDSL - 조인 QueryDSL - 집계 QueryDSL - 결과 조회 QueryDSL - 검색 조건 쿼리 QueryDSL - Q-Type 활용 QueryDSL - JPA JPQL vs JPA QueryDSL QueryDSL 시작하기 Querydsl 결과 조회 fetch : 리스트 조회, 데이터가 없으면 빈 리스트 반환 fetchOne : 단건 조회 결과가 없으면 : null 결과가 둘 이상이면 NonUniqueResultException fetchFirst : limit(1).fetchOne() 와 의미가 동일하다. fetchResults : 페이징 정보 포함, total count 쿼리 추가 실행 fetchCount : count 쿼리로 변경해서 count 수 조회 @Testpublic void resultFetch(){List<Member> fetch = queryFactory.selectFrom(member) .fetch();Member fetchOne = queryFactory.selectFrom(QMember.member) .fetchOne();Member fetchFirst = queryFactory.selectFrom(QMember.member) .fetchFirst();QueryResults<Member> results = queryFactory.selectFrom(member) .fetchResults();results.getTotal();List<Member> content = results.getResults();// Deprecatedlong total = queryFactory .selectFrom(member) .fetchCount();// Count 쿼리 작성long totalCount = queryFactory .select(member.count()) .from(member) .fetchOne(); fetchResults : 페이징 쿼리가 복잡해지면 content 를 가져오는 쿼리와 total count 를 가져오는 쿼리가 다를 때가 있어서 해당 메소드를 사용하면 안된다. 정렬@Testpublic void sort(){ em.persist(new Member(null, 100)); em.persist(new Member("member5", 100)); em.persist(new Member("member6", 100)); List<Member> result = queryFactory .selectFrom(member) .where(member.age.eq(100)) .orderBy(member.age.desc(), member.username.asc().nullsLast()) .fetch(); Member member5 = result.get(0); Member member6 = result.get(1); Member memberNull = result.get(2); assertThat(member5.getUsername()).isEqualTo("member5"); assertThat(member6.getUsername()).isEqualTo("member6"); assertThat(memberNull.getUsername()).isNull();} 페이징

0

QueryDSL - 검색 조건 쿼리

목차 QueryDSL - QueryDsl 페이징 사용하기 QueryDSL - 사용자 정의 Repository QueryDSL - 동적 쿼리와 성능 최적화 조회 QueryDSL - 순수 JPA 리포지토리와 Querydsl QueryDSL - SQL Function 호출하기 QueryDSL - 수정, 삭제 벌크 연산 QueryDSL - 동적 쿼리 QueryDSL - 프로젝션과 결과 반환 QueryDSL - 조인 QueryDSL - 집계 QueryDSL - 결과 조회 QueryDSL - 검색 조건 쿼리 QueryDSL - Q-Type 활용 QueryDSL - JPA JPQL vs JPA QueryDSL QueryDSL 시작하기 @Testpublic void startQuerydsl(){ QMember qMember = new QMember("m"); Member findMember = queryFactory .select(qMember) .from(qMember) .where(qMember.username.eq("member1")) .fetchOne(); assertThat(findMember.getUsername()).isEqualTo("member1");} @Testpublic void search(){ Member findMember = queryFactory .selectFrom(member) .where(member.username.eq("member1").and(member.age.eq(10))) .fetchOne(); assertThat(findMember.getUsername()).isEqualTo("member1");} and 를 풀어내는 방식 - and 메소드 사용 @Testpublic void search(){ Member findMember = queryFactory .selectFrom(member) .where( member.username.eq("member1").and(member.age.eq(10)) ) .fetchOne(); assertThat(findMember.getUsername()).isEqualTo("member1");} and 를 풀어내는 방식 - 파라미터로 넘기는 방법 @Testpublic void search(){ Member findMember = queryFactory .selectFrom(member) .where( member.username.eq("member1"), member.age.eq(10) ) .fetchOne(); assertThat(findMember.getUsername()).isEqualTo("member1");} Querydsl 에서 사용하는 검색 조건

0

QueryDSL - Q-Type 활용

목차 QueryDSL - QueryDsl 페이징 사용하기 QueryDSL - 사용자 정의 Repository QueryDSL - 동적 쿼리와 성능 최적화 조회 QueryDSL - 순수 JPA 리포지토리와 Querydsl QueryDSL - SQL Function 호출하기 QueryDSL - 수정, 삭제 벌크 연산 QueryDSL - 동적 쿼리 QueryDSL - 프로젝션과 결과 반환 QueryDSL - 조인 QueryDSL - 집계 QueryDSL - 결과 조회 QueryDSL - 검색 조건 쿼리 QueryDSL - Q-Type 활용 QueryDSL - JPA JPQL vs JPA QueryDSL QueryDSL 시작하기 Q 클래스 인스턴스를 사용하는 2가지 방법 생성자기 parameter 를 넘기게 되면 해당 값으로 alias 가 걸리게 된다. // 별칭 직접 지정 QMember qMember = new QMember("m"); // 기본 인스턴스 사용QMember qMember = QMember.member; use_sql_comments 옵션을 true 로 설정하게 되면 jpql comment 를 볼 수 있다. Configspring: datasource:# url: jdbc:h2:~/querydsl url: jdbc:h2:tcp://localhost/~/querydsl username: sa password: driver-class-name: org.h2.Driver jpa: hibernate: ddl-auto: create-drop properties: hibernate:# show_sql: true format_sql: true use_sql_comments: truelogging.level: org.hibernate.SQL: debug # org.hibernate.type: trace /* select m from Member m where m.username = :username */ select member0_.member_id as member_i1_1_, member0_.age as age2_1_, member0_.team_id as team_id4_1_, member0_.username as username3_1_ from member member0_ where member0_.username=?

0

JPA JPQL vs Querydsl

목차 Post not found: jpa/querydsl/querydsl-15 Post not found: jpa/querydsl/querydsl-14 QueryDSL - 동적 쿼리와 성능 최적화 조회 QueryDSL - 순수 JPA 리포지토리와 Querydsl QueryDSL - SQL Function 호출하기 Post not found: jpa/querydsl/querydsl-10 Post not found: jpa/querydsl/querydsl-09 Post not found: jpa/querydsl/querydsl-08 QueryDSL - 조인 QueryDSL - 집계 QueryDSL - 결과 조회 QueryDSL - 검색 조건 쿼리 Post not found: jpa/querydsl/querydsl-03 JPA JPQL vs Querydsl QueryDSL 시작하기 JPQL@Testpublic void startJPQL(){ // member1 을 찾아라 Member findByJPQL = em.createQuery("select m from Member m where m.username = :username", Member.class) .setParameter("username", "member1") .getSingleResult(); assertThat(findByJPQL.getUsername()).isEqualTo("member1");} Querydsl@Testpublic void startQuerydsl(){ JPAQueryFactory queryFactory = new JPAQueryFactory(em); QMember qMember = new QMember("m"); Member findMember = queryFactory .select(qMember) .from(qMember) .where(qMember.username.eq("member1")) .fetchOne(); assertThat(findMember.getUsername()).isEqualTo("member1");} Querydsl 은 기본적으로 parameter binding 시 preparedStatement 의 parameter binding 을 사용해 SQL injection 공격으로부터 안전하다. select member0_.member_id as member_i1_1_, member0_.age as age2_1_, member0_.team_id as team_id4_1_, member0_.username as username3_1_ from member member0_ where member0_.username=? jpql 은 런타임 오류가 발생하나 querydsl 은 컴파일시 에러가 발생하게 된다.

0

QueryDSL - JPA JPQL vs JPA QueryDSL

목차 QueryDSL - QueryDsl 페이징 사용하기 QueryDSL - 사용자 정의 Repository QueryDSL - 동적 쿼리와 성능 최적화 조회 QueryDSL - 순수 JPA 리포지토리와 Querydsl QueryDSL - SQL Function 호출하기 QueryDSL - 수정, 삭제 벌크 연산 QueryDSL - 동적 쿼리 QueryDSL - 프로젝션과 결과 반환 QueryDSL - 조인 QueryDSL - 집계 QueryDSL - 결과 조회 QueryDSL - 검색 조건 쿼리 QueryDSL - Q-Type 활용 QueryDSL - JPA JPQL vs JPA QueryDSL QueryDSL 시작하기 JPA JPQL JPQL 은 EntityManager 객체내 creatQuery 메소드를 이용해 쿼리를 작성한 후 실행한다. @Testpublic void startJPQL(){ // member1 을 찾아라 Member findByJPQL = em.createQuery("select m from Member m where m.username = :username", Member.class) .setParameter("username", "member1") .getSingleResult(); assertThat(findByJPQL.getUsername()).isEqualTo("member1");} JPA QueryDSL JPA QueryDSL 은 JPA Entity 와 관련해 정적 타입으로 쿼리를 작성 하게 해주는 라이브러리 JPA QueryDSL 에서는 JPAQueryFactory 객체를 이용해 쿼리를 작성합니다. JPAQueryFactory 객체를 통해 생성된 쿼리가 JPA Entity 를 대상으로 쿼리를 생성하고 실행하고 상태를 관리하기 위해서는 EntityMagager 인스턴스가 필요합니다. 따라서, JPA 기능을 사용하고 Entity 를 대상으로 쿼리를 수행할 수 있도록 EntityMagager 객체를 JPAQueryFactory 객체 생성시 전달할 필요가 있습니다.

0

QueryDSL 시작하기

목차 QueryDSL - QueryDsl 페이징 사용하기 QueryDSL - 사용자 정의 Repository QueryDSL - 동적 쿼리와 성능 최적화 조회 QueryDSL - 순수 JPA 리포지토리와 Querydsl QueryDSL - SQL Function 호출하기 QueryDSL - 수정, 삭제 벌크 연산 QueryDSL - 동적 쿼리 QueryDSL - 프로젝션과 결과 반환 QueryDSL - 조인 QueryDSL - 집계 QueryDSL - 결과 조회 QueryDSL - 검색 조건 쿼리 QueryDSL - Q-Type 활용 QueryDSL - JPA JPQL vs JPA QueryDSL QueryDSL 시작하기 QueryDSL 이란? QueryDSL 은 Query Domain Specific Language 의 약자로 쿼리를 코드로 작성할 수 있도록 해주는 쿼리 빌더 프레임워크 QueryDSL은 자바코드로 쿼리를 작성할 수 있으며, JPA, JDO, Hibernate, MongoDB, SQL, Lucene 등 다양한 데이터베이스를 지원합니다. QueryDSL은 코드 자동 완성 기능을 제공하므로 오타나 잘못된 쿼리를 작성하는 일을 방지하며, 런타임 오류를 방지할 수 있습니다. Plugin 추가plugins { id 'org.springframework.boot' version ‘2.2.2.RELEASE' id 'io.spring.dependency-management' version '1.0.8.RELEASE' //querydsl 추가 id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" id 'java'} 라이브러리 추가//querydsl 추가implementation 'com.querydsl:querydsl-jpa'

0

JPA 연관 관계 - 고아 객체

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 고아 객체란? 부모 엔티티와 연관관계가 끊어진 자식 엔티티 고아 객체 제거 부모 엔티티와 연관관계 가 끊어진 자식 엔티티를 자동으로 제거 @OneToOne, @OneToMany 만 가능하다. orphanRemoval = true @Entity@Getter@Setterpublic class Parent { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true) private List<Child> childList = new ArrayList<>(); public void addChild(Child child){ childList.add(child); child.setParent(this); }} public class JpaMain { public static void main(String[] ars) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello"); EntityManager em = entityManagerFactory.createEntityManager(); EntityTransaction transaction = em.getTransaction(); transaction.begin(); try { Child child1 = new Child(); Child child2 = new Child(); Parent parent = new Parent(); parent.addChild(child1); parent.addChild(child2); em.persist(parent); em.flush(); em.clear(); Parent savedParent = em.find(Parent.class, parent.getId()); savedParent.getChildList().remove(0); transaction.commit(); } catch (Exception e) { transaction.rollback(); } finally { em.close(); } entityManagerFactory.close(); }} Parent 에서 Child를 삭제할 때 delete 쿼리가 발생하게 된다.

0

JPA 연관 관계 - 즉시로딩과 지연로딩

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 N + 1 문제 하나의 쿼리(1) 를 날린 후 조회된 결과 값과 연관된 데이터 를 가져오기 위해 결과의 행수(N) 만큼 추가 쿼리가 발생하는 문제 즉시로딩 FetchType.EAGER 로 설정하게 되면 즉시 조회하게 된다. Join 해서 한방 쿼리로 가져오는 방법 데이터를 가져온 후 후속 쿼리를 날리는 기법, 해당 방법은 N + 1 문제를 일으킨다. @ManyToOne(fetch = FetchType.EAGER)@JoinColumn(name = "TEAM_ID")private Team team; 프록시와 즉시로딩 주의 즉시 로딩을 적용하면 예상하지 못한 SQL 이 발생 즉시 로딩은 JPQL 에서 N + 1 문제를 일으킨다. JPA 가 만들어주는 쿼리는 내부적으로 최적화가 이뤄진다. JPQL 은 내부적으로 SQL 로 번역된 후 데이터를 가져온 다음에 연관 데이터에 대해 후속적으로 쿼리가 발생한다. 해결법 1 : fetch join 해결법 2 : @EntityGraph 해결법 3 : batch size @ManyToOne, @OneToOne 은 기본이 즉시 로딩 LAZY 로 설정한다. @OneToMany, @ManyToMany 는 기본이 지연 로딩 지연로딩

0

JPA 연관 관계 - 프록시 객체

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 프록시 객체의 특징 실제 클래스를 상속 받아서 만들어진다. 실제 클래스와 겉 모양이 같다. 사용자 입장에서는 진짜 객체인지 프록시 객체인지 구분하지 않고 사용하면 된다. 프록시 객체는 실제 객체의 참조를 보관한다. 프록시 객체를 호출하면 프록시 객체는 실제 객체의 메소드를 호출한다. 프록시 객체는 처음 사용할 때 한번만 초기화 프록시 객체를 초기화 할때, 프록시 객체가 실제 엔티티로 바뀌는 것은 아니다. 초기화 되면 프록시 객체를 통해 실제 엔티티에 접근이 가능하다. 프록시 객체는 원본 엔티티를 상속받음, 따라서 타입 체크시 주의해야 한다. (== 비교 실패, 대신 instance of 사용) 영속성 컨텍스트에 찾는 엔티티가 이미 있으면 em.getReference() 를 호추랳도 실제 엔티티를 반환한다. 영속성 컨텍스트의 도움을 받을 수 없는 준 영속 상태일때, 프록시를 초기화 하면 문제 발생 org.hibernate.LazyInitializationException 예외를 터트린다. em.find() vs em.getReference() em.find() 데이터 베이스를 통해 실제 엔티티 객체를 조회한다. em.getReference() 데이터 베이스 조회를 미루는 가짜(프록시) 엔티티 객체 를 조회한다. public class JpaMain { public static void main(String[] ars) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello"); EntityManager em = entityManagerFactory.createEntityManager(); EntityTransaction transaction = em.getTransaction(); transaction.begin(); try { Member member = new Member(); member.setUsername("hello"); em.persist(member); em.flush(); em.clear(); Member savedMember = em.find(Member.class, 1L); printMemberAndTeam(savedMember); transaction.commit(); } catch (Exception e) { transaction.rollback(); } finally { em.close(); } entityManagerFactory.close(); } private static void printMember(Member member){ System.out.println("member = " + member.getUsername()); } private static void printMemberAndTeam(Member member) { String username = member.getUsername(); System.out.println("username = " + username); Team team = member.getTeam(); System.out.println("team = " + team.getName()); }}

0

JPA 연관 관계 - 일대다

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 공통 Mapping 정보를 관리하기 위한 MappedSuperclass Entity 에 공통적으로 들어가는 Mapping 정보를 관리해 코드가 중복해서 작성하는 것을 방지하기 위해 사용하는 어노테이션 상속관계 Mapping 이 아니다. 부모 클래스를 상속 받는 자식 클래스에 Mapping 정보만 을 제공한다. 직접 생성해서 사용할 일이 없으므로 추상클래스(abstract) 를 사용하는 것이 좋다. MappedSuperclass 클래스를 상속 받기 위해서는 같은 @MappedSuperclass 를 사용한 클래스나 @Entity 을 이용한 클래스만 상속이 가능하다. 요구 사항 모든 Entity 에는 생성자, 생성일, 수정자, 수정일 정보가 들어가야 한다. 모든 Entity 에 공통적으로 들어가는 Mapping 정보 를 관리하기 위한 BaseEntity 클래스를 생성한다. @MappedSuperclasspublic abstract class BaseEntity { private String createdBy; private LocalDateTime createdDate; private String lastModifiedBy; private LocalDateTime lastModifiedDate;} 공통 Mapping 정보는 상속 을 통해 현재 Entity 에 적용할 수 있다.

0

JPA 연관 관계 - 다대일

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 다 대 일연관관계 매핑시 고려사항 다중성 단방향, 양방향 연관관계 주인 테이블 외래키 하나로 양쪽 조인 가능 사실 방향이라는 개념이 없음 객체 참조용 필드가 있는 쪽으로만 참조 가능 한쪽만 참조하면 단방향 양쪽이 서로 참조하면 양방향 연관관계 주인