Jdbi: Docs / Example: spring-boot์—์„œ jdbi3๋ฅผ ํ†ตํ•ฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ฃผ๋Š” ์˜ˆ์ œ(repo) ์ œ๊ณต

์— ๋งŒ๋“  2018๋…„ 02์›” 20์ผ  ยท  10์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: jdbi/jdbi

jdbi3์„ spring-boot์— ํ†ตํ•ฉํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ธํ„ฐ๋„ท์—์„œ ์ „์ฒด ๊ทธ๋ฆผ์„ ์–ป๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ชจ๋“  ๋ถ€๋ถ„์„ ์ฐพ๊ธฐ๋Š” ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
jdbi3๋กœ ์Šคํ”„๋ง ๋ถ€ํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ฃผ๋Š” github์— jdbi-examples-repository๋ฅผ ์ œ๊ณตํ•  ๊ธฐํšŒ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

์ •๋ง ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
/์…‰

doc help wanted improvement

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋‚˜๋Š” ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ์—†์ด jdbi2.x์™€ ํ•จ๊ป˜ ๋‹ค์Œ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. jdbi3.x๋กœ ํ…Œ์ŠคํŠธํ•ด ๋ณด์•˜์ง€๋งŒ ๋ฌธ์ œ๋Š” ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ jdbi๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋™์•ˆ ํŠธ๋žœ์žญ์…˜์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด spring์„ ์–ป๋Š” ๋” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ํ”„๋ก์‹œ๋ฅผ TransactionAwareDataSourceProxy๋กœ ๋ž˜ํ•‘ํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Jdbi ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ์ œ๊ฐ€ ์ผ๊ด€๋˜๋„๋ก @arteam ์˜ ๋‹ต๋ณ€์—์„œ c/p'd๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค)

    <strong i="8">@Bean</strong>
    public DataSource dataSource() {
        // From Spring Boot's connection pool configuration;
    }

    <strong i="9">@Bean</strong>
    public TransactionAwareDataSourceProxy txDataSource(DataSource dataSource) {
        return new TransactionAwareDataSourceProxy(dataSource);
    }

    <strong i="10">@Bean</strong>
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        //not sure if this is needed
        return new DataSourceTransactionManager(dataSource);
    }

    <strong i="11">@Bean</strong>
    public Jdbi createJdbi(TransactionAwareDataSourceProxy dataSource) {
        //note that parameter is TransactionAwareDataSourceProxy instead of plain DataSource
        return Jdbi.create(dataSource);
    }

    <strong i="12">@Bean</strong>
    public UserDao userDao(Jdbi jdbi) {
        return jdbi.onDemand(UserDao.class);
    }

๋ชจ๋“  10 ๋Œ“๊ธ€

๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ์— Spring์˜ ํŠธ๋žœ์žญ์…˜ ๊ธฐ๋Šฅ๊ณผ์˜ ํ†ตํ•ฉ์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋ฉด Spring ๊ตฌ์„ฑ์—์„œ Jdbi ๋ฐ DAO๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ

    <strong i="7">@Bean</strong>
    public DataSource dataSource() {
        // From Spring Boot's connection pool configuration;
    }

    <strong i="8">@Bean</strong>
    public Jdbi createJdbi(DataSource dataSource) {
        return Jdbi.create(dataSource);
    }

    <strong i="9">@Bean</strong>
    public UserDao userDao(Jdbi jdbi) {
        return jdbi.onDemand(UserDao.class);
    }

@bastman ๋‹˜ , @alwins0n ์€ #989์—์„œ ๋” ๋‚˜์€ Spring ์ง€์›์— ๊ธฐ์—ฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ๊ทธ์˜ ์ž‘์—…์„ ๊ฒ€ํ† ํ•˜๊ณ  Spring ํ†ตํ•ฉ์„ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š”์ง€ ๋˜๋Š” ์•ฝ๊ฐ„ ๋‹ค๋ฅธ ๊ฒƒ์„ ์š”๊ตฌํ•˜๋Š”์ง€ ์—ฌ๋ถ€์— ๋Œ€ํ•ด ์˜๊ฒฌ์„ ๋ง์”€ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

jdbi๋ฅผ ์Šคํ”„๋ง ๋ถ€ํŠธ์— ํ†ตํ•ฉํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. @Configuration ํด๋ž˜์Šค์—์„œ @Bean ์ฃผ์„ ๋ฉ”์„œ๋“œ๋ฅผ ์„ค์ •ํ•˜์—ฌ Jdbi ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. @arteam์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด

