Server/SpringBoot

[JPA] ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘(๋‹ค๋Œ€์ผ, ์ผ๋Œ€๋‹ค, ์ผ๋Œ€์ผ, ๋‹ค๋Œ€๋‹ค)

meeeeejin 2021. 8. 25. 00:27

 

์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ง€์€์ด: ๊น€์˜ํ•œ)

๊น€์˜ํ•œ๋‹˜์˜ ์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ฝ๊ณ  ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค. 

 

 

 

1. ์—”ํ‹ฐํ‹ฐ ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘

 

๋‹ค์ค‘์„ฑ

  • ๋‹ค๋Œ€์ผ(@ManyToOne)
  • ์ผ๋Œ€๋‹ค(@OneToMany)
  • ์ผ๋Œ€์ผ(@OneToOne)
  • ๋‹ค๋Œ€๋‹ค(@ManyToMany)

 

๋‹จ๋ฐฉํ–ฅ, ์–‘๋ฐฉํ–ฅ

  • ๋‹จ๋ฐฉํ–ฅ: ๊ฐ์ฒด ๊ด€๊ณ„์—์„œ ํ•œ์ชฝ๋งŒ ์ฐธ์กฐ
  • ์–‘๋ฐฉํ–ฅ: ๊ฐ์ฒด ๊ด€๊ณ„์—์„œ ์–‘์ชฝ์ด ์„œ๋กœ ์ฐธ์กฐ

 

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

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

 

 

 

1. ๋‹ค๋Œ€์ผ(@ManyToOne)

 

๋‹ค๋Œ€์ผ ๋‹จ๋ฐฉํ–ฅ [N:1]

 

ํšŒ์› ์—”ํ‹ฐํ‹ฐ

@Entity
public class Member {
    
    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    
    private String username;
    
    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;
}

 

ํŒ€ ์—”ํ‹ฐํ‹ฐ

@Entity
public class Team {

    @Id @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;

    private String name;
}

 

  • ํšŒ์›์€ Member.team์œผ๋กœ ํŒ€ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ฐธ์กฐ ๊ฐ€๋Šฅ
  • ํŒ€์€ ํšŒ์› ์ฐธ์กฐ ํ•„๋“œ ์—†์–ด์„œ ์ฐธ์กฐ ๋ถˆ๊ฐ€๋Šฅ
  • ๋”ฐ๋ผ์„œ ํšŒ์›๊ณผ ํŒ€์€ ๋‹ค๋Œ€์ผ ๋‹จ๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„
  • @JoinColumn(name = "TEAM_ID")๋ฅผ ์‚ฌ์šฉํ•ด์„œ Member.team ํ•„๋“œ๋ฅผ TEAM_ID FK์™€ ๋งคํ•‘

 

 

๋‹ค๋Œ€์ผ ์–‘๋ฐฉํ–ฅ [N:1, 1:N]

์‹ค์„ ์ด ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ(Member.team)์ด๊ณ  ์ ์„ (Team.members)์€ ์ฃผ์ธ์ด ์•„๋‹ˆ๋‹ค. 

 

ํšŒ์› ์—”ํ‹ฐํ‹ฐ

@Entity
public class Member {

    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    private String username;

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

    public void setTeam(Team team) {
        this.team = team;
        // ๋ฌดํ•œ๋ฃจํ”„์— ๋น ์ง€์ง€ ์•Š๋„๋ก ์ฒดํฌ
        if(!team.getMembers().contains(this)) {

            team.getMembers().add(this)
        }
    }
}

 

ํŒ€ ์—”ํ‹ฐํ‹ฐ

@Entity
public class Team {

    @Id @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;

    private String name;

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

    public void addMember(Member member) {
        this.members.add(member);
        // ๋ฌดํ•œ๋ฃจํ”„์— ๋น ์ง€์ง€ ์•Š๋„๋ก ์ฒดํฌ
        if (member.getTeam() != this) {
            member.setTeam(this);
        }
    }
}

 

  • ์–‘๋ฐฉํ–ฅ์€ FK๊ฐ€ ์žˆ๋Š” ์ชฝ์ด ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ
  • 1:N, N:1 ๊ฒฝ์šฐ์— ํ•ญ์ƒ N์— FK๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ N ์ชฝ์ด ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ
  • JPA๋Š” FK๋ฅผ ๊ด€๋ฆฌํ•  ๋•Œ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ๋งŒ ์‚ฌ์šฉ
  • ์–‘๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„๋Š” ํ•ญ์ƒ ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•ด์•ผ ํ•จ

 

 

 

