์ž๋ฐ” ORM ํ‘œ์ค€ JPA

Updated:     Updated:

Categories:

Tags: , , ,

ํ•ด๋‹น ๊ฐ•์˜๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค. https://www.inflearn.com/course/ORM-JPA-Basic

JPA

JPA๋ž€ Java Persistent API์˜ ์•ฝ์ž๋กœ ์ž๋ฐ” ์ง„์˜์˜ ORM ๊ธฐ์ˆ  ํ‘œ์ค€์ด๋‹ค. ๊ฐ์ฒด์™€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์ด์— ์—ฐ๊ฒฐ๋‹ค๋ฆฌ๋ฅผ ํ•ด์ฃผ๋Š” ์—ญํ• ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

JPA๋Š” ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค์ด๊ณ , ๊ตฌํ˜„์ฒด๋กœ๋Š” Hibernate๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

JPA๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์–ป๋Š” ์ด์ 

  1. ๊ฐ์ฒด ์ค‘์‹ฌ์œผ๋กœ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ์ƒ์‚ฐ์„ฑ ์ฆ๊ฐ€ : entityManger๋ฅผ ํ†ตํ•ด persist(), find(), remove() ๋ฉ”์„œ๋“œ๋กœ CRUD๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
  3. 1์ฐจ์บ์‹œ์™€ ๋™์ผ์„ฑ ๋ณด์žฅ : ๊ฐ™์€ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ๋Š” ๊ฐ™์€ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  4. ์“ฐ๊ธฐ ์ง€์—ฐ : ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•  ๋•Œ๊นŒ์ง€ insert sql์„ ๋ชจ์œผ๊ณ  jdbc batch sql์„ ํ†ตํ•ด ํ•œ๋ฒˆ์— sql์„ ์ „์†กํ•œ๋‹ค.
  5. ์ง€์—ฐ๋กœ๋”ฉ : ๊ฐ์ฒด๊ฐ€ ์‹ค์ œ ์‚ฌ์šฉ๋  ๋•Œ ๋กœ๋”ฉ
  6. ์ฆ‰์‹œ๋กœ๋”ฉ : join ๊ตฌ๋ฌธ์— ์—ฐ๊ฒฐ๋œ ๊ฐ์ฒด๊นŒ์ง€ ํ•œ๋ฒˆ์— ๋ฏธ๋ฆฌ ์กฐํšŒ

JPA ์›๋ฆฌ

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ํ•˜๋‚˜์˜ EntityManagerFactory๋ฅผ ์ƒ์„ฑํ•ด EntityManager๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. EntityManager๋Š” ์“ฐ๋ ˆ๋“œ๊ฐ„์— ์ž์›๊ณต์œ ๋ฅผ ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋˜ํ•œ JPA์˜ ๋ชจ๋“  ๋ณ€๊ฒฝ์€ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์ด๋ฃจ์–ด ์ง„๋‹ค.

JPQL

JPQL์€ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆฐ๋‹ค. SQL์„ ์ถ”์ƒํ™”ํ•˜์—ฌ ํŠน์ • DB์— ์˜์กด์ ์ด์ง€ ์•Š๊ณ , ๊ฐ์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ

  • ์—”ํ‹ฐํ‹ฐ๋ฅผ ์˜๊ตฌ ์ €์žฅํ•˜๋Š” ํ™˜๊ฒฝ์ด๋‹ค.
  • ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €๋ฅผ ํ†ตํ•ด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

์—”ํ‹ฐํ‹ฐ์˜ ์ƒ๋ช…์ฃผ๊ธฐ

  • ๋น„์˜์† : ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€ ๊ด€๋ จ์ด ์—†๋Š” ์ƒˆ๋กœ์šด ์ƒํƒœ
  • ์˜์† : ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—๊ฒŒ ๊ด€๋ฆฌ๋˜๊ณ  ์žˆ๋Š” ์ƒํƒœ
  • ์ค€์˜์† : ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ๋ถ„๋ฆฌ๋œ ์ƒํƒœ
  • ์‚ญ์ œ : ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ์‚ญ์ œ๋œ ์ƒํƒœ
