2022. 9. 21. 17:12ใ์ธํ๋ฐ/์ค์ ! ์คํ๋ง ๋ฐ์ดํฐ JPA
์ค์ ! ์คํ๋ง ๋ฐ์ดํฐ JPA - ์ธํ๋ฐ | ๊ฐ์
์คํ๋ง ๋ฐ์ดํฐ JPA๋ ๊ธฐ์กด์ ํ๊ณ๋ฅผ ๋์ด ๋ง์น ๋ง๋ฒ์ฒ๋ผ ๋ฆฌํฌ์งํ ๋ฆฌ์ ๊ตฌํ ํด๋์ค ์์ด ์ธํฐํ์ด์ค๋ง์ผ๋ก ๊ฐ๋ฐ์ ์๋ฃํ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐ๋ณต ๊ฐ๋ฐํด์จ ๊ธฐ๋ณธ CRUD ๊ธฐ๋ฅ๋ ๋ชจ๋ ์ ๊ณตํฉ๋๋ค.
www.inflearn.com
์ค์ ! ์คํ๋ง ๋ฐ์ดํฐ JPA ๊ฐ์๋ฅผ ๋ฃ๊ณ ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค.
0๏ธโฃ ํ๋ก์ ํธ ํ๊ฒฝ์ค์
์ฌ์ฉ ๊ธฐ๋ฅ: Spring web, Jpa, h2, lombok
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test' //junit 5 ์์กด
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.7'
-> p6spy๋ jpa ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉํ๊ฑธ ๋ณด์ฌ์ฃผ๋ ๋ก๊ทธ?์ด๋ค.
1๏ธโฃ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ดํด๋ณด๊ธฐ
./gradlew dependencies --configuration compileClasspath
terminal์ ์ด ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ๋ฉด
![](https://blog.kakaocdn.net/dn/zAvF9/btrMIOFgtjv/DN5B6tY0koFjQVk9cpIgd1/img.png)
์ด๋ฐ์์ผ๋ก ํ์ธํ ์ ์์ง๋ง intellij์์ ๋ ํธํ๊ฒ ํ์ธ๋ ๊ฐ๋ฅ...
- ์คํ๋ง๋ถํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ดํด๋ณด๊ธฐ
spring-boot-starter-web
spring-boot-starter-tomcat: ํฐ์บฃ(์น์๋ฒ)
spring-web-mvc : ์คํ๋ง ์น MVC
spring-boot-starter-data-jpa
spring-boot-starter-aop
spring-boot-starter-jdbc -> HikarCP ์ปค๋ฅ์ ํ (๋ถํธ 2.0 ๋ถํฐ ๊ธฐ๋ณธ)
hibernate + JPA : ํ์ด๋ฒ๋ค์ดํธ + JPA
spring-data-jpa: ์คํ๋ง ๋ฐ์ดํฐ JPA
spring-boot-starter(๊ณตํต) : ์คํ๋ง ๋ถํธ + ์คํ๋ง ์ฝ์ด + ๋ก๊น
spring-boot:
spring-core
spring-boot-starter-logging:
logback, slf4j
- ํ ์คํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
spring-boot-starter-test
junit: ํ ์คํธ ํ๋ ์์ํฌ, ์คํ๋ง๋ถํธ 2.2๋ถํฐ Junit5์ฌ์ฉ (๊ณผ๊ฑฐ ๋ฒ์ ์ vintage)
mockito: ๋ชฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
assertj : ํ ์คํธ ์ฝ๋๋ฅผ ์ข ๋ ํธํ๊ฒ ์์ฑํ๊ฒ ๋์์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
spring-test: ์คํ๋ง ํตํฉ ํ ์คํธ ์ง์
-ํต์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
์คํ๋ง MVC
์คํ๋ง ORM
JPA, ํ์ด๋ฒ๋ค์ดํธ
์คํ๋ง ๋ฐ์ดํฐ JPA
-๊ธฐํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค ํด๋ผ์ด์ธํธ
์ปค๋ฅ์ ํ: ๋ถํธ ๊ธฐ๋ณธ์ HikariCP
๋ก๊น Slf4j & logback
ํ ์คํธ
2๏ธโฃ H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์น
: H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ๋ฐ์ด๋ ํ ์คํธ ์ฉ๋๋ก ๊ฐ๋ณ๊ณ ํธ๋ฆฌํ DB, ์น ํ๋ฉด ์ ๊ณต
๊ทธ๋ฆฌ๊ณ H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์คํ๋ง๋ถํธ์ ์ค์น๋ H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฒ์ ์ ๋ง์ถฐ์ผ ํ๋ค.
![](https://blog.kakaocdn.net/dn/evgcv6/btrMFG9oMp2/hEckhVhrMW6czPLmBkkEdk/img.png)
๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ผ ์์ฑ ๋ฐฉ๋ฒ
[Server]
jdbc:h2:~/datajpa (์ต์ดํ๋ฒ) -> ์ด๋ ํ์ผ ์ ๊ทผ ๋ฐฉ๋ฒ์์ ํ๊ณณ์์๋ง ์ ๊ทผ ๊ฐ๋ฅํ๋ฏ๋ก embedded ๋ฒ์ ์ผ๋ก ์ฌ์ฉํด์ผ ํ๋ค.
[Embedded]
jdbc:h2:tcp://localhost/~/datajpa ์ด๋ ๊ฒ ์ ์
3๏ธโฃ ์คํ๋ง ๋ฐ์ดํฐ JPA์ DB ์ค์ , ๋์ ํ์ธ
application.yml
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/datajpa
username: sa
password:
driver-class-name: org.h2.Driver
jpa:
hibernate:
ddl-auto: create
properties:
hibernate:
format_sql: true
logging:
level:
org.hibernate.SQL: debug
spring.jpa.hibernate.ddl-auto: create
-> ์ด ์ต์ ์ ์ ํ๋ฆฌ์ผ์ด์ ์คํ ์์ ์ ํ ์ด๋ธ์ drop ํ๊ณ ๋ค์ ์์ฑํ๋ค.
๋ชจ๋ ๋ก๊ทธ ์ถ๋ ฅ์ ๊ฐ๊ธ์ ๋ก๊ฑฐ๋ฅผ ํตํด ๋จ๊ฒจ์ผ ํ๋ค. System.out ์ด๋ฐ์์ผ๋ก ํด์ ์ฝ์์ ๋จ๊ธฐ๋๊ฑด ์์ข๋ค.
logging.level.org.hibernate.SQL : debug
-> ์ด ์ต์ ์ logger๋ฅผ ํตํด ํ์ด๋ฒ๋ค์ดํธ ์คํ SQL์ ๋จ๊ธด๋ค.
3๏ธโฃ ์ค์ ๋์ ํ์ธํ๊ธฐ
Member.class
JPA์์๋ ๊ธฐ๋ณธ ์์ฑ์๋ฅผ ํ์๋ก ์์ฑํด์ค์ผํ๋ค.
์๋ํ๋ฉด JPA์์๋ ํ๋ก์ ๊ธฐ์ ์ ์ฌ์ฉํ๋๋ฐ ์ด๋ ๊ธฐ๋ณธ ์์ฑ์๊ฐ ํ์ํ๋ค.
๊ทธ๋ฆฌ๊ณ access level์ protected๊น์ง๋ ์ด์ด๋ฌ์ผ ํ๋ค๊ณ ๋ฉ๋ด์ผ์ ๋์์๊ธฐ ๋๋ฌธ์ protected ๋ก ์ค์ ํ๋๋ฐ ๊ทธ ์ด์ ๋
์ธ๋ถ์์ ๊ธฐ๋ณธ ์์ฑ์ ๋จ๋ฐํ ๊น๋ด ์ด๋ ๊ฒ ์ค์ ํด์ค๋ค~~
๊ทธ๋ฆฌ๊ณ ์ฐธ๊ณ ๋ก Setter๋ ๊ฐ๊ธ์ ์ฌ์ฉํ์ง ์๋๊ฒ ์ข๋ค.
MemberJpaRepository.class
MemberJpaRepositoryTest.class
MemberJpaRepository๋ฅผ Testํ๋ ค๊ณ ํ ๋ ์ด์ Junit5๋ฅผ ์ฌ์ฉํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด์ ๊ฐ์ด ์ฌ์ฉํ๋ ์ด๋ ธํ ์ด์ ์ธ
@Runwith(SpringRunner.class)๋ฅผ ์ฌ์ฉํ์ง ์์๋ ๋๋ค.
๊ทธ๋ฆฌ๊ณ @Transactional ์ด๋ ธํ ์ด์ ์ ๋ถ์ฌ์ค์ผ ๋กค๋ฐฑ๋ ๋๊ณ , JPA์์ ๋ชจ๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ํธ๋์ญ์ ์์์ ์คํ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ํธ๋์ญ์ ์ด๋ ธํ ์ด์ ์ ๋ฐ๋์ ๋ถ์ฌ์ค์ผ ํ๋ค.
์คํ๋ง ๋ฐ์ดํฐ JPA ์ฌ์ฉ - MemberRepository.class
์คํ๋ง ๋ฐ์ดํฐ JPA๋ MemberRepository ์ธํฐํ์ด์ค๋ฅผ ์์ฑํ๊ณ JpaRepository๋ฅผ ์์๋ฐ์ ๋ง๋ค์ด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋์ด๋ค..!!
MemberRepositoryTest.class
์์์ JPA Repository Test ์ฝ๋์ ๊ฑฐ์ ๋น์ทํ๋ค.
๋์ jpaRepository๋ findById ๋ผ๋ ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ Optional๋ก ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ํ ์คํธ์์๋ ๊ฐ๋จํ ๊บผ๋ด๊ธฐ ์ํด get๋ฉ์๋๋ฅผ ํตํด Member๊ฐ์ฒด๋ฅผ ๋ฐํํ๋๋ฐ ์๋๋ getOrElse ? ์ด๋ฐ ๋ฉ์๋๋ก ๊บผ๋ด์ผํ๋ค..!
@Rollback(False) ์ง์ ํด์ฃผ๋ฉด ๋ณดํต ํ ์คํธ ๋๋๊ณ ๋ชจ๋ ๋กค๋ฐฑํด์ ์ค์ ๋๋น์๋ ๋ฐ์ดํฐ ์ํฅ์ ์์ฃผ๋๋ฐ ์ด๋ฅผ false๋ก ์ง์ ํด๋๋ฉด
์ค์ ๋๋น์ ๊ฐ์ด ์ง์์ง์ง ์๊ณ ๋จ์์๋๋ค.
โญ๏ธ ์ฐธ๊ณ
์คํ๋ง ๋ถํธ๋ฅผ ํตํด ๋ณต์กํ ์ค์ ์ด ๋ค ์๋ํ๋์๋ค.
persistence.xml ๋ ์๊ณ , LocalContainerExntityManagerFactoryBean ์ด๋ฐ๊ฒ๋ ์๋ค.
๐ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ ๋ก๊ทธ ๋จ๊ธฐ๊ธฐ
์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.7'
์ build.gradle ์ ์ถ๊ฐํด์ฃผ๊ณ ๋ฆฌํ๋ ์ฌ ํด์ฃผ๋ฉด
์ด๋ฐ์์ผ๋ก ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉํ ๋ก๊ทธ๋ฅผ ๋จ๊ฒจ์ค๋ค.
๊ทผ๋ฐ ์ด๋ ํ ์คํธ์ฉ์์๋ ์ฌ์ฉํด์ ๋ฐ๋ก ํ์ธํ๋๊ฒ ์ข์๋ฐ ์ค์ ์ด์ ํ๊ฒฝ์์๋ ์ฑ๋ฅ ํ ์คํธ๋ฅผ ํ๊ณ ์ถ๊ฐํด์ฃผ๋ ๊ฒ์ด ์ข๋ค.
โ๏ธ ์ฐธ๊ณ
์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ก๋ก ๋จ๊ธฐ๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์์คํ ์์์ ์ฌ์ฉํ๋ฏ๋ก, ๊ฐ๋ฐ ๋จ๊ณ์์๋ ํธํ๊ฒ ์ฌ์ฉํด๋ ๋์ง๋ง,
์ด์ ์์คํ ์ ์ ์ฉํ๋ ค๋ฉด ๊ผญ ์ฑ๋ฅ ํ ์คํธ๋ฅผ ํ๊ณ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค~~
'์ธํ๋ฐ > ์ค์ ! ์คํ๋ง ๋ฐ์ดํฐ JPA' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์คํ๋ง ๋ฐ์ดํฐ JPA] 6. ์คํ๋ง ๋ฐ์ดํฐ JPA ๋ถ์ (0) | 2022.10.03 |
---|---|
[์คํ๋ง ๋ฐ์ดํฐ JPA] 5. ํ์ฅ ๊ธฐ๋ฅ (1) | 2022.09.29 |
[์คํ๋ง ๋ฐ์ดํฐ JPA] 4. ์ฟผ๋ฆฌ ๋ฉ์๋ ๊ธฐ๋ฅ (0) | 2022.09.28 |
[์คํ๋ง ๋ฐ์ดํฐ JPA] 3. ๊ณตํต ์ธํฐํ์ด์ค ๊ธฐ๋ฅ (0) | 2022.09.22 |
[์คํ๋ง ๋ฐ์ดํฐ JPA] 2. ์์ ๋๋ฉ์ธ ๋ชจ๋ธ (0) | 2022.09.22 |