Bibi's DevLog ๐Ÿค“๐ŸŽ

[Spring Data JDBC] Spring Data JDBC๋ž€? ๋ณธ๋ฌธ

๐Ÿ–ฅ BE ๋ฐฑ์—”๋“œ/Spring ์Šคํ”„๋ง

[Spring Data JDBC] Spring Data JDBC๋ž€?

๋น„๋น„ bibi 2021. 4. 30. 19:49

Spring Data JDBC

๊ณต์‹ ๋ฌธ์„œ 1, 2๋ฅผ ์ฐธ๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค

์†Œ๊ฐœ

  • Spring Data family ๊ตฌ์„ฑ์›
  • JDBC ๊ธฐ๋ฐ˜์œผ๋กœ repository๋ฅผ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค
  • DDD(Domain Driven Design)์—์„œ ์˜๊ฐ์„ ๋ฐ›์Œ
  • JPA๋ณด๋‹ค ๊ธฐ๋Šฅ์€ ์ ์ง€๋งŒ ๋” ๋‹จ์ˆœํ•จ. ๊ฐ„๋‹จํ•˜๋ฉด์„œ ์ œํ•œ๋œ ๋ฐฉ๋ฒ•๋“ค์„ ์ง€์›ํ•จ

์ง€์› ๊ธฐ๋Šฅ

  • CrudRepository
  • @Query
  • Id ์ƒ์„ฑ
  • ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
  • MyBatis, Auditing, CustomConversions

์ง€์›๋˜์ง€ ์•Š๋Š” ๊ธฐ๋Šฅ

  • ์บ์‹ฑ, ์ง€์—ฐ ๋กœ๋”ฉ
  • JPA์™€ ๋‹ฌ๋ฆฌ save()ํ•˜๋ฉด ์ €์žฅ๋˜๊ณ , save()ํ•˜์ง€ ์•Š์œผ๋ฉด ์ €์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค.

DDD (๋„๋ฉ”์ธ ๊ธฐ๋ฐ˜ ์„ค๊ณ„)

๋ชจ๋“  spring data ๋ชจ๋“ˆ์€ DDD์˜ repository, aggregate, aggregate root์˜ ๊ฐœ๋…์—์„œ ์˜๊ฐ์„ ๋ฐ›์•˜๋‹ค.

aggregate

  • '์ง‘ํ•ฉ'์ด๋ผ๋Š” ๋œป
  • ๊ฐ’์ด ๋ณ€ํ™”ํ•  ๋•Œ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์ง‘ํ•ฉ.
  • ์˜ˆ : order์™€ item - item์ด ์ฃผ๋ฌธ๋˜๋ฉด order์˜ ์žฌ๊ณ ์ˆ˜๋Ÿ‰๋„ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•œ๋‹ค
  • aggregate์˜ ๊ฐ’ ๋ณ€ํ™”๋Š” ์›์ž์ ์ด๋ฉฐ ์ผ๊ด€์„ฑ์ด ๋ณด์žฅ๋œ๋‹ค.
  • Strong Consistency๋ฅผ ๋ณด์žฅํ•ด ์ฃผ์ง€ ์•Š๋Š”๋‹ค. (Eventual Consistency ๋ณด์žฅ) ์ฆ‰, aggregate์— ๋Œ€ํ•œ ์ฐธ์กฐ๋Š” ํ•ญ์ƒ ์ผ๊ด€์„ฑ์ด ๋ณด์žฅ๋˜์ง„ ์•Š์ง€๋งŒ ๊ฒฐ๊ตญ ์ผ๊ด€์„ฑ์ด ๋ณด์žฅ๋œ๋‹ค.

the Aggregate Root

  • ๊ฐ๊ฐ์˜ aggregate์—๋Š” ์ •ํ™•ํ•˜๊ฒŒ ํ•˜๋‚˜์˜ aggregate root๊ฐ€ ์กด์žฌํ•จ
  • aggregate root์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด์„œ๋งŒ aggregate์˜ ๊ฐ’์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค

repository

  • ์˜๊ตฌ์ ์ธ ๊ฐ์ฒด์˜ ์ €์žฅ์†Œ
  • ํ•˜๋‚˜์˜ aggregate root๋‹น ํ•˜๋‚˜์˜ repository๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.
  • ํ•˜๋‚˜์˜ aggregate root์—์„œ ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ๋Š” ๊ทธ aggregate root์˜ ์ผ๋ถ€๋กœ ๊ฐ„์ฃผ๋œ๋‹ค.
  • aggregate์—๋งŒ ํ…Œ์ด๋ธ”(๋ฃจํŠธ๊ฐ€ ์•„๋‹Œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ํ…Œ์ด๋ธ”)์— ๋Œ€ํ•œ ์™ธ๋ž˜ ํ‚ค๋ฅผ ๊ฐ€์ง€๋ฉฐ, ๋‹ค๋ฅธ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๋ฃจํŠธ๊ฐ€ ์•„๋‹Œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ผ์€ ์—†๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.
  • aggregate root์— ์ฐธ์กฐ๋˜๋Š” ์—”ํ‹ฐํ‹ฐ๋Š” Spring Data JDBC์— ์˜ํ•ด ์‚ญ์ œ๋˜๊ณ  ๋‹ค์‹œ ์ƒ์„ฑ๋œ๋‹ค.

