ABOUT ME

Today
Yesterday
Total
  • JPA (5) - 연관 관계 매핑 (다대일,일대다,일대일,다대다)
    카테고리 없음 2024. 1. 11. 14:45

     

    -> 관계를 왼쪽 테이블 기준으로 볼 것이다.

     

    1. 다대일

     

    1.1 다대일 단방향 

    출처: JPA기본편(김영한) -인프런

     

    - 가장 많이 사용하는 연관관계

    - 다대일의 반대가 일대다 

     

    1.2 다대일 양방향 

    출처: JPA기본편(김영한) -인프런

     

    - 외래키가 있는 쪽이 연관관계의 주인

    - 양쪽을 서로 참조하도록 개발 

    - 먼저 다대일 단방향을 했다가, 필요에 의해 양방향 전환 고려 

     

    2. 일대다 

     

    2.1 일대다 단방향 

    출처: JPA기본편(김영한) -인프런

     

    @Entity
    public class Team{
    
    	@Id @GeneratedValue
        private Long id;
        
        private String name;
        
        @OneToMany
        @JoinColumn(name ="TEAM_ID")
        List<Member> members = new ArrayList<>();
    
    }

     

     - 일이 연관관계의 주인이다.  (JoinColumn이 member한테 먹음)

    - 객체와 테이블의 차이로, 반대편 테이블의 외래키를 관리하는 구조 (운영상 매우 구리다. 차라리 다대일 양방향하자)

    - JoinColumn을 사용하지않으면, JoinTable라는 매핑 테이블을 생성한다. (joinColumn 꼭 사용하자)

    - 연관관계 관리를 위해 UPDATE SQL이 추가로 실행 될 수 있다.

     

    *JoinColumn에 다른 값 (pk외) 주고싶으면 엔티티를 Seializable한 뒤에, @JoinColumn에 옵션을 이용하자 

     

    2.2 일대다 양방향 

     

    출처: JPA기본편(김영한) -인프런

     

    - 공식적으로 존재하지 않는 매핑이다.

    - @JoinColumn(insertable=false,updatable=false)사용해서 억지로 넣은 것 

    - 그냥 다대일 양방향 써라..

     

     

    @Entity
    public class Team{
    
    	@Id @GeneratedValue
        private Long id;
        
        private String name;
        
        @OneToMany
        @JoinColumn(name ="TEAM_ID")
        List<Member> members = new ArrayList<>();
    
    }
    
    @Entity
    public class Member{
    
    	@Id @GeneratedValue
        private Long id;
        
        private String name;
        
        @ManyToOne
        @JoinColumn(name ="TEAM_ID",insertable=false,updatable=false)
        private Team team;
    
    }

     

    3. 일대일

     

    - 일대일은 주 테이블이나 대상 테이블 중에 외래 키 선택 가능하다 

    - 외래 키에 DB에 유니크 제약조건 추가하자

     

    3.1 일대일 단방향 

     

    출처: JPA기본편(김영한) -인프런

    - 1대1 연관관계라 테이블에 FK가 중복 저장되면 안됨! (그렇게된다면, 다대일이다)

     

    public class Member {
    
        @Id
        @Column(name = "MEMBER_ID")
        private Long id;
    
        @OneToOne
        @JoinColumn(name = "LOCKER_ID")
        private Locker locker;
        
        @Column(name = "USERNAME")
        private String username;
    
    
    }

     

    3.2 일대일 -  양방향 

     

    public class Member {
    
        @Id
        @Column(name = "MEMBER_ID")
        private Long id;
    
        @OneToOne
        @JoinColumn(name = "LOCKER_ID")
        private Locker locker;
        
        @Column(name = "USERNAME")
        private String username;
    
    
    }
    
    public class Locker {
    
        @Id
        private Long id;
    
        @OneToOne(mappedBy="locker")
        private Member member;
        
    
    }

     

    - 다대일과 유사

     

    *대상테이블 (Locker 등)에서 단뱡향으로 연관관계 맺는 것 현재로는 불가능함! (Locker가 Member를 관리하는건 이상)

      애초에 Locker에 Member가 없는데 어케 관리해...

     

    출처: JPA기본편(김영한) -인프런

     

    *양방향은 그냥 뒤집은것 헷갈리니까 주테이블 대상테이블 잘 설정해서 주테이블 방향으로 가자

    *대상테이블에 fk두고 사용할 것이라면 양방향으로 만들어야한다. 

      > 대상테이블에 fk를 두고 사용하면 편한점은 추후에 일대다 관계로 변경시 테이블 구조가 유지된다! 

      > 단점은 프록시 기능의 한계로 지연로딩으로 설정해도 항상 즉시 로딩됨 (주테이블 조회시 반드시 대상테이블 조회 -> 대상 테이블 fk값을 통해 주테이블을 불러오는 방식이라 그러하다!)

     

    4. 다대다

     

    - 관계형 데이터 베이스는 테이블 2개로 다대다 관계 표현불가

    - 연결 테이블 추가해서 일대다 - 다대일 관계로 풀어야한다. 

    (부모1 -자식1,2,3 일대다(다대일) -> 부모1 자식1,2,3 , 부모 2 자식1,2,3 (다대다)) 

    출처: JPA기본편(김영한) -인프런

     

    - 객체는 컬렉션을 사용해서 객체 2개로 다대다 관계 가능하다.

    - @ManyToMany사용하고 @JoinTable을 사용하자 

    - 단방향 양방향 둘다 가능하다.

    -편리해보이지만 실무에서 사용하지 않는다. -> 연결테이블이 단순히 연결만 하고 끝나지 않는다. (다른 데이터 들어올 수 있음)

    - 연결 테이블용 엔티티를 추가해서 OneToMany, ManyToOne으로 풀어내자

     

    출처: JPA기본편(김영한) -인프런

     	//카테고리
        @ManyToMany
        @JoinTable(name = "CATEGORY_ITEM",joinColumns = @JoinColumn(name = "CATEGORY_ID"),//내가 들어갈 컬럼
                inverseJoinColumns = @JoinColumn(name = "ITEM_ID") //중간테이블에서 내가 조인할 컬럼, 상대 컬럼 지정
        )
        private List<Item> items = new ArrayList<>();
    
    	
        //item 엔티티
     	@ManyToMany(mappedBy = "items") //어차피 값 가져오려면 category DB에서 찾아서 만든 후 만들어야함 
                                       //이때 category의 Items객체를 통해 맵핑된 categories찾음
        private List<Category> categories = new ArrayList<>();

     

    * 실무에서는 중간 테이블이 단순하지 않음

      무튼 ManyToMany는 사용금지여~ 

     

     

    5. 연관관계 어노테이션 속성 

     

    @JoinColumn

    출처: JPA기본편(김영한) -인프런

     

    @ManyToOne

     

    출처: JPA기본편(김영한) -인프런

     

     

    @OneToMany

    출처: JPA기본편(김영한) -인프런

    @OneToOne

     

    - ManyToOne,OneToMany 모든 속성 가지고 있음

Designed by Tistory.