๐ŸŒป JAVA/์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ

6-1) ๋‹ค์–‘ํ•œ ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘ (๋‹ค๋Œ€์ผ, ์ผ๋Œ€๋‹ค, ์ผ๋Œ€์ผ)

iseunghan 2020. 10. 19. 17:32
๋ฐ˜์‘ํ˜•

์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ - ๊ธฐ๋ณธํŽธ์„ ๊ณต๋ถ€ํ•˜๋ฉฐ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

 

์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ - ๊ธฐ๋ณธํŽธ - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜

JPA๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๊ฑฐ๋‚˜, ์‹ค๋ฌด์—์„œ JPA๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๊ธฐ๋ณธ ์ด๋ก ์ด ๋ถ€์กฑํ•˜์‹  ๋ถ„๋“ค์ด JPA์˜ ๊ธฐ๋ณธ ์ด๋ก ์„ ํƒ„ํƒ„ํ•˜๊ฒŒ ํ•™์Šตํ•ด์„œ ์ดˆ๋ณด์ž๋„ ์‹ค๋ฌด์—์„œ ์ž์‹ ์žˆ๊ฒŒ JPA๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค., - ๊ฐ•์˜ ์†Œ๊ฐœ | ์ธํ”„๋Ÿฐ

www.inflearn.com

 

โœ…๋‹ค๋Œ€์ผ [N:1]

๋‹จ๋ฐฉํ–ฅ

  • ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ์—ฐ๊ด€๊ด€๊ณ„

public class Member{
    @Id @GeneratedValue
    private Long id;

    @Column(name = "USERNAME")
    private String name;

    @ManyToOne
    @JoinColumn(name = "TEAM_ID") // ์ƒ๋žต ๊ฐ€๋Šฅ jpa๊ฐ€ ์ž๋™์œผ๋กœ "ํด๋ž˜์Šค์ด๋ฆ„" + "_ID"๋กœ ๋งคํ•‘
    private Team team;
}
------------------------------------

public class Team{
    @Id @GeneratedValue
    private Long id;

    private String name;
}

@JoinColumn ์–ด๋…ธํ…Œ์ด์…˜์„ ์ƒ๋žตํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์ „๋žต์— ๋”ฐ๋ผ ์™ธ๋ž˜ ํ‚ค๋ฅผ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค.

ํ•„๋“œ๋ช… + “_” + ์ฐธ์กฐํ•˜๋Š” ํ…Œ์ด๋ธ”์˜ ๊ธฐ๋ณธ ํ‚ค(@Id) ์ปฌ๋Ÿผ๋ช…

์™ธ๋ž˜ํ‚ค์— TEAM์˜ ๊ธฐ๋ณธํ‚ค๋ฅผ ๋งคํ•‘ ์‹œ์ผœ์ฃผ๋ฉด ๋œ๋‹ค.

์–‘๋ฐฉํ–ฅ

  • ๋‹ค๋Œ€์ผ์—์„œ ๋‹ค ๊ฐ€ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์ด ๋œ๋‹ค. (์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ๋Š” ์ชฝ์ด ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ!)

Member

public class Member{
    @Id @GeneratedValue
    private Long id;

    @Column(name = "USERNAME")
    private String name;

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

    // getter, setter ..
}

Team

public class Team{
    @Id @GeneratedValue
    private Long id;

    private String name;

    @OneToMany(mappedBy = "team")
    private List<Member> members;

    // getter, setter ..
}

๋‹จ๋ฐฉํ–ฅ์—์„œ Team์— ์ปฌ๋ ‰์…˜์„ ์ถ”๊ฐ€ ์‹œ์ผœ์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค.

์–‘๋ฐฉํ–ฅ ๋งคํ•‘์‹œ ๊ฐ’ ๋„ฃ์„ ๋•Œ ์‹ค์ˆ˜ํ•˜์ง€ ๋ง๊ธฐ!!

// team ์ƒ์„ฑ
Team team = new Team();
team.setName("team 1");

