2022. 3. 12. 01:11ใProgramming Project ์์ ์ค/๋ด์ฉ ์ ๋ฆฌ

๐ง๐ป๐ป Git Hub ์ฃผ์
๐ ๋ชฉ์ฐจ
โ [BackEnd][Maven-PJ] ๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ ์๋น์ค - ๊ฒ์ํ ๋ง๋ค๊ธฐ : ๋ชฉ๋ก ์กฐํ
โ [BackEnd][Maven-PJ]๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ ์๋น์ค - ๊ฒ์ํ ๋ง๋ค๊ธฐ : ์์ธ ์กฐํ
โ [BackEnd][Maven-PJ]๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ ์๋น์ค - ๊ฒ์ํ ๋ง๋ค๊ธฐ : ์ญ์
โ [BackEnd][Maven-PJ] ์ฌ๋ด ๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ ์๋น์ค - ๊ฒ์ํ : ๋ต๋ณ ๋ฑ๋ก / ์์
โ [BackEnd][Maven-PJ] ์ฌ๋ด ๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ ์๋น์ค - ๊ฒ์ํ : ๋ต๋ณ ์ญ์
๐จ๐ฉ๐ง๐ฆ ํ์ ๊ด๋ จ
โ [BackEnd][Maven-PJ] ์ฌ๋ด ๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ ์๋น์ค - ํ์ ๊ด๋ จ : ํ์ ๊ฐ์
๐๋ถ ๋ก
โ [BackEnd][Maven-PJ]๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ ์๋น์ค - ๊ฒ์ํ ๋ง๋ค๊ธฐ : Paging์ฒ๋ฆฌ
๐ค ๋ด๊ฐ ๋ง๋ Exception
โ [Exception ์ ๋ฆฌ] org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
โ [Vue.js][Spring] Post Data ์ ์ก ๊ฐ null๊ฐ ์ ์ก ๋ฌธ์
โ
๐ ๊ฐ๋ฐ ๊ด๋ จ Q&A ๊ฒ์ํ ์๋น์ค - ์์ธ ์กฐํ


๐ฝ DevInquryController.java

199 ~ 213๋ฒ์งธ ์ค๊น์ง์ ๋ด์ฉ์ '๊ธ ๋ฑ๋ก' ๋ด์ฉ์ ์ค๋น ํด ๋์์ต๋๋ค!
HashMap result๋ฅผ ์ค๋นํด์ ์๋ต์ผ๋ก ๋ณด๋ด์ค Data๋ค์ ๋ด์ ์ค ๊ฒ์ด์์.
๊ทธ๋ฐ ๋ค 218๋ฒ์งธ ์ค์์ Service์ ํด๋น Method๋ฅผ ํธ์ถํ์ฌ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๋ ค๊ณ ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ , ๊ฒฐ๊ณผ๊ฐ์ด ๋ฐํ๋๋ฉด ํด๋น ๊ฐ์ DevInqryVO ๊ฐ์ฒด ์๋ฃํ Type์ผ๋ก ๋ฐ์์ result์ ๋ด์์ฃผ๋ ๊ฒ์ด์์.
๊ทธ๋ฐ ๋ค์ ํด๋น result๋ฅผ ์๋ต์ผ๋ก ๋ฐํ ํด ์ค๋๋ค.
๐ฝ DevInquryService.java

๐ฝ DevInquryServiceImpl.java

์ฌ๊ธฐ์๋ ๊ฐ๋จํ๊ฒ ์ด๋ค Logic์ ์ฒ๋ฆฌํ๋ ๊ฒ์ ์๋๊ณ , Mapper์ ํด๋น Class๋ฅผ ํธ์ถ ํด ์ฃผ๋ ๊ฒ์ด์์.
๐ฝ DevInquryMapper.java

