πŸ“Œ MyBatis Mapper μ™„μ „ 정볡 β‘’ - ν‚€ 생성 μ „λž΅ μ™„λ²½ κ°€μ΄λ“œ

My Pale Blue DotΒ·2025λ…„ 4μ›” 25일
0

SPRING

λͺ©λ‘ 보기
16/36
post-thumbnail

πŸ“… λ‚ μ§œ

2025-04-25


πŸ“ 1️⃣ ν‚€ 생성 μ „λž΅μ΄λž€?

λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œλŠ” 각 λ ˆμ½”λ“œλ₯Ό μ‹λ³„ν•˜κΈ° μœ„ν•΄ κΈ°λ³Έ ν‚€(Primary Key) κ°€ ν•„μš”ν•©λ‹ˆλ‹€.

MyBatisμ—μ„œλŠ” INSERT μ‹œ μžλ™ λ˜λŠ” μˆ˜λ™μœΌλ‘œ ν‚€λ₯Ό μƒμ„±ν•˜μ—¬ 객체에 μ£Όμž…ν•  수 μžˆλ„λ‘ λ‹€μ–‘ν•œ μ „λž΅μ„ μ œκ³΅ν•©λ‹ˆλ‹€.

πŸ”Ή λŒ€ν‘œμ μΈ ν‚€ 생성 방식

방식섀λͺ…
AUTO_INCREMENTDBκ°€ μžλ™μœΌλ‘œ ν‚€ 값을 생성
SequenceOracle λ“±μ—μ„œ μ‹œν€€μŠ€λ₯Ό μ΄μš©ν•œ ν‚€ 생성
μˆ˜λ™ μƒμ„±κ°œλ°œμžκ°€ 직접 둜직으둜 ν‚€ 값을 생성

πŸ’‘ Tip

λ°μ΄ν„°λ² μ΄μŠ€κ°€ μ œκ³΅ν•˜λŠ” μžλ™ 생성 κΈ°λŠ₯을 μš°μ„  ν™œμš©ν•˜λŠ” 것이 κ°€μž₯ μ•ˆμ „ν•©λ‹ˆλ‹€.


πŸ“ 2️⃣ useGeneratedKeys ν™œμš©λ²• (DB μžλ™ 생성)

πŸ”Ή μ–΄λ…Έν…Œμ΄μ…˜ 방식

