Spring๐ŸŒธ

Spring MVC - JDBC ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ณ„์ธต

Jeein0313 2023. 4. 18. 23:43

๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ณ„์ธต์€ ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ํ†ตํ•ด ์ฒ˜๋ฆฌ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๊ณ , ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋Š” ๋“ฑ์˜ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

๐Ÿ’กJDBC(Java Database Connectivity)๋ž€?

Java ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ฝ”๋“œ ๋ ˆ๋ฒจ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ ๋ฐ ์—…๋ฐ์ดํŠธ ํ•˜๊ฑฐ๋‚˜ ๋ฐ˜๋Œ€๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ Java ์ฝ”๋“œ ๋ ˆ๋ฒจ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” Java์—์„œ ์ œ๊ณตํ•˜๋Š” ํ‘œ์ค€ ์‚ฌ์–‘.

Java ํ”„๋กœ๊ทธ๋žจ์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ํ‘œ์ค€ Java API.

 

Spring์—์„œ๋Š” JDBC API๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ๋ณด๋‹ค๋Š” Spring Data JDBC๋‚˜ Spring Data JPA๊ฐ™์€ ๊ธฐ์ˆ ์„ ์ œ๊ณตํ•จ์œผ๋กœ์จ ๊ฐœ๋ฐœ์ž๋“ค์ด ์กฐ๊ธˆ ๋” ํŽธ๋ฆฌํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๋กœ์ง์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. (Spring Data JDBC๋‚˜ Spring Data JPA ๊ฐ™์€ ๊ธฐ์ˆ  ์—ญ์‹œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์—ฐ๋™ํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด๋ถ€์ ์œผ๋กœ JDBC๋ฅผ ์ด์šฉํ•จ.)

 

๐Ÿ’กJDBC ๋™์ž‘ ํ๋ฆ„

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

Java ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ JDBC API๋ฅผ ์ด์šฉํ•ด ์ ์ ˆํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๋กœ๋”ฉํ•œ ํ›„, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์ธํ„ฐ๋ž™์…˜ํ•œ๋‹ค.

์ด์ฒ˜๋Ÿผ, JDBC API๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๊ตฌ์ฒด์ ์ธ ์ธํ„ฐ๋ ‰์…˜์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” JDBC ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๋จผ์ € ๋กœ๋”ฉํ•œ ํ›„์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—ฐ๊ฒฐํ•ด์•ผ ํ•œ๋‹ค.

 

 

๐Ÿ’กJDBC ๋“œ๋ผ์ด๋ฒ„

 

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ํ†ต์‹ ์„ ๋‹ด๋‹นํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค. Oracle, MySQL, My SQL ๊ฐ™์€ ๋‹ค์–‘ํ•œ ๋ฒค๋”์—์„œ๋Š” ํ•ด๋‹น ๋ฒค๋”์— ๋งž๋Š” JDBC ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๊ตฌํ˜„ํ•ด์„œ ์ œ๊ณตํ•˜๊ฒŒ ๋˜๊ณ , ์ด JDBC ๋“œ๋ผ์ด๋ฒ„์˜ ๊ตฌํ˜„์ฒด๋ฅผ ์ด์šฉํ•ด์„œ ํŠน์ • ๋ฒค๋”์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Œ.

 

 

JDBC API ์‚ฌ์šฉ ํ๋ฆ„

 

1) JDBC ๋“œ๋ผ์ด๋ฒ„ ๋กœ๋”ฉ : JDBC ๋“œ๋ผ์ด๋ฒ„๋Š” DriveManager๋ผ๋Š” ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ๋กœ๋”ฉ๋จ.

2) Connection ๊ฐ์ฒด ์ƒ์„ฑ : DriverManager๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์—ฐ๊ฒฐ๋œ๋А ์„ธ์…˜(Session)์ธ Connection ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•จ.

3) Statement ๊ฐ์ฒด ์ƒ์„ฑ : Statement ๊ฐ์ฒด๋Š” ์ž‘์„ฑ๋œ SQL ์ฟผ๋ฆฌ๋ฌธ์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ ํ›„์— ์ •์ ์ธ SQL ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด์„ ์ž…๋ ฅ์œผ๋กœ ๊ฐ€์ง.

4) Query ์ƒ์„ฑ : ์ƒ์„ฑ๋œ Statement ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ ์ž…๋ ฅํ•œ SQL ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•จ.

