JPA Repository์์ ์ ๊ณตํ๋ Query Methods๋ ๊ฐ๋ฐ์๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์๊ฒ ์ง์ํ๊ธฐ ์ํ ๋ฉ์๋๋ฅผ ์ ๊ณตํฉ๋๋ค. QueryMethods๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํ ์ฟผ๋ฆฌ๋ฅผ ๊ฐํธํ๊ฒ ์์ฑํ ์ ์์ด ๊ฐ๋ฐ ์์ฐ์ฑ์ด ํฅ์๋๋ ๊ฒ์ ๊ธฐ๋ํ ์ ์์ต๋๋ค.
QueryMethods๋ ๋ฉ์๋ ์ด๋ฆ ๊ท์น์ ์ด์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฟผ๋ฆฌ๋ฅผ ์์ฑํฉ๋๋ค. ์๋ฅผ ๋ค์ด findBy๋ค์ Id์ ๊ฐ์ ์์ฑ์ ์ด์ฉํ์ฌ ํด๋น Id๋ฅผ ๊ฐ์ง ์ํฐํฐ๋ฅผ ์กฐํํ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
repository์ธํฐํ์ด์ค๋ฅผ ์์ฑํ์ฌ JpaRepository๋ฅผ ์์๋ฐ์ต๋๋ค. Query Methods์์ฑ์ ๋ฉ์๋ ์ด๋ฆ์ ํตํด ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. Spring Data JPA์์๋ ๋ฉ์๋ ์ด๋ฆ์ ๋ฐ๋ผ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ ์ ์ ํ ์ด๋ฆ์ ์์ฑํด์ผ ํฉ๋๋ค.
JPA Repository
public interface UserRepository extends JpaRepository<UserData, Long> {
UserData findByEmail(String email);
UserData findById(int id);
List<UserData> findAllByName(String name);
}
Test
@Test
void findTest() {
UserData data1 = repository.findByEmail("dennis@naver.com");
List<UserData> data2 = repository.findAllByName("martin");
UserData data3 = repository.findSomethingByEmail("dennis@naver.com");
System.out.println("data 1 : "+data1);
System.out.println("data 2 : "+data2);
System.out.println("data 3 : "+data3);
}
data 1 : UserData(id=2, name=dennis, email=dennis@naver.com, createdAt=2023-02-21T15:00:13.745773, updatedAt=2023-02-21T15:00:13.745773)
data 2 : [UserData(id=1, name=martin, email=martin@naver.com, createdAt=2023-02-21T15:00:13.744833, updatedAt=2023-02-21T15:00:13.744833), UserData(id=5, name=martin, email=martin@another.com, createdAt=2023-02-21T15:00:13.746473, updatedAt=2023-02-21T15:00:13.746473)]
data 3 : UserData(id=2, name=dennis, email=dennis@naver.com, createdAt=2023-02-21T15:00:13.745773, updatedAt=2023-02-21T15:00:13.745773)
๋ง๋ค์ด์ง ์ฟผ๋ฆฌ๋ฌธ
data1
select
u1_0.id,
u1_0.created_at,
u1_0.email,
u1_0.name,
u1_0.updated_at
from
user_data u1_0
where
u1_0.email=?
data2
select
u1_0.id,
u1_0.created_at,
u1_0.email,
u1_0.name,
u1_0.updated_at
from
user_data u1_0
where
u1_0.name=?
data3
select
u1_0.id,
u1_0.created_at,
u1_0.email,
u1_0.name,
u1_0.updated_at
from
user_data u1_0
where
u1_0.email=?
data2์ ๊ฒฝ์ฐ find{All
}By{Name
} ๋ฉ์๋ ๋ค์์ ์ฟผ๋ฆฌ๋ฌธ์ ๋ง๋ค๊ณ ๊ฒฐ๊ณผ๊ฐ๋ ์ ๋์์ต๋๋ค.
data1, data3์ ๋ค๋ฅธ ๋ฉ์๋ ๋ค์์ ๊ฐ์ง๊ณ ์์ง๋ง ๋์ผํ ๊ฒฐ๊ณผ๊ฐ ๋์์ต๋๋ค. find{Something
}By{Email}์ ๋ฉ์๋์์ Something
์ด ํด์๋์ง ์์์ต๋๋ค. ์ ์ ์๋ ์๋ฏธ์ ๋จ์ด๋ ๋ฌด์ํ๊ณ ๋ฉ์๋๋ฅผ ์คํํ๋ ๊ฒ์ ์ ์ ์์ผ๋ฉฐ ์๋ฌ๋ฅผ ๋ฐ์์ํค์ง ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
๋ฉ์๋ ์ด๋ฆ์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋๋ฐ ์ํฅ์ ๋ฏธ์น๊ธฐ ๋๋ฌธ์ ์ ์ ํ๊ฒ ์์ฑํด์ผ ํฉ๋๋ค. ๊ท๊ฒฉ์๋ ๋ง๊ฒ ์์ฑํ์์ผ๋ ์๋ฏธ๋ฅผ ์๊ธฐ ํ๋ ๋ฉ์๋ ๋ค์์ ์์ ์์ ์ฒ๋ผ ํด๋น ๋จ์ด๋ฅผ ๋นผ๊ณ ์คํํ๊ณ ์๋ฌ๋ฅผ ์ถ๋ ฅํ์ง ์์ต๋๋ค. ๊ทธ๋ผ Repository์ ์ฌ์ฉํ๋ ๋ฉ์๋๋ ์๋ฌ๊ฐ ๋์ง ์๋๊ฑธ๊น์? ๊ทธ๋ ์ง ์์ต๋๋ค.
๋ถ์ ์ ํ ๋ฉ์๋
@Test
void runTimeTest() {
UserData data = repository.findByByName("dennis");
System.out.println("data : "+data);
}
์ปดํ์ผ ์ค๋ฅ๊ฐ ์๋ ๋์์ ์ฐพ์ง ๋ชปํด ์ฟผ๋ฆฌ๋ฅผ ๋ง๋ค์ง ๋ชปํ๋ค๋ ๋ฐํ์ ์ค๋ฅ๊ฐ ๋์ค๊ฒ ๋ฉ๋๋ค.
์ด์ฒ๋ผ ๋ฉ์๋ ์ด๋ฆ์ผ๋ก ์ฟผ๋ฆฌ๋ฌธ์ด ์ด๋ป๊ฒ ์์ฑ๋๋์ง ํ์ธํ์์ต๋๋ค. ์ด์ ๊น์ง๋ ์กฐ๊ฑด์ด ํ๋ ํน์ ํ๋์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ ๋ถ๋ฌ์ค๋ ๊ฒ์ ํ์์ต๋๋ค. ์กฐ๊ฑด์ด 2๊ฐ์ธ ๊ฒฝ์ฐ ์ญ์ ๋์ผํ๊ฒ ๋ฉ์๋ ๋ค์์ผ๋ก ๊ฒฐ์ ํฉ๋๋ค.
์์
@Test
void findAndOrTest() {
UserData data1 = repository.findByNameAndEmail("martin", "martin@another.com");
List<UserData> data2 = repository.findByNameOrEmail("martin", "dennis@naver.com");
List<UserData> data3 = repository.findFirstByName("martin");
System.out.println("data 1 : "+data1);
System.out.println("data 2 : "+data2);
System.out.println("data 3 : "+data3);
}
Query
select
u1_0.id,
u1_0.created_at,
u1_0.email,
u1_0.name,
u1_0.updated_at
from
user_data u1_0
where
u1_0.name=?
and u1_0.email=?
select
u1_0.id,
u1_0.created_at,
u1_0.email,
u1_0.name,
u1_0.updated_at
from
user_data u1_0
where
u1_0.name=?
or u1_0.email=?
select
u1_0.id,
u1_0.created_at,
u1_0.email,
u1_0.name,
u1_0.updated_at
from
user_data u1_0
where
u1_0.name=? fetch first ? rows only
์คํ๊ฒฐ๊ณผ
data 1 : UserData(id=5, name=martin, email=martin@another.com, createdAt=2023-02-21T15:42:19.088832, updatedAt=2023-02-21T15:42:19.088832)
data 2 : [UserData(id=1, name=martin, email=martin@naver.com, createdAt=2023-02-21T15:42:19.086632, updatedAt=2023-02-21T15:42:19.086632), UserData(id=2, name=dennis, email=dennis@naver.com, createdAt=2023-02-21T15:42:19.088095, updatedAt=2023-02-21T15:42:19.088095), UserData(id=5, name=martin, email=martin@another.com, createdAt=2023-02-21T15:42:19.088832, updatedAt=2023-02-21T15:42:19.088832)]
data 3 : [UserData(id=1, name=martin, email=martin@naver.com, createdAt=2023-02-21T15:42:19.086632, updatedAt=2023-02-21T15:42:19.086632)]
๋ฉ์๋ ๋ค์์ ์๋๋๋ก ์์ฑ๋ ์ฟผ๋ฆฌ๋ฌธ๊ณผ ์คํ๊ฒฐ๊ณผ๊ฐ ๋์ค๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
๊ทธ ๋ฐ์๋ ์ฌ๋ฌ๊ฐ์ง ๋ฉ์๋๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ ์ ์์ผ๋ฉฐ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
JPA Repository์์ ๋ฉ์๋์ ๋ฐํํ์ ๋ค์ํ ํํ๋ก ์ง์ ํ ์ ์์ต๋๋ค. ๊ฐ์ฅ ์ผ๋ฐ์ ์ผ๋ก ์ํฐํฐ, ์ํฐํฐ๋ฅผ ๋ด๊ณ ์๋ ๋ฆฌ์คํธ์ ๊ฐ์ ์ปฌ๋ ์ ํ์ ์ด ์์ต๋๋ค. ๋ค๋ฅธ ๋ฐํํ์ผ๋ก๋ ํ๋ก๋์ ํ์ ์ด ์์ต๋๋ค.
ํ๋ก๋์ ์ ์ํฐํฐ์ ์ผ๋ถ ์์ฑ๋ง ์ ํํ์ฌ ์กฐํํ๊ณ ์ผ๋ถ ์์ฑ๋ง ๋ฐํํ์ฌ int,long๊ณผ ๊ฐ์ ๊ธฐ๋ณธํ ๋ฐํํ ์๋ ์์ต๋๋ค. ๋ํ ์ผ๋ถ ์์ฑ์ด ๋ค์ด์๋ ์ธํฐํ์ด์ค, ํด๋์ค๋ก ์ง์ ํ ์๋ ์์ต๋๋ค. ํ์์ ๊ฒฝ์ฐ DTO ๊ฐ๋ ์ ์ด์ฉํ์ฌ ๊ฐ์ฒด๋ฅผ ๋ณํํ์ฌ ์ฌ์ฉํฉ๋๋ค.
ํด๋น ๋ฉ์๋๊ฐ null ๊ฐ์ ๋ฐํํ๋ ๊ฒฝ์ฐ๊ฐ ์์ ๋ ๋ช ์์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํ์ฌ Optional๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์๋ ์์ต๋๋ค. ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ๋, ํด๋นํ๋ ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ์ง ์์ ์ ์์ต๋๋ค. ๋ฉ์๋๊ฐ null์ ๋ฐํํ๋ ๊ฒฝ์ฐ ํธ์ถํ ์ฝ๋์์ ์ด๋ฅผ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค. Optional ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ์๋๊ฐ null๋ฐํ์ Optional.empty()๋ฅผ ๋ฐํํ์ฌ ํธ์ถํ ์ฝ๋์์ ์ฒ๋ฆฌํ๊ธฐ ์ฉ์ดํฉ๋๋ค.
์กฐํ ๊ฒฐ๊ณผ๊ฐ null์ผ ๊ฐ๋ฅ์ฑ์ด ์์ด Optional ๊ฐ์ฒด๋ก ๊ฐ์ธ ๋ฐํํ๋ฉด ํด๋น ๊ฐ์ฒด๊ฐ null์ธ์ง ์๋์ง ๋ช ์์ ์ผ๋ก ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ์ฌ ์์ ์ฑ๊ณผ ๊ฐ๋ ์ฑ์ด ๊ฐ์ ๋ ์ ์์ต๋๋ค. ํ์ง๋ง ๋ฉ์๋๊ฐ null์ ๋ฐํํ๋ ๊ฒฝ์ฐ๋ฅผ ๋ชจ๋ ์ฒดํฌํ๋ ๊ฒ์ ์ข์ง ์์ต๋๋ค. Wrapperํด๋์ค ์ด๊ธฐ ๋๋ฌธ์ ๋๊ฐ์ ์ฐธ์กฐ๋ฅผ ๊ฐ์ง๋ฏ๋ก ์์ฑํ๋๋ฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ ์ฐจ์งํ๊ฒ ๋ฉ๋๋ค. Optional์ด ํ์ํ ๋ถ๋ถ์๋ง ์ฌ์ฉํ๋ฉด ์ ์ฐํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
๊ธฐ๋ณธ์ ์ธ CRUD์ ๊ฒฝ์ฐ JpaRepository๋ฅผ ์์๋ฐ๊ฒ ๋๋ฉด ๋ฐ๋ก ์ ์ง ์์๋ ์คํ์ด ๊ฐ๋ฅํฉ๋๋ค. @Entity
๋ฅผ ์ฌ์ฉํ๊ณ JpaRepository
๋ฅผ ์์๋ฐ์์ผ๋ฉด Create
์ญํ ์ ์๋์ผ๋ก ๋์์ต๋๋ค. ํ์ง๋ง ์ฝ๋๋ฅผ ๋ค์ด๊ฐ์ ๋ณด๋ฉด save,delete,find ์ ๊ฐ์ ๋ฉ์๋๋ง ๋ณด์ด๊ฒ ๋ฉ๋๋ค. delete๋ D, find๋ R์ ํด๋น๋๋๋ฐ save๋ insert,update๋ฅผ ๋ค ํด์ฃผ๋ ๊ฑธ๊น์?
save ์์
@Test
void saveTest() {
UserData data = new UserData("name", "mail");
repository.save(data);
printList();
data.setName("Chan");
repository.save(data);
printList();
}
๊ฒฐ๊ณผ
UserData(id=6, name=name, email=mail, createdAt=null, updatedAt=null)
UserData(id=6, name=Chan, email=mail, createdAt=null, updatedAt=null)
์ฒซ๋ฒ์งธ๋ insert, ๋๋ฒ์งธ ๊ฒฝ์ฐ์๋ update๊ฐ ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. save๋ฉ์๋์ ์ฝ๋๋ฅผ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋์ค๊ฒ ๋ฉ๋๋ค.
@Transactional
@Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must not be null");
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
JpaRepository์ save๋ฅผ ํธ์ถํ๊ฒ๋๋ฉด CrudRepository
์์ save๋ฅผ ํธ์ถํ๊ณ ๊ตฌํ๋ ๋ฉ์๋๋ SimpleJpaRepository
์์ ๊ตฌํ๋ฉ๋๋ค. ํด๋น ๋ฉ์๋๋ฅผ ์ดํด๋ณด๋ฉด Entity๊ฐ null์ด ์๋๊ฒฝ์ฐ์ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ฉฐ isNew(entity) ๋ฅผ ํธ์ถํ์ฌ true
์ธ ๊ฒฝ์ฐ insert, false
์ธ ๊ฒฝ์ฐ update๋ก ์งํ๋๋๊ฑฐ ๊ฐ์ด ๋ณด์
๋๋ค. ์ข ๋ ์์ธํ ํ์ธํด๋ณด๊ฒ ์ต๋๋ค.
isNew(entity)
public boolean isNew(T entity) {
ID id = getId(entity);
Class<ID> idType = getIdType();
if (!idType.isPrimitive()) {
return id == null;
}
if (id instanceof Number) {
return ((Number) id).longValue() == 0L;
}
throw new IllegalArgumentException(String.format("Unsupported primitive id type %s", idType));
}
ํด๋น ์ํฐํฐ์ id๊ฐ null ๋๋ 0์ธ์ง ํ๋จํ์ฌ ํด๋น๋๋ ๊ฒฝ์ฐ์ ์๋ก์ด ์ํฐํฐ์์ booleanํ์ ์ผ๋ก ์๋ ค์ค๋๋ค.
์ด ๊ณผ์ ์ ๊ฑฐ์ณ persist() ํธ์ถ ํ entity๋ฐํ ํน์ merge()๋ฅผ ํธ์ถ ํ entity ๋ฐํํ๊ฒ ๋ฉ๋๋ค. ํด๋น ๋ฉ์๋๋ค์ EntityManager์ ์ํ์ฌ ์์ต๋๋ค. JPA๋ EntityManager, ์์์ฑ ์ปจํ ์คํธ๋ฅผ ํตํด ๋ฐ์ดํฐ ์ํ ๋ณํ๋ฅผ ๊ฐ์งํ๊ณ ํ์ํ ์ฟผ๋ฆฌ๋ฅผ ์๋์ผ๋ก ์ํํฉ๋๋ค. Application์ด ์์๋ ๋ ํด๋น ํด๋์ค๋ฅผ ์๋์ผ๋ก bean์ ๋ฑ๋กํฉ๋๋ค.
EntityManager๋ Entity์ ์๋ช ์ฃผ๊ธฐ์ ํธ๋์ญ์ ๋ฑ์ ๊ด๋ฆฌํ๋ฉฐ ์์์ฑ ์ปจํ ์คํธ(์ํฐํฐ๋ฅผ ์๊ตฌ ์ ์ฅํ๋ ํ๊ฒฝ)์ ์ ๊ทผํ๋ ๊ฐ์ฒด์ ๋๋ค.
์์์ฑ ์ปจํ ์คํธ๋ ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ด์ ๊ฐ์ฒด๋ฅผ ๋ณด๊ดํ๋ ๊ฐ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ์ ์ญํ ์ ํฉ๋๋ค. ์ํฐํฐ ๋งค๋์ ๋ฅผ ์์ฑํ ๋ ํ๋ ๋ง๋ค์ด์ง๋ฉฐ ์ํฐํฐ ๋งค๋์ ๋ฅผ ํตํด ์ ๊ทผ ๋ฐ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
์ด๋ฌํ ์์์ฑ ์ปจํ ์คํธ, EntityManager์์ ๊ด๋ฆฌ๋๋ฉด Entity์๋ ์๋ช ์ฃผ๊ธฐ๊ฐ ์กด์ฌํฉ๋๋ค.
Entity ์๋ช ์ฃผ๊ธฐ
๋ค์ ๋์์์ persist(), merge()์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค. Entity๋ฅผ ์ฒ์ ์์ฑํ๋ฉด ๋น์์ ์ํ์ด๊ธฐ ๋๋ฌธ์ save -> TRANSIENT ์ํ ํ์ธ -> persist()๋ฅผ ํธ์ถํ์ฌ ์์์ํ๋ก ๋ง๋ค์ด ์ค๋๋ค.
๋์ผํ Entity๋ฅผ ๊ฐ์ง๊ณ save๋ฅผ ํธ์ถํ๋ค๋ฉด ํด๋น ์ํฐํฐ์ ์ํ๊ฐ ๋น์์ ์ํ๊ฐ ์๋ ๊ฒ์ ํ์ธํฉ๋๋ค. ์ด ๋ ์์์ฑ ์ปจํ
์คํธ์์ ๋์๊ธฐ ๋๋ฌธ์ Detached์ํ ์
๋๋ค. 1์ฐจ ์บ์์ ํด๋น ์ํฐํฐ์ ์๋ณ์๊ฐ ์์ผ๋ฉด db์กฐํ๋ฅผ ํ์ง ์๊ณ ์๋ ๊ฒฝ์ฐ db์กฐํ๋ฅผ ํ์ฌ ์
๋ ฅ๋ฐ์ ๊ฐ์ฒด๋ฅผ ๋ณต์ฌํฉ๋๋ค. ๋ณต์ฌํ ๊ฐ์ฒด๋ฅผ db์ ๋ฐ์ํฉ๋๋ค. ์ฆ, merge()
-> select ์ดํ insert๊ฐ ์คํ๋๋ ํ์์
๋๋ค.
QueryMethods๋ฅผ ์ด์ฉํ์ฌ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋๋ฐ ํ์ํ ๋ณต์กํ ์ฝ๋๋ฅผ ์ค์ผ ์ ์์ผ๋ฉฐ, ๊ฐ๋ฐ ์์ฐ์ฑ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. QueryMethods๋ ๋ฉ์๋ ์ด๋ฆ์ ๋ฐ๋ผ ๋ค์ํ ํ๋ผ๋ฏธํฐ ํ์ ์ ์ ๊ณตํ์ฌ ์ ์ ํ๊ฒ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ฅ์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๋๋๋ ์ดํ๋ฆฌ์ผ์ด์ ์ ์ฝ๊ณ ๋น ๋ฅด๊ฒ ๊ฐ๋ฐํ๋๋ฐ ๋์์ ์ค๋๋ค.
1. ๋ฉ์๋ ๋ค์ด๋ฐ
QueryMethod๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ์๋๋ช ์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ๋ง๋ค๊ธฐ ๋๋ฌธ์ ๋ณต์กํด์ง ์ ์์ผ๋ฉฐ ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง ์ ์์ต๋๋ค.
2. ์ฟผ๋ฆฌ๋ฌธ์ ์ ์ฝ
JPA Repository์์ ์ ๊ณตํ๋ ๋ฉ์๋๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ ๋ณต์กํ ์ฟผ๋ฆฌ๋ ์ง์ ์์ฑํด์ผํ๋ ์ ์ฝ์ด ์๊ธธ ์ ์์ต๋๋ค.
3. ์ ์ฐ์ฑ ๋ฌธ์
๋ฉ์๋ ์๊ทธ๋์ฒ๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ ํ ์ ์์ต๋๋ค. ์ฟผ๋ฆฌ ๋ณ๊ฒฝ์ ์ํด์๋ ์๋ก์ด ๋ฉ์๋๋ฅผ ์ถ๊ฐํด์ผ ํ๋ฉฐ ๋ณต์กํ ์ฟผ๋ฆฌ๋ฌธ์ ๊ฒฝ์ฐ ์ง์ ์์ฑํ๋ ๊ฒ์ด ๋ ๋์ ์๋ ์์ต๋๋ค.
์ด๋ฌํ ์ ์ฝ์ฌํญ๋ค์ ํด๊ฒฐํ๊ธฐ ์ํด ORM์ ๋ํ ์ดํด๋ฅผ ๋์ด๊ณ ์ ์ ํ ์ฟผ๋ฆฌ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ต์ ํ๋ฅผ ํด์ผํฉ๋๋ค.