Spring Data JDBC ์— ๋Œ€ํ•ด..

๊ฐ€๋ฒผ์šด ๋งˆ์Œ์œผ๋กœ ์Šคํ”„๋ง ๋ฐ์ดํ„ฐ JDBC์— ๋Œ€ํ•œ ๊ธ€์„ ํ•˜๋‚˜ ์ฝ์–ด ๋ณด์•˜๋‹ค.

(spring data jdbc๋ถ€๋ถ„๋งŒ ์ฝ์—ˆ๋‹ค)

JDBC๋Š”...

DB์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ์ž๋ฐ” ํ‘œ์ค€ API.

  • JDBC ๋“œ๋ผ์ด๋ฒ„ ๋กœ๋”ฉ
  • DBMS์— ์—ฐ๊ฒฐ
  • SQL๋ฌธ์„ DB์— ์ „์†กํ•˜๊ณ  ๊ฒฐ๊ณผ ๊ฐ’์„ ๋ฐ›๋Š”๋‹ค

์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - JDBC API - JDBC Driver Manager - JDBC Driver - DBMS

  • JDBC Driver
    • ์ž๋ฐ” ์•ฑ์˜ ์š”์ฒญ์„ DBMS๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํ† ์ฝœ๋กœ ๋ณ€ํ™˜ํ•ด ์ฃผ๋Š” ์–ด๋Œ‘ํ„ฐ ์—ญํ• 
  • ์ผ๋ฐ˜์ ์œผ๋กœ DB์—ฐ๋™ ์ž‘์—…์€ ์ปค๋„ฅ์…˜ ์—ฐ๊ฒฐ, SQL ์ฟผ๋ฆฌ ์ „์†ก ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
    • Connection : DB์™€ ์—ฐ๊ฒฐ (=session)
    • Statement : SQL๋ฌธ์„ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜, SQL๋ฌธ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ
    • ์กฐ๊ธˆ ๋” ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์“ฐ๋Š” ๊ฒƒ์ด Spring JDBC Templateํด๋ž˜์Šค๋‚˜ MyBatis ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค.

ORM

Object-Relational Mapping

๊ฐ์ฒด์™€ ๊ด€๊ณ„ํ˜•DB๋ฅผ ๋งตํ•‘ํ•˜๋Š” ๊ธฐ์ˆ 

  • ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ณด๋‹ค ๋กœ์ง ์ž์ฒด์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ
  • SQL๋ฌธ์„ ์ง์ ‘ ์งœ์ง€ ์•Š์•„๋„ ๋จ
  • ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ํŽธํ•ด์ง

JPA, Hibernate

JPA : ORM ๊ธฐ์ˆ ์— ๋Œ€ํ•œ ํ‘œ์ค€ ๋ช…์„ธ.

Hibernate : JPA ํ‘œ์ค€์„ ๊ตฌํ˜„ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ ์ค‘ ํ•˜๋‚˜

Spring Data JPA

Spring Data JPA : JPA์œ„์— ์ถ”๊ฐ€๋œ ์ถ”์ƒํ™” ๊ณ„์ธต

JPA๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค๋ฅผ ์œ„ํ•œ ๋” ๊ฐ„๋‹จํ•˜๊ณ  ํ–ฅ์ƒ๋œ ๊ธฐ๋Šฅ ์ œ๊ณต

Spring Data JDBC

  • Spring Data JPA๊ฐ€ ์ด๋ฏธ ์žˆ๋Š” ์ƒํƒœ์—์„œ 2018๋…„์— ์ถœ์‹œ๋˜์—ˆ๋‹ค
    • ์™œ? JPA๊ฐ€ ๋” ๋งŽ์ด ์ž๋™ํ™” ๋˜์–ด์žˆ๊ณ  ํŽธํ•˜๊ณ  ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋Š”๋ฐ?
      1. ๋„ˆ๋ฌด ๋ณต์žกํ•˜๋‹ค
      2. ๊ทธ ์™ธ ์—ฌ๋Ÿฌ ๋‹จ์ ๋“ค (Lazy Loading Exception, Dirty Checking ... ๋“ฑ)