2. ์ผ๋Œ€๋‹ค(@OneToMany)

 

์ผ๋Œ€๋‹ค ๋‹จ๋ฐฉํ–ฅ [1:N]

 

ํŒ€ ์—”ํ‹ฐํ‹ฐ

@Entity
public class Team {

    @Id @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;

    private String name;

    @OneToMany(mappedBy = "team")
    @JoinColumn(name = "TEAM_ID")  // MEMBER ํ…Œ์ด๋ธ”์˜ TEAM_ID (FK)
    private List<Member> members = new ArrayList<Member>();
}

 

ํšŒ์› ์—”ํ‹ฐํ‹ฐ

@Entity
public class Member {

    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    private String username;
}

 

  • 1:N ๊ด€๊ณ„์—์„  N ์ชฝ์— FK๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํŒ€ ์—”ํ‹ฐํ‹ฐ์˜ Team.members๋กœ ํšŒ์› ํ…Œ์ด๋ธ”์˜ TEAM_ID FK ๊ด€๋ฆฌ
  • ๋”ฐ๋ผ์„œ 1์ชฝ์—์„œ ๊ด€๋ฆฌํ•˜๋Š” FK๊ฐ€ N ์ชฝ์˜ ํ…Œ์ด๋ธ”์— ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ๋‹จ์ 
  • ์ด ๊ฒฝ์šฐ ์—”ํ‹ฐํ‹ฐ ์ €์žฅ๊ณผ ์—ฐ๊ด€๊ด€๊ณ„ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด insert ์ด์™ธ์— ์ถ”๊ฐ€๋กœ update sql์„ ์‹คํ–‰ํ•ด์•ผ ํ•จ
  • ๊ฒฐ๋ก  => ์ผ๋Œ€๋‹ค ๋‹จ๋ฐฉํ–ฅ๋ณด๋‹ค๋Š” ๋‹ค๋Œ€์ผ ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์„ ์‚ฌ์šฉํ•˜์ž!!!

 

 

์ผ๋Œ€๋‹ค ์–‘๋ฐฉํ–ฅ [1:N, N:1]

1:N, N:1 ๊ด€๊ณ„์—์„œ ํ•ญ์ƒ N ์ชฝ์— FK๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์—์„œ @OneToMany๋Š” ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์ด ๋  ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ ์ผ์ด ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์ธ ์ผ๋Œ€๋‹ค ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋‹ค๋งŒ ์ผ๋Œ€๋‹ค ๋‹จ๋ฐฉํ–ฅ ๋งคํ•‘ ๋ฐ˜๋Œ€ํŽธ์— ๋‹ค๋Œ€์ผ ๋‹จ๋ฐฉํ–ฅ ๋งคํ•‘์„ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์ถ”๊ฐ€ํ•ด์„œ ์ผ๋Œ€๋‹ค ์–‘๋ฐฉํ–ฅ์ฒ˜๋Ÿผ ๋ณด์ด๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•๋„ ์œ„์—์„œ ์„ค๋ช…ํ•œ ์ผ๋Œ€๋‹ค ๋‹จ๋ฐฉํ–ฅ ๋งคํ•‘์˜ ๋‹จ์ ์„ ๊ทธ๋Œ€๋กœ ๊ฐ€์ง„๋‹ค. 

 

 

ํŒ€ ์—”ํ‹ฐํ‹ฐ

@Entity
public class Team {

    @Id @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;

    private String name;

    @OneToMany(mappedBy = "team")
    @JoinColumn(name = "TEAM_ID")  // MEMBER ํ…Œ์ด๋ธ”์˜ TEAM_ID (FK)
    private List<Member> members = new ArrayList<Member>();
}

 

ํšŒ์› ์—”ํ‹ฐํ‹ฐ

@Entity
public class Member {

    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    private String username;

    @ManyToOne
    @JoinColumn(name = "TEAM_ID", insertable = false, updatable = false)  // ์ฝ๊ธฐ ์ „์šฉ
    private Team team;
}

 

 

 

3. ์ผ๋Œ€์ผ [1:1]

 

