[자바 ORM 표준 JPA 프로그래밍 - 기본편] 5-1강
https://inf.run/2zDo 강의를 수강하고 작성하는 게시물입니다.
단방향 연관관계
매핑하기 전 객체지향적 문제 확인하기
우리는 아래의 사진처럼 객체지향 모델링을 하려 한다.
우선 아래처럼 엔티티 두개를 저장해보자.
@Table(name="member")
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String name;
@Column(name = "TEAM_ID")
private Long teamId;
}
@Entity
public class Team {
@Id
@GeneratedValue
@Column
private Long id;
private String name;
}
그리고 아래 코드를 이용해 테이블이 생성되는지 확인해보자.
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
try {
transaction.commit();
} catch (Exception e) {
transaction.rollback();
} finally {
em.close();
}
emf.close();
}
}
create table member (
MEMBER_ID bigint not null,
USERNAME varchar(255),
TEAM_ID bigint,
primary key (MEMBER_ID)
)
create table Team (
id bigint not null,
name varchar(255),
primary key (id)
)
테이블은 생성이 되었지만 각각 속성이 연결되지는 않았다. (외래키를 갖고 있지는 않는다.)
실제 데이터를 저장해보자. 아래 소스처럼 저장을 한다.
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
try {
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
member.setTeamId(team.getId()); // 이 부분이 객체지향스럽지 못한 느낌이다.
em.persist(member);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
} finally {
em.close();
}
emf.close();
}
}
위의 소스를 실행하면 아래와같이 데이터가 들어가게된다.
이렇게 되면 조회할때도 문제가 있다.
Member findMember = em.find(Member.class, member.getId());
Long findteamId = findMember.getTeamId();
Team findTeam = em.find(Team.class, findteamId);
조회할 때 가져온 객체의 데이터를 가져와 다시 조회하는 형태가 되기 때문이다.
객체지향스럽지 못하다.
단방향 연관관계 맺기
맨처음 사진의 객체 지향 모델링 처럼 연결을 하기 위해 아래처럼 Member 엔티티의 코드를 바꿔 작성한다.
@Table(name="member")
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String name;
// @Column(name = "TEAM_ID")
// private Long teamId;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
ManyToOne 은 다대일 매핑하는 어노테이션이고
JoinColumn 은 join 하려는 속성을 설정하는 어노테이션이다.
조회해보기
위처럼 설정하고 아래처럼 메인코드를 실행해보자.
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
try {
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
member.setTeam(team);
em.persist(member);
//만약 쿼리문이 날라가는걸 보고싶으면 아래 두 줄을 작성하면 된다.
em.flush(); // 영속성 컨텍스트와 db의 싱크를 맞춰준다.
em.clear(); // 영속성 컨텍스트 비워버리기!
Member findMember = em.find(Member.class, member.getId());
Team findTeam = findMember.getTeam();
transaction.commit();
} catch (Exception e) {
transaction.rollback();
} finally {
em.close();
}
emf.close();
}
}
위처럼 Member의 ID를 찾아서 다시 찾도록 실행시키는 것이 아닌 Member를 찾으면 Team이 같이 가져와지도록 할 수 있다.
수정해보기
그렇다면 수정할때는…?
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
try {
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
member.setTeam(team);
em.persist(member);
//만약 쿼리문이 날라가는걸 보고싶으면 아래 두 줄을 작성하면 된다.
em.flush(); // 영속성 컨텍스트와 db의 싱크를 맞춰준다.
em.clear(); // 영속성 컨텍스트 비워버리기!
Member findMember = em.find(Member.class, member.getId());
Team findTeam = findMember.getTeam();
Team teamNew = new Team();
teamNew.setName("TeamB");
em.persist(teamNew);
member.setTeam(teamNew);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
} finally {
em.close();
}
emf.close();
}
}
위와같이 teamNew를 생성하여 member에 setTeam 해주면 자동으로 teamNew가 매핑된다.
댓글 남기기