//์—”ํ‹ฐํ‹ฐ๋ฅผ ์ƒ์„ฑํ•œ ์ƒํƒœ(๋น„์˜์†)
Member member = new Member();
member.setId("member1");
member.setUsername("ํšŒ์›1");

//์—”ํ‹ฐํ‹ฐ๋ฅผ ์˜์†
em.persist(member);

//ํšŒ์› ์—”ํ‹ฐํ‹ฐ๋ฅผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ๋ถ„๋ฆฌ, ์ค€์˜์† ์ƒํƒœ
em.detach(member);

//๊ฐ์ฒด๋ฅผ ์‚ญ์ œํ•œ ์ƒํƒœ(์‚ญ์ œ)
em.remove(member);

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ 1์ฐจ ์บ์‹œ

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ €์žฅ๋˜๋ฉด 1์ฐจ ์บ์‹œ์—์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ฐพ์•„์˜จ๋‹ค. 1์ฐจ ์บ์‹œ์— ์—†๋‹ค๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ฟผ๋ฆฌ๊ฐ€ ๋‚ ๋ผ๊ฐ„๋‹ค.

Member member = new Member();
member.setId("member1");
member.setUsername("ํšŒ์›1");
//1์ฐจ ์บ์‹œ์— ์ €์žฅ๋จ
em.persist(member);
//1์ฐจ ์บ์‹œ์—์„œ ์กฐํšŒ
Member findMember = em.find(Member.class, "member1");

์—”ํ‹ฐํ‹ฐ ๋“ฑ๋ก

์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ์— SQL์„ ์ €์žฅํ•˜๊ณ , 1์ฐจ ์บ์‹œ์— ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ €์žฅํ•œ๋‹ค. ํŠธ๋žœ์žญ์…˜์ด ์ปค๋ฐ‹๋˜๋ฉด ์“ฐ๊ธฐ ์ง€์—ฐ ์ €์žฅ์†Œ์— ์ €์žฅ๋œ ๋‚ด์šฉ์„ DB๋กœ ๋‚ด๋ ค์ค€๋‹ค.

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €๋Š” ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์‹œ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค.
transaction.begin(); // [ํŠธ๋žœ์žญ์…˜] ์‹œ์ž‘
em.persist(memberA);
em.persist(memberB);
//์—ฌ๊ธฐ๊นŒ์ง€ INSERT SQL์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ณด๋‚ด์ง€ ์•Š๋Š”๋‹ค.
//์ปค๋ฐ‹ํ•˜๋Š” ์ˆœ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— INSERT SQL์„ ๋ณด๋‚ธ๋‹ค.
transaction.commit(); // [ํŠธ๋žœ์žญ์…˜] ์ปค๋ฐ‹

์—”ํ‹ฐํ‹ฐ ์ˆ˜์ • (๋ณ€๊ฒฝ ๊ฐ์ง€)

// ์˜์† ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ
Member memberA = em.find(Member.class, "memberA");
// ์˜์† ์—”ํ‹ฐํ‹ฐ ๋ฐ์ดํ„ฐ ์ˆ˜์ •
memberA.setUsername("hi");
memberA.setAge(10);
//em.update(member) ์ด๋Ÿฐ ์ฝ”๋“œ๊ฐ€ ์žˆ์–ด์•ผ ํ•˜์ง€ ์•Š์„๊นŒ?
transaction.commit(); // [ํŠธ๋žœ์žญ์…˜] ์ปค๋ฐ‹

flush : ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ๋‚ด์šฉ์„ DB์— ๋ฐ˜์˜ํ•˜๋Š” ๊ณผ์ •

์—”ํ‹ฐํ‹ฐ ์ˆ˜์ •์‹œ์—๋Š” ๋ณ€๊ฒฝ ๊ฐ์ง€๊ฐ€ ์ผ์–ด๋‚˜๋Š”๋ฐ, flush ํ•˜๋Š” ์‹œ์ ์— ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์žˆ๋Š” ์Šค๋ƒ…์ƒท๊ณผ ๋น„๊ตํ•ด UPDATE ์ฟผ๋ฆฌ๋ฅผ ๊ฐ™์ด flush ์‹œ์ผœ์ค€๋‹ค.

