πJPA μ°κ΄κ΄κ³ λ§€ν
Spring JPA
μν°ν° λ§€ν
@Entity
κ° λΆμ ν΄λμ€λ JPAκ° κ΄λ¦¬νλ©° μν°ν°λΌκ³ λΆλ₯Έλ€.- RDBMSμ
Table
κ³Ό λ§€νλλ€.
μ£Όμμ¬ν
- νλΌλ©ν°κ° μλ public λλ protected κΈ°λ³Έ μμ±μκ° νμνλ€.
- final ν΄λμ€, enum, interface, inner ν΄λμ€μλ μ¬μ©ν μ μλ€.
- μ μ₯ν νλμ finalμ μ¬μ©ν μ μλ€.
- λ΄λΆ ꡬνμ μμλ°λ νλ‘μ κ°μ²΄κ° μ겨μ λ°μνλ μ£Όμμ¬νλ€μ΄λ€.
λ°μ΄ν°λ² μ΄μ€ μ€ν€λ§ μλ μμ±
create
: κΈ°μ‘΄ ν μ΄λΈ μμ ν λ€μ μμ±(DROP + CREATE) νλ€.
create-drop
: createμ κ°μΌλ μ’ λ£ μμ μ ν μ΄λΈμ dropνλ€
update
: λ³κ²½λ μ¬νλ§ λ°μλλ€.
validate
: μν°ν°μ ν μ΄λΈμ΄ μ μ λ§€νλμλμ§ νμΈλ§ νλ€.
none
: μ¬μ©νμ§ μμ
- μ΄μ νκ²½μμλ μ λ create, create-drop, updateλ₯Ό μ¬μ©ν΄μλ μλλ€.
- κ°λ° μ΄κΈ°λ¨κ³λ create λλ update, ν μ€νΈμλ²λ update λλ validate, μ€ν μ΄μ§κ³Ό μ΄μ μλ²λ validate λλ noneμ΄ κΆμ₯λλ€.
μλ² λλ νμ
@Embeddable
: κ° νμ μ μ μνλ κ³³μ νμ@Embedded
: κ° νμ μ μ¬μ©νλ κ³³μ νμ- κΈ°λ³Έ μμ±μκ° νμμ΄λ€.
- λ³λμ ν΄λμ€λ‘ μ μν μ μμ§λ§ ν μ΄λΈ μμΌλ‘λ μ¬μ©νλ κ³³κ³Ό κ°μ ν μ΄λΈμ μμΉνλ€.
- μ μ€κ³ν ORM μ΄ν리μΌμ΄μ μ λ§€νν ν μ΄λΈμ μλ³΄λ€ ν΄λμ€μ μκ° λ λ§λ€.
- λ€λ§ μλ² λλ νμ μΌλ‘ μ μν κ°μ²΄λ κ°μ²΄μ΄λ―λ‘ λμ μ 볡μ¬κ° μλλΌ μ°Έμ‘°κ° μΌμ΄λλ€. 곡μ μ°Έμ‘°μ λ¬Έμ κ° μμ μ μμΌλ―λ‘ μ£Όμνλ€. λΆλ³κ°μ²΄λ‘ λ§λ λ€λ©΄ κ°μ₯ μ’λ€.
- μλ² λλ νμ μ²λΌ κ°νμ μΈ κ²½μ° μ»¬λ μ μΌλ‘ μ¬λ¬κ°λ₯Ό μ μ₯ν λ λ³λμ ν μ΄λΈμ΄ νμνλ€. κ·Έλ¦¬κ³ κ° νμ μ μΆμ μ΄ μ΄λ ΅λ€. 컬λ μ μΌλ‘ μ¬μ©ν΄μΌν κ²½μ° μΌλλ€ κ΄κ³λ₯Ό μ¬μ©νλ κ²μ΄ κΆμ₯λλ€.
- μλ³μκ° νμνκ³ , μ§μν΄μ κ°μ μΆμ νκ³ λ³κ²½ν΄μΌ νλ€λ©΄ κ·Έκ²μ κ° νμ μ΄ μλλΌ μν°ν°μ΄λ€.
μμμ± μ μ΄
- μν°ν°λ₯Ό μμν ν λ μ°κ΄λ μν°ν°λ ν¨κ» μμννλ κΈ°λ₯μ μ 곡νλ€.
- μλ₯Ό λ€μ΄ λ©€λ²λ₯Ό μ μ₯ν λ νλ ν¨κ» μ μ₯, μμ
- μ°κ΄κ΄κ³ λ§€νκ³Όλ μ ν κ΄κ³κ° μλ€! μ£Όμ. (μ΄κ±΄ μ λ νΈμ κ΄κ±λκ±°)
@OneToMany(mappedBy="parent", cascade=CascadeType.PERSIST)
μ’ λ₯
ALL : λͺ¨λ μ μ©
PERSIST : μμ
REMOVE : μμ
MERGE : λ³ν©
REFRESH
DETACH
μ°κ΄κ΄κ³ λ§€ν
λ¨λ°©ν₯
@Entity
public class Member {
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
- μμ κ°μ΄
@JoinColumn
μ ν΅ν΄ μ°κ΄κ΄κ³λ₯Ό λ§€ννλ κ²½μ°,MEMBER
ν μ΄λΈμTEAM_ID
λΌλ ForeignKeyκ° μΆκ°λλ ννκ° λλ€.
νλ‘μ κ°μ²΄
- νμ§λ§
team
μ΄ μ€μ λ‘ μ½λμμμ μ°Έμ‘°λκΈ° μ κΉμ§λ teamμ νλ‘μ κ°μ²΄μ ννλ‘ μ‘΄μ¬νκ² λκ³ μ΄λ₯Ό ν΅ν΄μ§μ° λ‘λ©
μ΄ κ°λ₯νκ² λλ€. - μμ κ²½μ°μλ μμμ± μ»¨ν μ€νΈμ μ°Ύλ μν°ν°κ° μ΄λ―Έ μλ€λ©΄ νλ‘₯μκ° μλ μ€μ μν°ν°κ° λ°νλλ€.
@ManyToOne(fetch = FetchType.EAGER)
λ‘ μ€μ ν κ²½μ°(μ¬μ€ κΈ°λ³Έκ°μ΄λ€) μ§μ°λ‘λ©μ΄ μΌμ΄λμ§ μκ³ μ¦μ λ‘λ©μ΄ μΌμ΄λλ€. νμ§λ§ μ λλ‘ EAGERλ₯Ό μ¬μ©νμ§ λ§μ.- μ¦μλ‘λ©μ N+1 λ¬Έμ λ₯Ό μΌμΌν¨λ€. μμλ§ ν΄λ΄λ μμ² ν° νΈλ¦¬ ννμ κ°μ²΄λ₯Ό κ°μ Έμ€κΈ° μν΄ μμ²λ λΆνκ° λ°μνλ μΌμ΄ μμ μ μλ€. κΈ°λ³Έκ°μ΄ EAGERμ΄λ―λ‘ μ΄μ¬ν LAZYλ‘ μ€μ νμ.
- μ¦μλ‘λ©μ΄ νμνλ€λ©΄? EAGERκ° μλλΌ
FETCH JOIN
μ μ΄μ©νμ! N+1 λ¬Έμ κ° ν΄κ²°λλ€.
μλ°©ν₯
@Entity
public class Member {
@ManyToOne
@JoinColumn(name = "TEAM_ID") // μΈλν€λ₯Ό λ§€νν λ μ¬μ©νλ€. μ¦ λ©€λ²μ ν
μ΄λΈμ μΈλν€
private Team team;
}
@Entity
public class Team {
@OneToMany(mappedBy = "team") // λ°λμͺ½μ λ§€νλλ νλμ κ°μ μ€λ€
List<Member> members = new ArrayList<>();
}
- ν μ΄λΈμ μΈλν€ νλλ‘ λ ν μ΄λΈμ μ°κ΄ κ΄κ³λ₯Ό κ΄λ¦¬νλ€.
- λ°λ©΄ κ°μ²΄λ κ°κ°μ μ°Έμ‘°(team, members)λ₯Ό κ°κ° κ°μ§λ€.
- μ°κ΄ κ΄κ³μ μ£ΌμΈμ΄ μΈλ ν€λ₯Ό κ°μ§λ€.
- μ£ΌμΈμ΄ μλμͺ½μ μ½κΈ° λ§μ΄ κ°λ₯νλ€.
- λ¨λ°©ν₯ λ§€νλ§μΌλ‘ λ°μ΄ν°λ² μ΄μ€ μ μ₯μμλ μ΄λ―Έ μ°κ΄κ΄κ³κ° λ§€νλμ§λ§ μλ°©ν₯μ ν΅ν΄ λ°λ λ°©ν₯μΌλ‘ κ°μ²΄ κ·Έλν νμκΈ°λ₯μ΄ μΆκ°λλ κ²μ΄λ€.
- μ£ΌμΈμ΄ μλ κ²½μ°
mappedBy
μμ±μ ν΅ν΄ μ£ΌμΈμ μ§μ νλ€. - μΌλλ€λ μ§κ΄μ μ΄μ§ μλ€. λ€λμΌμ μ¬μ©νλλ‘ νκ³ λ€μͺ½μ μΈλν€λ₯Ό λλλ‘ νλ€.
μ°κ΄κ΄κ³ νΈμ λ©μλ
Member member = new Member();
Team team = new Team;
member.setTeam(team);
team.addMember(member);
// μλ°©ν₯μ κ²½μ° μ°κ΄κ΄κ³ νΈμ λ©μλ νμ©μ ν΅ν΄ null μ°Έμ‘°λ₯Ό νΌνμ
public void setTeam(Team team) {
this.team = team;
team.addMember(this);
}
- μλ°©ν₯ λ§€νμ
toString
,lombok
,JSON λΌμ΄λΈλ¬λ¦¬
λ±μ ν΅ν 무ν루νλ μ‘°μ¬ν΄μΌ νλ€.