Study Repository

[JPA] ๊ณ ๊ธ‰ ๋งคํ•‘ : ์ƒ์† ๊ด€๊ณ„ ๋งคํ•‘

by Dongwoongkim

๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—๋Š” ์ƒ์†์ด๋ผ๋Š” ๊ฐœ๋…์ด ์—†๋Š” ๋Œ€์‹  ์ƒ์†๊ณผ ์œ ์‚ฌํ•œ ์Šˆํผํƒ€์ž… ์„œ๋ธŒํƒ€์ž… ๊ด€๊ณ„๋ผ๋Š” ๋ชจ๋ธ๋ง ๊ธฐ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. 

ORM์—์„œ์˜ ์ƒ์†๊ด€๊ณ„ ๋งคํ•‘์€ ์Šˆํผํƒ€์ž… ์„œ๋ธŒํƒ€์ž… ๊ด€๊ณ„๋ฅผ ๋งคํ•‘์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

 

์Šˆํผํƒ€์ž… ์„œ๋ธŒํƒ€์ž… ๋…ผ๋ฆฌ ๋ชจ๋ธ์„ ์‹ค์ œ ๋ฌผ๋ฆฌ ๋ชจ๋ธ์ธ ํ…Œ์ด๋ธ”๋กœ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

1. ๊ฐ๊ฐ์˜ ํ…Œ์ด๋ธ”๋กœ ๋ณ€ํ™˜ (์กฐ์ธ ์ „๋žต) : ์Šˆํผํƒ€์ž… ์„œ๋ธŒํƒ€์ž… ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ชจ๋‘ ๊ฐ๊ฐ ํ…Œ์ด๋ธ”๋กœ ๋งŒ๋“ค๊ณ  ์กฐํšŒํ•  ๋•Œ ์กฐ์ธ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

2. ํ†ตํ•ฉ ํ…Œ์ด๋ธ”๋กœ ๋ณ€ํ™˜ (๋‹จ์ผ ํ…Œ์ด๋ธ” ์ „๋žต): ์„œ๋ธŒํƒ€์ž… ์—”ํ‹ฐํ‹ฐ์™€ ์Šˆํผํƒ€์ž… ์—”ํ‹ฐํ‹ฐ๋ฅผ ํ•œ๊ณณ์— ๋ชจ์•„ ํ•˜๋‚˜์˜ ์—”ํ‹ฐํ‹ฐ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

3. ์„œ๋ธŒํƒ€์ž… ํ…Œ์ด๋ธ”๋กœ ๋ณ€ํ™˜ (๊ตฌํ˜„ ํด๋ž˜์Šค๋งˆ๋‹ค ํ…Œ์ด๋ธ” ์ „๋žต) : ์„œ๋ธŒํƒ€์ž… ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ชจ๋‘ ๊ฐ๊ฐ ํ…Œ์ด๋ธ”๋กœ ๋งŒ๋“ค๊ณ , ์ž์‹ ํ…Œ์ด๋ธ”์ด ๋ถ€๋ชจ ํ…Œ์ด๋ธ”์˜ ๊ธฐ๋ณธํ‚ค๋ฅผ ๊ทธ๋Œ€                                                  


์กฐ์ธ ์ „๋žต 

์Šˆํผํƒ€์ž… ์„œ๋ธŒํƒ€์ž… ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ชจ๋‘ ๊ฐ๊ฐ ํ…Œ์ด๋ธ”๋กœ ๋งŒ๋“ค๊ณ , ์ž์‹ ํ…Œ์ด๋ธ”์ด ๋ถ€๋ชจ ํ…Œ์ด๋ธ”์˜ ๊ธฐ๋ณธํ‚ค๋ฅผ ๋ฐ›์•„์„œ ๊ธฐ๋ณธ ํ‚ค + ์™ธ๋ž˜ํ‚ค์ธ ๋ณตํ•ฉํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ „๋žต์ž…๋‹ˆ๋‹ค. 

 

์Šˆํผํƒ€์ž… ์„œ๋ธŒํƒ€์ž… ๊ด€๊ณ„๋ฅผ ์กฐ์ธ์ „๋žต์œผ๋กœ ๋งคํ•‘ํ•  ๋•Œ๋Š” Dtype์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์ฒด๋Š” ํƒ€์ž…์œผ๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ…Œ์ด๋ธ”์—๋Š” ํƒ€์ž…์˜ ๊ฐœ๋…์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— Dtype์„ ๊ตฌ๋ถ„ํ•˜๋Š” ์ปฌ๋Ÿผ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด Item์ด๋ผ๋Š” ๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ, Item์„ ์ƒ์†๋ฐ›์€ ์ž์‹ ์—”ํ‹ฐํ‹ฐ Album, Movie, Book ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค.

 