ํ”Œ๋Ÿฌ์‹œ๋ฅผ ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • em.flush() ๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•œ๋‹ค.
  • transaction์„ commitํ•œ๋‹ค.
  • JPQL ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค : JPQL ์ฟผ๋ฆฌ ์‹คํ–‰ ์‹œ SQL์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด์„œ๋Š” ์˜์† ์ปจํ…์ŠคํŠธ์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๋™๊ธฐํ™”๊ฐ€ ๋˜์–ด์žˆ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์—”ํ‹ฐํ‹ฐ ๋งคํ•‘

@Entity: @Entity๊ฐ€ ๋ถ™์€ ํด๋ž˜์Šค๋Š” JPA๊ฐ€ ๊ด€๋ฆฌํ•œ๋‹ค.

๊ฐ์ฒด - ํ…Œ์ด๋ธ” ๋งคํ•‘ : @Entity , @Table ํ•„๋“œ - ์ปฌ๋Ÿผ ๋งคํ•‘ : @Column ๊ธฐ๋ณธํ‚ค ๋งคํ•‘ : @Id ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘ : @ManyToOne

์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ ์ž๋™ ์ƒ์„ฑ

DDL์„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์‹œ ์ž๋™ ์ƒ์„ฑํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค.

์˜ต์…˜์€ 5๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค.

  • create : ๊ธฐ์กดํ…Œ์ด๋ธ” ์‚ญ์ œ ํ›„ ๋‹ค์‹œ ์ƒ์„ฑ
  • create-drop : create์™€ ๊ฐ™์œผ๋‚˜ ์ข…๋ฃŒ์‹œ์ ์— ํ…Œ์ด๋ธ” DROP
  • update : ๋ณ€๊ฒฝ๋ถ„๋งŒ ๋ฐ˜์˜
  • validate : ์—”ํ‹ฐํ‹ฐ์™€ ํ…Œ์ด๋ธ”์ด ์ •์ƒ ๋งคํ•‘๋˜์—ˆ๋Š”์ง€๋งŒ ํ™•์ธ
  • none : ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ

์šด์˜์‹œ์—๋Š” create, create-drop, update๋ฅผ ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ๋˜๊ณ , validate ๋˜๋Š” none์„ ์‚ฌ์šฉํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

ํ•„๋“œ์™€ ์ปฌ๋Ÿผ ๋งคํ•‘

@Entity
public class Member {
@Id
private Long id;
@Column(name = "name")
private String username;
private Integer age;
@Enumerated(EnumType.STRING)
private RoleType roleType;
@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;
@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
@Lob
private String description;
}

๋งคํ•‘ ์–ด๋…ธํ…Œ์ด์…˜

@Column : ์ปฌ๋Ÿผ ๋งคํ•‘ @Temporal : ๋‚ ์งœ ํƒ€์ž… ๋งคํ•‘ @Enumerated : enum ํƒ€์ž… ๋งคํ•‘ @Lob : BLOB, CLOB ๋งคํ•‘ @Transient : ํŠน์ • ํ•„๋“œ๋ฅผ ์ปฌ๋Ÿผ์— ๋งคํ•‘ํ•˜์ง€ ์•Š์Œ(๋งคํ•‘ ๋ฌด์‹œ)

๊ธฐ๋ณธ ํ‚ค ๋งคํ•‘

@Id @GeneratedValue(strategy = GenerationType.AUTO) 
private Long id;

@GeneratedValue : ์ž๋™์ƒ์„ฑ ์ „๋žต๋“ค

  • IDENTITY: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์œ„์ž„, MYSQL
  • SEQUENCE: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‹œํ€€์Šค ์˜ค๋ธŒ์ ํŠธ ์‚ฌ์šฉ, ORACLE(@SequenceGenerator ํ•„์š”)
  • TABLE: ํ‚ค ์ƒ์„ฑ์šฉ ํ…Œ์ด๋ธ” ์‚ฌ์šฉ, ๋ชจ๋“  DB์—์„œ ์‚ฌ์šฉ(@TableGenerator ํ•„์š”)
  • AUTO: ๋ฐฉ์–ธ์— ๋”ฐ๋ผ ์ž๋™ ์ง€์ •, ๊ธฐ๋ณธ๊ฐ’