๋‚ด ์Šคํ”„๋ง PR์—์„œ ์ˆ˜ํ–‰ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋” ์–ด๋ ค์šด ๊ฒƒ์€ jdbi๋ฅผ ์Šคํ”„๋ง ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ์— ํ†ตํ•ฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋‹น์‹ ์ด ์ฐพ๊ณ ์žˆ๋Š” ๊ฒƒ์ด๋ผ๋ฉด ๋ฐ˜๋“œ์‹œ ํ™•์ธํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์ด๊ฒƒ์ด ์Šน์ธ๋˜๋ฉด ์Šคํ”„๋ง ๋ถ€ํŠธ(2)๋ฅผ ์œ„ํ•œ autoconfiguration/spring-boot-starter๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋‹น์‹ ์ด ์ฐพ๊ณ ์žˆ๋Š” ๊ฒƒ์ด๋ผ๋ฉด. (์ž์‹ ์„ ์‹œ๋„ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์‹ค์ œ๋กœ ์ข‹์€ ์—ฐ์Šต์ž…๋‹ˆ๋‹ค: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-develping-auto-configuration.html )

๋‚˜๋Š” ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ์—†์ด jdbi2.x์™€ ํ•จ๊ป˜ ๋‹ค์Œ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. jdbi3.x๋กœ ํ…Œ์ŠคํŠธํ•ด ๋ณด์•˜์ง€๋งŒ ๋ฌธ์ œ๋Š” ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ jdbi๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋™์•ˆ ํŠธ๋žœ์žญ์…˜์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด spring์„ ์–ป๋Š” ๋” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ํ”„๋ก์‹œ๋ฅผ TransactionAwareDataSourceProxy๋กœ ๋ž˜ํ•‘ํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Jdbi ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ์ œ๊ฐ€ ์ผ๊ด€๋˜๋„๋ก @arteam ์˜ ๋‹ต๋ณ€์—์„œ c/p'd๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค)

    <strong i="8">@Bean</strong>
    public DataSource dataSource() {
        // From Spring Boot's connection pool configuration;
    }

    <strong i="9">@Bean</strong>
    public TransactionAwareDataSourceProxy txDataSource(DataSource dataSource) {
        return new TransactionAwareDataSourceProxy(dataSource);
    }

    <strong i="10">@Bean</strong>
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        //not sure if this is needed
        return new DataSourceTransactionManager(dataSource);
    }

    <strong i="11">@Bean</strong>
    public Jdbi createJdbi(TransactionAwareDataSourceProxy dataSource) {
        //note that parameter is TransactionAwareDataSourceProxy instead of plain DataSource
        return Jdbi.create(dataSource);
    }

    <strong i="12">@Bean</strong>
    public UserDao userDao(Jdbi jdbi) {
        return jdbi.onDemand(UserDao.class);
    }

์ข‹์€๋ฐ ์ด๋Ÿฐ ํด๋ž˜์Šค๊ฐ€ ์žˆ๋Š”์ง€ ๋ชฐ๋ž๋„ค์š”.

์•ž์„œ ์–ธ๊ธ‰ํ•œ PR์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? jdbi์˜ ๊ธฐ๋ณธ์ด ๋˜๋Š” "ํŠธ๋žœ์žญ์…˜ ์ธ์‹" ์—ฐ๊ฒฐ ํŒฉํ† ๋ฆฌ์™€ ๊ด€๋ จํ•˜์—ฌ ์ด๋ฏธ ์ œ์•ˆ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

iirc ์—ฐ๊ฒฐ๊ณผ ํ•ธ๋“ค์ด ๋™๊ธฐํ™” ์ƒํƒœ๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ๋ฌธ์ œ๊ฐ€ ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ds๋Š” ํŠธ๋žœ์žญ์…˜ ์ข…๋ฃŒ ์‹œ ๋‹ซํžŒ ์—ฐ๊ฒฐ(ํŠธ๋žœ์žญ์…˜์— ๋ฐ”์ธ๋”ฉ๋จ)์„ โ€‹โ€‹๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด ์‚ฌ์šฉ๋œ ํ•ธ๋“ค์€ ๋‹ซํžˆ์ง€ ์•Š๊ณ  (์žฌ)์‚ฌ์šฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ•  ๋•Œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ๊ทธ๋‹ค์ง€ ํฐ ๊ฑฐ๋ž˜๊ฐ€ ์•„๋‹ˆ๋ฉฐ ์˜คํžˆ๋ ค ๋ชจ์„œ๋ฆฌ ์ผ€์ด์Šค y์ด๋ฉฐ ๊ท€ํ•˜์˜ ์†”๋ฃจ์…˜์€ ์‚ฌ์šฉ ์‚ฌ๋ก€์˜ 99%์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

์š”์ปจ๋Œ€: ๊ท€ํ•˜์˜ ์ ‘๊ทผ ๋ฐฉ์‹์—์„œ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๋ฆฌ์†Œ์Šค๋Š” ์—ฐ๊ฒฐ์ž…๋‹ˆ๋‹ค. ๋‚ด PR์—์„œ ๊ด€๋ฆฌ ์ž์›์€ ํ•ธ๋“ค์ž…๋‹ˆ๋‹ค.

