/images/profile.png

๋‹ค์‹œ ์‹œ์ž‘ํ•˜์ž

๋งˆ์ง€๋ง‰ ํฌ์ŠคํŒ…์„ ํ•œ์ง€ ๋ฒŒ์จ 3๊ฐœ์›”์ด ์ง€๋‚ฌ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๋ฐ”๋นด๋˜๊ฒƒ๋„ ์•„๋‹ˆ๊ณ  ๋ธ”๋กœ๊ทธํฌ์ŠคํŒ…์„ ํ•  ์‹œ๊ฐ„์ด ์•ˆ๋‚œ๊ฒƒ๋„ ์•„๋‹Œ๋ฐ ์–ด๋Š๋ง ๋‹ค์‹œ ์ •์‹ ์ฐจ๋ฆฌ๊ณ  ๋ธ”๋กœ๊ทธ๋ฅผ ํฌ์ŠคํŒ… ํ•˜๋ ค๊ณ ๋ณด๋‹ˆ 3๊ฐœ์›”์ด๋ผ๋Š” ์‹œ๊ฐ„์ด ํ˜๋Ÿฌ๋ฒ„๋ ธ๋„ค์ฑ—๋ฐ”ํ€ด๊ฐ™์€ ์ผ์ƒ, ๋Š์ฆˆ๋ง‰ํžˆ ์ผ์–ด๋‚˜์„œ ํšŒ์‚ฌ์ถœ๊ทผํ•˜๊ณ  ์ •์‹ ์—†์ด ์ผํ•˜๋‹ค๊ฐ€ ํ‡ด๊ทผ, ๊ทธ๋ฆฌ๊ณ  ๋Šฆ๊ฒŒ๊นŒ์ง€ ์ž ๋ชป์ด๋ฃจ๋‹ค ๋˜ ๋‹ค์Œ๋‚ ์ด๋ฉด ๋Š์ฆˆ๋ง‰ํžˆ ์ผ์–ด๋‚˜๊ณ … ๋ญ”๊ฐ€ ๋ณ€ํ™”๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ๋งค์ผ ์ผ๊ธฐ์“ฐ๊ธฐ : ์ผ๊ธฐ๋ผ๊ณ  ํ•ด๋ดค์ž ๊ฑฐ์ฐฝํ•œ๊ฑด ์•„๋‹ˆ๊ณ  ๋”ฑ 3๊ฐœ์›”๋งŒ ์จ๋ณด์ž. ์˜ค๋Š˜ ๋ญํ–ˆ๋Š”์ง€. ์ž๊ธฐ์ „์— ๋”ฑ 10๋ถ„์ด๋ฉด ์ข‹์„๋“ฏ ์•„์นจ์— ์ผ์ฐ ์ผ์–ด๋‚˜๊ธฐ : ์›”์ˆ˜๊ธˆ ์ˆ˜์˜์— ํ™”๋ชฉ ๋ฐฐ๋“œ๋ฏผํ„ด. ์ฃผ๋ง์—๋„ ์ผ์ฐ์ผ์–ด๋‚˜๊ณ . ์ผ์ฐ์ผ์–ด๋‚˜๋ฉด ๋จน์ด๋„ ๋” ๋จน๋Š”๋‹ค๊ณ  ํ•˜์ง€ ์•Š์•˜๋˜๊ฐ€ ๋‹ฌ๋ ฅํ™œ์šฉํ•˜๊ธฐ : ์šด๋™ํ•˜๋Š”๊ฒƒ๋„ ๊ทธ๋ ‡์ง€๋งŒ, ๋‹ฌ๋ ฅ์„ ์ž์ฃผ ๋ณด๋ฉด์„œ ๋นผ๋จน์ง€ ๋ง์•„์•ผ ํ•  ์ค‘์š”ํ•œ ๋‚ ๋“ค์€ ๋ฐ˜๋“œ์‹œ ๋ฉ”๋ชจํ•˜๊ณ  ๊ธฐ์–ตํ•˜์ž ๊ธฐํƒ€ : ์ฑ…์ข€ ๋งŽ์ด ์ฝ๊ณ  ์šด๋™๋„ ๊พธ์ค€ํžˆ ํ•ด์•ผ๊ฒ ๋‹ค. ๋ฌผ๋ก  ๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŒ…๋„ ์žŠ์ง€๋ง๊ณ . ์ฒซ์ˆ ์— ๋ฐฐ๋ถ€๋ฅด๋žด. ํ•˜๋‚˜๋‘˜์”ฉ ํผ์ฆ ๋งž์ถฐ๋‚˜๊ฐ€๋“ฏ ํ•ด๋ณด๋‹ค๋ณด๋ฉด ๋‚ด ์ž์‹ ์ด ๋ฐ”๋€Œ์–ด ์žˆ๊ฒ ์ง€.

mybatis insert/update ์ฟผ๋ฆฌ์‹คํ–‰ํ›„ ๊ฒฐ๊ณผ ๊ฐ€์ ธ์˜ค๊ธฐ

Select๋ฌธ์ด ์•„๋‹Œ ๋‹ค๋ฅธ SQL Query(insert, update ๋“ฑ) ๋ฅผ ์‹คํ–‰ํ•˜๊ณ ์„œ ๊ฒฐ๊ณผ๋ฅผ ๋ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด ์ƒ๊ธด๋‹ค. ์ •ํ™•ํžˆ ์ž˜ ์ˆ˜ํ–‰๋˜์—ˆ๋‚˜์— ๋Œ€ํ•œ ํ™•์ธ. ์–ด๋–ป๊ฒŒ ์ฟผ๋ฆฌ๊ฐ€ ์ž˜ ์ˆ˜ํ–‰๋˜์—ˆ๋‚˜๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. โ€ป ์ฐธ๊ณ  url : http://www.mybatis.org/mybatis-3/ko/sqlmap-xml.html useGeneratedKeys, keyProperty ์˜ต์…˜ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์ž๋™์ƒ์„ฑํ‚ค๋ฅผ ์ง€์›ํ•œ๋‹ค๋ฉด(mySql ๊ฐ™์€) ํ•ด๋‹น์˜ต์…˜์„ ์ด์šฉํ•ด ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ด ๋ฐ›์„์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋กœ๋“ค์–ด ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์•„๋ž˜ ๋ชจ๋ธ๊ฐ์ฒด๋ฅผ ๋„˜๊ธด๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  public Student { int id; String name; String email; Date regist_date; } ์•„๋ž˜ mybatis ๊ตฌ๋ฌธ์œผ๋กœ insert๋ฅผ ์‹œ๋„ํ•˜๊ฒŒ๋˜๋ฉด, ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ธด Student ๊ฐ์ฒด์˜ id๊ฐ’์— insert ํ–ˆ์„๋•Œ์˜ key๊ฐ’(id)์ด ๋“ค์–ด์˜ค๊ฒŒ ๋œ๋‹ค. Student student = new Student(); student.setName('bla'); student.setEmail('bla@naver.com'); mapper.insertStudents(student); // ์ฟผ๋ฆฌ์‹คํ–‰ student.getId(); // ์ถ”์ถœ ๊ฐ€๋Šฅ <insert id="insertStudents" useGeneratedKeys="true" keyProperty="id" parameterType="Student"> insert into Students ( name, email ) values ( #{name}, #{email} ) </insert> selectKey ์˜ต์…˜ Oracle ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” Auto Increment ๊ฐ€ ์—†๊ณ  Sequence๋ฅผ ์‚ฌ์šฉํ•ด์•ผ๋งŒ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ„ ์˜ต์…˜์„ ์‚ฌ์šฉํ• ์ˆ˜๊ฐ€ ์—†๋‹ค. ํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ์šฐํšŒ์ ์ธ(?) ๋ฐฉ๋ฒ•์œผ๋กœ ์œ„์™€๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๋ณผ์ˆ˜๊ฐ€ ์žˆ๋‹ค. ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ๋ชจ๋ธ์ด๋‚˜ java๊ตฌ๋ฌธ์€ ์œ„์™€ ๋™์ผํ•˜๊ณ  xml ์ฟผ๋ฆฌ ๋ถ€๋ถ„๋งŒ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. <insert id="insertStudents" parameterType="Student"> <selectKey keyProperty="id" resultType="int" order="BEFORE"> select SEQ_ID.nexyval FROM DUAL </selectKey> insert into Students (id, name , email) values (#{id}, #{name}, #{email}) </insert> ์œ„์™€๊ฐ™์€ ์ฝ”๋“œ์—์„œ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— id๊ฐ’์— Sequence์— ์˜ํ•ด ๊ฐ’์„ ์…‹ํŒ…ํ•˜๊ฒŒ ๋˜๊ณ , ์ž๋™์ ์œผ๋กœ ํ•ด๋‹น ๊ฐ’์„ Student์˜ id์— setํ•˜๊ฒŒ ๋˜์„œ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ์ˆ˜๊ฐ€ ์žˆ๋‹ค. ํ•ญ์ƒ ํ…Œ์ด๋ธ”์˜ key๊ฐ’์—๋งŒ ํ•ด๋‹นํ•˜๋Š”๊ฒƒ์ด ์•„๋‹ˆ๋‹ค. key๊ฐ’๊ณผ๋Š” ์ „ํ˜€ ์ƒ๊ด€์—†๋Š” ๊ฐ’๋„ selectKey ๊ตฌ๋ฌธ์œผ๋กœ ๋ฆฌํ„ดํ• ์ˆ˜๊ฐ€ ์žˆ๋Š”๋ฐ order์˜ต์…˜์„ AFTER๋กœ ์ฃผ๊ณ  ๋ฆฌํ„ดํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฐ’์„ ๋ช…์‹œํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ์—์„œ๋Š” ์ž…๋ ฅํ• ์‹œ id๊ฐ’์„ Sequence์—์„œ ๊ฐ€์ ธ์˜ค๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ์ˆ˜๋™์œผ๋กœ ๋„ฃ์–ด์ฃผ๊ณ , ์ž…๋ ฅํ–ˆ๋˜ id์— ๋งž๋Š” regist_date ๊ฐ’์„ ๋ฆฌํ„ด๋ฐ›์•„ ์œ„์—์„œ์ฒ˜๋Ÿผ ๋™์ผํ•˜๊ฒŒ ๊ฐ’๋ฅผ ๊ฐ€์ ธ์˜ฌ์ˆ˜ ์žˆ๋‹ค. <insert id="insertStudents" parameterType="Student"> <selectKey keyProperty="regist_date" resultType="java.util.Date" order="AFTER"> select regist_date FROM students WHERE id = #{id} </selectKey> insert into Students (id, name , email, regist_date) values (#{id}, #{name}, #{email}, syadate) </insert>

