목표 값 타입 컬렉션에 대해 알아보고 이를 코드를 통해 저장, 조회, 수정해본다. 값 타입 컬렉션 - 값 타입을 하나 이상 저장할 때 사용한다. - @ElementCollection, @CollectionTable을 사용한다. - 데이터베이스는 컬렉션을 같은 테이블에 저장할 수 없다. - 컬렉션을 저장하기 위한 별도의 테이블이 필요하다. (일대다 등의 매핑을 통해 서로 연관되도록 할 것임) @Entity @Getter @Setter public class Member { @Id @GeneratedValue @Column(name="MEMBER_ID") private Long id; @Column(name="USERNAME") private String username; ...(생략)... @Element..
JPA
목표 인스턴스가 달라도 그 안의 값이 같으면 같은 것으로 볼 수 있게한다. (특히 참조 객체에서) int a = 5; int b = 5; System.out.println("a==b : " + (a==b)); // true City city1 = new City("Seoul", "street", "10000"); City city2 = new City("Seoul", "street", "10000"); System.out.println("city1==city2 : " + (city1==city2)); // false System.out.println("city1==city2 : " + (city1.equals(city2))); // false 값 타입 비교 1) 동일성(identity) 비교 : 인스턴스..
값 타입이란? String, int와 같은 특정 값을 저장하는 타입 - 복잡한 객체 세상을 조금이라도 단순화하려고 만든 개념으로, 단순하고 안전하게 다룰 수 있어야한다. 값 타입 공유 참조 - 임베디드 타입같은 값 타입을 여러 엔티티에서 공유할 수 있다. - 단, 여러 엔티티에서 공유하는 경우 하나의 엔티티에서 값을 변경하면 의도치않게 함께 공유했었던 엔티티에서의 값도 변하는 부작용(side effect)이 발생할 수 있다. Address address = new Address("city", "strett", "10000"); Member member = new Member(); member.setUsername("member1"); member.setHomeAddress(address); em.pers..
임베디드 타입이란? 기본 값 타입을 모아서 만든 새로운 복합 값 타입으로 JPA에서 임베디드 타입이라고 한다. 장점 1) 재사용도 높음 2) 높은 응집도 3) 해당 값 타입만 사용하는 의미있는 메소드를 만들 수 있음(2번 장점과 연관) 4) 임베디드 타입을 포함한 모든 값 타입은,값 타입을 소유한 엔티티에 생명주기를 의존함 임베디드 타입과 테이블 매핑 - 임베디드 타입은 엔티티의 값이다. - 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블을 같다. - 객체와 테이블을 아주 세밀하게 매핑하는 것이 가능하다. - 잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많다. @Entity @Getter @Setter public class Member { @Id @GeneratedVal..
영속성 전이(CASCADE) 아래 코드들은 영속성 전이가 적용되지 않은 부모 엔티티와 자식 엔티티, 그리고 이를 활용한 비지니스 메소드들이 구현된 main 클래스이다. 부모 엔티티 @Entity @Getter @Setter public class Parent { @Id @GeneratedValue private Long id; private String name; @OneToMany(mappedBy = "parent") private List childList = new ArrayList(); public void addChild(Child child){ childList.add(child); child.setParent(this); } } Child 엔티티와 OneToMany를 어노테이션을 통해 연관되..
em.find()와 em.getReference() 차이는? em.find는 데이터베이스를 통해 실제 엔티티 객체를 조회한것 이고 em.getReference()는 프록시에서 값을 조회하는 것으로 프록시에 없는 값을 조회할 때까지 데이터베이스 조회를 미룬다. 프록시 특징 - 실제 클래스를 상속 받아서 만들어짐 - 실제 클래스와 겉 모양이 같음 - 사용하는 입장에서 진짜 객체인지 프록시 객체인지 구분하지 않고 사용 가능 - 프록시 객체는 현재 자신이 갖고 있지 않은 데이터에 접근해야 할 때, 처음 한 번만 초기화 한다. - 프록시 객체를 초기화 할때, 프록시 객체가 실제 엔티티로 바뀌는 것은 아님 - 초기화되면 프록시 객체를 통해서 실제 엔티티에 접근 가능 - 프록시 객체는 원본 엔티티를 상속받음, 따라서..
기존 테이블 방식의 연관 관계 //팀 저장 Team team = new Team(); team.setName("TeamA"); em.persist(team); //회원 저장 Member member = new Member(); member.setName("member1"); member.setTeamId(team.getId()); em.persist(member) //조회 Member findMember = em.find(Member.class, member.getId()); //연관관계가 없음 Team findTeam = em.find(Team.class, team.getId()); Member가 하나의 팀에 가입할 수 있을 때, Member가 특정 팀에 가입하기 위해서는 위와같이 teamID를 통해서..
@Column - name : 필드와 매핑할 테이블의 컬럼 이름 [Default : 객체의 필드 이름] - insertable, updateable : 등록, 변경 가능 여부 [Default : true] - nullable(DDL) : null 값의 허용 여부를 설정한다. false로 설정하면 DDL 생성 시에 not null 제약조건이 붙는다. [Default : true] - unique(DDL) : @Table의 uniqueConstraints와 같지만 한 컬럼에 간단히 유니크 제약조건을 걸 때 사용한다. [Default : false] (하지만 Column에서의 unique 제약은 값에 이상한 값이 들어가기 때문에 잘 사용 안함) - columnDefinition(DDL) : 데이터베이스 컬럼 ..
@Entity - @Entity가 붙은 클래스는 JPA가 관리, 엔티티라 한다 -JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 어노테이션이 필수 주의점 - 기본 생성자 필수(파라미터가 없는 public 또는 protected 생성자) - final 클래스, enum, interface, inner 클래스에는 사용할 수 없음 - DB에 저장하고 싶은 필드에는 final을 사용하면 안됨 @Entity 속성 name - JPA에서 사용할 엔티티 이름을 지정 - 기본값 : 클래스 이름을 그대로 사용 - 같은 클래스 이름이 없으면 헤깔릴 수 있으므로 가급적 기본값 사용 @Table : 엔티티와 매핑할 테이블 지정 - name 속성을 통해 매핑할 테이블 이름을 지정해줄 수 있음 데이터베이스 스키마 자동 ..
준영속 상태 -> 영속 상태 변환될 때 em.persist(member); em.find(Member.class, "member1"); 영속 상태 -> 준영속 상태 1) 영속 상태의 엔티티가 영속성 컨텍스트에서 분리되는 것 2) 영속성 컨텍스트가 제공하는 기능(1차 캐시, 변경 감지 등)을 사용 못함 준영속 상태로 만드는 방법 1) em.detach : 특정 엔티티만 준영속 상태로 전환 Member member = em.find(Member.class, 150L); // id가 Long타입이므로 뒤에 L붙임 member.setName("AAAAA"); em.detach(member); tx.commit(); // 아무리 커밋해도 변경 내용이 DB에 저장되지 않음 2) em.clear() : 영속성 컨텍스..