JPA를 활용한 DB연동 및 쿼리 자동 작성 확인

노건우·2023년 10월 10일
0

Spring

목록 보기
14/22

DB 구현하기

이러한 엔티티를 가진 DB를 만들어 보자
1. 일단은 Member와 Team이라는 테이블 2개가 필요하다.
2. Member는 MEMBER_ID를 PK값으로 가지고 Team은 TEAM_ID를 PK값으로 가진다.
3. TEAM_ID는 Foregin key값이다.

Member

package com.codingbox.jpashop.relation;



import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.Getter;
import lombok.Setter;

@Entity
@Getter @Setter
public class Member {
	
	@Id
	@GeneratedValue
	@Column(name = "MEMBER_ID")
	private Long id;
	private String username;
//	@Column(name="TEAM_ID")
//	private Long teamId;
	
	/*
	 * 1대다의 개념을 객체에게 알려야 하는데, 
	 * DB기준으로 1대다의 개념을 알려줘야한다.
	 * @ManyToOne  : 여기선 Team의 개념이 하나이다.
	 * @JoinColumn(name = "TEAM_ID") : 관계 컬럼을 적어준다. TEAM_ID와 조인해야 한다.
	 */
	
	@ManyToOne
	@JoinColumn(name = "TEAM_ID")
	private Team team;
	
}
  1. @Id 어노테이션은 JPA(Java Persistence API)에서 사용되는 엔티티 클래스의 필드를 식별자(Identifier)로 표시하는 역할이다. @Id 어노테이션을 사용하여 엔티티 클래스의 필드를 식별자로 지정하면 JPA가 해당 필드를 엔티티의 주요 식별자(primary key)로 사용 가능하다.
  2. @GeneratedValue 은 전략 사용이 가능하다. 즉 sequence가 자동으로 생성된다.

    sequence를 생성하고 있다.
  3. @Column(name = "MEMBER_ID")을 이용하여 pk값을 MEMBER_ID로 설정한다.
  4. @ManyToOne
    @JoinColumn(name = "TEAM_ID") 여기서 TEAM_ID 를 fk값으로 받는다.
    • 물론 @Column(name="TEAM_ID")
      private Long teamId; 이렇게 객체를 따로 만들어 설정해 주어도 되지만 위의 방법이 좀 더 간편하다.

Team

package com.codingbox.jpashop.relation;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.Setter;

@Entity
@Getter @Setter
public class Team {
	@Id
	@GeneratedValue //sequence 값 세팅
	@Column(name="TEAM_ID")
	private Long Id;
	private String Name;
}

Team 테이블은 사실 간단하다. 그냥 pk값 지정하는 것 말고는 크게 신경쓸 부분이 없다.
위와 동일하게 @Id
@GeneratedValue //sequence
@Column(name="TEAM_ID") 이용하여 코드를 구성하자.

DB의 모습이다.

Main

package com.codingbox.jpashop;

import com.codingbox.jpashop.relation.Member;
import com.codingbox.jpashop.relation.Team;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.Persistence;

public class JpaMain {

	public static void main(String[] args) {
		EntityManagerFactory emf 
			= Persistence.createEntityManagerFactory("hello");
		EntityManager em = emf.createEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		
		
		
		tx.commit();
		
		em.close();
		emf.close();
	}

}

이 틀을 기억하자. main을 위한 기본적인 설정이다. 트랜잭션을 생성하고 커밋하는 과정이며, 아직 엔티티 클래스의 인스턴스를 생성하지는 않았다.
현재는 비어있는 트랜잭션을 커밋하는 것이므로 데이터베이스에 아무런 변경 사항이 없다.

package com.codingbox.jpashop;

import com.codingbox.jpashop.relation.Member;
import com.codingbox.jpashop.relation.Team;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.Persistence;

public class JpaMain {

	public static void main(String[] args) {
		EntityManagerFactory emf 
			= Persistence.createEntityManagerFactory("hello");
		EntityManager em = emf.createEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		
		Team team = new Team();
		team.setName("TeamA");
		
		//영속 상태가 되면 pk의 값이 세팅이 된 후에 영속상태 된다.
		em.persist(team);
		
		Member member = new Member();
		member.setUsername("member1");
		//member.setTeamId(team.getId());
		member.setTeam(team); // 아이디만 가져오는게 아니라 전부
		em.persist(member);
		
		
		//select
		//어떤 멤버의 pk값을 아는 상태에서 그 멤버가 어느 팀 소속인지 알고 싶을 때 확인
//		Member findMember = em.find(Member.class, member.getId()); //여기서 팀의 정보까지 다 가져온다. member정보만 가져오는게 아님. foregin 키까지 연관되어 있어서.
//		Long findTeamId = findMember.getTeamId();
//		Team findTeam = em.find(Team.class, findTeamId);
//		System.out.println("findTeam : " + findTeam.getName());
		
		//강제로 db쿼리를 보고 싶을때
		em.flush();
		em.clear();
		
		
		//어떤 멤버의 pk값을 아는 상태에서 그 멤버가 어느 팀 소속인지 알고 싶을 때 확인
		Member findMember = em.find(Member.class, member.getId()); //여기서 팀의 정보까지 다 가져온다. member정보만 가져오는게 아님. foregin 키까지 연관되어 있어서.
		Team findTeam = findMember.getTeam();  //여기서도 팀의 정보 가져옴. 아이디만 가져오는게 아니라 전부. 위에서는 id값을 가져오지만 이건 전부 다 가져온다.
		System.out.println("findTeam : " + findTeam.getName());
		
		
		tx.commit();
		
		em.close();
		emf.close();
	}

}

이것이 연관관계이다.
1.Team team = new Team();
team.setName("TeamA"); 일단 team객체를 만들어 주자. 다음은 TeamA라는 이름을 세팅해준다.
2. em.persist(team); 영속상태를 만들어 주자 이렇게 함으로써 트랜잭션 커밋 시 데이터베이스에 반영할 수 있다.
3. Member member = new Member();
member.setUsername("member1");
//member.setTeamId(team.getId()); 멤버 객체를 만들고 유저 이름을 member1로 세팅.

    주석 처리한 부분은 member테이블에서 team테이블에 있는 id값을 가져오는 역할을 한다.
   바로 team에서 가져오는 것이 아닌 연관관계를 이용해 id값을 가져오는 역할

3-1. member.setTeam(team); 이 코드는 위에서 id만 가지고 온 것과 다르게 team테이블의 전체를 다 가져온 것이다.

System.out.println("findTeam : " + findTeam.getName()); 따라서 이 코드의 결과는 뭘까? team의 이름을 가져오는 것이 요구조건이다.

주석 처리한 부분만 봐도 사실 이해는 충분하다.

조금 더 추가적으로 분석하자면,
em.find() 메서드는 member를 데이터베이스에서 조회한다. 이때 Member 엔티티와 Team 엔티티 간의 관계가 설정되어 있으므로, Member를 조회할 때 연관된 Team 정보도 함께 가져온다.
이 메서드가 db와 연동하는 역할을 한다고 볼 수 있다.


            
            






profile
초보 개발자 이야기

0개의 댓글

관련 채용 정보