๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • ์žฅ์›์ต ๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ
๐Ÿ“š ์‹œ๋ฆฌ์ฆˆ/- ๋ฐฐ์›Œ๋ณด์ž Spring Data JPA

[๋ฐฐ์›Œ๋ณด์ž Spring Data JPA] JPA์˜ ๊ธฐ๋ณธ ์–ด๋…ธํ…Œ์ด์…˜๋“ค

by Wonit 2021. 4. 7.

ํ•ด๋‹น ๊ธ€์€ ๋ฐฐ์›Œ๋ณด์ž Spring Data JPA ์‹œ๋ฆฌ์ฆˆ ์ž…๋‹ˆ๋‹ค.
ํ•ด๋‹น ์‹œ๋ฆฌ์ฆˆ์˜ ๋‚ด์šฉ์ด ์ด์–ด์ง€๋Š” ํ˜•ํƒœ์ด๋ฏ€๋กœ ๊ธ€์˜ ๋‚ด์šฉ ์ค‘์— ์ƒ๋žต๋˜๋Š” ๋ง๋“ค์ด ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋‹ˆ, ์ž์„ธํ•œ ์‚ฌํ•ญ์€ ์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”!


JPA ์—์„œ๋Š” ์—”ํ‹ฐํ‹ฐ์™€ ๋งคํ•‘ํ•˜๊ธฐ, ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘ํ•˜๊ธฐ, ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด์„œ ์—ฌ๋Ÿฌ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ œ๊ณตํ•œ๋‹ค.

 

์ง€๊ธˆ ์ด์•ผ๊ธฐํ•  ๋‚ด์šฉ๋“ค์€ Spring Data JPA ์™€๋Š” ๋ณ„๊ฐœ๋กœ ์ˆœ์ˆ˜ JPA Framework์— ๋Œ€ํ•œ ๋‚ด์šฉ์ด๋‹ค.

JPA ๊ธฐ๋ณธ ์–ด๋…ธํ…Œ์ด์…˜

JPA๋Š” ORM, ์ฆ‰ ๊ฐ์ฒด์™€ ํ…Œ์ด๋ธ”์„ ๋งคํ•‘ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค.

 

๊ทธ๋Ÿฌ๋ฏ€๋กœ ๊ฐ์ฒด์™€ ํ…Œ์ด๋ธ”์„ ์ •ํ™•ํ•˜๊ฒŒ ๋งคํ•‘ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ๋ฐ, JPA ์—์„œ๋Š” ์ด๋Ÿฐ ๋งคํ•‘์„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์–ด๋…ธํ…Œ์ด์…˜๋“ค์„ ์ด์šฉํ•œ๋‹ค.

 

  • ๊ฐ์ฒด์™€ ํ…Œ์ด๋ธ” ๋งคํ•‘ํ•˜๊ธฐ
    • @Entity
    • @Table
  • ๊ธฐ๋ณธ ํ‚ค ๋งคํ•‘ํ•˜๊ธฐ
    • @Id
  • ํ•„๋“œ์™€ ์ปฌ๋Ÿผ ๋งคํ•‘ํ•˜๊ธฐ
    • @GeneratedValue
    • @Column
    • @Enumerated
  • ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘ํ•˜๊ธฐ
    • @OneToOne
    • @OneToMany
    • @ManyToOne
    • @ManyToMany

์–ด๋ ต์ง€ ์•Š์œผ๋‹ˆ ๊ฐ™์ด ํ•˜๋‚˜์”ฉ ์•Œ์•„๋ณด์ž.

์–ด๋–ค ํ˜•ํƒœ๋กœ ์“ฐ๋Š”์ง€ ์•Œ์•„๋ณด์ž.

@Entity // 1
@Table(name = "Member_tb") // 2
public class Member {

    @Id // 3
    @GeneratedValue(stretagy = GenerationType.IDENTITY) // 4
    @Column(name = "member_id", nullable = false) // 5
    private Long id;
    private String username;
    private int age;
    @Enumerated(EnumType.STRING) // 6
    private RoleType role = RoleType.USER;
}

@Entity, JPA ๊ด€๋ฆฌ ํด๋ž˜์Šค

@Entity ์–ด๋…ธํ…Œ์ด์…˜์€ JPA์˜ ์‹œ์ž‘์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

 

ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘ํ•  ํด๋ž˜์Šค์— @Entity ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™ํ˜€์ฃผ๋Š” ๊ฒƒ์œผ๋กœ JPA์—๊ฒŒ ํ•ด๋‹น ํด๋ž˜์Šค๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๋งคํ•‘ํ•  ๊ฐ์ฒด๋‹ค๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

 