@Insert("INSERT INTO tbl_memo (text) VALUES (#{text})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(MemoDto dto);

πŸ”Ή XML 방식

<insert id="insertXml" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO tbl_memo (text) VALUES (#{text})
</insert>

βœ… μ„€λͺ…

  • useGeneratedKeys = true : DB의 AUTO_INCREMENT κΈ°λŠ₯ μ‚¬μš©.
  • keyProperty : μƒμ„±λœ ν‚€κ°€ μ£Όμž…λ  DTO의 ν•„λ“œλͺ….

⚠️ 주의:

useGeneratedKeysλŠ” MySQL, MariaDB λ“± AUTO_INCREMENTλ₯Ό μ§€μ›ν•˜λŠ” DBμ—μ„œλ§Œ λ™μž‘ν•©λ‹ˆλ‹€.


πŸ“ 3️⃣ @SelectKey μ–΄λ…Έν…Œμ΄μ…˜ 방식 (μ»€μŠ€ν…€ ν‚€ 생성)

DBκ°€ μžλ™μœΌλ‘œ ν‚€λ₯Ό μƒμ„±ν•˜μ§€ μ•ŠλŠ” 경우, κ°œλ°œμžκ°€ 직접 ν‚€ 생성 λ‘œμ§μ„ μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

@SelectKey(statement = "SELECT MAX(id) + 1 FROM tbl_memo", keyProperty = "id", before = false, resultType = int.class)
@Insert("INSERT INTO tbl_memo (id, text) VALUES (#{id}, #{text})")
int insert(MemoDto dto);

βœ… μ£Όμš” 속성

속성섀λͺ…
statementν‚€ 생성 SQL
keyPropertyDTO에 μ£Όμž…ν•  ν•„λ“œλͺ…
beforetrue: INSERT 이전 μ‹€ν–‰false: 이후 μ‹€ν–‰
resultTypeλ°˜ν™˜ νƒ€μž…

πŸ’‘ μ„€μ • κ°€μ΄λ“œ

  • μ‹œν€€μŠ€ μ‚¬μš© μ‹œ βž” before = true
  • MAX(id) + 1 방식 βž” before = false

πŸ“ 4️⃣ XML 방식

<insert id="insertXml" parameterType="MemoDto">
    <selectKey keyProperty="id" order="AFTER" resultType="int">
        SELECT MAX(id) + 1 FROM tbl_memo
    </selectKey>
    INSERT INTO tbl_memo (id, text) VALUES (#{id}, #{text})
</insert>

πŸ”Ή Oracle μ‹œν€€μŠ€ μ˜ˆμ‹œ

<insert id="insertXml" parameterType="MemoDto">
    <selectKey keyProperty="id" order="BEFORE" resultType="int">
        SELECT sequence_name.NEXTVAL FROM DUAL
    </selectKey>
    INSERT INTO tbl_memo (id, text) VALUES (#{id}, #{text})
</insert>

⚠️ Oracle λ“± μ‹œν€€μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” DBλŠ” λ°˜λ“œμ‹œ order="BEFORE"둜 μ„€μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.


πŸ“ 5️⃣ ν‚€ 생성 μ „λž΅ 비ꡐ

ꡬ뢄useGeneratedKeys@SelectKey /
λŒ€μƒ DBMySQL, MariaDBOracle, μ»€μŠ€ν…€ 둜직
μžλ™ 생성 지원OX
λ³΅μž‘ν•œ 둜직XO
λ™μ‹œμ„± μ•ˆμ „μ„±O주의 ν•„μš”
μ„€μ • λ‚œμ΄λ„μ‰¬μ›€SQL μž‘μ„± 및 μ„€μ • ν•„μš”

πŸ’‘ Tip

λ‹¨μˆœ μžλ™ 생성은 useGeneratedKeys,

λ³΅μž‘ν•œ ν‚€ 생성 λ‘œμ§μ΄λ‚˜ μ‹œν€€μŠ€κ°€ ν•„μš”ν•œ 경우 selectKeyλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.


πŸ“ 6️⃣ ν…ŒμŠ€νŠΈ μ½”λ“œ μ˜ˆμ‹œ

@Test
void testInsertWithKey() {
    MemoDto dto = new MemoDto(null, "Key Test", "user@domain.com", LocalDateTime.now(), null);
    int result = memoMapper.insertXml(dto);
    System.out.println("Generated ID: " + dto.getId());
    assertEquals(1, result);
    assertNotNull(dto.getId());
}

βœ”οΈ 좜λ ₯ μ˜ˆμ‹œ

Generated ID: 1050

⚠️ 자주 λ°œμƒν•˜λŠ” 였λ₯˜

  1. ν‚€ κ°’ λˆ„λ½
    • keyProperty 섀정이 μ—†μœΌλ©΄ DTO에 값이 μ£Όμž…λ˜μ§€ μ•ŠμŒ.
  2. 쀑볡 ν‚€ 였λ₯˜
    • SELECT MAX(id) + 1 방식 μ‚¬μš© μ‹œ λ™μ‹œμ„± 문제 λ°œμƒ κ°€λŠ₯.
  3. Generated keys not requested
    • useGeneratedKeys 섀정을 λΉΌλ¨Ήμ—ˆμ„ λ•Œ λ°œμƒν•˜λŠ” 였λ₯˜.
  4. before/after μ„€μ • 였λ₯˜
    • μ‹œν€€μŠ€λŠ” BEFORE, μ»€μŠ€ν…€ λ‘œμ§μ€ 보톡 AFTER μ‚¬μš©.

πŸ”₯ 정리

  • useGeneratedKeys: DB μžλ™ 생성 κΈ°λŠ₯ ν™œμš© (κ°€μž₯ μ•ˆμ „ν•˜κ³  간단)
  • selectKey: μ»€μŠ€ν…€ ν‚€ 생성, μ‹œν€€μŠ€ 기반 DB에 적합
  • μ‹€λ¬΄μ—μ„œλŠ” DB ꡬ쑰와 ν™˜κ²½μ— λ§žλŠ” μ „λž΅μ„ 선택해야 ν•˜λ©°, λ™μ‹œμ„± λ¬Έμ œμ— μ£Όμ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.

πŸ”— μ°Έκ³  자료


profile
Here, My Pale Blue.🌏

0개의 λŒ“κΈ€