Oracle + Mybatis ํ™˜๊ฒฝ์—์„œ์˜ Date ๋‹ค๋ฃจ๊ธฐ

์ƒํ™ฉ Oracle, Java 8, mybatis3 ํ™˜๊ฒฝ Date์ปฌ๋Ÿผ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š”๋ฐ ์ด๋ฅผ select query๋กœ ์กฐํšŒํ•˜์—ฌ Model์— ๋ฐ”์ธ๋”ฉ ์‹œํ‚ค๊ณ ์ž ํ•จ. ์ฟผ๋ฆฌ์— ์•„๋ฌด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  Date ํ˜•ํƒœ๋กœ Model์— ๋ฐ”์ธ๋”ฉ์„ ํ•˜๋ฉด ์‹œ๋ถ„์ดˆ๊ฐ€ ์—†์–ด์ง„ 2017-01-01 00:00:00 ํ˜•ํƒœ๋กœ ๋‚จ๊ฒŒ๋จ ๊ทธ๋ž˜์„œ ์•„๋ž˜์ฒ˜๋Ÿผ ์ฟผ๋ฆฌ ์ž‘์„ฑํ•  ๋•Œ๋งˆ๋‹ค TO_CHAR๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํฌ๋งท์— ๋งž์ถ”์–ด ํ˜•๋ณ€ํ™˜์„ ์‹œํ‚ค๊ณ  Date ๋˜๋Š” String์œผ๋กœ Model์— ๋ฐ”์ธ๋”ฉ ํ•˜๊ณค ํ–ˆ์Œ. SELECT TO_CHAR(reg_ymdt, 'YYYY-MM-DD HH24:MI:SS') AS registDate FROM ... ์ด๋ ‡๊ฒŒ ํ•˜๋‹ค๋ณด๋‹ˆ query ๋งŒ๋“ค๋•Œ๋งˆ๋‹ค ํ˜•๋ณ€ํ™˜ํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด์ค˜์•ผํ•˜๊ณ , ์ž์นซ ํฌ๋งทํ˜•์‹์„ ๋‹ค๋ฅด๊ฒŒ ์ ์œผ๋ฉด ์—‰๋šฑํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•˜๊ฑฐ๋‚˜, Dateํ˜•์„ ๊ทธ๋Œ€๋กœ ๋ฐ›์•„ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” ๋‹ค์‹œ ํ˜•๋ณ€ํ™˜ํ•˜๋Š” ๊ณผ์ •(String to Date)์„ ํ•ด์ค˜์•ผ๋งŒ ํ•จ. .. ๊ท€์ฐจ๋‹ˆ์ฆ˜์˜ ์‹œ์ž‘ : ์‚ฝ์งˆ 1. ์‚ฝ์งˆ์˜ ์‹œ์ž‘ 1-1. ์˜ค๋ผํด์˜ DATEํ˜• โ†’ java.sql.Date ์˜ ๊ฒฝ์šฐ mybatis์—์„œ๋Š” ์ž๋™์ ์œผ๋กœ org.apache.ibatis.type.SqlDateTypeHandler๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ๋จ mybatis 3 ๋ฌธ์„œ ์ฐธ๊ณ  ํ•ด๋‹น ํ•ธ๋“ค๋Ÿฌ์˜ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Œ @Override public Date getNullableResult(ResultSet rs, String columnName) throws SQLException { return rs.getDate(columnName); } java.sql.ResultSet.getDate()๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์‹ค์ œ ‘yyyy-mm-dd’ ๋งŒ ๊ฐ€์ ธ์™€ ๋ฆฌํ„ดํ•˜๊ฒŒ๋จ (์—ฌ๊ธฐ์„œ ๋””๋ฒ„๊น… ํ•ด๋ณด๋ฉด rs.getTimestamp(columnName)๊ฐ’์€ ์‹œ๋ถ„์ดˆ๊นŒ์ง€ ๋‹ค ๋“ค์–ด๊ฐ€ ์žˆ์Œ) ๋”ฐ๋ผ์„œ ์‹œ๊ฐ„๊ฐ’์ด ์—†๋Š” yyyy-mm-dd ํ˜•ํƒœ๋กœ ๋ฆฌํ„ด์ด ๋จ 1-2. ์˜ค๋ผํด์˜ DATEํ˜• โ†’ java.util.Date ์˜ ๊ฒฝ์šฐ mybatis์—์„œ๋Š” ์ž๋™์ ์œผ๋กœ org.apache.ibatis.type.DateOnlyTypeHandler๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ๋จ mybatis 3 ๋ฌธ์„œ ์ฐธ๊ณ  ํ•ด๋‹น ํ•ธ๋“ค๋Ÿฌ์˜ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Œ @Override public Date getNullableResult(ResultSet rs, String columnName) throws SQLException { java.sql.Date sqlDate = rs.getDate(columnName); if (sqlDate != null) { return new java.util.Date(sqlDate.getTime()); } return null; } ์œ„์˜ org.apache.ibatis.type.SqlDateTypeHandler ๋ณ€ํ™˜์ฝ”๋“œ์—์„œ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์ ๊ณผ ๊ฐ™์ด yyyy-mm-dd ๋งŒ ๊ฐ€์ ธ์™€์„œ java.sql.Date ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ , ์ด ์ •๋ณด๋ฅผ ํ† ๋Œ€๋กœ java.util.Date ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜๋Š”๋ฐ ์•ž์„œ ์‹œ๊ฐ„๊ฐ’์„ ๋บ€ ์ •๋ณด๋กœ ๋งŒ๋“ค์–ด์กŒ๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ๊ตญ ๋™์ผํ•˜๊ฒŒ yyyy-mm-dd ํ˜•ํƒœ๋กœ ๋ฆฌํ„ด์ด ๋จ 2. ์‚ฝ์งˆ์™„๋ฃŒ, ํ•ด๊ฒฐ์˜ ์‹œ์ž‘ ์˜ค๋ผํด + mybatis ํ™˜๊ฒฝ์—์„œ Dateํƒ€์ž…์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด์„œ๋Š” ํƒ€์ž…ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•œ๋‹ค๋Š”๊ฑธ ์•Œ๊ฒŒ๋จ. 2-1. ์˜ค๋ผํด์˜ DATEํ˜• โ†’ java.sql.Date ์˜ ๊ฒฝ์šฐ ์•„๋ž˜์ฒ˜๋Ÿผ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ์ปค์Šคํ…€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋งŒ๋“ค์–ด ๋“ฑ๋ก์„ ์‹œ์ผœ์ค€๋‹ค. mybatis-config.xml <typeHandlers> <typeHandler handler="com.naver.dbill.admin.common.handler.CustomDateHandler"/> </typeHandlers> CustomDateHandler.java ... import java.sql.Date; ... public class CustomDateHandler extends BaseTypeHandler<Date> { ... @Override public Date getNullableResult(ResultSet rs, String columnName) throws SQLException { Timestamp sqlTimestamp = rs.getTimestamp(columnName); if (sqlTimestamp != null) { return new Date(sqlTimestamp.getTime()); } return null; } ... } ์œ„ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•ด๋ณด๋ฉด ์ •์ƒ์ ์œผ๋กœ ์‹œ๋ถ„์ดˆ ๊ฐ’์ด ์žˆ๋Š” ์™„์ „ํ•œ Date ํ˜•ํƒœ๋ฅผ ๋ณผ์ˆ˜ ์žˆ๋‹ค. 2-2. ์˜ค๋ผํด์˜ DATEํ˜• โ†’ java.util.Date ์˜ ๊ฒฝ์šฐ ์•„๋ž˜์ฒ˜๋Ÿผ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ์ปค์Šคํ…€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋งŒ๋“ค์–ด ๋“ฑ๋ก์„ ์‹œ์ผœ์ค€๋‹ค. ๋‹จ, mybatis 3 ๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด java.sql.Date ์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ๊ธฐ๋ณธ์œผ๋กœ ์„ค์ •๋œ typeHandler๊ฐ€ JDBC์— ๋”ฐ๋ผ 3๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ž‘์„ฑํ•œ ์ปค์Šคํ…€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ช…์‹œ์ ์œผ๋กœ ์ž๋ฐ”ํƒ€์ž… ๊ณผ JDBCํƒ€์ž… ์„ ์ ์–ด์ค˜์•ผ ์ •์ƒ์ ์œผ๋กœ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ๋˜์–ด ํ•ด๋‹น ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. mybatis-config.xml <typeHandlers> <typeHandler handler="com.naver.dbill.admin.common.handler.CustomDateHandler" javaType="java.util.Date" jdbcType="DATE"/> </typeHandlers> CustomDateHandler.java ๋Š” ์œ„์™€ ๋™์ผํ•˜๋‹ค. ( import java.util.Date; ์‚ฌ์šฉ์œผ๋กœ ๋ณ€๊ฒฝ ) ์‚ฝ์งˆํ•˜๋ฉฐ ์•Œ๊ฒŒ๋œ ๋ณด๋„ˆ์Šค ์ง€์‹ java.sql.Date ๋Š” java.util.Date ์„ ์ƒ์†๋ฐ›์•˜๋‹ค. public class Date extends java.util.Date { } ๊ฒ€์ƒ‰์„ ํ•˜๋‹ค๋ณด๋ฉด ์•Œ์ˆ˜์žˆ๊ฒ ์ง€๋งŒ java.sql.Date ๋Š” JDBC๋“ฑ์„ ์ด์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์ ํ•ฉํ•˜๊ณ , java.util.Date ์€ ๋ณด๋‹ค ๋ฒ”์šฉ์ ์ธ ๋‚ ์งœ๋‚˜ ์‹œ๊ฐ์ •๋ณด๋ฅผ ๋‹ค๋ฃฐ๋•Œ ์ ํ•ฉํ•˜๋‹ค๊ณ  ํ•œ๋‹ค. toString ๋ฉ”์†Œ๋“œ์˜ ๋ฆฌํ„ด Format ํ˜•ํƒœ java.sql.Date : yyyy-mm-dd java.util.Date : EEE MMM dd HH:mm:ss zzz yyyy mybatis ์—์„œ ํ˜•๋ณ€ํ™˜์€ mybatis 3 ๋ฌธ์„œ์— ๋‚˜์™€์žˆ๋Š” ์ž๋ฐ”ํƒ€์ž…๊ณผ JDBCํƒ€์ž…์ด ์ผ์น˜ํ•  ๊ฒฝ์šฐ์— ํ•ด๋‹น ํƒ€์ž… ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. ์ •์ƒํ˜ ๋‹˜ ์กฐ์–ธ ( http://d2.naver.com/helloworld/645609 ์ž‘์„ฑํ•˜์‹ ๋ถ„ ) Oracle์˜ JDBC ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ์˜ˆ์ƒ ๋ฐ–์œผ๋กœ ๋™์ž‘ํ•˜๋„ค์š”.

์Šคํ”„๋งํ™˜๊ฒฝ์—์„œ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ด€๋ จ ์ •๋ฆฌ

์ผ๋ฐ˜์ ์ธ ์›น ํ”„๋กœ์ ํŠธ ๊ตฌ์„ฑ์—์„œ๋Š” Controller๋ ˆ๋ฒจ์—์„œ ์‘๋‹ต์„ ๋ฐ›๊ณ  ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌ ํ›„์— ๋‹ค์‹œ View๋ ˆ๋ฒจ๋กœ ๋„˜์–ด๊ฐ€๋Š”๊ฒŒ ํ†ต์ƒ์ ์ธ ํ๋ฆ„์ด๋‹ค. ์ด ๋ถ€๋ถ„์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ด€๋ จํ•œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค. httpServletRequest.getParameter() ์•„๋ž˜์†Œ์Šค์ฒ˜๋Ÿผ HttpServletRequest์˜ getParameter() ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. @RequestMapping("/") public String home(HttpServletRequest httpServletRequest) { String id = httpServletRequest.getParameter("id"); return "home"; } @RequestParam ๋˜๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” @RequestParam ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•˜๋ฉด ๊ฐ„๋‹จํ•˜๊ฒŒ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ์ˆ˜ ์žˆ๋‹ค. ์šฐ์„ , ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์˜ ์˜ต์…˜๊ฐ’๋“ค์— ๋Œ€ํ•ด ๊ฐ„๋žตํ•˜๊ฒŒ ํ™•์ธํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋Š”๊ฒŒ ์ข‹์„๋“ฏ ์‹ถ๋‹ค. API๋ฌธ์„œ 4.3.6 ๊ธฐ์ค€ ์ด๋ฆ„ ํƒ€์ž… ์„ค๋ช… name, value (Alias for name) String ํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„ required boolean ํ•ด๋‹น ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๋ฐ˜๋“œ์‹œ ํ•„์ˆ˜์ธ์ง€ ์—ฌ๋ถ€, ๊ธฐ๋ณธ๊ฐ’์€ true defaultValue String ํ•ด๋‹น ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ๊ธฐ๋ณธ๊ฐ’ ์œ„ ์˜ต์…˜๊ฐ’๋“ค์„ ์กฐํ•ฉํ•˜์—ฌ ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ์— ์ ์šฉํ•ด๋ณด๋ฉด ์•„๋ž˜ ์†Œ์Šค์™€ ๊ฐ™์ด ๋งŒ๋“ค์–ด์ง€๊ณ , ์ด๋ ‡๊ฒŒ reqeust์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ์ˆ˜ ์žˆ๋‹ค. @RequestMapping("/") public String home(@RequestParam(value="id", defaultValue="false") String id) { return "home"; } ์ด ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•˜๊ฒŒ๋˜๋ฉด ์ž์นซ ์ž˜๋ชปํ•˜๋‹ค๊ฐ„ ์—๋Ÿฌ๋ฅผ ๋งŒ๋‚ ์ˆ˜๊ฐ€ ์žˆ๋Š”๋ฐ required๊ฐ’์„ true๋กœ ํ•ด๋†“๊ณ  (ํ•„์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ ์„ค์ •) ํ•ด๋‹น ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋˜๋ฉด HTTP 400 ์—๋Ÿฌ๋ฅผ ๋ฐ›๊ฒŒ ๋˜๋‹ˆ ๊ฐ ์˜ต์…˜๋“ค์„ ์ •ํ™•ํžˆ ํ™•์ธํ•˜๊ณ  ์‚ฌ์šฉํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค. ๋ฌผ๋ก  ์ปจํŠธ๋กค๋Ÿฌ์˜ ๋ฉ”์†Œ๋“œ์—์„œ ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ์•„๋ž˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ๋ฐ”๋กœ ๋ฐ›์„์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋ฐ”๋กœ ๋ฐ›์„ ๊ฒฝ์šฐ๋Š” ํ•„์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์ด false๋กœ ์„ค์ •์ด ๋˜๊ณ  ๋ณ€์ˆ˜๋ช…๊ณผ ๋™์ผํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ๋งŒ ๋ฐ›์„์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ฉฐ ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •์„ ํ• ์ˆ˜๋Š” ์—†๋‹ค. ๋ฐฉ๋ฒ•์˜ ์ฐจ์ด๋ผ์„œ ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋งž์ถฐ ์‚ฌ์šฉํ•˜๋ฉด ๋ ๋“ฏ ํ•˜๋‹ค. @RequestMapping("/") public String home(String id) { return "home"; } @RequestBody @RequestBody์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ POSTํ˜•์‹์œผ๋กœ ์‘๋‹ต์„ ๋ฐ›๋Š” ๊ตฌ์กฐ์—ฌ์•ผ๋งŒ ํ•œ๋‹ค. ์ด๋ฅผํ…Œ๋ฉด JSON ์ด๋‚˜ XML๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ ์ ˆํ•œ messageConverter๋กœ ์ฝ์„๋•Œ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, POJOํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ ์ „์ฒด๋กœ ๋ฐ›์„๊ฒฝ์šฐ์— ์‚ฌ์šฉ๋œ๋‹ค. ๋‹จ, ์ด ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์„ ๊ฒฝ์šฐ ๋ณ„๋„์˜ ์ถ”๊ฐ€ ์„ค์ •(POJO ์˜ get/set ์ด๋‚˜ json/xml ๋“ฑ์˜ messageConverter ๋“ฑ)์„ ํ•ด์ค˜์•ผ ์ ์ ˆํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์„์ˆ˜๊ฐ€ ์žˆ๋‹ค. @PostMapping("/") public String home(@ReqeustBody Student student) { return "home"; } @ModelAttribute @RequestParam๊ณผ ๋น„์Šทํ•œ๋ฐ 1:1๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์„๊ฒฝ์šฐ๋Š” @RequestParam๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๋„๋ฉ”์ธ์ด๋‚˜ ์˜ค๋ธŒ์ ํŠธ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์„ ๊ฒฝ์šฐ๋Š” @ModelAttribute์œผ๋กœ ๋ฐ›์„์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ ์ด ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒ€์ฆ(Validation)์ž‘์—…์„ ์ถ”๊ฐ€๋กœ ํ• ์ˆ˜ ์žˆ๋Š”๋ฐ ์˜ˆ๋กœ๋“ค์–ด null์ด๋ผ๋˜์ง€, ๊ฐ ๋ฉค๋ฒ„๋ณ€์ˆ˜๋งˆ๋‹ค valid์˜ต์…˜์„ ์ค„์ˆ˜๊ฐ€ ์žˆ๊ณ  ์—ฌ๊ธฐ์„œ ์—๋Ÿฌ๊ฐ€ ๋‚  ๊ฒฝ์šฐ BindException ์ด ๋ฐœ์ƒํ•œ๋‹ค. Spring command ๊ฐ์ฒด ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์€ ์ •๋ณด์— ๋Œ€ํ•ด์„œ๋Š” view ์—์„œ ๋ฐ”๋กœ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ์˜ˆ๋กœ ๋“ค์–ด ์•„๋ž˜๊ทธ๋ฆผ์ฒ˜๋Ÿผ ์ด๋ ‡๊ฒŒ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ๊ตฌ์„ฑ๋˜์–ด์žˆ๊ณ  ์ด๋ ‡๊ฒŒ ๋ชจ๋ธ์ด ๊ตฌ์„ฑ๋˜์–ด์žˆ์„๋•Œ view ์—์„œ ์ด๋Ÿฐ์‹์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ์ด๋•Œ /student?name=taetaetae&age=32&address=green-factory๋กœ ํ˜ธ์ถœ์„ ํ•ด๋ณด๋ฉด ๊ตฌ์ง€ Model์— ๊ฐ’์„ ์…‹ํŒ…ํ•ด์ฃผ์ง€ ์•Š์•„๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •๋ณด๋ฅผ ์ฝ์„์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ๋งˆ์น˜๋ฉฐ ์Šคํ”„๋ง์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›๋Š” ๋ฐฉ๋ฒ•์€ ์ƒ๋‹นํžˆ ๋‹ค์–‘ํ•˜๋‹ค. ์ด๊ฒŒ ์ •๋‹ต์ด๋‹ค ์ •์˜ํ• ์ˆ˜ ์—†์„์ •๋„๋กœ. ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋งž๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์•„์•ผ ํ•˜๊ฒ ๊ณ , ๊ฐ ๋ฐฉ๋ฒ•์— ์žฅ/๋‹จ์ ์„ ์ตœ๋Œ€ํ•œ ์‚ด๋ ค์„œ ์ข€๋” ๊น”๋”ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ• ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๊ฒ ๋‹ค.

๋ฒŒ์จ 3์›”, ๋‹ค์‹œ ์ผ์–ด์„œ์•ผํ•  ๋•Œ

๋ฒŒ์จ 3์›”์ด๋‹ค. ๋ญํ•˜๋‚˜ ์ œ๋Œ€๋กœ ํ•œ๊ฒƒ๋„ ์—†๋Š”๋ฐ ์‹œ๊ฐ„์€ ์•ผ์†ํ•˜๊ฒŒ๋„ ๋ฉˆ์ถ”์ง€ ์•Š๊ณ  ์ง€๋‚˜๊ฐ€๊ณ  ์žˆ๋‹ค. ์˜ค๋žœ๋งŒ์— ๋™๊ธฐํ˜•์„ ๋งŒ๋‚ฌ๋‹ค. ์‹ ์ž…์‚ฌ์›์ด ๋˜๊ธฐ ์ „ ์—ฐ์Šต์ƒ(?)์‹œ์ ˆ ๋™๊ฑฐ๋™๋ฝํ•˜๋ฉฐ ๊ฐœ๋ฐœ์— ๋Œ€ํ•ด ๊ณ ๊ตฐ๋ถ„ํˆฌ ํ•˜๋˜ ์‚ฌ์ด์ธ์ง€๋ผ. ์˜ค๋žœ๋งŒ์— ๋งŒ๋‚˜๋„ ์„œ๋กœ ์ด์•ผ๊ธฐ ํ•˜๊ณ ์ž ํ•˜๋Š” ์ฃผ์ œ๋Š” ์–ธ์ œ๋‚˜ ๋™์ผํ•˜๋‹ค. ๊ฐœ๋ฐœ์ž๋กœ์„œ์˜ ์‚ถ ์ด๋Ÿฐ์ €๋Ÿฐ ์ด์•ผ๊ธฐ๋ฅผ ํ•˜๋ฉฐ ๋‹ค์‹œ ๋‚˜๋ฅผ ๋Œ์•„๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค. ๋‚ด ๋…ธ๋ ฅ์— ์˜ํ•ด, ์•„๋‹ˆ๋ฉด ์šด์ด ์ข‹์•„ ์ง€๊ธˆ ๋‹ค๋‹ˆ๊ณ ์žˆ๋Š” ํšŒ์‚ฌ์— ๋“ค์–ด์˜จ ์ดํ›„๋กœ ์˜ˆ์ „๋งŒํผ์˜ ์—ด์ •์€ ์˜จ๋ฐ๊ฐ„๋ฐ ์—†์œผ๋ฉฐ, ๊ทธ๋งŒํผ ๊ฐ„์ ˆํ•˜์ง€๋„ ์•Š๊ณ  ์น˜์—ดํ•˜์ง€๋„ ์•Š๋Š” ๋‚ด ์ž์‹ ์ด ๋„ˆ๋ฌด ๋ฏธ์•ˆํ•˜๊ณ  ์ชฝํŒ”๋ฆด์ •๋„๋กœ ํ•œ์‹ฌํ•˜๊ธฐ ๊ทธ์ง€ ์—†์—ˆ๋‹ค. ๋ฌด์—‡๋•Œ๋ฌธ์ผ๊นŒ, ๋„๋Œ€์ฒด ์™œ ์ด๋ ‡๊ฒŒ ์•ˆ์ผํ•ด์กŒ๊ณ  ์ ๊ทน์ ์ด์ง€ ๋ชปํ•˜๊ฒŒ ๋˜์—ˆ์„๊นŒ. ๊ทธ ์งˆ๋ฌธ์— ๋Œ€ํ•œ ์ •๋‹ต์€ ์ด๊ฒƒ์ด๋‹ค ๋ผ๊ณ  ์ •์˜๋ฅผ ํ• ์ˆ˜๋Š” ์—†๊ฒ ์ง€๋งŒ ํ™•์‹คํ•œ๊ฑด, ํ˜„์žฌ ๋‚ด ์ƒํ™ฉ์— ์•ˆ์ฃผํ•˜๊ณ  ํƒ€ํ˜‘ํ•˜๋ คํ•˜๋Š” ๋งˆ์Œ๊ฐ€์ง์ด ์ƒ๊ฒผ๋‹ค๋Š”๊ฑด ํšŒํ”ผํ• ์ˆ˜ ์—†์„์ •๋„๋กœ ๋‚˜๋„ ์ •๋ง ๋งŽ์ด ๋ณ€ํ•ด๋ฒ„๋ฆฐ๊ฒƒ ๊ฐ™๋‹ค. ๋ฌผ๋ก  ์ง€๊ธˆ ์ƒํ™ฉ์ด ์ž˜๋ชป๋˜์—ˆ๋‹ค๋Š”๊ฑด ์•„๋‹ˆ์ง€๋งŒ ๋‚ด ์ง์—… ํŠน์„ฑ์ƒ ๋Š์ž„์—†์ด ๋…ธ๋ ฅํ•˜๊ณ  ๋„์ „ํ•˜๋ฉฐ ๋ฐฐ์›Œ์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ธ๋ฐ ์ง€๊ธˆ ๋‚œ ํ‡ด๊ทผํ•˜๊ณ  ์ง‘์—๊ฐ€๋ฉด ์‰ฌ๊ณ ์‹ถ๊ณ  ์ž๊ธฐ ๋ฐ”์˜๊ณ  ๋‹ค์Œ๋‚  ๋Šฆ์ž ์ž๊ณ … ๊ณ„์†๋œ ์ƒํ™œํŒจํ„ด์— ์ –์–ด ์‚ฌ๋Š”๊ฒƒ ๊ฐ™๋‹ค. ์ผ๋‹จ ๋…์„œ์ข€ ๋งŽ์ด ํ•ด์•ผ๊ฒŸ๋‹ค. ํšŒ์‚ฌ์—, ์ง‘์— ์Œ“์ธ ์ฑ…๋งŒ ๋ฒŒ์จ ๋ช‡๊ถŒ์ธ์ง€… ๊ธฐ๋ณธ์ด ๋˜๋Š” ์ „๊ณต์„œ์  ํ•˜๋‚˜ ์ •ํ•˜๊ณ  ๋๊นŒ์ง€ ์™„๋…ํ•ด๋ณด์ž. ๊ทธ๊ฒŒ ์ž๋ฐ”๋“  ์Šคํ”„๋ง์ด๋“ , ์ตœ์‹  ์‹ ๊ธฐ์ˆ ๋ณด๋‹ค ๊ธฐ๋ณธ์ด ํƒ„ํƒ„ํ•ด์ ธ์•ผ ํ•˜๋Š”๊ฑด ๋ฐฑ๋ฒˆ ์ฒœ๋ฒˆ ๋งํ•ด๋„ ๋‹น์—ฐํ•˜๊ธฐ์—. ๋‹ค์‹œ ์ •์‹ ์ฐจ๋ฆฌ์ž. ์˜ค๋Š˜ ๊ฑท์ง€ ์•Š์œผ๋ฉด ๋‚ด์ผ์€ ๋‹ฌ๋ ค์•ผ ํ•œ๋‹ค๊ณ  ๋ˆ„๊ตฐ๊ฐ€ ๊ทธ๋žฌ๋“ฏ..

github api ์‚ฌ์šฉ๋ฐฉ๋ฒ•

github ์—์„œ๋Š” ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ์˜ ์ „๋ฐ˜์ ์ธ ์ƒํ™ฉ์— ๋Œ€ํ•ด ๋‹ค์–‘ํ•œ API๋ฅผ ์ œ๊ณตํ•ด์ฃผ๊ณ  ์žˆ๋‹ค. ์ด๋ฒˆ์—๋Š” ๊ทธ API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ ์ž ํ•œ๋‹ค. Personal access tokens ๋ฐœ๊ธ‰ ์šฐ์„  ์ •์ƒ์ ์ธ API๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด Personal access tokens๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์•„์•ผ ํ•œ๋‹ค. github ์ดˆ๊ธฐํ™”๋ฉด > ์šฐ์ธก์ƒ๋‹จ ํ”„๋กœํ•„์‚ฌ์ง„ ํด๋ฆญ > setting > Personal access tokens ์— ๋“ค์–ด๊ฐ€ ํ† ํฐ์„ ์ƒ์„ฑ์„ ํ•œ๋‹ค. ํ•ด๋‹น ํ† ํฐ์˜ ํ—ˆ์šฉ๋ฒ”์œ„๋ฅผ ์„ค์ •ํ•œ๋’ค ์ƒ์„ฑ์„ ํ•˜๋ฉด ๋งŒ๋“ค์–ด ์ง€๋Š”๋ฐ ์—ฌ๊ธฐ์„œ ๋ฐœ๊ธ‰๋˜๋Š” ๋ฌธ์ž์—ด์€ ๋”ฐ๋กœ ๋ณด๊ด€ํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค. (๋‚˜์ค‘์— ๋‹ค์‹œ ํ™•์ธํ•˜๋ ค๋ฉด ์ƒˆ๋กœ ์žฌ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•๋ง๊ณ ๋Š” ์—†๊ธฐ ๋•Œ๋ฌธ์— ํ•œ๋ฒˆ ๋งŒ๋“ค๋•Œ ๋ฉ”๋ชจํ•ด ๋‘๋Š”๊ฒŒ ์ข‹๋‹ค.) ์•„๋ž˜์™€ ๊ฐ™์ด ์ƒ์„ฑ์™„๋ฃŒ. API ์‚ฌ์šฉ๋ฐฉ๋ฒ• ๊ถŒํ•œ์ด ์—†๋Š” Repository ์˜ ๋‚ด์šฉ์„ ํ™•์ธํ• ์ˆ˜ ์—†๋“ฏ์ด github์—์„œ ์ œ๊ณตํ•˜๋Š” API๋˜ํ•œ ๊ถŒํ•œ์ด ์žˆ๋Š” Repository์— ๋Œ€ํ•ด์„œ๋งŒ API๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์œ„์—์„œ ๋ฐœ๊ธ‰ํ•œ token ์„ ๊ถŒํ•œ ์ฒดํฌํ• ๋•Œ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ์„์ˆ˜ ์žˆ๊ฒ ์œผ๋‚˜ ๋‚˜๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ ํ—ค๋”์— ํฌํ•จ์‹œ์ผœ์„œ ์ผ๋ฐ˜ GET ํ˜ธ์ถœ์„ ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•˜์˜€๋‹ค. ์œˆ๋„์šฐ ํ™˜๊ฒฝ์—์„œ๋Š” ํ—ค๋” ์…‹ํŒ…ํ•˜๊ณ  ํ˜ธ์ถœํ•˜๋Š”๊ฒŒ ์กฐ๊ธˆ ์–ด๋ ค์šธ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ด๋Ÿฌํ•œ ๋ถ€๋ถ„์„ ์„ค์ •ํ• ์ˆ˜ ์žˆ๋Š” Postman์ด๋ผ๋Š” ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ํ˜ธ์ถœ์„ ํ•ด๋ณธ๋‹ค. ์•„๋ž˜์ฒ˜๋Ÿผ url์€ https://api.github.com/์œผ๋กœ ์„ค์ •ํ•˜๊ณ  HeadersํŒŒ๋ผ๋ฏธํ„ฐ์— Authorization๋ผ๋Š” key์— value๋ฅผ ์œ„์—์„œ ๋ฐœ๊ธ‰๋ฐ›์•˜๋˜ token์„ ์ด์šฉํ•˜์—ฌ token abcd~~์‹์œผ๋กœ ์ž…๋ ฅํ•ด์ค€๋‹ค์Œ send๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์ฃผ๋ฉด ์‘๋‹ต์„ ๋ฐ›์„์ˆ˜๊ฐ€ ์žˆ๋Š”๋ฐ, ์•„๋ž˜ ๊ทธ๋ฆผ์€ ์ œ๊ณตํ•˜๋Š” api์˜ ๋ชจ๋“  url์„ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ์•„๋ž˜์• ์„œ๋Š” ์œ„์—์„œ ํ™•์ธ๋œ api url์„ ํ™œ์šฉํ•˜์—ฌ ๋‚ด๊ฐ€ ๊ถŒํ•œ์ด ์žˆ๋Š” ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ ๋‚ด์—์„œ ํ™•์ธํ• ์ˆ˜์žˆ๋Š” ์ •๋ณด์— ๋Œ€ํ•œ API๋ฅผ ํ˜ธ์ถœํ•ด๋ณด์•˜๋‹ค. API ํ˜ธ์ถœ์‹œ ๊ฐ€์žฅ ๋ณดํŽธํ™”๋˜์–ด์žˆ๋Š”(?) ์ŠคํŒฉ์ธ JSON์œผ๋กœ ์‘๋‹ต์ด ๋‚ด๋ ค์˜ค๊ธฐ๋•Œ๋ฌธ์— ์–ด๋– ํ•œ ํ™˜๊ฒฝ์—์„œ๋„ ์ถฉ๋ถ„ํžˆ ํ™œ์šฉํ• ์ˆ˜ ์žˆ์„๊ฒƒ์ด๋ผ ์ƒ๊ฐํ•œ๋‹ค. ๋‚˜๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ํŒ€ ๋‚ด์—์„œ ํ•˜๋‚˜์˜ Organizations๋‚ด์— ์—ฌ๋Ÿฌ Repository๊ฐ€ ์žˆ๋Š”๋ฐ ๊ฐ๊ฐ์˜ PullRequest์— ๋Œ€ํ•ด ์ฝ”๋“œ๋ฆฌ๋ทฐ๋ฅผ ํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์—์„œ ์ผ์ผํžˆ ๋‹ค ์ฐพ์•„๋ณด๊ธฐ ๊ท€์ฐฎ์•„ github-api๋ฅผ ํ™œ์šฉํ•ด open๋œ PullRequest๊ฐ€ ์žˆ์œผ๋ฉด ์•Œ๋ฆผ์„ ์ฃผ๋Š” ๊ฑธ ๋งŒ๋“ค์–ด ๋ณด์•˜๋‹ค.

๋ฆฌ๋ˆ…์Šค์ƒ์—์„œ json ํŒŒ์‹ฑ

๋ฆฌ๋ˆ…์Šค ์ƒ์—์„œ jsonํ˜•ํƒœ์˜ String ์„ ํŒŒ์‹ฑํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด ์•„๋ž˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๋Š”๊ฒƒ์„ ์ถ”์ฒœํ•ด๋ณธ๋‹ค. jq ์‚ฌ์šฉ๋ฐฉ๋ฒ•์€ ๋„ˆ๋ฌด๋„ˆ๋ฌด ๊ฐ„๋‹จํ•˜๋‹ค. ์ž์‹ ์˜ ์‹œ์Šคํ…œ์— ๋งž๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค์šด๋ฐ›๊ณ  (32-bit system) $ wget http://stedolan.github.io/jq/download/linux32/jq (64-bit system) $ wget http://stedolan.github.io/jq/download/linux64/jq ์‹คํ–‰ ๊ถŒํ•œ์„ ์„ค์ •ํ•ด ์ค€ ๋’ค chmod +x ./jq root ๊ถŒํ•œ์œผ๋กœ ํ•ด๋‹น ํŒŒ์ผ์„ ์ด๋™์‹œํ‚จ๋‹ค. sudo cp jq /usr/bin ์‹คํ–‰์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•œ๋‹ค. Json String ์ด ์•„๋ž˜์™€ ๊ฐ™์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„๋•Œ { "name": "Google", "location": { "street": "1600 Amphitheatre Parkway", "city": "Mountain View", "state": "California", "country": "US" }, "employees": [ { "name": "Michael", "division": "Engineering" }, { "name": "Laura", "division": "HR" }, { "name": "Elise", "division": "Marketing" } ] } ์‹ค์ œ ์‚ฌ์šฉ๊ณผ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด๋ฃจ์–ด ์ง„๋‹ค. $ cat json.txt | jq '.name' "Google" $ cat json.txt | jq '.location.city' "Mountain View" $ cat json.txt | jq '.employees[0].name' "Michael" $ cat json.txt | jq '.location | {street, city}' { "city": "Mountain View", "street": "1600 Amphitheatre Parkway" } ๋ณด๋‹ค ์ž์„ธํ•œ ์‚ฌ์šฉ๋ฐฉ๋ฒ•์€ ๊ณต์‹ํ™ˆํŽ˜์ด์ง€( https://stedolan.github.io/jq/ )๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ์ข‹์„๋“ฏ ํ•˜๋‹ค.

eclipse์—์„œ spring-boot๋กœ web ๋งŒ๋“ค๊ธฐ

Spring ํ™˜๊ฒฝ์—์„œ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋ฉด pom.xml ์— ์ด๋Ÿฐ์ €๋Ÿฐ ์„ค์ •๋“ค์„ ์ ์–ด์ค˜์•ผ ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ์ˆ˜๊ณ (?)๋ฅผ ๋œ์–ด์ค„์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ค‘์— ํ•œ๊ฐ€์ง€๊ฐ€ ๋ฐ”๋กœ Spring Boot๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์ธ๋ฐ, ์ดํด๋ฆฝ์Šค ํ™˜๊ฒฝ์—์„œ ๋งŒ๋“œ๋Š” ๋ฒ•์„ ์ •๋ฆฌํ•˜๊ณ ์ž ํ•œ๋‹ค. new > Maven Project ๋นˆ Maven Project ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ ์•„์ฃผ ๊ฐ„๋‹จํ•˜๋‹ˆ ์ƒ๋žตํ•˜๊ณ … ๋งŒ๋“ค๊ฒŒ ๋˜๋ฉด pom.xml ์€ ์•„๋ž˜์ฒ˜๋Ÿผ ์•„์ฃผ ๊น”๋”ํ•œ(?)์ƒํƒœ๋กœ ๋งŒ๋“ค์–ด์ง€๊ฒŒ ๋œ๋‹ค. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>boot</artifactId> <version>0.0.1-SNAPSHOT</version> </project> ๊ทธ๋Ÿฌ๋ฉด ์ด ๋น„์–ด์žˆ๋Š” pom.xml ์— Spring-Boot ์— ํ•„์š”ํ•œ ์„ค์ •๋“ค์„ ์ถ”๊ฐ€ํ•ด์ฃผ๊ธฐ๋กœ ํ•œ๋‹ค. <parent> <!--boot์˜ ์Šคํƒ€ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๊ณ  ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •--> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> <relativePath /> </parent> <dependencies> <dependency> <!--boot์—์„œ ์Šคํƒ€ํ„ฐํŒจํ‚ค์ง€๋กœ ์ œ๊ณตํ•ด์ฃผ๋Š” ๊ฒƒ๋“ค์ค‘์— web ์„ค์ • ๋ถ€๋ถ„ --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> ๊ทธ๋‹ค์Œ ์ž„์˜์˜ java ํด๋ž˜์Šค๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ  ๊ฑฐ๊ธฐ์— ์•„๋ž˜์ฒ˜๋Ÿผ ์„ค์ •ํ•˜๋ฉด ๋ @SpringBootApplication // @Configuration + @EnableAutoConfiguration + @ComponentScan ๋“ค์˜ ์ข…ํ•ฉ ์–ด๋…ธํ…Œ์ด์…˜ public class TestApplication{ public static void main(String[] args) throws Exception { SpringApplication.run(TestApplication.class, args); } } Spring Boot ์—์„œ๋Š” ๋‚ด์žฅWAS๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— main ๋ฉ”์†Œ๋“œ์—์„œ ์šฐํด๋ฆญํ›„ run AS โ†’ Spring Boot App ์„ ์„ ํƒํ•ด์ฃผ๋ฉด 8080ํฌํŠธ๋กœ ๋„์›Œ์ง€๊ฒŒ ๋œ๋‹ค. new > Spring Starter project (STS๊ฐ€ ์„ค์น˜๋˜์–ด์žˆ๋‹ค๋Š” ๊ฐ€์ •ํ•˜์—)์ด ๋ฉ”๋‰ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์œ„์—์„œ ํ–ˆ๋˜ ์ผ๋ จ์˜ ์„ค์ •๋“ค์„ ์ž๋™์œผ๋กœ ํ•ด์ฃผ๊ฒŒ ๋œ๋‹ค. ๊ฐ„๋‹จํ•œ ๋‚ด์šฉ์ด๋‹ˆ next๋ฅผ ํ•ด์ฃผ๋‹ค ๋งˆ์ง€๋ง‰์— Dependencies ์„ค์ •ํ•˜๋Š” ๋ถ€๋ถ„์—์„œ Web ์„ ์ฒดํฌํ•ด์ฃผ๊ณ  Finish ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋ Spring Initializr (start.spring.io) http://start.spring.io/ ์— ๋“ค์–ด๊ฐ€๋ณด๋ฉด ๊ตฌ์ง€ ์„ค๋ช…ํ•˜์ง€ ์•Š์•„๋„ ์นœ์ ˆํ•˜๊ฒŒ Generate ํ•ด์ฃผ๋Š” ํŽ˜์ด์ง€๊ฐ€ ๋ณด์ธ๋‹ค. ์—ฌ๊ธฐ์„œ web ์„ Dependencies์— ์ถ”๊ฐ€ํ•˜๊ณ  Generate๋ฅผ ํ•˜๋ฉด ํ•ด๋‹น ํ”„๋กœ์ ํŠธ๊ฐ€ ์••์ถ•๋œ ์ƒํƒœ๋กœ ๋‹ค์šด์ด ๋ฐ›์•„์ง€๊ฒŒ ๋˜๊ณ  ์ด๋ฅผ IDE ์—์„œ ์—ด์–ด๋ณด๋ฉด ์œ„์—์„œ ํ–ˆ๋˜ ์ผ๋ จ์˜ ๊ณผ์ •๋“ค์ด ์„ค์ •๋˜์–ด ์žˆ๋Š”๊ฒƒ์„ ํ™•์ธํ•ด๋ณผ์ˆ˜๊ฐ€ ์žˆ๋‹ค. ๋‚ด์žฅํ†ฐ์ผ“์„ ์‚ฌ์šฉ์•ˆํ•˜๊ณ  ๋ณ„๋„ ํ†ฐ์ผ“์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ Spring boot๋Š” ์ž์ฒด์ ์œผ๋กœ ๋‚ด์žฅ WAS๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ด€๋ฆฌํฌ์ธํŠธ๋‚˜ ์ด๋Ÿฐ์ €๋Ÿฐ ์ด์œ ๋กœ ๋‚ด์žฅํ†ฐ์ผ“์„ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋Š” ํ™˜๊ฒฝ์ด๋ผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์„ค์ •์„ ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋นŒ๋“œ๊ฐ€ ๋˜๋ฉด jar๋กœ ๋งŒ๋“ค์–ด ์งˆํ…๋ฐ war๋กœ ๋นŒ๋“œ ๋˜๋„๋ก ์ˆ˜์ •์„ ํ•ด์•ผํ•œ๋‹ค. (was๊ฐ€ WAR๋ฅผ ๋ฌผ๊ณ  ๋– ์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ..) <packaging>war</packaging> dependency ์— tomcat์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค. <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> ์•„๋ž˜์ฒ˜๋Ÿผ main ๋ฉ”์†Œ๋“œ๊ฐ€ ์žˆ๋Š” ํด๋ž˜์Šค์— SpringBootServletInitializer๋ฅผ ์ƒ์†๋ฐ›๊ฒŒ ํ•œ ํ›„ configure๋ฉ”์†Œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•ด์ค€๋‹ค. @SpringBootApplication public class TestApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(TestApplication.class); } public static void main(String[] args) throws Exception { SpringApplication.run(TestApplication.class, args); } } ํ†ฐ์ผ“์— ๋„์šฐ๊ธฐ ์œ„ํ•˜์—ฌ ํ”„๋กœ์ ํŠธ ์„ค์ •(Project Facets)์—์„œ Dynamic Web Module์„ ์ฒดํฌํ•ด์ค€๋‹ค. ์ฐธ๊ณ  URL http://www.donnert.net/86 http://opennote46.tistory.com/124

lombok(๋กฌ๋ณต)์†Œ๊ฐœ ๋ฐ ์„ค์น˜

์ผ๋ฐ˜์ ์œผ๋กœ ์ž๋ฐ”๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด Model ์„ ๋งŒ๋“ค๊ณ  ๊ฐ ๋ฉค๋ฒ„๋ณ€์ˆ˜๋ฅผ ์ ‘๊ทผํ• ์ˆ˜ ์žˆ๋Š” (๊ฐ ์š”์†Œ๋“ค์ด private ์ ‘๊ทผ๊ถŒํ•œ์„ ๊ฐ€์ง€๊ณ  ์žˆ์„๋•Œ) method ๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋œ๋‹ค. IDE์—์„œ ์ œ๊ณตํ•˜๋Š” ์•„๋ž˜์ฒ˜๋Ÿผ… (์œˆ๋„์šฐ/์ดํด๋ฆฝ์Šค ๊ธฐ์ค€) get/set ๋ฉ”์†Œ๋“œ : Alt + Shift + S + R toString ๋ฉ”์†Œ๋“œ : Alt + Shift + S + S ๊ธฐํƒ€ ๋“ฑ๋“ฑ… public class Student { private int id; private String name; private int grade; private String department; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getGrade() { return grade; } public void setGrade(int grade) { this.grade = grade; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", grade=" + grade + ", department=" + department + "]"; } } ์ด๋ ‡๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์ง€๋งŒ ์–ด๋…ธํ…Œ์ด์…˜ ์„ค์ •์œผ๋กœ ์ ์šฉํ• ์ˆ˜ ์žˆ๋Š” ๊ฐ„๋‹จํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์†Œ๊ฐœํ•˜๊ณ ์ž ํ•œ๋‹ค. ๋ฐ”๋กœ lombok, ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€ : https://projectlombok.org ์„ค์น˜ ๋ฐ ์‚ฌ์šฉ๋ฐฉ๋ฒ•์€ ์•„์ฃผ ๊ฐ„๋‹จํ•˜๋‹ค. ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์—์„œ jar๋ฅผ ๋‹ค์šด๋ฐ›๊ณ  ์‹คํ–‰, ์•„๋ž˜์ฒ˜๋Ÿผ ์ดํด๋ฆฝ์Šค ์‹คํ–‰ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์„ค์ •ํ•ด์ค€๋‹ค์Œ์— ์ธ์Šคํ†จ์„ ๋ˆ„๋ฅด๋ฉด ๋œ๋‹ค. maven ํ™˜๊ฒฝ์—์„œ dependency๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹น์—ฐํžˆ ์ถ”๊ฐ€์„ค์ •์„ ํ•ด์ค˜์•ผ ํ•œ๋‹ค. <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version> <!--๋ฒ„์ „์€ ๊ทธ๋•Œ ๋งž์ถฐ์„œ--> </dependency> ์‹ค์ œ๋กœ ์ฝ”๋“œ์ƒ์—์„œ ์‚ฌ์šฉ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. ์ •๋ง ๊ฐ„๋‹จํžˆ, ์–ด๋…ธํ…Œ์ด์…˜๋งŒ ์ ์šฉํ•ด์ฃผ๋ฉด ๋! import lombok.Data; @Data public class Student { private int id; private String name; private int grade; private String department; } ๊ทธ๋Ÿผ ์ด๋ ‡๊ฒŒ ๊ธฐ๋ณธ์ ์ธ method๋“ค์ด ์ƒ์„ฑ๋œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ @Data๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ƒํ™ฉ์— ๋”ฐ๋ผ ํ•„์š”ํ•œ ์–ด๋…ธํ…Œ์ด์…˜๋งŒ ์ง€์ •๋„ ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ํ•œ๋‹ค. @Getter and @Setter @NonNull @ToString @EqualsAndHashCode @Data @Cleanup @Synchronized @SneakyThrows ์ฐธ๊ณ  URL : http://jnb.ociweb.com/jnb/jnbJan2010.html

logback ์„ค์ •ํ•˜๊ธฐ

์ž๋ฐ” ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ํ•œ๋ฒˆ์ฏค์€ ๋“ค์–ด๋ดค๊ณ , ํ•œ๋ฒˆ์ฏค์€ ์‚ฌ์šฉํ–ˆ์„๋ฒ•ํ•œ logger ๋กœ log4j๊ฐ€ ์žˆ์„๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ตœ๊ทผ๋“ค์–ด logback์ด๋ผ๋Š”๊ฒƒ์„ ์•Œ๊ฒŒ๋˜์—ˆ๊ณ , ์™œ logback์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๋ผ๋Š” ๊ธ€์ด ์žˆ์„์ •๋„๋กœ ์—ฌ๋Ÿฌ ์ธก๋ฉด์—์„œ ๊ฐœ์„ ์ด ๋œ๋“ฏ ํ•˜๋‹ค. (๋งํฌ) ์ด๋ฒˆ์— ์ž‘์„ฑํ•  ๊ธ€์˜ ๋ชฉ์ ์€ logback์„ ์„ค์ •ํ•˜๊ณ  ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ์ž‘์„ฑํ•ด ๋ณด๊ณ ์ž ํ•œ๋‹ค. โ€ป ๊ณต์‹์‚ฌ์ดํŠธ : https://logback.qos.ch/ pom.xml maven๊ตฌ์กฐ๋ผ๊ณ  ๊ฐ€์ •ํ–ˆ์„๋•Œ logback Dependency๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด pom.xml ์— ์„ค์ •ํ•ด ์ฃผ๋ฉด ๋œ๋‹ค. <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.7</version> <!--๋ฒ„์ „์€ ์ƒํ™ฉ์— ๋”ฐ๋ผ --> </dependency> ๋กœ๊ทธ๋ ˆ๋ฒจ ERROR, WARN, INFO, DEBUG or TRACE # logback ์„ค์ •ํŒŒ์ผ ์ผ๋ฐ˜์ ์œผ๋กœ logback.xml ์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋งŒ๋“ค์–ด src/main/resources/์•„๋ž˜์— ์œ„์น˜ํ•˜๊ฒŒ ๋œ๋‹ค. Spring-Boot ํ™˜๊ฒฝ์—์„œ๋Š” logback-spring.xml ์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์„ค์ •ํ•ด์•ผ ํ•˜๋Š”๋ฐ logback.xml๋กœ ์„ค์ •ํ•˜๋ฉด ์Šคํ”„๋ง๋ถ€ํŠธ๊ฐ€ ์„ค์ •ํ•˜๊ธฐ ์ „์— ๋กœ๊ทธ๋ฐฑ ๊ด€๋ จํ•œ ์„ค์ •์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ œ์–ดํ•  ์ˆ˜๊ฐ€ ์—†๊ฒŒ ๋œ๋‹ค. ( ๊ณต์‹์‚ฌ์ดํŠธ ๋ฉ”๋‰ด์–ผ : https://logback.qos.ch/documentation.html ) <?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/defaults.xml" /> <include resource="org/springframework/boot/logging/logback/console-appender.xml" /> <!-- ๋ณ€์ˆ˜ ์ง€์ • --> <property name="LOG_DIR" value="/logs" /> <property name="LOG_PATH_NAME" value="${LOG_DIR}/data.log" /> <!-- FILE Appender --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH_NAME}</file> <!-- ์ผ์ž๋ณ„๋กœ ๋กœ๊ทธํŒŒ์ผ ์ ์šฉํ•˜๊ธฐ --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH_NAME}.%d{yyyyMMdd}</fileNamePattern> <maxHistory>60</maxHistory> <!-- ์ผ์ž๋ณ„ ๋ฐฑ์—…ํŒŒ์ผ์˜ ๋ณด๊ด€๊ธฐ๊ฐ„ --> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5p] [%F]%M\(%L\) : %m%n</pattern> </encoder> </appender> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5p] [%F]%M\(%L\) : %m%n</pattern> </layout> </appender> <!-- TRACE > DEBUG > INFO > WARN > ERROR, ๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ถ„ ์•ˆํ•จ --> <!-- profile ์„ ์ฝ์–ด์„œ appender ์„ ์„ค์ •ํ• ์ˆ˜ ์žˆ๋‹ค.(phase๋ณ„ ํŒŒ์ผ์„ ์•ˆ๋งŒ๋“ค์–ด๋„ ๋˜๋Š” ์ข‹์€ ๊ธฐ๋Šฅ) --> <springProfile name="local"> <root level="DEBUG"> <appender-ref ref="FILE" /> <appender-ref ref="STDOUT" /> </root> </springProfile> <springProfile name="real"> <root level="INFO"> <appender-ref ref="FILE" /> <appender-ref ref="STDOUT" /> </root> </springProfile> </configuration> java ์ฝ”๋”ฉ์—์„œ์˜ ๋กœ๊น… ์‹ค์ œ ์‚ฌ์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด LoggerFactory๋ฅผ ์ด์šฉํ•ด์„œ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ Lombok์–ด๋…ธํ…Œ์ด์…˜์„ ํ™œ์šฉํ•˜๋ฉด ์‹ฌํ”Œํ•˜๊ฒŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. LoggerFactory ์‚ฌ์šฉ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Foo { static final Logger logger = LoggerFactory.getLogger(Foo.class); public void test() { logger.debug("ID : {}", "foo"); } } Lombok ์–ด๋…ธํ…Œ์ด์…˜ ์‚ฌ์šฉ import lombok.extern.slf4j.Slf4j; @Slf4j public class Foo { public void test() { log.debug("ID : {}", "foo"); } } ๋งˆ์น˜๋ฉฐ ์ผ๋ฐ˜์ ์ธ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” WAS์—์„œ ๋กœ๊น…์„ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— file ๋กœ ๋กœ๊น…์„ ํ•  ํ•„์š”๋Š” ์—†์„๊ฒƒ ๊ฐ™๋‹ค.(์ผ๋ฐ˜ jar ํ˜•ํƒœ์—์„œ๋Š” ํŒŒ์ผ ๋กœ๊น…์ด ํ•„์š” ํ• ์ˆ˜๋„…) ์ฐธ๊ณ ์‚ฌ์ดํŠธ http://yookeun.github.io/java/2015/11/10/log4jtologback/ http://java.ihoney.pe.kr/397 https://logback.qos.ch/