์ด ์ƒ์†๊ด€๊ณ„๋ฅผ ์Šˆํผํƒ€์ž… ์„œ๋ธŒํƒ€์ž… ์กฐ์ธ์ „๋žต์œผ๋กœ ๋งคํ•‘ํ•ด๋ด…์‹œ๋‹ค. 

 

Super Type - Item

@Entity
@Inheritance(strategy = InheritanceType.JOINED) // ์กฐ์ธ ์ „๋žต์œผ๋กœ ์Šˆํผ-์„œ๋ธŒํƒ€์ž… ๋งคํ•‘
@DiscriminatorColumn(name = "DTYPE") // ์ž์‹ ๊ตฌ๋ถ„ ์ปฌ๋Ÿผ์„ Dtype์„ ์„ค์ •
public abstract class Item { // ์‹ค์ œ ์—”ํ‹ฐํ‹ฐ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๋•Œ ์ถ”์ƒ ํด๋ž˜์Šค๋กœ ์„ ์–ธ 
	
    @Id @GeneratedValue
    @Column(name = "ITEM_ID")
    private Long id;

    private String name;
    private int price;

	...
}
  • ์ƒ์† ๋งคํ•‘์„ ๋ถ€๋ชจ ํด๋ž˜์Šค์— @Inheritance๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋งคํ•‘ ์ „๋žต์„ ์กฐ์ธ ์ „๋žต์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ startegy ์†์„ฑ์„ Inheritance.JOINED๋กœ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์ถ”๊ฐ€์ ์œผ๋กœ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—๋Š” ํƒ€์ž…์˜ ๊ฐœ๋…์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ž์‹ ๊ตฌ๋ถ„ ์ปฌ๋Ÿผ์„ @DiscriminatorColuimn ์–ด๋…ธํ…Œ์ด์…˜์— Dtype์œผ๋กœ ์ง€์ •ํ•ด์ค๋‹ˆ๋‹ค.
  • ๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ํ…Œ์ด๋ธ”๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋Š” ์ถ”์ƒ ํด๋ž˜์Šค๋กœ ์„ ์–ธํ•ด์„œ ๋งคํ•‘ํ•ด์ค๋‹ˆ๋‹ค.

 

Sub Type - Album

@Entity
@DiscriminatorValue("A")
public class Album extends Item{
    private String artist;
}
  • Item์„ ์ƒ์†๋ฐ›์€ ์ž์‹ ํด๋ž˜์Šค์ด๋ฏ€๋กœ extends ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ์‹œ๋‹ค.
  • ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ €์žฅํ•  ๋•Œ ๊ตฌ๋ถ„ ์ปฌ๋Ÿผ์— ์ž…๋ ฅํ•  ๊ฐ’์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋ณ„๋„๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ํด๋ž˜์Šค ์ด๋ฆ„์œผ๋กœ ์ž๋™ ์ง€์ •๋ฉ๋‹ˆ๋‹ค. 
๋งŒ์•ฝ ์ž์‹ ํ…Œ์ด๋ธ”์˜ ๊ธฐ๋ณธ ํ‚ค ์ปฌ๋Ÿผ๋ช… (item_id)๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ 
@PrimaryKeyJoinColumn(name = "์ง€์ •ํ•˜๊ณ  ์‹ถ์€ ์ปฌ๋Ÿผ๋ช…")์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์กฐ์ธ์ „๋žต ์žฅ-๋‹จ์ 

์žฅ์ 

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

๋‹จ์ 

  • ์กฐํšŒํ•  ๋•Œ join์ด ๋งŽ์ด ์‚ฌ์šฉ๋˜๋ฏ€๋กœ ์„ฑ๋Šฅ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ๋‹ค.
  • ๋“ฑ๋กํ•  ๋•Œ insert SQL์„ n๋ฒˆ ์‹คํ–‰

๋‹จ์ผ ํ…Œ์ด๋ธ” ์ „๋žต

์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ํ…Œ์ด๋ธ”์„ ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉํ•ด์„œ ๊ตฌ๋ถ„ ์ปฌ๋Ÿผ์œผ๋กœ ์–ด๋–ค ์ž์‹ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜์—ˆ๋Š”์ง€ ๊ตฌ๋ถ„ํ•˜๋Š” ์ „๋žต์ž…๋‹ˆ๋‹ค. ํ•œ ํ…Œ์ด๋ธ” ๋‚ด์—์„œ ์กฐํšŒํ•˜๋ฏ€๋กœ ์ผ๋ฐ˜์ ์œผ๋กœ ์กฐํšŒ๊ฐ€ ๊ฐ€์žฅ ๋น ๋ฆ…๋‹ˆ๋‹ค.