Spring Data JDBC์˜ ํŠน์ง•

  • ์‹ฌํ”Œํ•˜๋‹ค.
  • Very simple & limited & opinionated ORM
  • No Lazy Loading, Caching, Proxies and Deffered Flushing

Spring ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - Spring Data JDBC - JDBC API - JDBC Driver Manager - JDBC Driver - DBMS

Spring Data JDBC - ๊ณต์‹๋ฌธ์„œ ์ฝ์–ด๋ณด๊ธฐ

Spring Data JDBC ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฝ๊ณ  ์ผ๋ถ€๋ฅผ ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

9.5. Annotation-based Configuration

Spring Data JDBC์˜ repository ์ง€์›์€ ์ž๋ฐ” configuration์„ ํ†ตํ•œ ์–ด๋…ธํ…Œ์ด์…˜์— ์˜ํ•ด ํ™œ์„ฑํ™”๋œ๋‹ค.

Example 54. ์ž๋ฐ” configuration์„ ์‚ฌ์šฉํ•˜๋Š” Spring Data JDBC repositories

@Configuration
@EnableJdbcRepositories                                                                
class ApplicationConfig extends AbstractJdbcConfiguration {      

    @Bean
    public DataSource dataSource() {  
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        return builder.setType(EmbeddedDatabaseType.HSQL).build();
    }

    @Bean
    NamedParameterJdbcOperations namedParameterJdbcOperations(DataSource dataSource) { 
        return new NamedParameterJdbcTemplate(dataSource);
    }

    @Bean
    TransactionManager transactionManager(DataSource dataSource) {    
        return new DataSourceTransactionManager(dataSource);
    }
}
  • @EnableJdbcRepositories๋Š” Repository๋กœ๋ถ€ํ„ฐ ๋‚˜์˜จ ์ธํ„ฐํŽ˜์ด์Šค๋“ค์„ ์œ„ํ•œ ๊ตฌํ˜„์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค
    • Spring Data JDBC ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ํ™œ์„ฑํ™”ํ•œ๋‹ค.
  • AbstractJdbcConfiguration์€ Spring Data JDBC์— ์š”๊ตฌ๋˜๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ๋ณธ ๋นˆ๋“ค์„ ์ œ๊ณตํ•œ๋‹ค
  • DataSource๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ์„ ์ƒ์„ฑํ•œ๋‹ค.
    • ์•„๋ž˜์˜ ๋‘ bean ๋ฉ”์„œ๋“œ๋“ค ๋•Œ๋ฌธ์— ํ•„์š”ํ•˜๋‹ค.
  • NamedParameterJdbcOperations๋Š” SpringDataJDBC๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.
  • Spring Data JDBC๋Š” Spring JDBC์— ์˜ํ•ด ์ œ๊ณต๋˜๋Š” ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ๋ฅผ ํ™œ์šฉํ•œ๋‹ค.

โœ” Spring Boot๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ›จ์”ฌ ํŽธํ•˜๋‹ค.

- `DataSource`๋ฅผ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋‹ค. (`spring-boot-starter-data-jdbc` ์˜์กด์„ฑ๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.)

9.5.1. Dialects

Spring Data JDBC๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋‚˜ JDBC ๋“œ๋ผ์ด๋ฒ„์— ์˜ํ•ด ํŠน์ •๋˜๋Š” ํ–‰๋™์„ ์บก์Šํ™”ํ•˜๊ธฐ ์œ„ํ•ด, ์ธํ„ฐํŽ˜์ด์Šค์ธ Dialect์˜ ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” AbstractJdbcConfiguration์ด ์‚ฌ์šฉ ์ค‘์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๊ฒฐ์ •ํ•˜๊ณ  ์˜ฌ๋ฐ”๋ฅธ Dialect๋ฅผ ๋“ฑ๋กํ•˜๋ ค ํ•œ๋‹ค.
(์ด ๋™์ž‘์€ jdbcDialect(NamedParameterJdbcOperations)์„ overwritingํ•ด ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค)

๋งŒ์•ฝ ์•„๋ฌด Dialect๋„ ์‚ฌ์šฉ ๋ถˆ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ๋‹น์‹ ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹œ์ž‘ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ ๊ณต๊ธ‰์—…์ž์—๊ฒŒ Dialect์˜ ๊ตฌํ˜„์ฒด๋ฅผ ์ œ๊ณตํ•˜๋„๋ก ์š”์ฒญํ•ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค. ๋˜๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํ•  ์ˆ˜ ์žˆ๋‹ค :

  1. ๋‹น์‹ ๋งŒ์˜ Dialect๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.
  2. Dialect๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” JdbcDialectProvider๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.
  3. Register the provider by creating a spring.factories resource under META-INF and perform the registration by adding a line
    org.springframework.data.jdbc.repository.config.DialectResolver$JdbcDialectProvider=<fully qualified name of your JdbcDialectProvider>