5) ResultSet ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ ์กฐํšŒ : ์‹คํ–‰๋œ SQL ์ฟผ๋ฆฌ๋ฌธ์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ ๋ฐ์ดํ„ฐ ์…‹.

6) ResultSet ๊ฐ์ฒด Close : JDBC API๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ๋œ ๊ฐ์ฒด๋“ค์€ ์‚ฌ์šฉ ์ดํ›„์— ์‚ฌ์šฉํ•œ ์ˆœ์„œ์˜ ์—ญ์ˆœ์œผ๋กœ ์ฐจ๋ก€๋กœ Close๋ฅผ ํ•ด์ฃผ์–ด์•ผ ํ•จ.

7) Statement ๊ฐ์ฒด Close

8) Connection ๊ฐ์ฒด Close

 

 

Connection Pool์ด๋ž€?

JDBC API๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ์—ฐ๊ฒฐ์„ ์œ„ํ•œ Connection ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ž‘์—…์€ ๋น„์šฉ์ด ๋งŽ์€ ๋“œ๋Š” ์ž‘์—… ์ค‘ ํ•˜๋‚˜.

๋”ฐ๋ผ์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๋”ฉ ์‹œ์ ์— Connection ๊ฐ์ฒด๋ฅผ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด๋‘๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—ฐ๊ฒฐ์ด ํ•„์š”ํ•  ๊ฒฝ์šฐ, Connection ๊ฐ์ฒด๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด ๋‘” Connection ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค Connection์„ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด์„œ ๋ณด๊ด€ํ•˜๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํ•„์š”ํ•  ๋•Œ ์ด Connection์„ ์ œ๊ณตํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•˜๋Š” Connection ๊ด€๋ฆฌ์ž๋ฅผ ๋ฐ”๋กœ Connection Pool์ด๋ผ๊ณ  ํ•œ๋‹ค.

 

Spring Boot 2.0 ์ด์ „์—๋Š” Apache ์žฌ๋‹จ์˜ ์˜คํ”ˆ ์†Œ์Šค์ธ Apache Commons DBCP(Database Connection Pool)๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉํ–ˆ์œผ๋‚˜ Spring Boot 2.0๋ถ€ํ„ฐ๋Š” ์„ฑ๋Šฅ๋ฉด์—์„œ ๋” ๋‚˜์€ ์ด์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” HikariCP๋ฅผ ๊ธฐ๋ณธ DBCP๋กœ ์ฑ„ํƒํ•จ.

 

 

๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ธฐ์ˆ   ์œ ํ˜•์œผ๋กœ, Spring์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋Œ€ํ‘œ์ ์ธ ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ธฐ์ˆ ์—๋Š” mybatis, Spring JDBC, Spring Data JDBC, JPA, Spring Data JPA ๋“ฑ์ด ์žˆ๋‹ค.

 

SQL ์ค‘์‹ฌ ๊ธฐ์ˆ ๋กœ๋Š” iBatis, mybatis, Spring JDBC๊ฐ€ ์žˆ๋‹ค. SQL ์ค‘์‹ฌ ๊ธฐ์ˆ ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด SQL ์ฟผ๋ฆฌ๋ฌธ์„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด๋ถ€์—์„œ ์ง์ ‘์ ์œผ๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ค‘์‹ฌ์ด ๋˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค.

 

๋‹ค์Œ์€ mybatis์—์„œ ์‚ฌ์šฉ๋˜๋Š” SQL Mapper์˜ ์˜ˆ์ด๋‹ค.

<select id="findMember" resultType="Member">
  SELECT * FROM MEMBER WHERE member_id = #{memberId}
</select>

mybatis์˜ ๊ฒฝ์šฐ, SQL Mapper๋ผ๋Š” ์„ค์ • ํŒŒ์ผ์ด ์กด์žฌํ•˜๋Š”๋ฐ, ์ด SQL Mapper์—์„œ SQL ์ฟผ๋ฆฌ๋ฌธ์„ ์ง์ ‘์ ์œผ๋กœ ์ž‘์„ฑํ•œ๋‹ค.

์ž‘์„ฑ๋œ SQL ์ฟผ๋ฆฌ๋ฌธ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํŠน์ • ํ…Œ์ด๋ธ”์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•œ ํ›„, Java ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ๊ฒƒ์ด mybatis์˜ ๋Œ€ํ‘œ์ ์ธ ๊ธฐ์ˆ ์  ํŠน์ง•์ด๋‹ค.