์ฃผ ํ…Œ์ด๋ธ”์— FK

  • ์ฃผ ํ…Œ์ด๋ธ”์— FK๋ฅผ ๋‘๊ณ  ๋Œ€์ƒ ํ…Œ์ด๋ธ” ์ฐธ์กฐ
  • FK๋ฅผ ๊ฐ์ฒด ์ฐธ์กฐ์™€ ๋น„์Šทํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
  • ์ฃผ ํ…Œ์ด๋ธ”๋งŒ ํ™•์ธํ•ด๋„ ๋Œ€์ƒ ํ…Œ์ด๋ธ”๊ณผ ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ ๊ฐ€๋Šฅ

 

๋‹จ๋ฐฉํ–ฅ

ํšŒ์› MEMBER๊ฐ€ ์ฃผ ํ…Œ์ด๋ธ”์ด๊ณ  ์‚ฌ๋ฌผํ•จ LOCKER๊ฐ€ ๋Œ€์ƒ ํ…Œ์ด๋ธ”์ธ ์˜ˆ์‹œ

ํšŒ์›, ์‚ฌ๋ฌผํ•จ ์—”ํ‹ฐํ‹ฐ

@Entity
public class Member {

    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    private String username;

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

@Entity
public class Locker {
    
    @Id @GeneratedValue
    @Column(name = "LOCKER_ID")
    private Long id;
    
    private String name;
}

 

์–‘๋ฐฉํ–ฅ

MEMBER ํ…Œ์ด๋ธ”์ด FK๋กœ LOCKER_ID๋ฅผ ๊ฐ€์ง„๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค. 

 

ํšŒ์›, ์‚ฌ๋ฌผํ•จ ์—”ํ‹ฐํ‹ฐ

@Entity
public class Member {

    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    private String username;

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

@Entity
public class Locker {

    @Id @GeneratedValue
    @Column(name = "LOCKER_ID")
    private Long id;

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

 

  • MEMBER ํ…Œ์ด๋ธ”์ด FK๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฏ€๋กœ Member.locker๊ฐ€ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ
  • ๋”ฐ๋ผ์„œ Locker.member๋Š” mappedBy๋ฅผ ์„ ์–ธํ•ด์„œ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์ด ์•„๋‹ˆ๋ผ๊ณ  ์„ค์ •

 

 

 

๋Œ€์ƒ ํ…Œ์ด๋ธ”์— FK

  • ํ…Œ์ด๋ธ” ๊ด€๊ณ„๋ฅผ 1:1์—์„œ 1:N์œผ๋กœ ์‰ฝ๊ฒŒ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ

 

๋‹จ๋ฐฉํ–ฅ

1:1 ๊ด€๊ณ„์—์„œ ๋Œ€์ƒ ํ…Œ์ด๋ธ”์— FK๊ฐ€ ์žˆ๋Š” ๋‹จ๋ฐฉํ–ฅ ๊ด€๊ณ„๋Š” JPA์—์„œ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. 

 

์–‘๋ฐฉํ–ฅ

ํšŒ์› MEMBER๊ฐ€ ์ฃผ ํ…Œ์ด๋ธ”์ด๊ณ  ์‚ฌ๋ฌผํ•จ LOCKER๊ฐ€ ๋Œ€์ƒ ํ…Œ์ด๋ธ”์ธ ์˜ˆ์‹œ

ํšŒ์›, ์‚ฌ๋ฌผํ•จ ์—”ํ‹ฐํ‹ฐ

@Entity
public class Member {

    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    private String username;

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

@Entity
public class Locker {

    @Id @GeneratedValue
    @Column(name = "LOCKER_ID")
    private Long id;

    private String name;