์ด๋Ÿฐ Entity ์—๋Š” ์ค‘์š”ํ•œ 3๊ฐ€์ง€ ์›์น™์ด ์žˆ๋‹ค.

 

  1. ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ๊ผญ ๊ฐ€์ง€๊ณ  ์žˆ์„ ๊ฒƒ,
  2. final class, interface, enum, inner ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ๊ธฐ๋ณธ ํด๋ž˜์Šค์ผ ๊ฒƒ
  3. ์ €์žฅํ•  ํ•„๋“œ์— final ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒƒ

์ด ์„ธ ๊ฐ€์ง€๋งŒ ๋งŒ์กฑํ•˜๋ฉด Entity๋กœ์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

@Table, ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘

Table์€ ์•คํ‹ฐํ‹ฐ์™€ ๋งคํ•‘ํ•  ํ…Œ์ด๋ธ”์„ ์ด๋ฆ„์œผ๋กœ ์ง์ ‘ ์ง€์ •ํ•œ๋‹ค.

 

์œ„์—์„œ ๋ณด๋ฉด @Table(name = "") ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ํ…Œ์ด๋ธ”์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์‚ฌ์‹ค @Entity(name = "") ์œผ๋กœ๋„ ํ…Œ์ด๋ธ”์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, @Table ์–ด๋…ธํ…Œ์ด์…˜์—๋Š” ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ๋“ค์ด ๋” ์žˆ๋‹ค.

  1. DDL ์œ ๋‹ˆํฌ ์ œ์•ฝ ์กฐ๊ฑด ์ถ”๊ฐ€.
  2. ์Šคํ‚ค๋งˆ ๋งคํ•‘
  3. Catalog ๋งคํ•‘

์œ„์˜ ์‚ฌํ•ญ๋“ค์€ ํ˜„์žฌ๋กœ์จ๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋‹ˆ ๋„˜์–ด๊ฐ€๋„๋ก ํ•˜์ž.

 

@Id, ๊ธฐ๋ณธํ‚ค ๋งคํ•‘ํ•˜๊ธฐ

๊ธฐ๋ณธํ‚ค๋ž€?

๊ธฐ๋ณธ ํ‚ค๋Š” ์ฃผ ํ‚ค ๋˜๋Š” ํ”„๋ผ์ด๋จธ๋ฆฌ ํ‚ค๋ผ๊ณ  ํ•˜๋ฉฐ, ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์กฐ์˜ ์‹๋ณ„์ž๋กœ ์ด์šฉํ•˜๊ธฐ์— ๊ฐ€์žฅ ์ ํ•ฉํ•œ ๊ฒƒ์„ ๊ด€๊ณ„ ๋งˆ๋‹ค ๋‹จ ํ•œ ์„ค๊ณ„์ž์— ์˜ํ•ด ์„ ํƒ, ์ •์˜๋œ ํ›„๋ณด ํ‚ค๋ฅผ ๋งํ•œ๋‹ค.

@Id ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•˜๋ฉด Primary Key, ๊ธฐ๋ณธํ‚ค ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด๋Ÿฌํ•œ ๊ธฐ๋ณธํ‚ค์—๋Š” ๋‹ค์–‘ํ•œ ์ „๋žต์ด ์กด์žฌํ•˜๋Š”๋ฐ, ์ด๋ฅผํ…Œ๋ฉด MySql ์˜ AUTO_INCREAMENT ์™€ ๊ฐ™์ด ์ž๋™ ์ฆ๊ฐ€ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๊ณ , ์•„๋‹ˆ๋ฉด ์ง์ ‘ ๊ธฐ๋ณธ ํ‚ค๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

@GeneratedValue, ๊ธฐ๋ณธ ํ‚ค ์ƒ์„ฑ ์ „๋žต

์•ž์„œ ๋ง ํ•œ ๊ธฐ๋ณธ ํ‚ค์˜ ๋‹ค์–‘ํ•œ ์ƒ์„ฑ ์ „๋žต์„ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๊ธฐ๋ณธ ํ‚ค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ์—๋Š” ์ง์ ‘ ํ• ๋‹น๊ณผ ์ž๋™ ์ƒ์„ฑ ์ด ๋‚˜๋‰œ๋‹ค.

 

์šฐ๋ฆฌ๋Š” ์ž๋™ ์ƒ์„ฑ์— ์ดˆ์ ์„ ๋งž์ถฐ๋ณด์ž.

 

JPA์—์„œ ์ž๋™ ์ƒ์„ฑ์—๋Š” 3๊ฐ€์ง€ ์ „๋žต์ด ์žˆ๋‹ค.

 

