๊ด€๋ฆฌ ๋ฉ”๋‰ด

Coding Planet

MyBatis - ๋™์  SQL ๊ตฌํ˜„ํ•˜๊ธฐ(if / choose / trim/ foreach) ๋ณธ๋ฌธ

๐ŸŒฑSPRING

MyBatis - ๋™์  SQL ๊ตฌํ˜„ํ•˜๊ธฐ(if / choose / trim/ foreach)

jhj.sharon 2023. 5. 3. 16:59
๋ฐ˜์‘ํ˜•

 

 

JDBC MVC ํŒจํ„ด์œผ๋กœ DB๋ฅผ ์ˆ˜์ •, ํŽธ์ง‘ํ•˜๊ธฐ ์œ„ํ•ด์„œ sql.xml์— SQL๋ฌธ์„ ์ €์žฅํ•ด๋‘๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค. ๋‹ค๋งŒ ์ด๋ ‡๊ฒŒ ๊ฐœ๋ฐœ์„ ํ•  ๋•Œ, ์ƒํ™ฉ์— ๋”ฐ๋ผ ์š”๊ตฌํ•˜๋Š” ์ปฌ๋Ÿผ์ด ๋‹ค๋ฅด๊ฑฐ๋‚˜ ํŠน์ •์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด sql๋ฌธ์„ ๋งŒ๋“ค๊ณ  key๊ฐ’์„ ์„ค์ •ํ•ด์ค˜์•ผํ–ˆ๋‹ค. ๋™์  SQL์„ ๊ตฌํ˜„ํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ ๋งค์šฐ ๋ณต์žกํ–ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋งˆ์ด๋ฐ”ํ‹ฐ์Šค๋ฅผ ์ด์šฉํ•˜๋ฉด ๋™์  SQL์„  JSTL์„ ์‚ฌ์šฉํ•˜์—ฌ ์ข€ ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ๋ฌธ๋ฒ•์„ ๋งˆ์ด๋ฐ”ํ‹ฐ์Šค ํ™ˆํŽ˜์ด์ง€๋ฅผ ์ฐธ์กฐํ•˜์—ฌ ์†Œ๊ฐœํ•˜๊ณ  ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•œ๋‹ค.

 

 

1. if

  • ์กฐ๊ฑด๋ฌธ if๋Š” ์กฐ๊ฑด์ ˆ WHERE์˜ ์ผ๋ถ€๋กœ ํฌํ•จ๋˜์–ด ์กฐ๊ฑด๋ฌธ ์‚ฌ์šฉ์— ์œ ๋™์„ฑ์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค.
  • ์•„๋ž˜ ์กฐ๊ฑด๋ฌธ์€ ๊ฒŒ์‹œํŒ ํ…Œ์ด๋ธ”์—์„œ ๊ฒŒ์‹œ๊ธ€์— ๋Œ€ํ•œ ๋ชจ๋“  ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” sql๋ฌธ์ด๋‹ค. ํ•ด๋‹น sql๋ฌธ์€ ์‚ญ์ œ๋˜์ง€ ์•Š์€ ๋ชจ๋“  ๊ฒŒ์‹œ๋ฌผ ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
  • ์ด ๊ตฌ๋ฌธ์€ ์„ ํƒ์ ์œผ๋กœ ๋ฌธ์ž์—ด์„ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ๋งŒ์•ฝ title๊ฐ’์ด ์—†๋‹ค๋ฉด ๋ชจ๋“  active ์ƒํƒœ์˜ ๊ฒŒ์‹œ๊ธ€์ด ๋ฆฌํ„ด๋˜๋Ÿฏ์ด๋‹ค. ํ•˜์ง€๋งŒ title ๊ฐ’์ด ์žˆ๋‹ค๋ฉด ๊ทธ ๊ฐ’๊ณผ ๋น„์Šทํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.
  • writer๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด if๋ฌธ์„ ์ค‘๋ณตํ•˜์—ฌ ์‚ฌ์šฉํ•˜์—ฌ ์กฐ๊ฑด๋ฌธ์„ ์œ ์—ฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
<select id="boardDetail" resultType="board">
  SELECT * FROM BOARD WHERE state = ‘ACTIVE’
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="writer != null and writer.name != null">
    AND writer_name like #{writer.name}
  </if>