์ฝ”๋“œ์—์„œ ๋ณด๋‹ค์‹œํ”ผ SQL ๋ฌธ์ด ์ง์ ‘์ ์œผ๋กœ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.

 

๋‹ค์Œ์€ Spring JDBC์˜ JdbcTemplate์ด๋ผ๋Š” ํ…œํ”Œ๋ฆฟ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ์˜ ์˜ˆ์ด๋‹ค.

Member member = this.jdbcTemplate.queryForObject(
"select * from member where member_id=?", 1, Member.class);

Spring JDBC์˜ ๊ฒฝ์šฐ, Java ์ฝ”๋“œ์— SQL ์ฟผ๋ฆฌ๋ฌธ์ด ์ง์ ‘์ ์œผ๋กœ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.

์ด์ฒ˜๋Ÿผ, SQL ์ฟผ๋ฆฌ๋ฌธ์ด ์ง์ ‘์ ์œผ๋กœ ํ‘œํ•จ๋˜๋Š” ๋ฐฉ์‹์€ ๊ณผ๊ฑฐ๋ถ€ํ„ฐ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋˜ ๋ฐฉ์‹์œผ๋กœ, ํ˜„์žฌ๋„ ์‚ฌ์šฉ์ด ๋˜๊ณ  ์žˆ์œผ๋‚˜ Java ์ง„์˜์—์„œ๋Š” SQL ์ค‘์‹ฌ์˜ ๊ธฐ์ˆ ์—์„œ ๊ฐ์ฒด(Object) ์ค‘์‹ฌ์˜ ๊ธฐ์ˆ ๋กœ ์ง€์†์ ์œผ๋กœ ์ด์ „์„ ํ•˜๊ณ  ์žˆ๋Š” ์ถ”์„ธ์ด๋‹ค.

 

๊ฐ์ฒด(Object) ์ค‘์‹ฌ ๊ธฐ์ˆ ์€ Spring Data JDBC, JPA, Spring Data JPA๊ฐ€ ์žˆ๋‹ค.

๊ฐ์ฒด ์ค‘์‹ฌ ๊ธฐ์ˆ ์€ SQL ์ฟผ๋ฆฌ๋ฌธ ์œ„์ฃผ๋กœ ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ์ฒด ๊ด€์ ์œผ๋กœ ๋ฐ”๋ผ๋ณด๋Š” ๊ธฐ์ˆ ์ด๋‹ค.

์ฆ‰, ๊ฐ์ฒด ์ค‘์‹ฌ ๊ธฐ์ˆ ์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ SQL ์ฟผ๋ฆฌ๋ฌธ์„ ์ง์ ‘์ ์œผ๋กœ ์ž‘์„ฑํ•˜๊ธฐ๋ณด๋‹ค๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํ…Œ์ด๋ธ”์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ์กฐํšŒํ•  ๊ฒฝ์šฐ, Java ๊ฐ์ฒด(Object)๋ฅผ ์ด์šฉํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด๋ถ€์—์„œ ์ด Java ๊ฐ์ฒด๋ฅผ SQL ์ฟผ๋ฆฌ๋ฌธ์œผ๋กœ ์ž๋™ ๋ณ€ํ™˜ํ•œ ํ›„์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํ…Œ์ด๋ธ”์— ์ ‘๊ทผํ•œ๋‹ค.

 

์ด๋Ÿฌํ•œ ๊ฐ์ฒด(Object) ์ค‘์‹ฌ์˜ ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ธฐ์ˆ ์„ ORM(Object-Relational Mapping)์ด๋ผ๊ณ  ํ•œ๋‹ค.

 

Java์—์„œ ๋Œ€ํ‘œ์ ์ธ ORM ๊ธฐ์ˆ ์ด JPA(Java Persistence API).

JPA๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด SQL ์ฟผ๋ฆฌ๋ฌธ์„ ์ง์ ‘์ ์œผ๋กœ ๋‹ค๋ฃฐ ์ผ์€ ๋งŽ์ง€ ์•Š๋‹ค.

๋ฌผ๋ก , ๋ณต์žกํ•œ ์กฐ๊ฑด์˜ ๋ฐ์ดํ„ฐ ์กฐํšŒ๋ฅผ ์œ„ํ•ด SQL ์ฟผ๋ฆฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•˜์ง€๋งŒ, ๊ทธ ์‚ฌ์šฉ ๋นˆ๋„์ˆ˜๊ฐ€ ์ด ์ „๋ณด๋‹ค ๊ธ‰๊ฒฉํžˆ ์ค„์—ˆ๋‹ค.

 

 