๊ทธ ์ค‘์— IDENTITY ๋ฅผ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋‹ˆ IDENTITY์— ์ง‘์ค‘ํ•˜์ž.

 

  1. IDENTITY : ๊ธฐ๋ณธ ํ‚ค ์ƒ์„ฑ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—๊ฒŒ ์œ„์ž„ํ•œ๋‹ค.
  2. SEQUENCE : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‹œํ€€์Šค๋ฅผ ์ด์šฉํ•ด์„œ ๊ธฐ๋ณธ ํ‚ค๋ฅผ ํ• ๋‹นํ•œ๋‹ค.
  3. TABLE : ํ‚ค ์ƒ์„ฑ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•œ๋‹ค.

JPA ์—์„œ๋Š” strategy = GenerationType.IDENTITY ๋กœ ์ง€์ •ํ•œ๋‹ค.

@Column, ํ•„๋“œ ๋งคํ•‘ํ•˜๊ธฐ

๊ธฐ๋ณธ์ ์œผ๋กœ JPA ์—์„œ @Column์„ ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด ํ•ด๋‹น ํ•„๋“œ์˜ ์ด๋ฆ„์œผ๋กœ ๋งคํ•‘ ํ•˜๋Š”๋ฐ, ๋งŒ์•ฝ ๊ทธ๋ ‡์ง€ ์•Š์„ ๊ฒฝ์šฐ๋„ ์™•์™• ๋ฐœ์ƒํ•œ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด ํ…Œ์ด๋ธ”์—์„œ๋Š” Member์˜ ๊ธฐ๋ณธ ํ‚ค๊ฐ€ member_id ์ด๋ฉฐ, ์ž๋ฐ” ํด๋ž˜์Šค์—์„œ๋Š” id ๋กœ ์“ฐ์ด๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ด์— ํ•ด๋‹น๋œ๋‹ค.

 

์ด ๊ฒฝ์šฐ @Column(name = "") ์†์„ฑ์„ ์ด์šฉํ•˜๋ฉด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋˜ํ•œ DDL ์ƒ์„ฑ ๊ธฐ๋Šฅ์œผ๋กœ @Column(nullable = true) ๊ณผ @Column(length = 400) ์ด ๋Œ€ํ‘œ์ ์ด๋‹ค.

 

์˜ˆ์ƒํ–ˆ๋‹ค ์‹ถ์ด nullable์€ null ์ œ์•ฝ ์กฐ๊ฑด๊ณผ length ์€ ๊ธธ์ด ์ œ์•ฝ ์กฐ๊ฑด์ด๋‹ค.

 

@Enumerated, ENUM ํƒ€์ž… ๋งคํ•‘ํ•˜๊ธฐ

Enum ํƒ€์ž… ์ด๋ž€?

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

์ด๋Ÿฌํ•œ Enum ํƒ€์ž…์„ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, Enum ํƒ€์ž…์„ ์œ„ํ•œ ์–ด๋…ธํ…Œ์ด์…˜๋„ ์กด์žฌํ•œ๋‹ค.

 

@Enumerated

enum RoleType {
  ADMIN, USER
}

๊ณผ ๊ฐ™์€ Enum ์ด ์กด์žฌํ•œ๋‹ค๊ณ  ํ•ด๋ณด์ž.


๊ทธ๋Ÿผ ์œ„์™€ ๊ฐ™์ด @Enumerated ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

@Enumerated ์—๋Š” 2๊ฐ€์ง€ ํƒ€์ž…์ด ์กด์žฌํ•œ๋‹ค.

 

  1. EnumType.ORDINAL
  2. EnumType.STRING

ORDINAL์€ Enum ์— ์ •์˜๋œ ์ˆœ์„œ๋Œ€๋กœ JPA๊ฐ€ ์ด์šฉํ•˜๋Š”๋ฐ, ๋งŒ์•ฝ ์ˆœ์„œ๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด ๊ผฌ์ด๊ฒŒ ๋˜๋Š”๋ฐ, ๋ฌด์กฐ๊ฑด์ ์œผ๋กœ STRING ํƒ€์ž…์„ ์ด์šฉํ•˜์ž.

 

STRING ํƒ€์ž…์€ ๋ฌธ์ž๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋œ๋‹ค.

 

์•ฝ๊ฐ„์˜ ์„ฑ๋Šฅ์ƒ ORDINAL์ด ์ด์ ์ด ์žˆ์œผ๋‚˜ ์•ˆ์ •์„ฑ์„ ํƒํ•˜๋„๋ก ํ•˜์ž

๋Œ“๊ธ€