</select>

 

 

 

2. choose, when, otherwise

  • ์ž๋ฐ”์—์„œ switch์™€ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์„์„ ํ•œ๋‹ค. ์ž๋ฐ”์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ if๋ฌธ์€ ๋‹จ์ˆœํ•œ ์กฐ๊ฑด๋ฌธ์œผ๋กœ ์กฐ๊ฑด์‹์ด ์ฐธ(true)์ด๋ฉด if๋ฌธ ์•ˆ์— ์žˆ๋Š” ์ฝ”๋“œ ๋ธ”๋ก์ด ์‹คํ–‰๋˜๊ณ  ์กฐ๊ฑด์‹์ด ๊ฑฐ์ง“(false)์ด๋ฉด ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค. 
  • switch๋ฌธ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์กฐ๊ฑด ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ด์„œ ์‹คํ–‰ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. switch๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ณ€์ˆ˜๋‚˜ ํ‘œํ˜„์‹์˜ ๊ฐ’์„ ๊ฒ€์‚ฌํ•ด์„œ ์ผ์น˜ํ•˜๋Š” case๋ฌธ์„ ์ฐพ์•„ ํ•ด๋‹นํ•˜๋Š” ์ฝ”๋“œ ๋ธ”๋ก์„ ์‹คํ–‰ํ•˜๊ณ  ์ผ์น˜ํ•˜๋Š” case๊ฐ€ ์—†์œผ๋ฉด default๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
  • ์•„๋ž˜ ์ฝ”๋“œ๋Š” BOARD ํ…Œ์ด๋ธ”์—์„œ STATE๊ฐ€ 'ACTIVE'์ธ ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ , ์„ ํƒ์ ์œผ๋กœ title ํ˜น์€ writer์˜ ์ด๋ฆ„์œผ๋กœ ๊ฒ€์ƒ‰ํ•œ๋‹ค.
  • ์œ„ ์ฝ”๋“œ์—์„œ๋Š” title ๋ณ€์ˆ˜๊ฐ€ null์ด ์•„๋‹ˆ๋ฉด, ์ฆ‰ ๊ฐ’์ด ์žˆ๋‹ค๋ฉด AND title like #{title} ๊ตฌ๋ฌธ์ด ์ถ”๊ฐ€๋œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š๊ณ  writer.name ๋ณ€์ˆ˜๊ฐ€ null์ด ์•„๋‹ˆ๋ฉด AND writer_name like #{writer.name} ๊ตฌ๋ฌธ์ด ์ถ”๊ฐ€๋œ๋‹ค.
  • ๋‘˜ ๋‹ค null์ด๋ฉด AND featured = 1 ๊ตฌ๋ฌธ์ด ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
  • <when>์š”์†Œ๋Š” switch์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์—ฌ๋Ÿฌ ์กฐ๊ฑด ์ค‘ ํ•ด๋‹นํ•˜๋Š” ํ•˜๋‚˜๋งŒ ์„ ํƒ๋˜๋ฉฐ ๋จผ์ € ์„œ์ˆ ๋˜์–ด์žˆ์„ ์ˆ˜๋ก ์šฐ์„  ์ˆœ์œ„๊ฐ€ ๋†’๋‹ค. ์ฆ‰, title ๋ณ€์ˆ˜๊ฐ€ ๊ฐ’์ด ์žˆ๋‹ค๋ฉด, AND title like #{title} ๊ตฌ๋ฌธ์ด ์‹คํ–‰๋˜๊ณ  writer.name ๋ณ€์ˆ˜๋Š” ์ฒซ ๋ฒˆ์งธ <when> ์š”์†Œ๊ฐ€ false์ธ ๊ฒฝ์šฐ์—๋งŒ ๊ฒ€์‚ฌ๋œ๋‹ค.

 

<select id="boardDetailSearch"  resultType="board">
  SELECT * FROM BOARD WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="writer != null and writer.name != null">
      AND writer_name like #{writer.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

 

 

3. trim, where, set

 

1) where

<select id="boardDetail" resultType="board">
  SELECT * FROM BOARD
  WHERE
  <if test="state != null">
    state = #{state}
  </if>
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="writer != null and writer.name != null">
    AND writer_name like #{writer.name}
  </if>