Spring Data JDBC๋ž€?

 

Spring Data JDBC๋Š” JPA์ฒ˜๋Ÿผ ORM ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ, JPA์˜ ๊ธฐ์ˆ ์  ๋ณต์žก๋„๋ฅผ ๋‚ฎ์ถ˜ ๊ธฐ์ˆ ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๋Œ€์ ์œผ๋กœ ์‰ฝ๋‹ค.

 

๋”๋ณด๊ธฐ

Spring Data JDBC ์™€ Spring Data JPA

์šฐ์„ , Spring Data JDBC ๊ธฐ์ˆ ์€ 2018๋…„์— 1.0๋ฒ„์ „์ด ์ฒ˜์Œ ๋ฆด๋ฆฌ์ฆˆ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์ˆ ์˜ ์—ญ์‚ฌ๊ฐ€ ์•„์ง ์งง์€ ํŽธ.

๋”ฐ๋ผ์„œ ํ˜„์žฌ๋„ ๊ธฐ๋Šฅ ์—…๊ทธ๋ ˆ์ด๋“œ๊ฐ€ ๊พธ์ค€ํžˆ ์ด๋ฃจ์–ด์ง€๊ณ  ์žˆ์ง€๋งŒ, ์•„์ง๊นŒ์ง€๋Š” JPA๋ณด๋‹ค ์ƒ๋Œ€์ ์œผ๋กœ ์ ๊ฒŒ ์‚ฌ์šฉ๋œ๋‹ค.

 

ํ•˜์ง€๋งŒ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ทœ๋ชจ๊ฐ€ ์ƒ๋Œ€์ ์œผ๋กœ ํฌ์ง€ ์•Š๊ณ , ๋ณต์žกํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ์—๋Š” Spring Data JDBC๊ฐ€ ๋›ฐ์–ด๋‚œ ์ƒ์‚ฐ์„ฑ์„ ๋ณด์—ฌ์ค€๋‹ค.

๊ทธ๋ฆฌ๊ณ  Spring Data JDBC๋ฅผ ํ†ตํ•ด ๊ธฐ๋ณธ์ ์€ ORM ๊ฐœ๋…๊ณผ Spring์—์„œ Data์— ์ ‘๊ทผํ•˜๋Š” ์ผ๊ด€๋œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋จผ์ € ์ ‘ํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ, JPA์™€ Spring Data JPA๋ฅผ ์ดํ•ดํ•˜๋Š”๋ฐ ๊ฝค ๋งŽ์€ ๋„์›€์ด ๋œ๋‹ค.

 

JPA๋Š” ์‹ค๋ฌด์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ์ˆ ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋‹น์—ฐํžˆ ์•Œ์•„์•ผ ํ•œ๋‹ค.

Spring Data JPA๋Š” Spring์—์„œ JPA๊ธฐ์ˆ ์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ์ˆ ์ด๊ธฐ ๋•Œ๋ฌธ์— JPA์— ๋Œ€ํ•œ ์„ ํ–‰ ์ง€์‹์ด ์žˆ์–ด์•ผ ์ œ๋Œ€๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

Spring Data JDBC๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Spring Boot Starter๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

dependencies {
	...
	...
	implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
	runtimeOnly 'com.h2database:h2'
}

 

Hello World ์ƒ˜ํ”Œ ์ฝ”๋“œ ๊ตฌํ˜„

 

ํด๋ผ์ด์–ธํŠธ ์ชฝ์—์„œ "Hello, World" ๋ฌธ์ž์—ด ๋ฐ์ดํ„ฐ๋ฅผ Request Body๋กœ ์ „์†กํ•œ ํ›„์— Spring Data JDBC๋ฅผ ์ด์šฉํ•ด์„œ "Hello, World" ๋ฌธ์ž์—ด์„ H2 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•ด ๋ณด๋„๋ก ํ•˜์ž.

 

์„œ๋น„์Šค ๊ณ„์ธต์˜ MessageService ํด๋ž˜์Šค์™€ ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ณ„์ธต์˜ MessageRepository ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์–ด๋–ป๊ฒŒ ์—ฐ๋™ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ด๋‹ค.

 

