maven webapp으로 생성 build path 로 library new servertime 으로 jsp 오류 해결
main 폴더 밑에 java 생성 test 밑에 resources 생성 main resources 밑에 META-INF 폴더 만들고 persistence.xml 생성
pom.xml도 수정
실습 pjt
다음과 같이 생성. 테이블 생성완료. /test 말고 따로 db 명 해서 만들어줌(jpashop으로 해둠)
실습 pjt end
Order.java를 보면 id와 memberId가 있다. 실행을 해서 memberId를 가지고 온 다음에 Member에서 이 memberId를 통해 정보를 가지고 오는 것은 객체스럽지 않다. Order안에 그냥 Member를 넣어주면 더 좋을텐데.. 이것을 해결하기 위해 연관관계 매핑에 대해 공부를 해야한다.
team 설정을 하고 member설정을 했다. member 의 id 를 통해 그 member를 찾고 그 member의 team id를 받아와서 이를 통해 team 찾았다. 정말 복잡하다. 연관관계 매핑이 안되어있으면.
Member.java, 이제 다음과 같이 바로 team 을 정의해 주었고, 어노테이션을 2개를 달아 주었다.
ManytoOne 은 1:n을 의미한다. member가 n team이 1 이다. 이 team은 Team.java의 TEAM_ID와 매핑이 된다. 그래서 JoinColumn으로 말그대로 해당 name과 Join 한다는 뜻이다.
그러면 다음과 같이 그냥 바로 findMember.getTeam()으로 가지고올 수가 있다. teamId로 뭐 찾고 그런 번거로운 일들이 생략 된다.
이제 team 쪽에는 OneToMany(mappedBy="team") 을 작성해주었다.
테이블에서는 연관관계가 1개이다. 객체에서는 2개이다. 테이블에서는 fk 하나면 연관 매핑이 되어있다는 것이다.
객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 한다.
양방향 매핑 규칙은 이렇다.
1. 객체의 두 관계 중 하나를 연관관계의 주인으로 지정한다.
2. 연관관계의 주인만이 외래 키를 관리(등록,수정) 한다.
3. 주인이 아닌쪽은 읽기만 가능한다.
4. 주인은 mappedBy 속성을 사용하지 않는다.
5. 주인이 아니면 mappedBy 속성으로 주인을 지정한다.
주인이 아닌 쪽에서 넣으려 하면 들어가지 않는다.
다음과 같이 주인에서 넣으니깐 옳바르게 실행이 된다.
다음과 같은 상황에서
flush clear을 하면서 insert 문이 2번 실행된다. (team과 member 때문에)
그러고 team 을 find 하는 과정에서 team 을 들고오고
여기서 members 를 찾을 때에
이 부분을 위해 team_Id로 member db를 저렇게 찾고나서 m= member1으로 출력을 한다.
만약에 이곳에서 flush clear를 하지않았다면?? db에 올라가기 전에 1차캐시에 new ArrayList<>(); 의 그대로의 상태를 1차캐시에서 가져오기 때문에 size가 0으로 출력이 원활하게 진행되지 않을 것이다.
만약 team.getMembers().add(member); 이것을 추가했다면 나올 것이다.
그래서, 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정하는 것이 좋다.
아예 setTeam에서 다음과 같이 사용을 해주는 것이다. main에는 코드를 없애주고
그러면 양쪽으로 세팅이 된 것이 된다.
실습 pjt
다음과 같이 연관을 지으려고 한다.
n:1 일 때에는 위에서 배웠을 때에 ManytoOne으로 joinColumn 으로 정해주었다.
그 반대편에서 1:n 의 경우에 OneToMany 로 mappedBy 로 해당 변수를 등록해준다. 위에 Member member로 매니투원 해주었으니 member.java에서는 mappedBy로 member를 해주고 리스트
main에서의 코드를 예로들면 setOrderItem을 위에서 배운대로 양쪽 값을 추가해주었다. setOrderItem 대신 add로 이름만 바꾼 것이다.
실습 PJT END
지금까지는 다대일에서 다 부분이 주인이였다.
이번에는 일대다인데 일 이 주인인 것을 봐보겠다.
onetomany에 joincolumn을 한다.
엔티티가 관리하는 외래 키가 다른 테이블에 있기 때문에 연관관계 관리를 위해 추가로 UPDATE SQL 실행해야 한다.
그래서 이것보다는 그냥 다대일 양방향 매핑을 사용하는 것이 낫다. 그것을 사용하자.
이번엔 일대일 관계이다.
주 테이블이나 대상 테이블 중에 외래 키를 선택할 수 있다. 둘 중 하나에 넣으면 된다.
주 테이블에 외래 키를 넣거나 대상 테이블에 외래 키를 넣거나이다.
한 쪽을 잡고 onetoone 해주고 joincolumn 해주고 나머지는 mappedby 해준다. 다대일 관계랑 매우 유사하다.
주 테이블에 외래 키를 넣는 것은 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인이 가능하다는 장점이 있지만, 값이 없으면 외래 키에 null를 허용하게 된다. 그래서 이건 객체지향 개발자가 선호한다.
대상 테이블에 외래 키를 넣는 것은 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때에 테이블 구조 유지에 이점이 있지만, 지연 로딩을 사용할 수 없다는 단점이 있다고 한다.
실습pjt
추가하려하는 것은 delivery 와 category 이다. category와 item은 다대다 이다.
다대다는 사용하는 경우가 드물어 위에 정리를 안해놨다.
order와 delivery는 1대1 이며 주 테이블인 order 외래키를 두었다.
각각 OneToOne을 달아주고 주 테이블인 order에 joinColumn delivery_id 해준다.
받아주는 delivery에서는 OneToOne mappedBy를 실행하였다.
다대다는 중간에 조인한 테이블을 만들어야 하는데 위와 같이 생성하였다.
특이하게 카테고리에는 parent 와 child가 있는데 child가 n parent가 1이므로
ManyToOne으로 parent를 조인했고 OneToMany로 list의 child 를 가지게된다.
JoinColumn name="" 여기는 내가 조인할 테이블의 해당 컬럼 명이 아니라 만들어질 외래키 컬럼 명을 뜻하는 것 같다.
김영한님의 유료jpa강의를 보고 정리하였습니다.
'공부 기록들' 카테고리의 다른 글
2020.06.21-22 JPA(5) (0) | 2020.06.21 |
---|---|
2020.06.18 JPA(4) (0) | 2020.06.18 |
2020.06.16 JPA(2) (0) | 2020.06.17 |
2020.06.15 JPA(1) (0) | 2020.06.15 |
2020.06.05 백준2352 반도체 설계, ssafy 준비... (0) | 2020.06.05 |