</select>
  • ๋‹ค์Œ์˜ sql๋ฌธ ์ค‘ ์–ด๋–ค ์กฐ๊ฑด์—๋„ ํ•ด๋‹นํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ถœ๋ ฅ๋˜๋Š” sql๋ฌธ์€ [SELECT * FROM BOARD WHERE] ์ผ ๊ฒƒ ์ด๋‹ค.
  • ์ด ๊ฒฝ์šฐ SQL๋ฌธ์€ ์ •์ƒ์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋•Œ <where> ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ <where>์—˜๋ฆฌ๋จผํŠธ๋Š” ํƒœ๊ทธ์— ์˜ํ•ด ์ปจํ…์ธ ๊ฐ€ ๋ฆฌํ„ด๋˜๋ฉด ๋‹จ์ˆœํžˆ "WHERE"๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ถœ๋ ฅํ•œ๋‹ค. ์กฐ๊ฑด์ด ์—†๋Š” ๊ฒฝ์šฐ where๋Š” ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ๋‹ค๋งŒ, ์ปจํ…์ธ ๊ฐ€ “AND”๋‚˜ “OR”๋กœ ์‹œ์ž‘ํ•œ๋‹ค๋ฉด ๊ทธ “AND”๋‚˜ “OR”๋ฅผ ์ง€์›Œ๋ฒ„๋ฆฐ๋‹ค.
<select id="boardDetail" resultType="board">
  SELECT * FROM BOARD
  <where>
  <if test="state != null">
    state = #{state}
  </if>
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="writer != null and writer.name != null">
    AND writer_name like #{writer.name}
  </if>
  </where>
</select>

 

2) trim

  • <trm>์€ <where>์ ˆ๊ณผ ๋‹ฌ๋ฆฌ where๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์—ฌ๋Ÿฌ ์š”์†Œ๋ฅผ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ ๋œ๋‹ค. SQL ์ฟผ๋ฆฌ์˜ ์‹œ์ž‘, ๋ ๋˜๋Š” ์–ด๋””๋“ ์ง€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋˜ํ•œ ๋ถˆํ•„์š”ํ•œ ๊ณต๋ฐฑ ๋ฌธ์ž๋„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • override ์†์„ฑ์€ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜๋Š” ํ…์ŠคํŠธ์˜ ๋ชฉ๋ก์„ ์ œํ•œํ•œ๋‹ค. ๊ฒฐ๊ณผ๋Š” override ์†์„ฑ์— ๋ช…์‹œ๋œ ๊ฒƒ๋“ค์„ ์ง€์šฐ๊ณ  with ์†์„ฑ์— ๋ช…์‹œ๋œ ๊ฒƒ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.
  • ๋”ฐ๋ผ์„œ, ์•„๋ž˜ ์ฝ”๋“œ๋Š” 'AND' ์™€ 'OR'์˜ ์ ‘๋‘์‚ฌ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ด๋ฅผ ์ง€์šฐ๊ณ  ์ ‘๋‘์‚ฌ WHERE๋ฅผ ์ถœ๋ ฅํ•˜๋ผ๋Š” ๋œป์ด๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์กฐ๊ฑด์ ˆ์ด ๋ถˆํ•„์š”ํ•˜๊ฒŒ 'AND' ์™€ 'OR'๋กœ ์‹œ์ž‘ํ•˜์ง€ ์•Š๊ณ  'WHERE'๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.
<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>

 

 

 