ํด๋ผ์ด์–ธํŠธ๊ฐ€ Request Body๋ฅผ ์ „๋‹ฌํ•˜๋Š” 'Hello, World' ๋ฌธ์ž์—ด์„ ๋ฐ”์ธ๋”ฉํ•˜๋Š” DTO ํด๋ž˜์Šค

@Getter
public class MessagePostDto {
    @NotBlank
    private String message;
}

 

Response์— ์‚ฌ์šฉํ•  DTO ํด๋ž˜์Šค

package com.codestates.hello_world;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class MessageResponseDto {
    private long messageId;
    private String message;
}

 

Controller ํด๋ž˜์Šค

package com.codestates.hello_world;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

@RequestMapping("/v1/messages")
@RestController
public class MessageController {
    private final MessageService messageService;
    private final MessageMapper mapper;

    public MessageController(MessageService messageService, MessageMapper mapper) {
        this.messageService = messageService;
        this.mapper = mapper;
    }

    @PostMapping
    public ResponseEntity postMessage(@Valid @RequestBody MessagePostDto messagePostDto){
        Message message = messageService.createMessage(mapper.messageDtoToMessage(messagePostDto));
        return ResponseEntity.ok(mapper.messageToMessageResponseDto(message));
    }
}

 

DTOํด๋ž˜์Šค์™€ ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค๋ฅผ ๋งคํ•‘ํ•ด์ฃผ๋Š” Mapper ์ธํ„ฐํŽ˜์ด์Šค

package com.codestates.hello_world;

import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface MessageMapper {
    Message messageDtoToMessage(MessagePostDto messagePostDto);
    MessageResponseDto messageToMessageResponseDto(Message message);
}

 

๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ณ„์ธต์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ์—ฐ๋™์„ ๋‹ด๋‹นํ•˜๋Š” Repository์ธ MessageRepository ์ธํ„ฐํŽ˜์ด์Šค

package com.codestates.hello_world; 

import org.springframework.data.repository.CrudRepository;

public interface MessageRepository extends CrudRepository<Message,Long> {

}

 

MessageService

package com.codestates.hello_world;

import org.springframework.stereotype.Service;

@Service
public class MessageService {
		//(1)
    private final MessageRepository messageRepository;

    public MessageService(MessageRepository messageRepository) {
        this.messageRepository = messageRepository;
    }
		
		//(2)
    public Message createMessage(Message message){
        return messageRepository.save(message);
    }
}

 

Message ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค

package com.codestates.hello_world;

import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.Id;


@Getter
@Setter
public class Message { //(1)
    @Id //(2)
    private long messageId;
    private String message;
}

 

H2 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— MESSAGE ํ…Œ์ด๋ธ” ์ƒ์„ฑ

spring:
  h2:
    console:
      enabled: true
      path: /h2     
  datasource:
    url: jdbc:h2:mem:test
  sql:
    init:
      schema-locations: classpath*:db/h2/schema.sql   // (1) ํ…Œ์ด๋ธ” ์ƒ์„ฑ ํŒŒ์ผ ๊ฒฝ๋กœ

 

src/main/resources/db/h2/schema.sql 

CREATE TABLE IF NOT EXISTS MESSAGE (
    message_id bigint NOT NULL AUTO_INCREMENT,
    message varchar(100) NOT NULL,
    PRIMARY KEY (message_id)
);

 

 

 

Spring Data JDBC ์ ์šฉ ์ˆœ์„œ

 

1. build.gradle์— ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์œ„ํ•œ ์˜์กด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

2. application.yml ํŒŒ์ผ์— ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์„ค์ •์„ ํ•œ๋‹ค.

3. schema.sql ํŒŒ์ผ์— ํ•„์š”ํ•œ ํ…Œ์ด๋ธ” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์„ค์ •ํ•œ๋‹ค.

4. application.yml ํŒŒ์ผ์—์„œ schema.sql ํŒŒ์ผ์„ ์ฝ์–ด๋“ค์—ฌ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ์ดˆ๊ธฐํ™” ์„ค์ •์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

5. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘ํ•  ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

6. ์ž‘์„ฑํ•œ ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  Repository ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

7. ์ž‘์„ฑ๋œ Repository ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์„œ๋น„์Šค ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก  DI ํ•œ๋‹ค.

8. DI๋œ Repository ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„œ๋น„์Šค ํด๋ž˜์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— CRUD ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.