์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘

**๋‹จ๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„ **

๋‹จ๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„์—์„œ๋Š” ์•„๋ž˜์˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ํ•œ์ชฝ์œผ๋กœ๋งŒ ์—ฐ๊ฒฐ ๋œ ๊ฒฝ์šฐ์ด๋‹ค. Member ๊ฐ์ฒด์—๋งŒ Team ๊ฐ์ฒด๊ฐ€ ์žˆ๊ณ , Team ๊ฐ์ฒด์—๋Š” Member์— ๊ด€๋ จ๋œ ๋‚ด์šฉ์ด ์—†๋‹ค.

@Entity
public class Member {
    @Id @GeneratedValue
    private Long id;
    @Column(name = "USERNAME")
    private String name;
    private int age;
//    @Column(name = "TEAM_ID")
//    private Long teamId;
    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;
}

** ์–‘๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„ **

@Entity
public class Member {

    private Long id;
    @Column(name = "USERNAME")
    private String name;
    private int age;

    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;
}


@Entity
public class Team {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
    @OneToMany(mappedBy = "team")
    List<Member> members = new ArrayList<Member>();
}

๊ฐ์ฒด์™€ ํ…Œ์ด๋ธ”์˜ ์ฐจ์ด

๊ฐ์ฒด์˜ ์–‘๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘์€ ๋‘๊ฐœ์˜ ๋‹จ๋ฐฉํ–ฅ ๋งคํ•‘๊ณผ ๊ฐ™๋‹ค.

  • ๊ฐ์ฒด

    ํšŒ์› -> ํŒ€ ( ๋‹จ๋ฐฉํ–ฅ ) ํŒ€ -> ํšŒ์› ( ๋‹จ๋ฐฉํ–ฅ )

  • ํ…Œ์ด๋ธ” ํ…Œ์ด๋ธ”์€ ์™ธ๋ž˜ํ‚ค๋กœ ๋‘ ํ…Œ์ด๋ธ”์˜ ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์—ฐ๊ด€๊ด€๊ณ„ 1๊ฐœ๋กœ ์–‘๋ฐฉํ–ฅ์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฐ์ฒด์—์„œ๋Š” ์–‘๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘์˜ ๊ฒฝ์šฐ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์ด ํ•„์š”ํ•˜๋‹ค.

์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ

  • ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ๋งŒ ์™ธ๋ž˜ํ‚ค๋ฅผ ๊ด€๋ฆฌ
  • ๋‘ ๊ฐ์ฒด ์ค‘ ํ•˜๋‚˜๋งŒ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์ด ๋œ๋‹ค
  • ์ฃผ์ธ์ด ์•„๋‹Œ์ชฝ์€ ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅ
  • ์ฃผ์ธ์ด ์•„๋‹ˆ๋ฉด mappedBy ์†์„ฑ์œผ๋กœ ์ฃผ์ธ์„ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค
  • ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ๋Š” ์ชฝ์„ ์ฃผ์ธ์œผ๋กœ ์ •ํ•˜๊ธฐ

์–‘๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„์‹œ ์ฃผ์˜์ 

  • ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์‹œ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์— ๊ฐ’์„ ์ž…๋ ฅํ•ด์•ผ ํ•œ๋‹ค. (์ˆœ์ˆ˜ํ•œ ๊ฐ์ฒด ๊ด€๊ณ„๋ฅผ ๊ณ ๋ คํ•˜๋ฉด ํ•ญ์ƒ ์–‘์ชฝ๋‹ค ๊ฐ’์„ ์ž…๋ ฅํ•ด์•ผ ํ•œ๋‹ค.)

  • ์—ฐ๊ด€๊ด€๊ณ„ ํŽธ์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์ž ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์‹œ์— ๋ฌดํ•œ ๋ฃจํ”„๋ฅผ ์กฐ์‹ฌํ•˜์ž(toString(), lombok, JSON ์ƒ์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)