// member ์ƒ์„ฑ
Member member1 = new Member();
member1.setName("member1");
em.persist(member1);


// member -> Team์— ๋„ฃ์–ด์ค€๋‹ค.
team.getMembers().add(member1);

์‹คํ–‰์„ ํ•˜๋ฉด?

๋‹น์—ฐํ•˜๊ฒŒ๋„ member์˜ team_id๊ฐ€ ์•ˆ๋“ค์–ด๊ฐ”๋‹ค. ์™œ ๊ทธ๋Ÿฐ์ง€ ๊นŒ๋จน์—ˆ๋‹ค๋ฉด ๋‹ค์‹œ ๊ณต๋ถ€ํ•˜์ž .. ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ(Owner)

[5 - 3) ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘ ๊ธฐ์ดˆ - ์–‘๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ

์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ - ๊ธฐ๋ณธํŽธ์„ ๊ณต๋ถ€ํ•˜๋ฉฐ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค. ์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ - ๊ธฐ๋ณธํŽธ - ์ธํ”„๋Ÿฐ JPA๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๊ฑฐ๋‚˜, ์‹ค๋ฌด์—์„œ JPA๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๊ธฐ๋ณธ ์ด๋ก ์ด ๋ถ€์กฑํ•˜์‹  ๋ถ„๋“ค

