JPA #6 ๋ค์ํ ์ฐ๊ด๊ด๊ณ ๋งคํ (1:N, N:1, N:N)
by JiwonDev๐ ์ฐ๊ด๊ด๊ณ ์ ๋ ธํ ์ด์
์ฐธ๊ณ ๋ก ์ด๋ฐ 1:1, N:1 ์กฐ๊ฑด์ ํ์ ๊ฐ์ ๋น์จ ์ ์ฝ ์กฐ๊ฑด ( Cardinality Raito Constraint ) ์ด๋ผ๊ณ ํ๋ค.
JPA์์ ์ฌ์ฉ๋ฒ์ ์ ๋ง ๊ฐ๋จํ๊ธด ํ๋ค.
• ๋ค๋์ผ: @ManyToOne
• ์ผ๋๋ค: @OneToMany
• ์ผ๋์ผ: @OneToOne
• ๋ค๋๋ค: @ManyToMany
์ฐธ๊ณ ๋ก ๊ฐ ์ ๋ ธํ ์ด์ ์ ์ต์ ์ ์๋์ ๊ฐ๋ค.
fetch์ cascade๋ ๋ค์ ๊ธ์์ ์ค๋ช ํ ์์ ์ด๋, ๊ฐ๋จํ๊ฒ ๋ณด๊ณ ๋์ด๊ฐ์
@ManyToOne
@OneToMany
@JoinColumn (์ธ๋ํค ๋งคํ ์ฉ๋)
@JoinTable ( N:N ๊ด๊ณ ์ฌ์ฉ์ ์กฐ์ธํ ์ด๋ธ ์ง์ )
@JoinTable(name="JOIN_TABLE") ์ด๋ ๊ฒ ์ฌ์ฉํจ. ๊ทธ ์ธ๋ ๋ค๋๋ค ๊ด๊ณ๋ฅผ ์ฌ์ฉํ ์ผ์ด ์์ผ๋ฏ๋ก ์๋ต.
๋ณต์ต
๐ญ mappedBy๋ฅผ ์ํ๋ฉด? ๋งคํ ํ
์ด๋ธ์ด ์๊ธด๋ค.
: DB๋ ์ธ๋ํค ํ๋๋ก ์๋ฐฉํฅ ์ฐธ์กฐ๊ฐ ๊ฐ๋ฅํ๋ค.
: JPA(๊ฐ์ฒด)๋ ์ฐธ์กฐ์ ๋ฐฉํฅ์ด ์๋ค. ๋จ๋ฐฉํฅ์ด๋ค.
: DB ์๋ ์ปฌ๋ ์
์ด๋ผ๋ ๊ฐ๋
์ด ์๋ค. ์ธ๋ํค๋ง ์์ ๋ฟ์ด๋ค.
: JPA ์
์ฅ์์๋ ์ด์ฉ ์ ์์ด, ๋งคํ ํ
์ด๋ธ๋ก ์ปฌ๋ ์
์ ๊ตฌํํ๋ค.
: ์ธ๋ํค๋ก ๊ตฌํํ๊ณ ์ถ๋ค๋ฉด? -> mappedBy
# DB ์นผ๋ผ๋ช ์ ์ ์ผ์ ์ผ ํด์.
์ฐธ๊ณ ๋ก '์ธ๋ํค๊ฐ ์ฐธ์กฐํ๋ ํ ์ด๋ธ์ ์นผ๋ผ๋ช '์ DB ์นผ๋ผ๋ช ์ ์๋ฏธํ๋ค. ์๋ฐ ์ฝ๋๋ฅผ ์๋ฏธํ๋๊ฒ ์๋๋ค.
ํ์ง๋ง ๊ทธ๋ฅ ์นด๋ฉ์ผ์ด์ค๋ก ์ฐ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ ์๋ฐ ์ฝ๋ ์นผ๋ผ๋ช ์ธ์ค ์ฐฉ๊ฐํ๋ ๊ฒฝ์ฐ๊ฐ ์๋ค. ์ด๋ SpringPhysicalNamingStrategy ๊ฐ ๊ธฐ๋ณธ์ผ๋ก ์ ์ฉ๋์ด์์ด @JoinColumn์ ์ฌ์ฉ๋๋ DB ์นผ๋ผ๋ช ์นด๋ฉ์ผ์ด์ค (team_my_id -> teamMyId) ๋ก ์ ๋ ฅํด๋ ๋ณํํด์ฃผ๊ธฐ ๋๋ฌธ์ด๋ค.
- JoinColumn(name="๋ด DB ํ ์ด๋ธ ์ธ๋ํค ๋ช ", referencedColumnName="์ฐธ์กฐํ DB ํ ์ด๋ธ PK ๋ช ") ์ด ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ์ด๋ค
- name์ ์๋ตํ๋ฉด {ํ๋๋ช _ ์ฐธ์กฐ ํ ์ด๋ธ PK๋ช }์ผ๋ก ๋งคํ๋๋ค. *์ฃผ์* ๋ณตํฉ ์ธ๋ํค์ธ๊ฒฝ์ฐ, ์กฐ์ธ๋ฌธ์ด๋ ํค์์๊ฐ ๋ฐ๋๋ ๋ฒ๊ทธ ์์
- referencedColumnName ์ ์๋ตํ๋ฉด { ์ฐธ์กฐ ํ ์ด๋ธ PK๋ช }๋ฅผ ์ฌ์ฉํ๋ค.
- name๊ณผ referencedColumnName์ DB ์นผ๋ผ๋ช
์ ๊ทธ๋๋ก ์ ์ด์ผํ์ง๋ง, ์นด๋ฉ์ผ์ด์ค๋ก ์ ์ด๋ ๋งคํํด์ค๋ค. ( myId -> my_id )
๊ทธ๋ ๊ฒ ์ฌ์ฉํ ์ผ์ ์๊ฒ ์ง๋ง, PhysicalNamingStrategy ๊ตฌํ์ฒด๋ฅผ ๊น๋ณด๋ฉด my_familyMotherId_type ์ด๋ ๊ฒ ์์ด๋ ์ ๋งคํํ๋ค.
๐ @OneToMany
์์ ์๊ฐ์ Member๊ธฐ์ค์ผ๋ก ๋จ๋ฐฉํฅ (@ManyToOne)์ผ๋ก ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ์ ์ค์ ํ์๋ค.
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
๊ทธ๋ฐ๋ฐ ์ด๋ ๋น์ฆ๋์ค๋ง๋ค ๋ค๋ฅด๋ค. Team์ผ๋ก Member๋ฅผ ์กฐํํ๋ ์๋น์ค์ผ ์๋ ์๋ค.
์ฝ๊ฒ๋งํด์ Team์ Member ์ ๋ณด๋ฅผ ์์์ผํ์ง๋ง, ๋ฐ๋๋ก Member๋ Team์ ์ ๋ณด๊ฐ ํ์์๋ ๊ฒฝ์ฐ.
์ด ๊ฒฝ์ฐ ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ์ Team์ด ๋๊ณ , ์ผ๋๋ค (@OneToMany) ๊ด๊ณ๊ฐ ๋๋ค.
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
@OneToMany
@JoinColumn(name = "TEAM_ID") // ์ด๊ฒ ์์ผ๋ฉด ํ
์ด๋ธ์ ์ถ๊ฐ๋ก ๋ง๋ค์ด์ ์ฌ์ฉํ๊ฒ๋๋ค.
List<Member> members = new ArrayList<Member>();
private String name;
…
}
* ์ฐธ๊ณ ๋ก @JoinColumn์ ์ฌ์ฉํ์ง ์์ผ๋ฉด, ๊ธฐ๋ณธ ์ฒ๋ฆฌ๋ฐฉ์์ด ์กฐ์ธํ๋๊ฒ ์๋๋ผ์ ์ค๊ฐ์ ํ ์ด๋ธ์ ์ถ๊ฐํด์ ์ฒ๋ฆฌํ๋ค.
๋น์ฆ๋์ค๋ ๊ฐ์ฒด๋ ์ด๋ฐ ์ผ์ด ๊ฐ๋ฅํ๋ค. ํ์ง๋ง DB๋ ์ค๊ณ์ ๋ถ๊ฐ๋ฅํ๋ค. Member(Many)์ชฝ์ ์ธ๋ํค๊ฐ ์์ ์ ๋ฐ์ ์๋ค. ์ฆ Team ๊ด๊ณ(์ธ๋ํค)๋ฅผ ๋ณ๊ฒฝํ๋ฉด ์๋ง์ Member์ UPDATE ์ฟผ๋ฆฌ๊ฐ ๋๊ฐ๊ฒ ๋๋ค.
๋ค๋์ผ ์ฟผ๋ฆฌ์ ๋ค๋ฅด๊ฒ ์์ ์ด ์๋ ๋ค๋ฅธ ํ ์ด๋ธ๊น์ง ์๋ง์ ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ ค์ผํ๋ค๋ ๋จ์ ์ด ์๋ค.
์ด๋ Team์ ์์ ํ๋๋ฐ Member๊น์ง ๋ณ๊ฒฝ์ด ์ ํ๋๋ ๊ฒ์ด๋ค. ์ค๋ฌด์์๋ ์๋ง์ ํ ์ด๋ธ์ ์ฌ์ฉํ ๊ฑด๋ฐ ๋งค๋ฒ 1:N์ธ์ง N:1์ธ์ง ํ์ธํด๊ฐ๋ฉด์ ์กฐํํ๋๊ฑด ๊ฐ์ฒด์งํฅ์ ์ด์ง๋ ์๊ณ , ์ฌ์ค์ ๋ถ๊ฐ๋ฅํ๋ค.
๊ทธ๋์ ์ค๋ฌด์์๋ Team โก Member ์กฐํ๊ฐ ํ์ํ ๊ฒฝ์ฐ, ์ฐจ๋ผ๋ฆฌ ๋ค๋์ผ ์๋ฐฉํฅ(@ManyToOne)์ ์ฐ๋๊ฑธ ๊ถ์ฅํ๋ค. [ ์๋ฐฉํฅ vs ์ผ๋๋ค ] ์ ์ ํ์ ์กฐ๊ธ ์ ๋งคํ ๋ถ๋ถ์ด์ง๋ง, ํธ๋ ์ด๋ ์คํ๋ฅผ ๊ณ ๋ คํด๋ณด๋ฉด ๊ฑฐ์ ๋๋ถ๋ถ์ ์ด๊ฒ ๋ง๋ค.
โ @OneToMany๋ฅผ ์๋ฐฉํฅ์ฒ๋ผ ์ฐ๋ ๋ฐฉ๋ฒ
๐ : ?? ๋ฌด์ง์ฑ์ผ๋ก ์์ชฝ์ @JoinColumn ๋ถ์ด๋ฉด ์๋๋์?
์ฌ์ฉ ์ JPA์์ ์ค๋ฅ๋ฅผ ๋์ฐ๋ฉฐ, ๋๋ค๊ณ ํ๋๋ผ๋ ์ ๋ ์ฌ์ฉํด์๋ ์๋๋ ์ฝ๋์ด๋ค.
JPA์์๋ ์๋ฐฉํฅ ๊ด๊ณ์์ [์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ]์ ํ์ชฝ์ผ๋ก ์ง์ ํ๋ค.
๊ทธ ์ด์ ๋ ์์ชฝ์ ์ฃผ์ธ์ผ๋ก ์ง์ ํ๋๊ฒ ๋ถ๊ฐ๋ฅํด์ ๊ทธ๋ฐ๊ฒ ์๋๋ผ, ์์ธกํ ์ ์๋ ๋์์ ์ด๋ํ๊ธฐ ๋๋ฌธ์ด๋ค.
* ์ค์ ๋ก ์คํ๋ง์์ ์ฌ์ฉํ๋ฉด, ์ปดํ์ผ์ ๋์ง๋ง ์คํ์ ์๋์ ๊ฐ์ด ์ค๋ฅ๋จ๋ฉฐ ์ฑ์ด ๊บผ์ง๋ค.
2022-01-30 17:32:12.955 ERROR 24436
---[ restartedMain] j.LocalContainerEntityManagerFactoryBean :
Failed to initialize JPA EntityManagerFactory:
Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn: Team.members
์ฆ, ์์ชฝ์ @JoinColumn์ ์ฐ๋ฉด ์์ชฝ ๋ค [์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ]์ด ๋์ด๋ฒ๋ฆฌ๊ณ , ์ด๋ ์์ธกํ ์ ์๋ ๋์ => ์ค๋ฅ๋ฅผ ๋ง๋ค์ด๋ธ๋ค. ๊ทธ๋์ ์ฌ์ฉํ์ง ๋ชปํ๊ฒ ๋ง๋ ๊ฒ์ด๋ค.
๋ฐ๋ฉด mappedBy๋ ํ์ชฝ์ ์ฝ๊ธฐ์ ์ฉ(๊ฐ์ง๋งคํ)์ผ๋ก ๋ง๋ค์ด๋ฒ๋ ค์ ์ธ๋ํค ํ๋๋ก ์์ชฝ ์ฐธ์กฐ๊ฐ ๊ฐ๋ฅํ๊ฒ ํด์ค๋ค.
๋ฌผ๋ก ์ฃผ์ธ์ด ์๋์ชฝ์ ์ธ๋ํค ์์ ์ด ๋ถ๊ฐ๋ฅํ์ง๋ง.
JPA์์ ๊ณต์์ ์ผ๋ก ์ ๊ณตํด์ฃผ๋ ๊ธฐ๋ฅ์ ์๋ค. ์๋ํ๋ฉด @ManyToOne ์๋ mappedBy๋ผ๋ ์ต์ ์ด ์๊ธฐ ๋๋ฌธ.
๋ค๋ง ๊ผผ์๋ก ๋น์ทํ๊ฒ ๋ง๋ค ์๋ ์๋๋ฐ ์ผ๋๋ค(@OneToMany)๋ฅผ ์ฌ์ฉํ๋๋ฐ ์๋ฐฉํฅ์ผ๋ก ์กฐํํ๊ณ ์ถ๋ค๋ฉด ์๋์ ๊ฐ์ด ํ๋ฉด๋๋ค.
@Entity
public class Member{
@ManyToOne // JoinColumn์ ์ฃผ์ธ์ด ์๋์ชฝ์๋ ์ง์ ํ๋, ์์ ์ ๋ง์ DB ์ฝ๊ธฐ์ ์ฉ์ผ๋ก ๋ง๋ค์ด๋ฒ๋ฆฐ๋ค.
@JoinColumn(insertable = false, updateable= false)
private Team team;
}
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
@OneToMany // Team์ด ์ฃผ์ธ์ด๊ธฐ ๋๋ฌธ์ members์ (mappedBy = "team")์ ๊ฑธ์ง ์๋๋ค.
@JoinColumn(name = "TEAM_ID")
List<Member> members = new ArrayList<Member>();
private String name;
…
}
์ด๋ฐ ๊ฑธ ์๋ ค์ฃผ๋ ์ด์ ๋ ์ค๋ฌด์์ ์๋น์ค๊ฐ ๋ณต์กํด์ง๋ฉด ์ด๋ฐ ํ ํฌ๋์ด ๊ฐ๋ ํ์ํ ๋๊ฐ ์๋ค.
๐ @OneTOOne
์ ๋ ธํ ์ด์ ๋ง ๋ค๋ฅผ ๋ฟ, @ManyToOne๊ณผ ์ฌ์ฉ๋ฒ์ ๊ฐ๋ค.
@Entity
public class Member{
@OneToOne
@JoinColumn(name="LOCKER_ID");
private Locker locker;
}
@Entity
public class Locker{
@OneToOne(mappedBy = "locker") // member.locker
private Member member;
}
์ฐธ๊ณ ๋ก DB์์์ ์ผ๋์ผ ๊ด๊ณ๋, ์ธ๋ํค์ ์ ๋ํฌ ์ ์ฝ์กฐ๊ฑด(FK, UNI)์ด ์ถ๊ฐ๊ฐ ๋ ๊ฒ์ด๋ค.
๋ณ๋ก ์ค์ํ์ง๋ ์์ง๋ง, ๋จ๋ฐฉํฅ์ธ ๊ฒฝ์ฐ MemberโกLocker ์ฒ๋ผ, ์ฃผ ํ ์ด๋ธ(PK)์์ ํ๊ฒ ํ ์ด๋ธ(FK)๋ก ์ฐธ์กฐ๋ ๊ฐ๋ฅํ๋ค.
ํ์ง๋ง ๋ฐ๋์ ๊ฒฝ์ฐ๋ JPA์์ ์ง์ํด์ฃผ์ง ์๋๋ค. DB ๊ตฌ์กฐ์ ๋ถ๊ฐ๋ฅํ๋๊น.
ํ์ํ๋ค๋ฉด ์๋ฐฉํฅ์ผ๋ก ์ฌ์ฉํ์. ๋ค๋ง ์๋ฐฉํฅ์ผ ๋์๋ DB์ ์ธ๋ํค๋ ์ด๋์ ๋ฌ์ผํ๋๊ฐ? ๋ ๊ณ ๋ฏผ๊ฑฐ๋ฆฌ์ด๊ธด ํ๋ค.
- ๊ฐ์ฒด์งํฅ์ ์ผ๋ก ์๊ฐํด๋ณด๋ฉด, Member๊ฐ ์ธ๋ํค๋ฅผ ๊ฐ์ง๊ณ ์๋๊ฒ ์ฌ์ฉํ๊ธฐ๋ ํธํ๊ณ ์ฑ๋ฅ์ ์ผ๋ก ์ ๋ฆฌํ๋ค.
- ํ์ง๋ง ์ฅ๊ธฐ์ ์ธ ๊ด์ ์์ [ ํ๋์ Locker๊ฐ ์ฌ๋ฌ๊ฐ์ Member๋ฅผ ๊ฐ์ง ์๋ ์๋ค ]๋๊ฒ ์ถ๊ฐ ๋ ์ ์์์ ๊ณ ๋ คํ๋ฉด Locker๊ฐ ์ธ๋ํค๋ฅผ ๊ฐ์ง๊ณ ์๋๊ฒ DB๋ฅผ ์ ์ฐํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
์ฅ๋จ์ ์ ์ ๋ฆฌํด๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
- ์ฃผ ํ
์ด๋ธ์ ์ธ๋ํค (๊ฐ๋ฐ์๊ฐ ์ ํธ)
์ฅ์ : ๊ฐ์ฒด์งํฅ์ ์ผ๋ก ๊ฐ๋ฐํ๊ธฐ ์ข๋ค. ์ฃผ ํ ์ด๋ธ๋ง ์กฐํํด๋ ํ๊ฒ ํ ์ด๋ธ์ ๋ฐ์ดํฐ๊ฐ ์๋์ง ํ์ธ ๊ฐ๋ฅํ๋ค.
๋จ์ : ๊ฐ์ด ์๋ค๋ฉด ์ธ๋ ํค์ null์ด ๋ค์ด๊ฐ ์ ์๋ค. ( Member๋ Locker๊ฐ ์์ ์๋ ์๋ค. Locker= null) - ํ๊ฒ ํ
์ด๋ธ์ ์ธ๋ํค (DBA๊ฐ ์ ํธ)
์ฅ์ : ํ ์ด๋ธ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ณ๊ฒฝํ ๋ DB ํ ์ด๋ธ ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ ํ์๊ฐ ์๋ค. (์ ์ฐํ๋ค.)
๋จ์ : ํ๋ก์ ๊ธฐ๋ฅ์ ํ๊ณ๋ก, Lazy Loading์ผ๋ก ์ค์ ํด๋ ํญ์ ์ฆ์๋ก๋ฉ ๋๋ค. ( Locker๋ Member๊ฐ ๋ฐ๋์ ์์ด์ผํ๋ค. ์ฆ ๋์ ํ ์ด๋ธ์ ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ ค ์กด์ฌ์ฌ๋ถ๋ฅผ ํ์ธํด์ผ ํ๋ ์ง์ฐ๋ก๋ฉ์ด ๋ถ๊ฐ๋ฅ )
๐ ManyToMany
๋ค๋๋ค ๊ด๊ณ๋ ๋ง ํธํ๊ฒ ๋ค์ผ๋ฉด ๋๋ค. ๊ฑฐ์ ์ฌ์ฉํ ์ผ ์๋ค.
DB๋ฅผ ๊ณต๋ถํด๋ดค์ผ๋ฉด ์๊ฒ ์ง๋ง. N:N๊ด๊ณ๋ ์ ๊ทํ๋ฅผ ์ด์ฉํด ํ ์ด๋ธ์ ๋ง๋ค์ด 1:N N:1 ๊ด๊ณ๋ก ๋ฐ๊พธ๋๊ฒ ๋ง๊ธฐ ๋๋ฌธ์ด๋ค.
๋ค๋ง DB์์ ๊ฐ๋ฅํ๊ฒ JPA์์ ๋ถ๊ฐ๋ฅํ๋ฉด ์ด์ํ๋ฏ๋ก, ์ง์์ ํด์ค๋ค.
JPA์์ N:N ๊ด๊ณ๋ ์ค๊ฐ์ ์จ๊ฒจ์ง ์กฐ์ธํ ์ด๋ธ์ ๋ง๋ค์ด์ ๊ด๋ฆฌํ๋ค.
@Entity
public class Member{
@ManyToMany
@JoinTable(name = "MEMBER_PRODUCT") // ์กฐ์ธํ
์ด๋ธ ์ด๋ฆ์ ์ ์ด์ค๋ค.
private List<Product> products = new ArrayList<>();
}
@Entity
public class Product {
@Id
@GeneratedValue
private Long id;
@ManyToMany(mappedBy = "product")
private List<Product> members = new ArrayList<>();
}
ํ์ง๋ง ์ด๋ ๊ฒ ์จ๊ฒจ์ง ์กฐ์ธํ ์ด๋ธ์ ์ฌ์ฉํ ์ด์ ๋ ์๊ณ , ์ค์ ๋ก ์ฌ์ฉํ ์ผ๋ ์๋ค.
ManyToMany ๊ด๊ณ๋ ์๋์ ๊ฐ์ด ์์ ์๋ก์ด Entity๋ฅผ ๋ง๋ค์ด์ 1:N, N:1 ๊ด๊ณ๋ก ๋ณ๊ฒฝํ๋๋ก ํ์.
์๋์ฒ๋ผ ์ค๊ฐ ํ ์ด๋ธ์ ํค๋ฅผ [Member + Product]๋ก ์ฌ์ฉํ๊ธฐ ๋ณด๋ค๋ ๋ณ๋์ id๋ฅผ ๊ฐ์ง๋๊ฒ ๋น์ฆ๋์ค์ ์ผ๋ก ์ ์ฐํ๋ค.
@Entity
public class MemberProduct {
@Id
@GeneratedValue
private Long id; // ์ด๋ ๊ฒ PK๋ฅผ ๋ฐ๋ก ๊ฐ์ง๊ณ ์๋๊ฒ ์ ์ฐํ ๊ฐ๋ฐ์ด ๊ฐ๋ฅํ๋ค.
@ManyToOne
@JoinColumn(name = "MEMBER_ID")
private Member member;
@OneToMany
@JoinColumn(name = "PRODUCT_ID")
private Product product;
private LocalDateTime orderDateTime;
//...
}
๐ ๋ชจ๋ ์ฐ๊ด๊ด๊ณ ์ฌ์ฉํด๋ณด๊ธฐ
๋น์ฆ๋์ค๋ฅผ ์๋์ ๊ฐ์ด ๊ตฌํํ๋ค๊ณ ํ ๋
์ค์ ํ ์ด๋ธ๊ณผ ์ํฐํฐ๋ ์๋์ ๊ฐ๋ค. ๊ทธ๋ฆผ์ ์ฐธ์กฐํด์ ์ง์ ๋ง๋ค์ด๋ณด๋๋ก ํ์.
'๐ฑBackend > JDBC & JPA' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
JPA #8 ํ๋ก์์ ์ง์ฐ๋ก๋ฉ (join fetch) (0) | 2021.11.09 |
---|---|
JPA #7 ๊ณ ๊ธ ๋งคํ (์์ ๊ด๊ณ) (0) | 2021.11.09 |
JPA #5 ๋ฐ์ดํฐ ์ค์ฌ ์ค๊ณ์ ๋ฌธ์ ์ , ์ฐ๊ด ๊ด๊ณ ๋งคํ (0) | 2021.11.09 |
JPA #4 ์ํฐํฐ ๋งคํ (๊ฐ์ฒด-ํ ์ด๋ธ ๋งคํ) (0) | 2021.11.08 |
JPA #3 ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ, ์์์ฑ ์ปจํ ์คํธ (0) | 2021.11.07 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
JiwonDev
JiwonDev