์–‘๋ฐฉํ–ฅ ๋งคํ•‘ ์ •๋ฆฌ

  • ๋‹จ๋ฐฉํ–ฅ ๋งคํ•‘๋งŒ์œผ๋กœ๋„ ์ด๋ฏธ ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘์€ ์™„๋ฃŒ
  • ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์€ ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์œผ๋กœ ์กฐํšŒ(๊ฐ์ฒด ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰) ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋œ ๊ฒƒ ๋ฟ
  • JPQL์—์„œ ์—ญ๋ฐฉํ–ฅ์œผ๋กœ ํƒ์ƒ‰ํ•  ์ผ์ด ๋งŽ์Œ
  • ๋‹จ๋ฐฉํ–ฅ ๋งคํ•‘์„ ์ž˜ ํ•˜๊ณ  ์–‘๋ฐฉํ–ฅ์€ ํ•„์š”ํ•  ๋•Œ ์ถ”๊ฐ€ํ•ด๋„ ๋จ (ํ…Œ์ด๋ธ”์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์Œ)

์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์„ ์ •ํ•˜๋Š” ๊ธฐ์ค€

  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๊ธฐ์ค€์œผ๋กœ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์„ ์„ ํƒํ•˜๋ฉด ์•ˆ๋จ
  • ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์€ ์™ธ๋ž˜ํ‚ค์˜ ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •ํ•ด์•ผํ•จ ```java Team team = new Team(); team.setName(โ€œTeamAโ€); em.persist(team);

Member member = new Member(); member.setName(โ€œmember1โ€);

team.getMembers().add(member); //์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์— ๊ฐ’ ์„ค์ • member.setTeam(team); em.persist(member); ```

๋‹ค์–‘ํ•œ ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘

ManyToOne ๋‹ค๋Œ€์ผ ๊ด€๊ณ„ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ์—ฐ๊ด€๊ด€๊ณ„ ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ๋Š” ์ชฝ์ด ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์ด๋‹ค.

OneToMany

์ผ๋Œ€๋‹ค ๊ด€๊ณ„์—์„œ๋Š” ํ•ญ์ƒ Many ์ชฝ์— ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ๋‹ค.

  • ํ…Œ์ด๋ธ” ์ผ๋Œ€๋‹ค ๊ด€๊ณ„๋Š” ํ•ญ์ƒ ๋‹ค(N)์ชฝ์— ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ์Œ
  • ๊ฐ์ฒด์™€ ํ…Œ์ด๋ธ”์˜ ์ฐจ์ด ๋•Œ๋ฌธ์— ๋ฐ˜๋Œ€ํŽธ ํ…Œ์ด๋ธ”์˜ ์™ธ๋ž˜ํ‚ค๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ํŠน์ดํ•œ ๊ตฌ์กฐ
  • @JoinColumn์„ ๊ผญ ์‚ฌ์šฉํ•ด์•ผ ํ•จ. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์กฐ์ธ ํ…Œ์ด๋ธ” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•จ(์ค‘๊ฐ„์— ํ…Œ์ด๋ธ”์„ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•จ)

์ผ๋Œ€๋‹ค ๋‹จ๋ฐฉํ–ฅ ๋งคํ•‘์˜ ๋‹จ์ 

  • ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ์™ธ๋ž˜ํ‚ค๊ฐ€ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์— ์žˆ์Œ
  • ์—ฐ๊ด€๊ด€๊ณ„ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ์ถ”๊ฐ€๋กœ ์™ธ๋ž˜ํ‚ค์™€ ๊ด€๋ จํ•˜์—ฌ UPDATE SQL ์‹คํ–‰
  • ์ผ๋Œ€๋‹ค ์–‘๋ฐฉํ–ฅ์˜ ๊ฒฝ์šฐ ๊ณต์‹์ ์ธ ํ‘œ์ค€์ŠคํŽ™์€ ์•„๋‹ˆ๋ฉฐ ๊ถŒ์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.

= > ์ผ๋Œ€๋‹ค ๋‹จ๋ฐฉํ–ฅ ๋งคํ•‘๋ณด๋‹ค๋Š” ๋‹ค๋Œ€์ผ ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์„ ์‚ฌ์šฉํ•˜์ž