๐ฝ DevInquryMapper.xml
<!-- Q&A ์์ธ ์กฐํ -->
<select id="devInquryDetail" parameterType="com.devcommunity.junyharang.model.vo.support.DevInquryVO" resultType="com.devcommunity.junyharang.model.vo.support.DevInquryVO">
select X.* from (select i.INQRY_SN , i.INQRY_USER_SN , i.FILE_SN , i.INQRY_CN , i.INQRY_SJ , i.SECRET_AT , i.ANSWER_AT , i.ANSWER_CN , u1.USER_ID as ANSWER_USER_ID , DATE_FORMAT(i.ANSWER_DT, '%Y-%m-%d') AS ANSWER_DT , DATE_FORMAT(i.CREAT_DT, '%Y-%m-%d') AS CREAT_DT , i.UPDT_DT , i.UPDUSR_SN, u.USER_ID
, COALESCE(LAG(i.INQRY_SN) OVER(ORDER BY i.INQRY_SN), -1) AS BEFORE_INQRY_SN
, LAG(i.INQRY_SJ) OVER(ORDER BY i.INQRY_SN) AS BEFORE_INQRY_SJ
, COALESCE(LEAD(i.INQRY_SN) OVER(ORDER BY i.INQRY_SN), -1) AS NEXT_INQRY_SN
, LEAD(i.INQRY_SJ) OVER(ORDER BY i.INQRY_SN) AS NEXT_INQRY_SJ
from tb_com_inqry i
inner join tb_user u
on i.INQRY_USER_SN = u.user_sn
left outer join tb_user u1
on u1.USER_SN = i.ANSWER_USER_SN) X
where 1=1
<if test="inqrySn neq null and inqrySn neq ''">
and INQRY_SN like #{inqrySn}
</if>
</select>
์ฌ๊ธฐ์๋ from์ ์ Sub Query๋ฅผ ์ฌ์ฉํด ์ค ๊ฒ์ด์์.
Sub Query์ ๋ํด์๋ '์ด ๊ณณ'์ ์ ๋ฆฌํด์ ์ค๋น ํด ๋์์ต๋๋ค!
select i.INQRY_SN , i.INQRY_USER_SN , i.FILE_SN , i.INQRY_CN , i.INQRY_SJ , i.SECRET_AT , i.ANSWER_AT , i.ANSWER_CN , u1.USER_ID as ANSWER_USER_ID , DATE_FORMAT(i.ANSWER_DT, '%Y-%m-%d') AS ANSWER_DT , DATE_FORMAT(i.CREAT_DT, '%Y-%m-%d') AS CREAT_DT , i.UPDT_DT , i.UPDUSR_SN, u.USER_ID
, COALESCE(LAG(i.INQRY_SN) OVER(ORDER BY i.INQRY_SN), -1) AS BEFORE_INQRY_SN
, LAG(i.INQRY_SJ) OVER(ORDER BY i.INQRY_SN) AS BEFORE_INQRY_SJ
, COALESCE(LEAD(i.INQRY_SN) OVER(ORDER BY i.INQRY_SN), -1) AS NEXT_INQRY_SN
, LEAD(i.INQRY_SJ) OVER(ORDER BY i.INQRY_SN) AS NEXT_INQRY_SJ
from tb_com_inqry i
inner join tb_user u
on i.INQRY_USER_SN = u.user_sn
left outer join tb_user u1
on u1.USER_SN = i.ANSWER_USER_SN

