JDBC-intro
Categories: Spring
Tags: DB, Spring, ๊ฐ๋ ์ ๋ฆฌ
๐ ๊ฐ์ธ์ ์ธ ๊ณต๊ฐ์ผ๋ก ๊ณต๋ถ๋ฅผ ๊ธฐ๋กํ๊ณ ๋ณต์ตํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๋ธ๋ก๊ทธ์
๋๋ค.
์ ํํ์ง ์์ ์ ๋ณด๊ฐ ์์ ์ ์์ผ๋ ์ฐธ๊ณ ๋ฐ๋๋๋ค :๐ธ
[ํ๋ฆฐ ๋ด์ฉ์ ๋๊ธ๋ก ๋จ๊ฒจ์ฃผ์๋ฉด ๋ณต๋ฐ์ผ์ค๊ฑฐ์์]
JDBC๋?
- JDBC(Java Database Connectivity)
- Java ๊ธฐ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฝ๋ ๋ ๋ฒจ์์ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ ๋ฐ ์ ๋ฐ์ดํธํ๊ฑฐ๋ ๋ฐ๋๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ Java ์ฝ๋ ๋ ๋ฒจ์์ ์ฌ์ฉํ ์ ์๋๋ก ํด์ฃผ๋ Java์์ ์ ๊ณตํ๋ ํ์ค ์ฌ์(๋๋ ๋ช ์ธ, Specification)
- JDBC API๋ฅผ ์ฌ์ฉํด์ ๋ค์ํ ๋ฒค๋(Oracle, MS SQL, MySQL ๋ฑ)์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๋๊ฐ๋ฅ
JDBC ๋์ ํ๋ฆ
๊ฐ๋จํ๊ฒ ๋งํ๋ฉด Java ์ ํ๋ฆฌ์ผ์ด์ ์์ JDBC API๋ฅผ ์ด์ฉํด ์ ์ ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋๋ผ์ด๋ฒ๋ฅผ ๋ก๋ฉํ ํ, Database์ interaction ํ๋ค
- JDBC Driver
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ํต์ ์ ๋ด๋นํ๋ ์ธํฐํ์ด์ค
- Oracle์ด๋ MS SQL, MySQL ๊ฐ์ ๋ค์ํ ๋ฒค๋์์๋ ํด๋น ๋ฒค๋์ ๋ง๋ JDBC ๋๋ผ์ด๋ฒ๋ฅผ ๊ตฌํํด์ ์ ๊ณต์ ํจ,
- ์ฐ๋ฆฌ๋ ์ด JDBC ๋๋ผ์ด๋ฒ์ ๊ตฌํ์ฒด๋ฅผ ์ด์ฉํด์ ํน์ ๋ฒค๋์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ก์ธ์ค ํ ์ ์์
- JDBC API
-
JDBC API ์ฌ์ฉ ํ๋ฆ
์์ ์ DBํ ๋ ๋ง์ง๋ง์ JDBC์์ ๋ฐฐ์ ๋ ๊ฒ.
์์ธํ ์ ํ์๋ ์์ง๋ง ๊ฐ๋จํ ๋ณด๊ณ ๊ฐ๊ธฐ
- JDBC ๋๋ผ์ด๋ฒ ๋ก๋ฉ
- ์ฌ์ฉํ๊ณ ์ ํ๋ JDBC ๋๋ผ์ด๋ฒ๋ฅผ ๋ก๋ฉ
- JDBC ๋๋ผ์ด๋ฒ๋ DriverManager๋ผ๋ ํด๋์ค๋ฅผ ํตํด์ ๋ก๋ฉ๋จ
- Connection ๊ฐ์ฒด ์์ฑ
- JDBC ๋๋ผ์ด๋ฒ๊ฐ ์ ์์ ์ผ๋ก ๋ก๋ฉ๋๋ฉด DriverManager๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐ๋๋ ์ธ์ (Session)์ธ Connection ๊ฐ์ฒด๋ฅผ ์์ฑ
- Statement ๊ฐ์ฒด ์์ฑ
- Statement ๊ฐ์ฒด๋ ์์ฑ๋ SQL ์ฟผ๋ฆฌ๋ฌธ์ ์คํํ๊ธฐ ์ํ ๊ฐ์ฒด๋ก์จ ๊ฐ์ฒด ์์ฑ ํ์ ์ ์ ์ธ SQL ์ฟผ๋ฆฌ ๋ฌธ์์ด์ ์ ๋ ฅ์ผ๋ก ๊ฐ์ง
- Query ์คํ
- ์์ฑ๋ Statement ๊ฐ์ฒด๋ฅผ ์ด์ฉํด์ ์ ๋ ฅํ SQL ์ฟผ๋ฆฌ๋ฅผ ์คํํฉ๋๋ค.
- ResultSet ๊ฐ์ฒด๋ก๋ถํฐ ๋ฐ์ดํฐ ์กฐํ
- ์คํ๋ SQL ์ฟผ๋ฆฌ๋ฌธ์ ๋ํ ๊ฒฐ๊ณผ ๋ฐ์ดํฐ ์ ์ ๋๋ค.
- ResultSet ๊ฐ์ฒด Close, Statement ๊ฐ์ฒด Close, Connection ๊ฐ์ฒด Close
- JDBC API๋ฅผ ํตํด ์ฌ์ฉ๋ ๊ฐ์ฒด๋ค์ ์ฌ์ฉ ์ดํ์ ์ฌ์ฉํ ์์์ ์ญ์์ผ๋ก ์ฐจ๋ก๋ก Close ํด์ผํจ.
-
- Connection Pool
- ๋ฐ์ดํฐ๋ฒ ์ด์ค Connection ๊ฐ์ฒด๋ฅผ ๋ฏธ๋ฆฌ ๋ง๋ค์ด์ ๋ณด๊ดํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ด ํ์ํ ๋ ์ด Connection์ ์ ๊ณตํด ์ฃผ๋ ์ญํ ์ ํ๋ Connection ๊ด๋ฆฌ์
- DB์์ ์ฐ๊ฒฐ์ ์ํด Connection๊ฐ์ฒด ์์ฑํํ๋ ์์ ์ ๋น์ฉ์ด ๋ง์ด ๋๋ ๋ฏธ๋ฆฌ ๋ง๋ค์ด์ ๋ณด๊ดํ๊ณ ํ์ํ ๋ ์ ๊ณตํจ.
- ์๋ Apache Commons DBCP(Database Connection Pool, DBCP)๋ฅผ ์ฃผ๋ก ์ฌ์ฉํ์ง๋ง
-
Spring Boot 2.0๋ถํฐ๋ ์ฑ๋ฅ๋ฉด์์ ๋ ๋์ ์ด์ ์ ๊ฐ์ง๊ณ ์๋ HikariCP๋ฅผ ๊ธฐ๋ณธ DBCP๋ก ์ฑํ
Spring Data JDBC๋?
SQL ์ค์ฌ ๊ธฐ์
- ์์์ ์ธ๊ธํ mybatis์ Spring JDBC๋ ๋ํ์ ์ธ SQL ์ค์ฌ ๊ธฐ์
-
Spring JDBC์ JdbcTemplate ์ฌ์ฉ ์
1 2 3
Member member = this.jdbcTemplate.queryForObject( "select * from member where member_id=?", 1, Member.class);
- Java ์ง์์์๋ SQL ์ค์ฌ์ ๊ธฐ์ ์์ ๊ฐ์ฒด(Object) ์ค์ฌ์ ๊ธฐ์ ๋ก ์ง์์ ์ผ๋ก ์ด์ ์ ํ๊ณ ์๋ ์ถ์ธ
๊ฐ์ฒด(Object) ์ค์ฌ ๊ธฐ์
- ๊ฐ์ฒด(Object) ์ค์ฌ ๊ธฐ์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ๊ธฐ ์ํด์ SQL ์ฟผ๋ฆฌ๋ฌธ์ ์ง์ ์ ์ผ๋ก ์์ฑํ๊ธฐ๋ณด๋ค๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ฑฐ๋ ์กฐํํ ๊ฒฝ์ฐ, Java ๊ฐ์ฒด(Object)๋ฅผ ์ด์ฉํด ์ ํ๋ฆฌ์ผ์ด์ ๋ด๋ถ์์ ์ด Java ๊ฐ์ฒด(Object)๋ฅผ SQL ์ฟผ๋ฆฌ๋ฌธ์ผ๋ก ์๋ ๋ณํ ํ ํ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ์ ์ ๊ทผํจ.
- ๊ฐ์ฒด(Object) ์ค์ฌ์ ๋ฐ์ดํฐ ์ก์ธ์ค ๊ธฐ์ ์ ORM(Object-Relational Mapping)
- Java์์ ๋ํ์ ์ธ ORM ๊ธฐ์ ์ด ๋ฐ๋ก JPA(Java Persistence API)
Spring Data JDBC
Spring Data JDBC๋ JPA์ฒ๋ผ ORM ๊ธฐ์ ์ ์ฌ์ฉํ์ง๋ง JPA์ ๊ธฐ์ ์ ๋ณต์ก๋๋ฅผ ๋ฎ์ถ ๊ธฐ์
-
๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ถ๊ฐ
1 2 3 4 5 6
dependencies { ... ... implementation 'org.springframework.boot:spring-boot-starter-data-jdbc' runtimeOnly 'com.h2database:h2' }
-
์ธ๋ฉ๋ชจ๋ฆฌ(In-memory) DB์ธ H2๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์์กด ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์ ์ ์ถ๊ฐ
์ธ๋ฉ๋ชจ๋ฆฌ DB๋? ๋ฉ๋ชจ๋ฆฌ ์์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค
โ๏ธ ์ธ๋ฉ๋ชจ๋ฆฌ(In-memory) DB๋ฅผ ์ฌ์ฉํ๋ ์ด์
- ๋ก์ปฌ ๊ฐ๋ฐ ํ๊ฒฝ์์๋ ์ธ๋ฉ๋ชจ๋ฆฌ(In-memory) DB๋ฅผ ์ฃผ๋ก ์ฌ์ฉ
- ์ ? ์ ํ๋ฆฌ์ผ์ด์ ์ ํ ์คํธ ์ธก๋ฉด์์ ๋ง์ ์ด์
- ํ ์คํธ๊ฐ ๋๋๊ณ ๋๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ์ ๋จ์์๋ ๋ฐ์ดํฐ๋ ๊นจ๋์ด ๋น์์ ธ ์๋ ๊ฒ์ด ์ข์
-
-
H2 ๊ด๋ จ ์ค์ ์ถ๊ฐ
1 2 3 4 5
spring: h2: console: enabled: true
- ์น ๋ธ๋ผ์ฐ์ ์(H2 ์ฝ์)์์ H2 DB์ ์ ์ํ ํ, ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ด๋ฆฌ๊ฐ๋ฅ
- yml ํ์ผ์์๋ indent๋ฅผ ์ฃผ์ด์ depth๋ฅผ ์ค์ ํ ๋์๋ Tab(ํญ) ํค๋ฅผ ์ฌ์ฉํด์ ์ผ๊ด์ฑ์ ์ ์งํ๊ธฐ
- H2 Database์ ์ ์
- localhost:8080/h2-console
- ์ ํ๋ฆฌ์ผ์ด์ ๋ก๊ทธ์ ์ถ๋ ฅ๋๋ JDBC URL์ ํ์ธํ์ฌ JDBC URL์ ์ ๋ ฅ ํ Connect
-
H2 DB ์ค์ ์ถ๊ฐ โ JDBC URL์ด ๋๋ค์ผ๋ก ๋ฐ๋๋ ๋ถํธํจ ํด๊ฒฐํ๊ธฐ ์ํจ
1 2 3 4 5 6 7 8
spring: h2: console: enabled: true path: /h2 # (1) Context path ๋ณ๊ฒฝ datasource: url: jdbc:h2:mem:test # (2) JDBC URL ๋ณ๊ฒฝ
- H2 ์ฝ์์ ์ ์ URL Context path๋ฅผ ์กฐ๊ธ ๋ ๊ฐ๊ฒฐํ๊ฒ โ
/h2
โ๋ก ์ค์ - JDBC URL์ด ๋งค๋ฒ ๋๋คํ๊ฒ ๋ฐ๋์ง ์๋๋ก โ
jdbc:h2:mem:test
โ๋ก ์ค์
- H2 ์ฝ์์ ์ ์ URL Context path๋ฅผ ์กฐ๊ธ ๋ ๊ฐ๊ฒฐํ๊ฒ โ
- ํด๋์ค ๊ตฌํ [์๋ก ๋ฐฐ์ด ๊ฒ๋ง ์ ๋ฆฌํจ.]
- MessageDto(DTO ํด๋์ค)
- MessageController
- MessageMapper
-
MessageService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
package com.springboot.hello_world.service; import com.springboot.hello_world.entity.Message; import com.springboot.hello_world.repository.MessageRepository; import org.springframework.stereotype.Service; @Service public class MessageService { private final MessageRepository messageRepository; public MessageService(MessageRepository messageRepository) { this.messageRepository = messageRepository; } public Message createMessage(Message message){ return messageRepository.save(message); } }
- MessageRepository ์ธํฐํ์ด์ค๋ MessageService ํด๋์ค์์ DI๋ฅผ ํตํด ์ฃผ์ ๋ฐ์
-
messageRepository.save(message)์ ๊ฐ์ด save() ๋ฉ์๋๋ฅผ ์ฌ์ฉ
1) Sava ๋ฉ์๋๋
CrudRepository
๊ฐ ์ด ์์ ์ ๋์ ํด ์ฃผ๋ ์ญํ2) ์ฟผ๋ฆฌ๋ฌธ์ผ๋ก ๋ฐ์ดํฐ ์ ์ฅํ ๋ ๊ธฐ๋ฅ (==insert into)
-
Message (Entity ํด๋์ค)
1 2 3 4 5 6 7 8 9 10 11 12
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; }
1) Message๋ผ๋ ํด๋์ค ๋ช ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ ๋ช
2) @Id์ ๋ํ ์ด์ ์ ์ถ๊ฐํ ๋ฉค๋ฒ ๋ณ์๋ ํด๋น ์ํฐํฐ์ ๊ณ ์ ์๋ณ์ ์ญํ =primary key
-
MessageRepository
1 2 3 4 5
import org.springframework.data.repository.CrudRepository; public interface MessageRepository extends CrudRepository<Message, Long> { }
- ๋ฐ์ดํฐ ์ก์ธ์ค ๊ณ์ธต์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฐ๋์ ๋ด๋นํ๋ Repository
- CrudRepository
- CrudRepository๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ์์, ์ ๋๋ฆญ ํ์
์ด
<Message, Long>
์ผ๋ก ์ ์ธ - ๋ฐ์ดํฐ๋ฒ ์ด์ค์ CRUD(๋ฐ์ดํฐ ์์ฑ, ์กฐํ, ์์ , ์ญ์ ) ์์ ์ ์งํํ๊ธฐ ์ํด Spring์์ ์ง์ํด ์ฃผ๋ ์ธํฐํ์ด์ค
-
CrudRepository๋ฅผ ์์ํจ์ผ๋ก์จ query๋ฅผ ๋ฐ๋ก ์์ฑํ ์ผ๋ ์๊ณ container์ bean์ ๋ฑ๋กํ์ง ์์๋ CrudRepository๊ฐ ๊ฐ์ง๊ณ ์์ด์ ๊ด์ฐฎ์.
- CrudRepository๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ์์, ์ ๋๋ฆญ ํ์
์ด
-
application. yml ์ถ๊ฐ ์ค์ - H2 DB์ MESSAGE ํ ์ด๋ธ ์์ฑ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
spring: h2: console: enabled: true path: /h2 datasource: url: jdbc:h2:mem:test **sql: init: schema-locations: classpath*:db/h2/schema.sql** jpa: hibernate: ddl-auto: create # (1) ์คํค๋ง ์๋ ์์ฑ show-sql: true # (2) SQL ์ฟผ๋ฆฌ ์ถ๋ ฅ
schema.sql
1 2 3 4 5
CREATE TABLE IF NOT EXISTS MESSAGE( message_id BIGINT NOT NULL AUTO_INCREMENT, message varchar(100) NOT NULL, PRIMARY KEY (message_id) );
- ์ธ๋ฉ๋ชจ๋ฆฌ DB๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ, ์ ํ๋ฆฌ์ผ์ด์ ์ด ์คํ๋ ๋๋ง๋ค schema.sql ํ์ผ์ ์คํฌ๋ฆฝํธ๊ฐ ๋งค๋ฒ ์คํ๋๋ค๋ ๊ฒ ๊ธฐ์ตํ๊ธฐ.
-
H2 ์ฝ์์ ์ ์ํด์ MESSAGE ํ ์ด๋ธ ํ์ธ
-
POSTRUN
POST์์ฒญ์ผ๋ก message๋ง ์กฐ๊ธ ๋ณ๊ฒฝํจ
-
MESSAGE table ์กฐํ
POST ์์ฒญ์ด ์ ๋์๋์ง Message table ์กฐํ
Spring Data JDBC - Entity, table์ค๊ณ
DDD(Domain Driven Design) : ๋๋ฉ์ธ ์์ฃผ์ ์ค๊ณ ๊ธฐ๋ฒ
- Domain์ด๋
- ๋๋ฉ์ธ์ด๋ ์ฉ์ด ์์ฒด๋ ํ ๋ง๋๋ก ์ฐ๋ฆฌ๊ฐ ์ค์ ๋ก ํ์ค ์ธ๊ณ์์ ์ ํ๋ ์ ๋ฌด์ ํ ์์ญ
- ๋น์ฆ๋์ค ์ ๋ฌด ์์ญ์ ์๋ฏธํ๋ ๋๋ฉ์ธ ์ง์(Domain Knowledge)๋ค์ ์๋น์ค ๊ณ์ธต์์ ๋น์ฆ๋์ค ๋ก์ง์ผ๋ก ๊ตฌํํด์ผ ํ๋ค.
- Aggreagate
- ๋น์ทํ ์ ๋ฌด ๋๋ฉ์ธ๋ค์ ๋ฌถ์
- ์ ๊ทธ๋ฆฌ๊ฑฐํธ(Aggregate)๋ ํ๋ง๋๋ก ๋น์ทํ ๋ฒ์ฃผ์ ์ฐ๊ด๋ ์ ๋ฌด๋ค์ ํ๋๋ก ๊ทธ๋ฃนํํด๋์ ๊ทธ๋ฃน์ด๋ผ๊ณ ์๊ฐํ๊ธฐ
- Aggregate Root
- ๊ฐ๊ฐ์ ์ ๊ทธ๋ฆฌ๊ฑฐํธ์๋ ํด๋น ์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ฅผ ๋ํํ๋ ๋๋ฉ์ธ์ด ์กด์ฌํจ
- ํ๋์ ์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ฅผ ๋ํํ๋ ๋๋ฉ์ธ์ DDD์์๋ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ(Aggregate Root)
- ์ด๋ค ํน์ ์ง๋จ์ด๋ ๊ทธ๋ฃน์ ๋ํ๋ผ๊ณ ์๊ฐํ๊ธฐ
- ์ ๊ทธ๋ฆฌ๊ฑฐํธ์ ์ ์ ๊ธฐ์ค โ ๋๋ฉ์ธ๋ค๊ณผ ์ง๊ฐ์ ์ ์ผ๋ก ์ฐ๊ด๋์ด ์๋ ๋๋ฉ์ธ
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ ๊ฐ ๊ด๊ณ๋ก ๋ณด์๋ฉด, ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ๋ ๋ถ๋ชจ ํ ์ด๋ธ์ด ๋๊ณ , ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ๊ฐ ์๋ ๋ค๋ฅธ ๋๋ฉ์ธ๋ค์ ์์ ํ ์ด๋ธ์ด ๋๋ ๊ฒ๊ณผ ๋น์ท..
-
๋ฐฐ๋ฌ์ฃผ๋ฌธ ์ฑ์ ์ธ๋ถํ ํ๋ฉด
- ํ์ ์ ๊ทธ๋ฆฌ๊ฑฐํธ, ์ฃผ๋ฌธ ์ ๊ทธ๋ฆฌ๊ฑฐํธ, ์์ ์ ๊ทธ๋ฆฌ๊ฑฐํธ, ๊ฒฐ์ ์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ผ ํ ์ ์์.
์ํฐํฐ ๊ตฌํ
-
์ํฐํฐ ์ค๊ณ ํ์ธ - ์ปคํผ ์ฃผ๋ฌธ ์ํ ์ ํ๋ฆฌ์ผ์ด์
- Mebmer : Order =1: N
- Order์ member_Id ์ธ๋ํค๋ฅผ ์ถ๊ฐํ์ฌ ์กฐ์ธ.
- Order : Coffee =N:M โJoinTable๋ก OrderCoffee
- OrderCoffee์ order_Id์ coffee_Id ์ธ๋ํค ์ถ๊ฐํ์ฌ ์กฐ์ธ
- DB์์๋ ๋ค์ ํด๋นํ๋ ํ
์ด๋ธ์ด ์ฐธ์กฐํค๋ฅผ ๊ฐ์ก๋ค๋ฉด ํด๋์ค์์๋ 1์ ํด๋นํ๋ ํด๋์ค์์ ๊ฐ์ฒด ์ฐธ์กฐ ๋ฆฌ์คํธ๋ฅผ ๊ฐ์ง๊ฒ ๋จ, (List
)
- Mebmer : Order =1: N
-
์ ๊ทธ๋ฆฌ๊ฑฐํธ ๊ฐ์ฒด ๋งคํ ๊ท์น
- Aggregate : ๊ด๋ จ๋ ๊ฐ์ฒด๋ฅผ ๋ชจ์๋ ํ๋์ ๋จ์๋ก Value Object์ Entity๋ก ๊ตฌ์ฑ
- Aggregate ์ค์ฌ์๋ Aggregate Root๊ฐ ์กด์ฌ
(1) ๋ชจ๋ ์ํฐํฐ ๊ฐ์ฒด์ ์ํ๋ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ๋ฅผ ํตํด์๋ง ๋ณ๊ฒฝ๊ฐ๋ฅ
โ ์ด๋ค ์์ผ๋ก๋ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ๊ฐ ๋๋จธ์ง ๋ชจ๋ ์ํฐํฐ์ ๋ํ ๊ฐ์ฒด๋ฅผ ์ง๊ฐ์ ์ ์ผ๋ก ์ฐธ์กฐํ ์ ์๋ค๋ ์๋ฏธ
(2) ํ๋์ ๋์ผํ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ด์์์ ์ํฐํฐ ๊ฐ์ฒด ์ฐธ์กฐ
- ๋์ผํ ํ๋์ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ด์์๋ ์ํฐํฐ ๊ฐ์ ๊ฐ์ฒด๋ก ์ฐธ์กฐ
(3) ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ ๋ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ ๊ฐ์ ์ํฐํฐ ๊ฐ์ฒด ์ฐธ์กฐ
- ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ ๊ฐ์ ์ฐธ์กฐ๋ ๊ฐ์ฒด ์ฐธ์กฐ ๋์ ์ ID๋ก ์ฐธ์กฐํ๋ค.
- 1๋1 ๋๋ 1๋N ๊ด๊ณ์ผ ๋ ํ ์ด๋ธ ๊ฐ์ ์ธ๋ํค ๋ฐฉ์๊ณผ ๋์ผํ๋ค.
- N๋ N ๊ด๊ณ์ผ ๋๋ ์ธ๋ํค ๋ฐฉ์์ธ ID ์ฐธ์กฐ์ ๊ฐ์ฒด ์ฐธ์กฐ ๋ฐฉ์์ด ํจ๊ป ์ฌ์ฉ๋จ
์ํฐํฐ ๊ตฌํ - ์์
-
Order
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
package com.springboot.order.entity; import lombok.Getter; import lombok.Setter; import org.springframework.data.annotation.Id; import org.springframework.data.relational.core.mapping.MappedCollection; import org.springframework.data.relational.core.mapping.Table; import java.time.LocalDateTime; import java.util.LinkedHashSet; import java.util.Set; @Getter @Setter @Table("ORDERS") public class Order { @Id private long orderId; // ํ ์ด๋ธ ์ธ๋ํค์ฒ๋ผ memberId๋ฅผ ์ถ๊ฐํ๋ค. private long memberId; // (1) @MappedCollection(idColumn = "ORDER_ID") private Set<OrderCoffee> orderCoffees = new LinkedHashSet<>(); ... ... }
- Order ํด๋์ค๋ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ
-
long memberId๋ก ์ธ๋ํค๋ฅผ ํํํ๋๋ฐ Spring Data JDBC์์๋ AggregateReference ๋ผ๋ ํด๋์ค๋ฅผ ์ด์ฉํด ์๋ ์ฝ๋์ ๊ฐ์ด ์ธ๋ํค ํํ ๊ฐ๋ฅ
1
private AggregateReference<Member, Long> memberId;
- โ
@MappedCollection ์ ๋ํ
์ด์
์ ์ญํ
- ์ํฐํฐ ํด๋์ค ๊ฐ์ ์ฐ๊ด ๊ด๊ณ๋ฅผ ๋งบ์ด์ฃผ๋ ์ ๋ณด๋ฅผ ์๋ฏธ
- โญ idColumn ์ ํธ๋ฆฌ๋ทฐํธ๋ ์์ ํ ์ด๋ธ์ ์ถ๊ฐ๋๋ ์ธ๋ํค์ ํด๋น๋๋ ์ด๋ช ์ ์ง์
- โญ keyColumn ์ ํธ๋ฆฌ๋ทฐํธ๋ ์ธ๋ํค๋ฅผ ํฌํจํ๊ณ ์๋ ํ
์ด๋ธ์ ๊ธฐ๋ณธํค ์ด๋ช
์ ์ง์
- ex) ORDERS ํ
์ด๋ธ์ ์์ ํ
์ด๋ธ์ธ ORDER_COFFEE ํ
์ด๋ธ์ ๊ธฐ๋ณธํค๋ ORDER_COFFEE_ID ์ด๋ฏ๋ก,
keyColumn
์ ๊ฐ์ด โORDER_COFFEE_ID
- ex) ORDERS ํ
์ด๋ธ์ ์์ ํ
์ด๋ธ์ธ ORDER_COFFEE ํ
์ด๋ธ์ ๊ธฐ๋ณธํค๋ ORDER_COFFEE_ID ์ด๋ฏ๋ก,
-
OrderCoffee - ์ฃผ๋ฌธ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ด์ ์๋ ์ํฐํฐ ํด๋์ค
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
package com.springboot.order.entity; import lombok.Builder; import lombok.Getter; import org.springframework.data.annotation.Id; import org.springframework.data.relational.core.mapping.Table; @Getter @Builder @Table("ORDER_COFFEE") // (1) public class OrderCoffee { @Id private long orderCoffeeId; private long coffeeId; // (2) private int quantity; // (3) }
1) @Table
- @Table ์ ๋ํ ์ด์ ์ ์ถ๊ฐํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก ํด๋์ค๋ช ์ด ํ ์ด๋ธ์ ์ด๋ฆ๊ณผ ๋งคํ๋จ
@Table("ORDER_COFFEE")
์ ๊ฐ์ด ํ ์ด๋ธ ์ด๋ฆ์ ๋ณ๊ฒฝ
2) coffeeId๋ฅผ ์ธ๋ํค์ฒ๋ผ ์ถ๊ฐ
3) @Builder -> ๋ด์ผ ์ ๋ก๋ ํ๊ธฐ!
-
Order
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
import com.springboot.member.entity.Member; import lombok.Getter; import lombok.Setter; import org.springframework.data.annotation.Id; import org.springframework.data.relational.core.mapping.MappedCollection; import org.springframework.data.relational.core.mapping.Table; import java.time.LocalDateTime; import java.util.LinkedHashSet; import java.util.Set; @Getter @Setter @Table("ORDERS") public class Order { @Id private long orderId; // ํ ์ด๋ธ ์ธ๋ํค์ฒ๋ผ memberId๋ฅผ ์ถ๊ฐํ๋ค. private long memberId; @MappedCollection(idColumn = "ORDER_ID") private Set<OrderCoffee> orderCoffees = new LinkedHashSet<>(); // (1) private OrderStatus orderStatus = OrderStatus.ORDER_REQUEST; // (2) private LocalDateTime createdAt = LocalDateTime.now(); // (3) public enum OrderStatus { ORDER_REQUEST(1, "์ฃผ๋ฌธ ์์ฒญ"), ORDER_CONFIRM(2, "์ฃผ๋ฌธ ํ์ "), ORDER_COMPLETE(3, "์ฃผ๋ฌธ ์๋ฃ"), ORDER_CANCEL(4, "์ฃผ๋ฌธ ์ทจ์"); @Getter private int stepNumber; @Getter private String stepDescription; OrderStatus(int stepNumber, String stepDescription) { this.stepNumber = stepNumber; this.stepDescription = stepDescription; } } }
- ์ฃผ๋ฌธ ์ ๋ณด๊ฐ ์ ์ฅ๋ ๋ ๊ธฐ๋ณธ ๊ฐ์ ORDER_REQUEST (์ฃผ๋ฌธ ์์ฒญ)
- ์ฃผ๋ฌธ์ด ๋ฑ๋ก๋๋ ์๊ฐ ์ ๋ณด๋ฅผ ๋ํ๋ด๋ ๋ฉค๋ฒ ๋ณ์์ด๋ฉฐ, LocalDateTime ํ์
- OrderStatus enum
- OrderStatus enum์ด Order ํด๋์ค์ ๋ฉค๋ฒ๋ก ํฌํจ์ด ๋์ด ์๋ ์ด์ ๋ OrderStatus๋ ์ฃผ๋ฌธ์ ์ํ ์ ์ฉ ์ํ ๊ฐ์ผ๋ก ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ
- ๋ค๋ฅธ ๊ธฐ๋ฅ์์๋ ์ฌ์ฉํ ๊ฐ๋ฅ์ฑ์ด ์๋ค๋ฉด ํด๋์ค ์ธ๋ถ๋ก ๋ถ๋ฆฌ์ํฌ ์ ์๊ฒ ์ง๋ง ํ์ฌ๋ก์๋ ํน๋ณํ ๊ทธ๋ด ์ด์ ๊ฐ ์์
- coffee์ order์ ์ฐ๊ฒฐํ์ง ์์, ์ฌ์ฉํ์ง ์์๊ฒ์ด๋ผ์.
-
src/main/resources/db/h2/schema.sql
ํ์ผ์ ํ ์ด๋ธ ์์ฑ ์คํฌ๋ฆฝํธ ์ถ๊ฐํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์คํ์ ํ ์ด๋ธ ์์ฑ๋๋๋ก ํ๊ธฐ.
Spring Data JDBC - Service, Repository
Repository
-
Spring Data JDBC, Spring Data JPA์์๋ ๋ฐ์ดํฐ ์ก์ธ์ค ๊ณ์ธต์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธ์์ฉํ๋ ์ญํ ์ ํ๋ ์ธํฐํ์ด์ค๋ฅผ ๋ฆฌํฌ์งํ ๋ฆฌ(Repository)๋ผ๊ณ ํจ.
๋ฆฌํฌ์งํ ๋ฆฌ(Repository)๋ผ๋ ์ฉ์ด๋ DDD(Domain Driven Design, ๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ)์์ ์ฌ์ฉํ๋ ์ฉ์ด
- ์ฟผ๋ฆฌ ๋ฉ์๋(Query Method)
- Spring Data JDBC์์๋ ์ฟผ๋ฆฌ ๋ฉ์๋๋ฅผ ์ด์ฉํด์ SQL ์ฟผ๋ฆฌ๋ฌธ์ ์ฌ์ฉํ์ง ์๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ง์๊ฐ๋ฅ
- ์ฌ์ฉ๋ฒ โ โfind + By + SQL ์ฟผ๋ฆฌ๋ฌธ์์ WHERE ์ ์ ์ด๋ช + (WHERE ์ ์ด์ ์กฐ๊ฑด์ด ๋๋ ๋ฐ์ดํฐ) โ ํ์
- WHERE ์ ์ ์กฐ๊ฑด ์ด์ ์ฌ๋ฌ ๊ฐ ์ง์ ํ๊ณ ์ถ๋ค๋ฉด โAndโ๋ฅผ ์ฌ์ฉ
- Ex) findByEmailAndName(String email, String name)
- ๋ฐ๋์ ์ํฐํฐ ํด๋์ค์ ๋ฉค๋ฒ ๋ณ์๋ช ์ ์ ์ด์ฃผ์ด์ผ ํจ.
- ์ฝ Member ์ํฐํฐ ํด๋์ค์ firstName์ด๋ผ๋ ๋ฉค๋ฒ ๋ณ์, ํ ์ด๋ธ์ ์๋ FIRST_NAME์ด๋ผ๋ ์ด๋ช ๊ณผ ๋งคํ์ด ๋๋ค๊ณ ๊ฐ์ ํ๋ฉด findByFirstName์ด ๋์ด์ผ ํจ.
-
์์
1 2 3 4 5 6 7 8 9 10 11 12 13 14
import com.springboot.coffee.entity.Coffee; import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.repository.CrudRepository; import java.util.Optional; public interface CoffeeRepository extends CrudRepository<Coffee, Long> { //(1) Optional<Coffee> findByCoffeeCode(String coffeeCode); //(2) @Query("SELECT * FROM COFFEE WHERE COFFEE_ID = :coffeeId") Optional<Coffee> findByCoffee(Long coffeeId); }
- CrudRepository๋ฅผ ์์ โ CrudRepository ์ธํฐํ์ด์ค๋ฅผ ํตํด์ ํธ๋ฆฌํ๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ์ ์ ์ฅ, ์กฐํ, ์์ , ์ญ์ ๊ฐ๋ฅ
- Coffee ์ํฐํฐ ํด๋์ค,
Long
์Member
์ํฐํฐ ํด๋์ค์์@Id
์ ๋ํ ์ด์ ์ด ๋ถ์ ๋ฉค๋ฒ ๋ณ์์ ํ์ - Spring Data JDBC์์๋ Optional์ ์ง์ํ๊ธฐ ๋๋ฌธ์ ๋ฆฌํด ๊ฐ์ Optional๋ก ๋ํ ๊ฐ๋ฅ
- (1)์ WHERE ์ ์์ COFFEE_CODE๋ฅผ ์กฐ๊ฑด์ผ๋ก ์ง์ํ๊ฒ ํด์ฃผ๋ ์ฟผ๋ฆฌ ๋ฉ์๋
- (2) @Query ์ ๋ํ
์ด์
: COFFEE ํ
์ด๋ธ์ ์ง์ํ๊ธฐ ์ํจ,
- ์ค์ ๋ก๋ CrudRepository ์ธํฐํ์ด์ค์ ๋ด์ฅ๋์ด ์๋ findById(ID id)๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์.
- findById(ID id)๋ ํ ์ด๋ธ์์ ๊ธฐ๋ณธํค๋ฅผ WHERE์ ์ ์กฐ๊ฑด์ผ๋ก ์ง์ ํด ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ์ ์๋ ํธ๋ฆฌํ ์ฟผ๋ฆฌ๋ฉ์๋
- findBy~ ์ด๋ ๊ฒ ์์ฑํ๋ฉด ์์์ ์ฐพ์์ค-> ์นด๋ฉ์ผ์ด์ค๋ก ์์ฑ ํ์
COMMENT
๋ญ๊ฐ ํ ํ ์ง๋๊ฐ์ ๋ฐ๋ผ๊ฐ๊ณ ์ดํดํ๋๋ผ ์๊ฐ์ด ํ ํ ์ง๋๊ฐ๋ค.. ๋ถ๋ ์ ๋ฐ๋ผ๊ฐ์ ๋ฒ๋ฒ ๊ฑฐ๋ฆฌ์ง ๋ง์.
Leave a comment