iseunghan.tistory.com](https://iseunghan.tistory.com/173?category=934316)

์ด์œ ๋Š”, team์ด ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์ด ์•„๋‹ˆ๋ผ์„œ ์ด๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์ด ์ œ๋Œ€๋กœ ์•ˆ๋“ค์–ด๊ฐ„ ๊ฒƒ์ด๊ณ ,

    ..
team.getMembers().add(member);
member.setTeam(team); // * ์ค‘์š” *

member์— team์„ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค!

update ์ฟผ๋ฆฌ๊ฐ€ ์ž˜ ๋‚˜๊ฐ”๋‹ค.
DB์—๋„ ๊ฐ’์ด ์ž˜ ๋“ค์–ด๊ฐ”๋‹ค.


โœ…์ผ๋Œ€๋‹ค [1:N] (์ด ๋ชจ๋ธ์€ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Œ)

์ผ๋Œ€๋‹ค ๋‹จ๋ฐฉํ–ฅ ๋งคํ•‘๋ณด๋‹ค๋Š” ๋‹ค๋Œ€์ผ ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค.

์™œ ๊ทธ๋Ÿฐ์ง€๋Š” ํ•จ๊ป˜ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ์ผ๋Œ€๋‹ค ๋‹จ๋ฐฉํ–ฅ

์ฝ”๋“œ

Team

@Entity
public class Team {
    @Id @GeneratedValue
    private Long id;

    private String name;

    @OneToMany
    @JoinColumn(name = "TEAM_ID") // ์กฐ๊ธˆ ์ด์ƒํ•œ ๋ถ€๋ถ„(?), ์™ธ๋ž˜ํ‚ค๋ฅผ ๋งคํ•‘ํ•ด์ค€๋‹ค (์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์œผ๋กœ ์„ค์ •)
    private List<Member> members = new ArrayList<>();

   // getter, setter..
}

@JoinColumn ์„ ๊ผญ ํ•ด์ค˜์•ผ ํ•œ๋‹ค. ์•ˆ๊ทธ๋Ÿฌ๋ฉด join table๋กœ ๋˜์–ด ์ค‘๊ฐ„ ํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋˜๊ฒŒ ๋œ๋‹ค.

Member

@Entity
public class Member {
    @Id @GeneratedValue
    private Long id;

    private String name;

    // getter, setter ..
}

Main

// team์„ ๋งŒ๋“ค์–ด ์ค€๋‹ค.
Team team = new Team();
team.setName("team 1");

// member 3๋ช… ์ƒ์„ฑ
Member member1 = new Member();
member1.setName("member1");
em.persist(member1);

Member member2 = new Member();
member2.setName("member2");
em.persist(member2);

Member member3 = new Member();
member3.setName("member3");
em.persist(member3);

// member๋“ค์„ Team์— ๋„ฃ์–ด์ค€๋‹ค. (์—ฐ๊ด€๊ด€๊ณ„ ์ฃผ์ธ๋งŒ ์ˆ˜์ •,์‚ญ์ œ ๊ฐ€๋Šฅ!!)
team.getMembers().add(member1);
team.getMembers().add(member2);
team.getMembers().add(member3);

em.persist(team);

tx.commit();

์‹คํ–‰์„ ํ•ด์ฃผ๋ฉด,

insert ์ฟผ๋ฆฌ๊ฐ€ ์ด 4๊ฐœ (member 3๊ฐœ, team 1๊ฐœ) ๊ฐ€ ์ž˜ ๋‚˜๊ฐ„๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ?

?!!

๋‚˜๋Š” ๋ถ„๋ช… team์— ์žˆ๋Š” members (List)๋ฅผ ๋ฐ›์•„์™€์„œ add(member1,2,3)์„ ํ•ด์คฌ๋Š”๋ฐ, ์™œ update M**ember ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€๋Š” ๊ฑฐ์ง€?** ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด์œ ๋Š” ๊ฐ„๋‹จํ•˜๋‹ค. ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์€ Team์œผ๋กœ ์„ค์ • ๋˜์—ˆ์ง€๋งŒ, ์™ธ๋ž˜ํ‚ค์˜ ์œ„์น˜๋Š” (์ผ๋Œ€๋‹ค์˜ ๋‹ค์— ํ•ด๋‹นํ•˜๋Š”) memberํ…Œ์ด๋ธ”์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, team์— add๋ฅผ ํ•ด๋„ ์ฟผ๋ฆฌ๋Š” Member์— ๋Œ€ํ•ด์„œ ๋‚˜๊ฐ€๊ฒŒ ๋œ๋‹ค.

- ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ์™ธ๋ž˜ํ‚ค๊ฐ€ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์— ์žˆ๋‹ค.

- ์™ธ๋ž˜ํ‚ค๊ฐ€ Team ํ…Œ์ด๋ธ”์ด ์•„๋‹Œ, Member ํ…Œ์ด๋ธ”์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์—ฐ๊ด€๊ด€๊ณ„ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ์ถ”๊ฐ€๋กœ UPDATE SQL ์‹คํ–‰

  • ์ผ๋Œ€๋‹ค ์–‘๋ฐฉํ–ฅ

Member

@Entity
public class Member {
    @Id @GeneratedValue
    private Long id;

    private String name;

    @ManyToOne
    private Team team; // team๋งŒ ๋„ฃ์–ด์ค€๋‹ค.

    // getter, setter ..
}

โœ…์ผ๋Œ€์ผ [1:1]

๐Ÿš€๊ฐ€์žฅ ์„ ํ˜ธํ•˜๋Š” ๋ฐฉ๋ฒ•__ ์ฃผ ํ…Œ์ด๋ธ”์˜ ์™ธ๋ž˜ ํ‚ค ๋‹จ๋ฐฉํ–ฅ, ์–‘๋ฐฉํ–ฅ

  • ๋‹จ๋ฐฉํ–ฅ
    • ์™ธ๋ž˜ํ‚ค์˜ ์œ„์น˜๋ฅผ ์„ ํƒ ๊ฐ€๋Šฅ
    • ์™ธ๋ž˜ํ‚ค์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์œ ๋‹ˆํฌ(UNI) ์ œ์•ฝ์กฐ๊ฑด ์ถ”๊ฐ€

์ผ๋Œ€์ผ ๋‹จ๋ฐฉํ–ฅ ์ƒ๊ฐํ•ด๋ณด๊ธฐ

์™ธ๋ž˜ํ‚ค๋ฅผ ์–ด๋””์— ๋„ฃ์„์ง€ ์ฃผํ…Œ์ด๋ธ”์„ ๋จผ์ € ์ •ํ•ด์•ผํ•œ๋‹ค. ๊ฐ์ฒด์ง€ํ–ฅ์ ์œผ๋กœ ๋ดค์„ ๋•Œ, Member๊ฐ€ Locker๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์„ ์ˆœ ์žˆ์–ด๋„ Locker๊ฐ€ Member๊ฐ€ ์—†๋Š”๋ฐ ํ• ๋‹น๋œ ๊ฒƒ์€ ๋ญ”๊ฐ€ ์ด์ƒํ•˜๋‹ค. ํšŒ์›์ด ์ƒ๊ธฐ๋ฉด ๊ทธ๋•Œ ๋ฝ์ปค๋ฅผ ํ•˜๋‚˜ ๋ฐฐ์ •ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ฒด์ง€ํ–ฅ๊ด€์ ์œผ๋กœ ๋ดค์„ ๋•Œ Member๊ฐ€ Locker๋ฅผ ์†Œ์œ ํ•˜๊ณ  ์žˆ๋Š”๊ฒŒ ๋” ์ž์—ฐ์Šค๋Ÿฝ๋‹ค. ๊ทธ๋ž˜์„œ Member๊ฐ€ ์ฃผํ…Œ์ด๋ธ”์ด ๋œ๋‹ค.

public class Member{
    @Id @GeneratedValue
    private Long id;

    @Column(name = "USERNAME")
    private String name;

    @OneToOne
    @JoinColumn(name = "LOCKER_ID")
    private Locker locker;
}
--------------------------------

public class Locker{
    @Id @GeneratedValue
    private Long id;

    private String name;
}

๋‹ค๋Œ€์ผ(@ManyToOne) ๋‹จ๋ฐฉํ–ฅ ๋งคํ•‘๊ณผ ์œ ์‚ฌํ•˜๋‹ค.

  • ์–‘๋ฐฉํ–ฅ
    • ๋‹ค๋Œ€์ผ ์–‘๋ฐฉํ–ฅ ๋งคํ•‘ ์ฒ˜๋Ÿผ ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ๋Š” ๊ณณ์ด ์—ฐ๊ด€๊ด€๊ณ„ ์ฃผ์ธ
    • ๋ฐ˜๋Œ€ํŽธ์€ mappedBy ์ ์šฉ

public class Member{
    @Id @GeneratedValue
    private Long id;

    @Column(name = "USERNAME")
    private String name;

    @OneToOne
    @JoinColumn(name = "LOCKER_ID")
    private Locker locker;
}
--------------------------------

public class Locker{
    @Id @GeneratedValue
    private Long id;

    private String name;

    @OneToOne(mappedBy = "locker")
    private Member member;
}

์ฃผ์ธ์ด ์•„๋‹Œ์ชฝ์— mappedBy๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋งคํ•‘์‹œ์ผœ์ค€๋‹ค.


๋Œ€์ƒ ํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ํ‚ค ๋‹จ๋ฐฉํ–ฅ, ์–‘๋ฐฉํ–ฅ

  • ๋Œ€์ƒ ํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ํ‚ค ๋‹จ๋ฐฉํ–ฅ ์ •๋ฆฌ
    • ๋‹จ๋ฐฉํ–ฅ ๊ด€๊ณ„๋Š” JPA๊ฐ€ ์ง€์› X
    • ์–‘๋ฐฉํ–ฅ ๊ด€๊ณ„๋Š” ์ง€์› O

  • ๋Œ€์ƒ ํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ํ‚ค ์–‘๋ฐฉํ–ฅ
    • ์ผ๋Œ€์ผ ์ฃผ ํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ํ‚ค ์–‘๋ฐฉํ–ฅ ๋งคํ•‘๋ฐฉ๋ฒ•๊ณผ ๊ฐ™์Œ

REFERENCES

๋ฐ˜์‘ํ˜•