반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- springSecurityFilterChain 오류
- 유연한 컨트롤러1 - v5
- @Controller
- java.lang.AssertionError
- application-properties
- 쿠키란
- optional
- jpa
- spring MVC
- SpringMVC
- n+1
- 필터vs인터셉터
- 김영한
- 세션의 정의
- BindingResult
- controller
- 구글 보안 api 활용
- 세션vs쿠키
- 401오류
- spring
- 세션이란
- abap value in field Data Class error
- .orelseThrow
- Testcode
- 쿠키의 정의
- 필터의 정의
- 인터셉터의 정의
- MVC
- Validation
- filter vs interceptor
Archives
- Today
- Total
ABAP DUMP ERROR 24시
컬렉션 값 타입 (Collection value type)의 한계 본문
반응형
# 인프런 김영한의 자바 ORM 표준 JPA 프로그래밍 - 기본편을 개인적으로 정리한 글입니다.
<까먹지 말자> 기본 base
정리
Q. Entity Type 과 값Type 비교해줘
Entity type | 값 타입 |
식별자 존재 | 식별자 없음 |
생명주기 존재 | 생명주기를 엔티티에 의존 |
공유가능 | 공유하면 큰일 난다.(복사해서 사용해라) |
Q. 컬렉션이 뭐야?
A. 값 타입을 컬렉션에 담아서 쓰는 것 // 타입 하나하나를 모아주는 역할. 다 PK값을 갖는다.
Q. 왜 컬렉션 식별자 하나 하나를 PK로 사용하는거야?
A. 해당 테이블은 값 타입으로 정의되어있다.
하나로 묶어서 식별자로 두는 방법은 엔티티를 사용하는 방법이다.
따라서, 테이블에 값들만 저장하고 사용하기 위해서 pk로 둔다.
Q. 컬렉션 어떻게 사용해?
A. @ElementCollection, @CollectionTable 을 사용해!
// @ElementCollection
// @CollectionTable(name = "address",
// joinColumns = @JoinColumn(name = "member_id"))
// private List<Address> addressHistory = new ArrayList<>();
private List<Address> addressHistory = new ArrayList<>(); 만들기 // 변수 생성
그 위에 @ElementCollection 만들기
@CollectionTable( name = " db에 만들 table 이름", @JoinColumn(db와 조인할 컬럼 이름))
끝.
Q. 값 타입 그리고 객체 타입의 한계가 뭐야?
A. 복사 해서 재정의 후 사용하지 않으면 Side Effect가 난다. // 직원 이름을 바꿀려고 change name("홍길동") 했다가 모든 직원이 홍길동으로 변한다.
즉 , 객체 타입은 참조 값을 직접 대입하는 것을 막을 방법이 없다.
=> 항상 값을 복사해서 사용해야만 공유 참조로 인한 부작용을 피할수 있다.(side effect를 피할수 있다.)
=> Embedded 타입 처럼 직접 정의한 값타입은 자바의 기본 타입이 아닌 객체 타입이므로 추적이 어려움.
Q.그럼 어떻게 값 타입을 사용해야해?
A. 불변 객체로 만들면되.
Q.불변 객체가 뭐야? 어떻게 만들어?=> 변경이 불가능한 객체
A.
1. 객체 타입을 수정하지 않도록 만든다. // public 대신 private 로 만들어 사용하자!
2. @Setter를 사용하지 말자// @Setter는 그냥 사용하지 말자.
3. Integer 나 String 같은 자바가 제공하는 불변 객체를 사용하자.
4. DTO, Entity를 따로 만들어 사용한다.
5. Entity로 만들어 사용하자!! // 가장 NICE 그냥 이걸로 만들어!
살펴보기
Q. 컬렉션이 뭐야?
A. 값 타입을 컬렉션에 담아서 쓰는 것 // 타입 하나하나를 모아주는 역할. 다 PK값을 갖는다.
<Embbed 타입, Collection 타입 수정 방법>
//embedded type 수정하는 방법.
//Address address = new Address("city", "street", "10000");
//
// Member member1 = new Member();
// member1.setUsername("member1");
// member1.setHomeAddress(address);
// em.persist(member1);
//
// Address copyAddress = new Address(address.getCity(), address.getStreet(), address.getZipcode());
//
// Member member2 = new Member();
// member2.setUsername("member2");
// member2.setHomeAddress(copyAddress);
// em.persist(member2);
//
// member1.getHomeAddress().setCity("newCity");
Address copyAddress 객체를 새로 생성해서 복사 한다음, 변환해!!
Q. 컬렉션 어떻게 사용해?
// @ElementCollection
// @CollectionTable(name = "address",
// joinColumns = @JoinColumn(name = "member_id"))
// private List<Address> addressHistory = new ArrayList<>();
// @ElementCollection
// @CollectionTable(name = "favorite_food",
// joinColumns = @JoinColumn(name = "member_id"))
// @Column(name = "food_name")
// private Set<String> favoriteFoods = new HashSet<>();
다음과 같이 @ElementCollection을 설정한 후에! 객체를 꼭 복사후 재정의 해서 사용한다.
그리고 equal and Hashcode 를 정의하자..
<수정, 삭제 >
// //값 타입 컬렉션 사용 예제
//
// Member member = new Member();
// member.setUsername("member1");
// member.setHomeAddress(new Address("HomeCity", "street", "10000"));
//
// member.getFavoriteFoods().add("치킨");
// member.getFavoriteFoods().add("족발");
// member.getFavoriteFoods().add("피자");
//
// member.getAddressHistory().add(new Address("old1", "street", "10000"));
// member.getAddressHistory().add(new Address("old2", "street", "10000"));
//
// em.persist(member);
// em.flush();
// em.clear();
Address 객체를 새로 생성해서 복사 한다음, 변환해!!
<조회>
// // 값 타입 조회
// Member member = new Member();
// Member findMember = em.find(Member.class, member.getId());
//
// List<Address> addressHistory = findMember.getAddressHistory();
// for (Address address : addressHistory){
// System.out.println(" addreses= " + address.getCity());
// }
//
// Set<String> favoriteFoods = findMember.getFavoriteFoods();
// for (String favoriteFood: favoriteFoods){
// System.out.println("favoriteFood = " + favoriteFood);
// }
Q.불변 객체가 뭐야? 어떻게 만들어?
import javax.persistence.*;
@Entity
@Table(name = "address")
public class AddressEntity {
@Id @GeneratedValue
private Long id;
public AddressEntity(Address address){
this.address = address;
}
@Embedded
private Address address;
public AddressEntity(){
}
public AddressEntity(String city, String street, String zipcode) {
this.address = new Address(city, street, zipcode);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Dto를 만들어 사용하는 것이 안전해!
Entity에서 직접 가져와 변형 시키지 말고 DTO를 만들어서 조작하자!
//값 타입 수정
// // homecity = > newCity
// Member member = new Member();
// Member findMember = em.find(Member.class, member.getId());
// Address a = findMember.getHomeAddress();
// findMember.setHomeAddress(new Address("newCity", a.getStreet(), a.getZipcode()));
//
// findMember.getFavoriteFoods().remove("치킨");
// findMember.getFavoriteFoods().add("한식");
// findMember.getAddressHistory().remove(new AddressEntity("old1", "street", "10000"));
// findMember.getAddressHistory().add(new AddressEntity("newCity", "street", "10000"));
가장 좋은 방법
=> 임베디드, Collection 같은 값 타입은 여러 Entity에 공유되는 순간 큰 일이 나기 때문에.
Entity로 변경해서 사용하자!!!
반응형
'[WEB]Back-end > JPA' 카테고리의 다른 글
JPQL이 뭐야? 어떻게 사용해? (0) | 2022.01.21 |
---|---|
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 전략 (0) | 2022.01.21 |
Embedded 타입 (0) | 2022.01.17 |
영속성 전이 :CASCADE (0) | 2022.01.17 |
Proxy 어떻게 최적화해? (0) | 2022.01.14 |
Comments