9.6 Persisting Entities

์ง€์† ์—”ํ‹ฐํ‹ฐ?

aggregate๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒƒ์€ CrudRepository.save()๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ˆ˜ํ–‰๋œ๋‹ค.

  • ๋งŒ์•ฝ ๊ทธ aggregate๊ฐ€ ์ƒˆ๋กœ์šด ๊ฒƒ์ด๋ผ๋ฉด, ์ด๋Š” aggregate root์— ์‚ฝ์ž…๋˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋‚ณ์œผ๋ฉฐ, ์ด์–ด์„œ ๋ชจ๋“  ์ง์ ‘/๊ฐ„์ ‘์ ์œผ๋กœ ์ฐธ์กฐ๋˜๋Š” ์—”ํ‹ฐํ‹ฐ๋ฅผ ์œ„ํ•œ ๊ตฌ๋ฌธ์ด ์‚ฝ์ž…๋œ๋‹ค.
  • ๋งŒ์•ฝ ๊ทธ aggregate๊ฐ€ ์ƒˆ๋กœ์šด ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋ฉด, ๋ชจ๋“  ์ฐธ์กฐ๋œ ์—”ํ‹ฐํ‹ฐ๋“ค์€ ์‚ญ์ œ๋˜๋ฉฐ, aggregate root๋Š” ์ˆ˜์ •๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“  ์ฐธ์กฐ๋œ ์—”ํ‹ฐํ‹ฐ๋“ค์ด ๋‹ค์‹œ ์‚ฝ์ž…๋œ๋‹ค. ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒˆ๋กœ์šด ๊ฒƒ์ธ์ง€ ์—ฌ๋ถ€๋Š” ์ธ์Šคํ„ด์Šค์˜ ์ƒํƒœ์˜ ์ผ๋ถ€๋ผ๋Š” ๊ฒƒ์— ์ฃผ๋ชฉํ•˜๋ผ.

์ด ์ ‘๊ทผ์€ ๋ช‡๋ช‡ ๋ช…ํ™•ํ•œ ๋‹จ์ ๋“ค์ด ์žˆ๋‹ค.

๋งŒ์•ฝ ์ฐธ์กฐ๋œ ์—”ํ‹ฐํ‹ฐ์˜ ์ผ๋ถ€๋งŒ์ด ์‹ค์ œ๋กœ ๋ฐ”๋€Œ์—ˆ๋‹ค๊ณ  ํ•˜๋ฉด, ์‚ญ์ œ์™€ ์‚ฝ์ž…์€ ๋‚ญ๋น„์ด๋‹ค.

์ด ์ ˆ์ฐจ๊ฐ€ ๊ฐœ์„ ๋  ์ˆ˜ ์žˆ๊ณ  ์•ž์œผ๋กœ ๊ฐœ์„ ๋ ์ง€๋ผ๋„, Spring Data JDBC๊ฐ€ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋Š” ์–ด๋–ค ํ•œ๊ณ„๋“ค์ด ์žˆ๋‹ค. ๊ทธ๊ฒƒ์€ aggregate์˜ ์ด์ „ ์ƒํƒœ๋ฅผ ์•Œ์ง€ ๋ชปํ•œ๋‹ค(๋Š” ๊ฒƒ์ด๋‹ค?).

๋”ฐ๋ผ์„œ ๋ชจ๋“  ์ˆ˜์ • ์ ˆ์ฐจ๋Š” ํ•ญ์ƒ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ฐพ๋Š” ๋ฌด์—‡์ด๋“  ๋ชจ๋‘ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋ฉฐ, save๋ฉ”์†Œ๋“œ๋กœ ์ „๋‹ฌ๋œ ์—”ํ‹ฐํ‹ฐ์˜ ์ƒํƒœ๊ฐ€ ๋ฌด์—‡์ด๋“  ๊ทธ ์ƒํƒœ๋กœ ํ™•์‹คํžˆ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค.

์ฒ˜์Œ๋ถ€ํ„ฐ ์ฝ์–ด๋ณด๊ณ  ์žˆ๋Š”๋ฐ ๋„ˆ๋ฌด ๊ธธ๊ธฐ๋„ ํ•˜๊ณ  ๊ตฌ๊ธ€๋ฒˆ์—ญ์€ ๋งŽ์ด ๋ถ€์กฑํ•˜๊ณ  ๋‚ด๊ฐ€ ๋ฒˆ์—ญํ•˜๊ธฐ์—” ๋„ˆ๋ฌด ๋Š๋ฆฌ๋‹คใ…‹ใ…‹ใ… ใ… ...