OneToOne

  • ์ผ๋Œ€์ผ ๊ด€๊ณ„๋Š” ๊ทธ ๋ฐ˜๋Œ€๋„ ์ผ๋Œ€์ผ
  • ์ฃผํ…Œ์ด๋ธ”์ด๋‚˜ ๋Œ€์ƒํ…Œ์ด๋ธ” ์ค‘์— ์™ธ๋ž˜ํ‚ค ์„ ํƒ ๊ฐ€๋Šฅ
  • ์™ธ๋ž˜ ํ‚ค์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์œ ๋‹ˆํฌ(UNI) ์ œ์•ฝ์กฐ๊ฑด ์ถ”๊ฐ€

์ฃผํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ

  • ์ฃผ ๊ฐ์ฒด๊ฐ€ ๋Œ€์ƒ ๊ฐ์ฒด์˜ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ฃผ ํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ํ‚ค๋ฅผ ๋‘๊ณ  ๋Œ€์ƒ ํ…Œ์ด๋ธ”์„ ์ฐพ์Œ
  • ๊ฐ์ฒด์ง€ํ–ฅ ๊ฐœ๋ฐœ์ž ์„ ํ˜ธ
  • JPA ๋งคํ•‘ ํŽธ๋ฆฌ(์ฃผํ…Œ์ด๋ธ”์ด๋ฏ€๋กœ ๋‹จ๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„๋งŒ ์„ค์ •) ์žฅ์ : ์ฃผ ํ…Œ์ด๋ธ”๋งŒ ์กฐํšŒํ•ด๋„ ๋Œ€์ƒ ํ…Œ์ด๋ธ”์— ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ ๊ฐ€๋Šฅ ๋‹จ์ : ๊ฐ’์ด ์—†์œผ๋ฉด ์™ธ๋ž˜ ํ‚ค์— null ํ—ˆ์šฉ

๋Œ€์ƒํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ

  • ๋Œ€์ƒ ํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ ํ‚ค๊ฐ€ ์กด์žฌ
  • ์ „ํ†ต์ ์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐœ๋ฐœ์ž ์„ ํ˜ธ ์žฅ์ : ์ฃผ ํ…Œ์ด๋ธ”๊ณผ ๋Œ€์ƒ ํ…Œ์ด๋ธ”์„ ์ผ๋Œ€์ผ์—์„œ ์ผ๋Œ€๋‹ค ๊ด€๊ณ„๋กœ ๋ณ€๊ฒฝํ•  ๋•Œ ํ…Œ์ด๋ธ” ๊ตฌ์กฐ ์œ ์ง€ ๋‹จ์ : ํ”„๋ก์‹œ ๊ธฐ๋Šฅ์˜ ํ•œ๊ณ„๋กœ ์ง€์—ฐ ๋กœ๋”ฉ์œผ๋กœ ์„ค์ •ํ•ด๋„ ํ•ญ์ƒ ์ฆ‰์‹œ ๋กœ๋”ฉ๋จ ๋‹จ์ : ๋Œ€์ƒํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ์–‘๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„ ์„ค์ • ํ•„์š”

ManyToMany

  • ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ์ •๊ทœํ™”๋œ ํ…Œ์ด๋ธ” 2๊ฐœ๋กœ ๋‹ค๋Œ€๋‹ค ๊ด€๊ณ„๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์—†๋‹ค.
  • ์—ฐ๊ฒฐ ํ…Œ์ด๋ธ”์„ ํ†ตํ•ด์„œ ์ผ๋Œ€๋‹ค, ๋‹ค๋Œ€์ผ ๊ด€๊ณ„๋กœ ํ’€์–ด๋‚ด์•ผํ•จ

ManyToMany๋ฅผ ์ผ๋Œ€๋‹ค ํ˜น์€ ๋‹ค๋Œ€์ผ๋กœ ํ’€์–ด๋‚ด์–ด ์ƒˆ๋กœ์šด ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•จ.

jpa ์นดํ…Œ๊ณ ๋ฆฌ ๋‚ด ๋‹ค๋ฅธ ๊ธ€ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ

Leave a comment