3) set

 

  • ์•„๋ž˜ ์ฟผ๋ฆฌ๋Š” 'Writer'ํ…Œ์ด๋ธ”์—์„œ id๊ฐ€ ์ผ์น˜ํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.
  • <set> ์š”์†Œ๋Š” ์—…๋ฐ์ดํŠธํ•  ์ปฌ๋Ÿผ๊ณผ ๊ฐ’์„ ์ง€์ •ํ•˜๋Š” ๋ธ”๋ก์ด๋‹ค. <set> ์š”์†Œ ๋‚ด์—๋Š” <if> ์š”์†Œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๊ณ  ๊ฐ <if> ์š”์†Œ๋Š” ํ•ด๋‹น ์—ด์˜ ๊ฐ’์„ ๋™์ ์œผ๋กœ ์ €์žฅํ•œ๋‹ค.
  • ๊ฐ <if> ์š”์†Œ์—๋Š” test ์†์„ฑ์ด ์žˆ์œผ๋ฉฐ, ์ด ์†์„ฑ์€ ํ•ด๋‹น ์—ด์ด ์—…๋ฐ์ดํŠธ๋˜์–ด์•ผ ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๋Š” ์กฐ๊ฑด์„ ์ฃผ๋Š”๋ฐ ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด, username์ด null์ด ์•„๋‹ˆ๋ฉด ํ•ด๋‹น ์—ด์„ ์—…๋ฐ์ดํŠธํ•˜๊ณ , null์ด๋ฉด ์—…๋ฐ์ดํŠธํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

<update id="updateWriterIfNecessary">
  update Writer
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>

 

 

 

4. foreach

  • foreach๋Š” ๋™์  SQL์—์„œ collection์— ๋Œ€ํ•œ ๋ฐ˜๋ณต์ฒ˜๋ฆฌ๋ฅผ ํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค. 
  • ์•„๋ž˜ ์ฟผ๋ฆฌ๋Š” ID๊ฐ€ list์— ํฌํ•จ๋œ ๊ฐ’ ์ค‘ ํ•˜๋‚˜์™€ ์ผ์น˜ํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ์กฐํšŒํ•œ๋‹ค. ๊ฐ ์†์„ฑ์— ๋Œ€ํ•œ ์„ค๋ช…์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
  • list:  'foreach'๊ฐ€ ๋ฐ˜๋ณตํ•  ์ปฌ๋ ‰์…˜์„ ์ง€์ •
  • item: ๋ฐ˜๋ณต ์ค‘ ํ˜„์žฌ ํ•ญ๋ชฉ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ง€์ •ํ•œ๋‹ค.
  • index: ๋ฐ˜๋ณต ์ค‘ ํ˜„์žฌ ํ•ญ๋ชฉ์— ๋Œ€ํ•œ ์ธ๋ฑ์Šค์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ง€์ •ํ•œํ•œ๋‹ค.
  • open, separator, close ์†์„ฑ์€ ๋ฐ˜๋ณต๋˜๋Š” SQL ๊ตฌ๋ฌธ์˜ ์‹œ์ž‘, ๊ตฌ๋ถ„์ž ๋ฐ ๋์„ ์ง€์ •ํ•œ๋‹ค. ์œ„ ์ฝ”๋“œ์—์„œ๋Š” ID in (๋กœ ์‹œ์ž‘ํ•˜๊ณ , ,๋กœ ๊ตฌ๋ถ„ํ•˜๋ฉฐ, )๋กœ ๋๋‚˜๋Š” SQL ๊ตฌ๋ฌธ์ด ๋ฐ˜๋ณต๋œ๋‹ค.
  • nullable: ์ปฌ๋ ‰์…˜์ด null์ธ ๊ฒฝ์šฐ 'foreach'๊ฐ€ ๋ฌด์‹œ๋˜๋„๋ก ํ•œ๋‹ค.

 

<select id="selectPostIn" resultType="postList">
  SELECT *
  FROM POST P
  <where>
    <foreach item="item" index="index" collection="list"
        open="ID in (" separator="," close=")" nullable="true">
          #{item}
    </foreach>
  </where>
</select>

 

  • ์˜ˆ๋ฅผ ๋“ค์–ด, list๊ฐ€ {1, 3, 5}๋ผ๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์€ SQL๋ฌธ์ด ์‹คํ–‰๋œ๋‹ค. 
  • ๋งŒ์•ฝ list๊ฐ€ ๋น„์–ด์žˆ๊ฑฐ๋‚˜ null์ด๋ผ๋ฉด, ์•„๋ฌด๋Ÿฐ ๋ ˆ์ฝ”๋“œ๋„ ์กฐํšŒ๋˜์ง€ ์•Š๋Š”๋‹ค.
SELECT *
FROM POST P
WHERE ID IN (1, 3, 5)
๋ฐ˜์‘ํ˜•
Comments