    @OneToOne
    @JoinColumn(name = "MEMBER_ID")
    private Member member;
}

 

 

 

4. ๋‹ค๋Œ€๋‹ค [N:N]

 

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

 

์˜ˆ์‹œ๋กœ ํšŒ์›๊ณผ ์ƒํ’ˆ ํ…Œ์ด๋ธ”์„ ์ƒ๊ฐํ•ด๋ณด๋ฉด, ํšŒ์›๋“ค์€ ์—ฌ๋Ÿฌ ์ƒํ’ˆ์„ ์ฃผ๋ฌธํ•  ์ˆ˜ ์žˆ๊ณ  ์ƒํ’ˆ๋“ค์€ ์—ฌ๋Ÿฌ ํšŒ์›์— ์˜ํ•ด ์ฃผ๋ฌธ๋  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋Œ€๋‹ค ๊ด€๊ณ„์ด๋‹ค. ์ด ๊ฒฝ์šฐ ํšŒ์› ํ…Œ์ด๋ธ”๊ณผ ์ƒํ’ˆ ํ…Œ์ด๋ธ”๋งŒ์œผ๋กœ ์ด ๊ด€๊ณ„๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์—†๊ณ  Member_Product์™€ ๊ฐ™์€ ์—ฐ๊ฒฐ ํ…Œ์ด๋ธ”์„ ์ด์šฉํ•ด ๊ด€๊ณ„๋ฅผ ํ‘œํ˜„ํ•ด์•ผ ํ•œ๋‹ค. 

 

ํ•˜์ง€๋งŒ ๊ฐ์ฒด๋Š” ํ…Œ์ด๋ธ”๊ณผ ๋‹ค๋ฅด๊ฒŒ ๊ฐ์ฒด 2๊ฐœ๋กœ ๋‹ค๋Œ€๋‹ค ๊ด€๊ณ„๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. @ManyToMany๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‹ค์Œ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ๋‹ค๋Œ€๋‹ค ๊ด€๊ณ„๋ฅผ ๋งคํ•‘ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

๋‹จ๋ฐฉํ–ฅ

ํšŒ์›, ์ƒํ’ˆ ์—”ํ‹ฐํ‹ฐ

@Entity
public class Member {

    @Id
    @Column(name = "MEMBER_ID")
    private Long id;

    private String username;

    @ManyToMany
    @JoinTable(name = "MEMBER_PRODUCT", 
            joinColumns = @JoinColumn(name = "MEMBER_ID"), 
            inverseJoinColumns = @JoinColumn(name = "PRODUCT_ID"))
    private List<Product> products = new ArrayList<Product>();
}

@Entity
public class Product {

    @Id
    @Column(name = "PRODUCT_ID")
    private Long id;

    private String name;
}

 

 

์–‘๋ฐฉํ–ฅ

ํšŒ์› ์—”ํ‹ฐํ‹ฐ์— addProduct, ์ƒํ’ˆ ์—”ํ‹ฐํ‹ฐ์— ์—ญ๋ฐฉํ–ฅ ๋งคํ•‘ ์ถ”๊ฐ€

@Entity
public class Member {

    @Id
    @Column(name = "MEMBER_ID")
    private Long id;

    private String username;

    @ManyToMany
    @JoinTable(name = "MEMBER_PRODUCT",
            joinColumns = @JoinColumn(name = "MEMBER_ID"),
            inverseJoinColumns = @JoinColumn(name = "PRODUCT_ID"))
    private List<Product> products = new ArrayList<Product>();
    
    public void addProduct(Product product) {
        // ์ƒ๋žต
        products.add(product);
        product.getMembers().add(this);
    }
}

@Entity
public class Product {

    @Id
    @Column(name = "PRODUCT_ID")
    private Long id;

    private String name;
    
    @ManyToMany(mappedBy = "products")
    private List<Member> members;
}

 

@ManyToMany๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์—ฐ๊ฒฐ ํ…Œ์ด๋ธ”์„ ์ฒ˜๋ฆฌํ•  ๊ฒฝ์šฐ ์—ฐ๊ฒฐ ํ…Œ์ด๋ธ”์— ์ปฌ๋Ÿผ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ ์ด ๊ฒฝ์šฐ์—๋Š” ์—ฐ๊ฒฐ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋งŒ๋“ค๊ณ  ์ด๊ณณ์— ์ถ”๊ฐ€ํ•œ ์ปฌ๋Ÿผ๋“ค์„ ๋งคํ•‘ํ•ด์•ผ ํ•œ๋‹ค. 

 

์˜ˆ๋ฅผ ๋“ค์–ด, Member_Product ํ…Œ์ด๋ธ”์— ์ฃผ๋ฌธ ์ˆ˜๋Ÿ‰๊ณผ ์ฃผ๋ฌธ ๋‚ ์งœ ์ปฌ๋Ÿผ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๊ฒฝ์šฐ MemberProduct ์—”ํ‹ฐํ‹ฐ๋Š” (MEMBER_ID, PRODUCT_ID)๋ฅผ ๋ณตํ•ฉํ‚ค๋กœ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค. 

 

 

 

 

 

 

์ฐธ๊ณ : ์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ง€์€์ด: ๊น€์˜ํ•œ)

 

728x90