stringtemplate4 ๋ฐ ๊ทธ๋ฃน ๊ฐ€์ ธ์˜ค๊ธฐ์™€ ํ•จ๊ป˜ jdbi3์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จ๋œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ๋ฌธ์ œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค https://github.com/jdbi/jdbi/issues/1052
์ด ๋ฌธ์ œ์—๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ 2.0.0์—์„œ jdbi3์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์™„์ „ํžˆ ์ž‘๋™ํ•˜๋Š” repo ์Šค์ผˆ๋ ˆํ†ค์— ๋Œ€ํ•œ ๋งํฌ๋„ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Spring์˜ @Transactional ์ฃผ์„์œผ๋กœ @kaandok ์˜ ์†”๋ฃจ์…˜์„ ๊ตฌํ˜„ํ•  ๋•Œ ์—ด๋ฆฐ ํŠธ๋žœ์žญ์…˜์ด ์žˆ์„ ๋•Œ ํ•ธ๋“ค์„ ๋‹ซ๋Š” ๊ฒƒ์œผ๋กœ ์ธํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ๊ถŒ์žฅ/์ ์šฉ ๊ฐ€๋Šฅํ•œ ์†”๋ฃจ์…˜์ด ์žˆ์Šต๋‹ˆ๊นŒ?

"๋ถ€์ ์ ˆํ•œ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ์ง€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์—ด๋ ค ์žˆ๋Š” ํŠธ๋žœ์žญ์…˜์ด ์žˆ๋Š” ํ•ธ๋“ค์ด ๋‹ซํ˜”์Šต๋‹ˆ๋‹ค. ํ•ธ๋“ค์„ ๋‹ซ๊ธฐ ์ „์— ํŠธ๋žœ์žญ์…˜์„ ๋ช…์‹œ์ ์œผ๋กœ ์ปค๋ฐ‹ํ•˜๊ฑฐ๋‚˜ ๋กค๋ฐฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Jdbi๊ฐ€ ์ด ํŠธ๋žœ์žญ์…˜์„ ์ž๋™์œผ๋กœ ๋กค๋ฐฑํ–ˆ์Šต๋‹ˆ๋‹ค."

@cengha ๋ฌธ์ œ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ช‡ ๊ฐ€์ง€ ์ฝ”๋“œ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์•„๋ž˜๋Š” ๊ตฌ์„ฑ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

<strong i="6">@Bean</strong>
public HikariDataSource hikariDataSource() {
    HikariConfig dataSourceConfig = new HikariConfig();
    dataSourceConfig.setDriverClassName(driverClassName);
    dataSourceConfig.setJdbcUrl(jdbcUrl);
    dataSourceConfig.setUsername(username);
    dataSourceConfig.setPassword(password);
    dataSourceConfig.setAutoCommit(true);
    return new HikariDataSource(dataSourceConfig);
}

<strong i="7">@Bean</strong>
public TransactionAwareDataSourceProxy transactionAwareDataSourceProxy(HikariDataSource dataSource) {
    return new TransactionAwareDataSourceProxy(dataSource);
}

<strong i="8">@Bean</strong>
public PlatformTransactionManager platformTransactionManager(HikariDataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

<strong i="9">@Bean</strong>
public Jdbi jdbi(TransactionAwareDataSourceProxy transactionAwareDataSourceProxy) {
    Jdbi jdbi = Jdbi.create(transactionAwareDataSourceProxy);
    jdbi.installPlugin(new SqlObjectPlugin());
    return jdbi;
}

๋‹ค์Œ์€ ์„œ๋น„์Šค ๊ณ„์ธต์ž…๋‹ˆ๋‹ค.

    <strong i="13">@Override</strong>
    <strong i="14">@Transactional</strong>
    public Long createX(X x) {
        Long aLong = XDao.insertX(x);
        if(true) throw new RuntimeException();
        return aLong;
    }

์ž๋™ ์ปค๋ฐ‹์ด false๋กœ ์„ค์ •๋˜๋ฉด ํŠธ๋žœ์žญ์…˜ ์˜ค๋ฅ˜๊ฐ€ ์–ธ๊ธ‰๋˜์—ˆ์ง€๋งŒ true๋กœ ์„ค์ •ํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜ ์˜ค๋ฅ˜๊ฐ€ ์—†์ง€๋งŒ ์ด๋ฒˆ์—๋Š” ๋กค๋ฐฑ์ด ์ž‘๋™ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ(๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ ํ›„) X ๊ฐœ์ฒด๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ด„ 2.0.3, JDBI 3.0.0-beta2๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๋ฌธ์ œ ํ•ด๊ฒฐ๋จ. ์ด ์Šค๋ ˆ๋“œ ๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ๋ชจ๋“  ๊ฒƒ์ด ํ•ด๊ฒฐ๋œ ๊ฒƒ์„ ํ™•์ธํ•œ ํ›„ ์ด์ „ ๋ฒ„์ „์˜ JDBI๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