๋จผ์ ์๋ธ ์ฟผ๋ฆฌ๋ฅผ ํตํด ์๊ณ ์ํ๋ ๊ฒ์ ํ์ ํ ์ด๋ธ๊ณผ Inner join์ ํ๊ณ , left outer join์ผ๋ก ๋ค์ ํ์๊ณผ ์กฐ์ธ์ ํ tb_com_inqry Table์์ ๊ฐ ์ปฌ๋ผ์ ์กฐํ ํ๋๋ฐ, COALESCE ํจ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ณด์ด๋ ๊ฒ์ด์์. ์ด๊ฒ์ A Table์ phone์ด๋ผ๋ ์ปฌ๋ผ๊ณผ B Table์ tel์ด๋ผ๋ ์ปฌ๋ผ์ด ์๋๋ฐ, ์ฌ์ค ์ปฌ๋ผ๋ช ์ ๋ค๋ฅด์ง๋ง, ์๋ฏธํ๋ ๊ฒ์ด ๊ฐ์ ์ ํ๋ฒํธ ์ธ ๊ฒ์ด์์.
๊ทธ๋ฐ๋ฐ, ์ด๋ค ๊ฒฝ์ฐ์๋ Phone์ด๋ผ๋ ์ปฌ๋ผ์ ์ ํ๋ฒํธ Data๊ฐ ์ฝ์ ์ธ๊ณ , ๋ ๋ค๋ฅธ ๊ฒฝ์ฐ์ tel์ ์ฝ์ ์ด ๋๋ค๊ณ ํ ๋, phone์ ํ์ธ ํ๋ค๊ฐ ์์ผ๋ฉด tel์ ํ์ธํ๊ณ ํด์ผ ํ๋ ๋ถํธํจ์ด ์๊ธฐ๋ ๊ฒ์ด์์. ๊ทธ๋์ ์ด๋ฅผ ํ๋ฒ์ ํ์ธํ๋ ค๊ณ ์ฌ์ฉํ๋๋ฐ, ์ฒซ๋ฒ์งธ ์ธ์๋ถํฐ ์ ํํ ์ฐจ๋ก๋ก ํ์ธ ํด์ ์ฒ์์ผ๋ก Null์ด ์๋ ๊ฐ์ ๋ง๋๋ฉด ๊ทธ ๊ฐ์ ๋ฐํํ๋ ํจ์ ์ธ ๊ฒ์ด์์. ์ฆ, ์ฃผ์ด์ง ์ธ์์์ ์ฒซ ๋ฒ์งธ๊ฐ NULL ์ด ์๋ ๊ฐ์ ๋ฐํํ๋ ๊ฒ์ด ๋๋๋ค!
๊ทธ๋ฆฌ๊ณ , Lag ํจ์๋ ์ฌ๋ฌ ํ์ ๋๋์๋ณด๊ณ , ํ์ฌ ํ์์ ํด๋น ํ์ ๋ฐ์ดํฐ์ ์ก์ธ์ค ํ ์ ์๊ฒ ํด์ฃผ๋ ์๋์ฐ ํจ์์ธ ๊ฒ์ด์์.
์ด ์น๊ตฌ๋ ํํฐ์
๋๋ ๊ฒฐ๊ณผ ์งํฉ ๋ด์ ํ ์ ๋งํผ ํ์ฌ ํ ์์ ์๋ expressionํ์ ๊ฐ์ ๋ฐํํ๋ ๊ฒ์ด์์.
์ฝ๊ฒ ๋งํ๋ฉด ์ฒซ๋ฒ์งธ ๋งค๊ฐ๋ณ์ ๊ธฐ์ค ์ด ์ ์ ๊ฐ์ ๊ฐ์ ๋ฐํํ๋ ๊ฒ์ด์์.
์ฌ๊ธฐ์ ์๋์ฐ ํจ์๋ group by์ ๋น์ทํ๋, ์ง๊ณ๊ฐ ์๋ ํจ์๋ผ๊ณ ๋ณด๋ฉด ๋๋ ๊ฒ์ด์์. ํ๊ณผ ํ๊ฐ์ ๊ด๊ณ๋ฅผ ์ ์ํ๊ธฐ ์ํ ํจ์์ธ ๊ฒ์ด์์.
์ ๋ฆฌํ์๋ฉด
COALESCE(LAG(i.INQRY_SN) OVER(ORDER BY i.INQRY_SN), -1) AS BEFORE_INQRY_SN
์์ SQL๋ฌธ์ ์ด์ ๊ธ์ ๋ณด๊ธฐ ์ํ SQL๋ฌธ์ธ๋ฐ, ๊ฒ์๊ธ ์ผ๋ จ ๋ฒํธ๋ฅผ LAG ํจ์๋ก ๊ฐ์ธ ์ด์ ๊ฐ์ ๊ฐ์ ธ์ค๊ฒ ํ ๋ค, OVERํจ์๋ก ์ ๋ ฌ์ ํ ๋ค ๊ฒ์๊ธ ์ผ๋ จ๋ฒํธ(INQRY_SN)์ COUNT () ์์ด Count ํ๊ธฐ ์ํด ์ฌ์ฉํ ๊ฒ์ด์์. COALESCE()๋ฅผ ํตํด NULL ๊ฐ์ ์ฒดํฌํด์ ์ฒซ๋ฒ์งธ ๋งค๊ฐ ๋ณ์๊ฐ NULL์ด๋ฉด '-1'์ ๋ฐํํด์ Exception ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๊ฒ ํด ์ค ๊ฒ์ด์์.
COALESCE(LEAD(i.INQRY_SN) OVER(ORDER BY i.INQRY_SN), -1) AS NEXT_INQRY_SN
๋ค์ ๋ถ๋ถ์ ๋ค์ ๊ธ์ ๋ณด๊ธฐ ์ํ SQL๋ฌธ์ด์์. ์์์ ๊ฐ์ง๋ง, LAG ๋์ LEAD๋ฅผ ํตํด ๋ค์ ๊ฐ์ ๊ฐ์ ธ์ค๊ฒ ์ฒ๋ฆฌํ ๊ฒ์ด์์.
๊ทธ๋ฆฌ๊ณ , inner join์ ํตํด ํ์ Table๊ณผ join์ ํด์ ์์ฑ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๊ฒ ํ๊ณ , ๋ต๋ณ์ ๋จ๊ธด ํ์์ ์ ๋ณด๋ Null์ผ ์๋ ์๊ธฐ ๋๋ฌธ์(๋ต๋ณ์ด ์์ ๊ฒฝ์ฐ) left outer join์ ํตํด ๋ต๋ณ ํ์์ ๋ํ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๊ฒ join์ ํด ์ค ๊ฒ์ด์์.
์ด Sub Query์ ๋ณ๋ช
์ X๋ก ์ฃผ๊ณ , Main Query Select ์ ์์ X.*์ผ๋ก ๋ชจ๋ ์ปฌ๋ผ์ ์กฐํํ๊ฒ ํ ๋ค
where 1=1
์ ํตํด AND ์กฐ๊ฑด๋ฌธ์ ์ฌ์ฉํ๊ธฐ ์ํ ์์
์ ํ๊ณ ,
<if test="inqrySn neq null and inqrySn neq ''">
์ ํตํด์ ๊ฒ์๊ธ ์ผ๋ จ๋ฒํธ (inqrySn)์ด null์ธ์ง ํน์ ๋น์ด์๋์ง๋ฅผ ํ์ธ ํ ๋ค ๋น์ด์์ง ์์ผ๋ฉด if์ ์์
and INQRY_SN like #{inqrySn}
and ์กฐ๊ฑด์ ์ ํตํด ๊ฒ์๊ธ ์ผ๋ จ๋ฒํธ (INQRY_SN) ๊ฐ์ ๋ฐ์ ํด๋น ๋ด์ฉ์ ์กฐํํ๋ ๊ฒ์ด์์.
๐ฃ ๊ฒฐ๊ณผ

์ด๋ ๊ฒ Postman์ผ๋ก Test ์์ ์ ์์ ์ผ๋ก ๊ฐ์ ๊ฐ์ ธ์ค๋ ๊ฒ์ ๋ณผ ์ ์๋ ๊ฒ์ด์์.