์ž์‹ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๋งคํ•‘ํ•œ ์ปฌ๋Ÿผ์€ ๋ชจ๋‘ null์„ ํ—ˆ์šฉํ•˜๋„๋ก ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="DTYPE")
public abstract class Item{

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

    private String name;

    private int price;
    
    ...
}

@Entity
@DiscriminatorValue("A")
public class Album extends Item {...}

@Entity
@DiscriminatorValue("M")
public class Movie extends Item {...}

@Entity
@DiscriminatorValue("B")
public class Book extends Item {...}
  • @Inheritance.strategy๋ฅผ InheritanceType.SINGLE_TABLE ๋กœ ์„ค์ •ํ•˜๋ฉด ๋‹จ์ผ ํ…Œ์ด๋ธ” ์ „๋žต์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ํ…Œ์ด๋ธ” ํ•˜๋‚˜์— ๋ชจ๋“  ๊ฒƒ์„ ํ†ตํ•ฉํ•˜๋ฏ€๋กœ ๊ตฌ๋ถ„ ์ปฌ๋Ÿผ์„ ํ•„์ˆ˜๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • Dtype์œผ๋กœ ์–ด๋–ค ์ž์‹ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜์—ˆ๋Š”์ง€ ๊ตฌ๋ถ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜๋“œ์‹œ @DiscriminatorColumn์„ ์„ค์ •ํ•ด์ฃผ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์žฅ์ 

  • join ํ•˜์ง€ ์•Š๊ณ  ์กฐํšŒํ•  ์ˆ˜ ์žˆ์–ด์„œ ์กฐํšŒ ์„ฑ๋Šฅ์ด ๋น ๋ฆ…๋‹ˆ๋‹ค.
    • select * from item where ..
  • ์กฐํšŒ ์ฟผ๋ฆฌ๊ฐ€ ๋‹จ์ˆœํ•ฉ๋‹ˆ๋‹ค.

๋‹จ์ 

  • ์ž์‹ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๋งคํ•‘ํ•œ ์ปฌ๋Ÿผ์€ ๋ชจ๋‘ null์„ ํ—ˆ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹จ์ผ ํ…Œ์ด๋ธ”์— ๋ชจ๋“ ๊ฒƒ์„ ์ €์žฅํ•˜๋ฏ€๋กœ ํ…Œ์ด๋ธ”์ด ์ปค์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ตฌํ˜„ ํด๋ž˜์Šค๋งˆ๋‹ค ํ…Œ์ด๋ธ” ์ „๋žต

์ž์‹ ์—”ํ‹ฐํ‹ฐ๋งˆ๋‹ค ํ…Œ์ด๋ธ”์„ ๊ฐ๊ฐ ๋งŒ๋“œ๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. 

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn(name="DTYPE")
public abstract class Item{

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

    private String name;

    private int price;

    ...
}

@Entity
public class Album extends Item {...}

@Entity
public class Movie extends Item {...}

@Entity
public class Book extends Item {...}
  • @Inheritance.strategy๋ฅผ InheritanceType.TABLE_PER_CLASS ๋กœ ์„ค์ •ํ•˜๋ฉด ๊ตฌํ˜„ ํด๋ž˜์Šค๋งˆ๋‹ค ํ…Œ์ด๋ธ” ์ „๋žต์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ์ „๋žต์€ ์ž์‹ ์—”ํ‹ฐํ‹ฐ๋งˆ๋‹ค ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • not null ์ œ์•ฝ์กฐ๊ฑด์„ ์‚ฌ์šฉํ• ์ˆ˜ ์žˆ๊ณ , ์„œ๋ธŒํƒ€์ž…์„ ๊ตฌ๋ถ„ํ•ด์„œ ์ฒ˜๋ฆฌํ•  ๋•Œ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ ์ž์‹ ํ…Œ์ด๋ธ”์„ ํ•จ๊ป˜ ์กฐํšŒํ•  ๋•Œ UNION์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ธฐ ๋–„๋ฌธ์— ์„ฑ๋Šฅ์ด ๋А๋ฆฌ๊ณ  ์ž์‹ ํ…Œ์ด๋ธ”์„ ํ†ตํ•ฉํ•ด์„œ ์ฟผ๋ฆฌํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

์ด ์ „๋žต์„ ์ถ”์ฒœํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ „๋žต๋„ ์žˆ๊ตฌ๋‚˜ ์ •๋„๋กœ๋งŒ ์•Œ์•„๋‘ก์‹œ๋‹ค.

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

Dongwoongkim

ํ™œ๋™ํ•˜๊ธฐ