R2DBC์ ๋ํ ์ง์์ ๊ตฌํํฉ๋๋ค. jdbi-r2dbc
์ ๊ฐ์ ์ ์์ต๋๋ค. ์ฐธ๊ณ ๋ก:
https://r2dbc.io/
https://github.com/r2dbc
๋ํ ๋ฐ์ํ ํ๋ซํผ์ ์ผ๋ถ์ธ vlingo-symbio
์์ Jdbi๋ฅผ ์ง์ํฉ๋๋ค. ํ์ธ ํด๋ด. ์ ์ฒด ํ๋ซํผ์์ ํ์ ์๋๋ฅผ ๋์ด๊ณ ์ถ์ต๋๋ค.
์๋ Vaughn, ํฌ์ธํฐ ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. Reactive๋ ๋งค์ฐ ์๋กญ๊ณ ํฅ๋ฏธ๋กญ์ง๋ง ํ์ฌ JDBC ๊ตฌํ๊ณผ ์ค์ ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ฒ ์ํํธ์จ์ด ์์ฒด๊ฐ ํ์ ๊ณ์ธต์์ Reactive ๊ฐ๋ ์ ์ ํฉํ์ง ์๋ค๋ ์ ์ ์ดํดํฉ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ฒ์๋ ์ฟผ๋ฆฌ๋ฅผ ์ํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ๋ ์์ ์ ํ๋ก์ธ์ค๊ฐ ์์ผ๋ฉฐ ๊ฐ ํ๋ก์ธ์ค๋ ์๋ฃ๋ ๋๊น์ง ์ฟผ๋ฆฌ์ ๋ํด ์๋ํฉ๋๋ค. 10๊ฐ์ ์ฟผ๋ฆฌ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ์ ์ถํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๊ธฐ๋ฅ์ ์์ต๋๋ค.
์ด๊ฒ์ JDBC ๋ฐ์ํ์ ๊ตฌํํ ๋ ๊ฒฐ๊ตญ ์ฐ๊ฒฐ/ํธ๋ค, ์๋น์ค ์ฟผ๋ฆฌ๋ฅผ ๋ณด์ ํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ํ ํ๋ ์์ํฌ๋ก ๋ด๋ณด๋ด๋ ์ด์ ์คํ์ผ์ ์ค๋ ๋ ํ์ ๊ตฌํํด์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์ด๊ฒ์ ๋ฐ์ํ์ ์ด์ ์ค ์ผ๋ถ๋ฅผ ๊ฐ์ง ์ ์์์ ์๋ฏธํฉ๋๋ค. ํนํ ๋ฐ์ํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ง๋ง ๋ฐ์ํ์ด ๋ฌ์ฑํ๋ ค๋ ํ์ฅ์ฑ ์ด์ ์ ์ฌ๊ฐํ๊ฒ ์ ํํฉ๋๋ค.
๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ API ํตํฉ์ ํ์คํ ํ์ํ์ง๋ง, ๋ด๊ฐ ๋ง์ง๋ง์ผ๋ก ์กฐ์ฌํ ์ดํ๋ก JDBC ์ธ๊ณ์ ์ํ๊ฐ ๋ฐ๋์ง ์๋ ํ, ์๋์ ์ฝ๋๊ฐ ์ฌ์ ํ ๊ตฌ์ ์ค๋ ๋ ์ฝ๋๋ผ๋ ์ฌ์ค์ ์จ๊ธฐ๋ ๋ค์ ์ ํ๋ ๋ํผ๊ฐ ๋ ๊ฒ์ ๋๋ค.
๊ทํ์ ํ๋ซํผ์ ๋ํ ์ต์ ์ ๋ณด๋ฅผ ์ป์ ์ ์๋ค๋ ์ ์์ ๊ฐ์ฌํ์ง๋ง ์ฐ๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํ๋ซํผ์ด๋ ํ๋ ์์ํฌ์ ์ผ๋ถ๊ฐ ์๋ ๊ฑฐ์ ์์ ํ ๋ ๋ฆฝํ์ด๋ผ๋ ์ ์ ์๋์ค๋ฝ๊ฒ ์๊ฐํฉ๋๋ค. ๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ์๊ฐ์ ์ฐพ๊ณ ๊ณต์ ๋ชฉํ๋ฅผ ์ํด ํญ์ ๊ธฐ๊บผ์ด ํ๋ ฅํ์ง๋ง, ์ฐ๋ฆฌ๋ ๋งค์ฐ ๋ ๋ฆฝ์ ์ธ ํ๋ก์ ํธ์ ๋๋ค. :)
์ด๋ด, ์คํฐ๋ธ! ๊ทํ์ ์๊ฒฌ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ํ์ฌ ์ฐ๋ฆฌ๋ vlingo-symbio
๊ตฌํ์์ ์กํฐ ๋ด์์ ์์ฒญ์ ์ง๋ ฌํํ์ฌ Reactive-over-JDBC๋ฅผ ํด๊ฒฐํฉ๋๋ค. ์ฐ๊ฒฐ ์ ํ์ ๋ง๋ ๋งํผ JDBCObjectStoreActor
๋ฅผ ๋ง๋ค ์ ์์ง๋ง ์กํฐ ์์ฒด๋ JDBC์ ๋๊ธฐ์ ์ผ๋ก ์ก์ธ์คํฉ๋๋ค. ์กํฐ์์ ์คํ๋๋ ObjectStore
๊ตฌํ์ ํด๋ผ์ด์ธํธ๋ ์ฟผ๋ฆฌ๊ฐ ์ํ๋๋ ๋์ ์ฐจ๋จ๋์ง ์์ต๋๋ค.
๋๋ R2DBC๋ฅผ ์์ ํ ์ดํดํ์ง๋ ๋ชปํ์ง๋ง ์์ ํ JDBC ๋์ฒดํ์ผ๋ก ์ ์ ๋๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋๋ผ์ด๋ฒ๋ก์ ์์ ํ ๋น๋๊ธฐ์์ผ๋ก ์๋ํฉ๋๋ค. ํ์ฌ Postgres ๋ฐ MS SQL Server์ ๋ํ ๊ตฌํ๋ง ์์ง๋ง ์๊ฐ์ด ์ง๋๋ฉด์ ์ฆ๊ฐํ ๊ฒ์ ๋๋ค. Jdbi๊ฐ R2DBC๋ฅผ ํตํด ๊ตฌํํ๋ ๊ฒ์ด ์ด๋ค ๊ฒ์ธ์ง ๊ถ๊ธํฉ๋๋ค. ์ด๊ฒ์ด ์ง๊ธ ๋น์ ์๊ฒ ์๋ฏธ๊ฐ ์๋์ง ์ดํดํ์ง๋ง, ๋์ค์ ๊ทธ๋ด ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ ์ฌ๊ธฐ์ ์ฐธ์กฐ๊ฐ ์์ต๋๋ค. ์คํธ๋ ์ค์๋ :)
ํฅ๋ฏธ๋กญ๊ฒ๋ ๊ทธ๋ค์ ์ค์ ๋ก ์์ฒด ๋๋ผ์ด๋ฒ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋์ ์ฌ๊ธฐ์์ ์ป์ ์ ์๋ ์ด์ ์ด ์์ ์ ์์ต๋๋ค!
๋ฒค์น๋งํฌ, ๊ฐ๋
์ฆ๋ช
์ฝ๋ ๋ฑ์ ์ถ๊ฐ๋ก ํ์ํ๊ณ ์ถ์ต๋๋ค. ๋ช ๊ฐ์ง ์ ํ ์ฌํญ์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค. postgres์ฉ r2dbc ๋๋ผ์ด๋ฒ๋ BLOB
๋ฐ CLOB
์ ํ์ด ๊ทธ๋ ์ง ์๋ค๊ณ ๊ด๊ณ ํฉ๋๋ค. ์์ง ์๋ํ๊ณ ์ ์ฅ ํ๋ก ์์ ๋๋ CALL
๋ํ ์ธ๊ธ์ด ์์ต๋๋ค.
ํ์ง๋ง ์ ์ด๋ ์ง๊ธ์ ๊ฐ์ธ์ ์ผ๋ก ์ด์ ์ ๋ค๋ฅธ ๊ณณ์ ๋๊ณ ์์ผ๋ฏ๋ก ์์ผ๋ก ๋์๊ฐ๊ธฐ ์ํด์๋ ์ปค๋ฎค๋ํฐ์ ์๊ฒฌ๊ณผ ๊ด์ฌ์ด ํ์ํ ์ ์์ต๋๋ค. ์ง๊ธ ์ฌ๊ธฐ์์ ํ์์ ์์ํ ์๊ฐ์ด ์๊ณ ๋ค๋ฅธ ํต์ฌ ๊ตฌ์ฑ์์ด ๋ค์์ ์ฐพ๊ณ ์๋ค๊ณ ์๊ฐํ์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๊ฒ์ ๋ฐ์ด.
์ปค๋ฎค๋ํฐ์ ๋ค๋ฅธ ๊ตฌ์ฑ์๋ค์ด ์ด ๊ธฐ๋ฅ์ด ํ์ํ ๊ธฐ๋ฅ์ด๋ผ๋ ํฌํ๋ง ํด๋ ๋ ๋ง์ ์์์ ๋ค์ ์ ์๊ธฐ๋ฅผ ๊ธฐ๋ํฉ๋๋ค.
์ด ํฐ์ผ์ ๋ณด๋ ๋ฐ๊ฐ์ต๋๋ค.
R2DBC์ ์ํ๋ฅผ ๋ช ํํ ํ๊ธฐ ์ํด ๋ ๊ฐ์ง๋ฅผ ๋น ๋ฅด๊ฒ ์ญ์ ํ๊ณ ์ถ์์ต๋๋ค.
์ด์จ๋ R2DBC๋ Spring Data R2DBC, R2DBC Client(jdbi์์ ์์ด๋์ด๋ฅผ ๋น๋ ค์ฃผ๋ R2DBC SPI ์์ ์๋ ์์ ๋ํผ) ๋ฑ๊ณผ ๊ฐ์ ํด๋ผ์ด์ธํธ ๊ตฌํ์์ SPI๋ฅผ ์ ํํ๋ ๊ฒ์ ๋ชฉํ๋ก ํฉ๋๋ค.
์ ์๋ ํ๋กํ ํ์
/๋ฐ๋ชจ ํด๋ผ์ด์ธํธ ๊ณ์ธต์ธ r2dbc-client
๊ฐ Jdbi์ API์ ์ ์ ์ ๊ธฐ๋ฐ์ผ๋ก ์ค๊ณ๋์๋ค๋ ์ ์ ์ธ๊ธํ๊ณ ์ถ์์ต๋๋ค. ๋ ์์ธํ ์กฐ์ฌํ๊ธฐ๋ก ์ ํํ๋ฉด ์น์ํ๊ฒ ๋๊ปด์ง ๊ฒ์
๋๋ค ๐.
๋๋ ์ฌ๋๋ค์ด JDBI(์: @hgschmie) ์์ Rx ํญ๋ชฉ์ ๋ ธ์ถํ๋ ๊ฒ์ ๋ณด์์ต๋๋ค. R2DBC์ ๋ํ "์ง์"์ด ๋ฌด์์ ์๋ฏธํ๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
JDBI ์์ R2DBC๋ฅผ ๊ตฌํํ๋ ๊ฒ, JDBi๊ฐ R2DBC Connection
s๋ฅผ ์ฌ์ฉํ๋๋ก ํ๋ ๊ฒ, Rx ์ธํฐํ์ด์ค์ ์ด์ ์ ๋ง์ถ๊ธฐ ์ํด JDBI๋ฅผ ๊ต์ฒดํ๋ ๊ฒ, ์๋๋ฉด... ๋ค๋ฅธ ๊ฒ์
๋๊น?
"JDBI ์ธํฐํ์ด์ค๋ฅผ ๋ ธ์ถํ์ฌ JDBI์์ ์ฌ์ฉํ R2DBC ๋๋ผ์ด๋ฒ๋ฅผ ์ง์" ํ๋ค๊ณ ์๊ฐ ํฉ๋๊น?
R2DBC๋ JDBC์ ๋น๋๊ธฐ ๋์ฒดํ์ ๋๋ค.
@brianm R2DBC๋ ThreadPools์ JDBC๊ฐ ์๋๋๋ค. R2DBC๋ ๋ ๊ฐ์ง๋ฅผ ์๋ฏธํฉ๋๋ค.
org.reactivestreams.Publisher
์ ํ์ ๋ฐํํ๋ ๋น์ฐจ๋จ ์ ์ก ๊ณ์ธต์ ์ฌ์ฉํ๋ ๊ตฌํ์
๋๋ค. ๊ทธ๋ค์ ์๋์์ JDBC ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ์ง ์์ง๋ง ์ฒ์๋ถํฐ ์ ์ ํ๋กํ ์ฝ์ ๊ตฌํํฉ๋๋ค.JDBi๊ฐ R2DBC ์ฐ๊ฒฐ์ ์ฌ์ฉํ๋๋ก ํ์ฌ JDBI ์์ R2DBC๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๊น?
์, ์ด๊ฒ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฏธํ๋ ๊ฒ์ ๋๋ค. Project Reactor/RxJava2/Zerodep ์ ํ์ ๋ฐํํ๋ R2DBC ํน์ JDBI ๋ชจ๋์ด ์์ต๋๋ค.
๋๋ R2DBC๊ฐ ๋ฌด์์ธ์ง ํ์คํ ์๊ณ ์์ผ๋ฉฐ ๋งค์ฐ ์ข์ ์ผ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
"JDBI ์ง์"์ด ๋ฌด์์ธ์ง ์์ ๋ด๋ ค๊ณ ๋ ธ๋ ฅ ์ค์ ๋๋ค!
JDBI์ API๋ฅผ ํตํด ์ํํ ๊ฒ์ผ๋ก ์์๋๋ ์ฝ๋ ์ํ์ ์์ฑํ์๊ฒ ์ต๋๊น?
์ด๋ณด์๋ฅผ ์ํด ๋ค์์ ์ง์ํ๋ ๊ฒ์ ์ด๋ป์ต๋๊น?
Jdbi jdbi = Jdbi.create("r2dbc:h2:mem:///test"); // (H2 in-memory database), obtain ConnectionFactory via ConnectionFactories.get(String url)
// Reactor style:
Flux<User> users = jdbi.withHandle(handle -> {
return handle.execute("CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR)")
.then(handle.execute("INSERT INTO user(id, name) VALUES (?0, ?1)", 0, "Alice"))
.then(handle.createUpdate("INSERT INTO user(id, name) VALUES (?0, ?1)")
.bind(0, 1)
.bind(1, "Bob")
.execute())
.then(handle.createQuery("SELECT * FROM user ORDER BY name")
.mapToBean(User.class).many());
});
// RxJava style
Flowable<User> users = jdbi.withHandle(handle -> { โฆ });
์ธํฐํ์ด์ค ๊ธฐ๋ฐ ์ง์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
public interface UserDao {
@SqlUpdate("CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR)")
Completable createTableRxJava();
@SqlUpdate("CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR)")
Mono<Void> createTableProjectReactor();
@SqlQuery("SELECT * FROM user ORDER BY name")
@RegisterBeanMapper(User.class)
Flowable<User> listUsersRxJava();
@SqlQuery("SELECT * FROM user ORDER BY name")
@RegisterBeanMapper(User.class)
Flux<User> listUsersProjectReactor();
}
๋๋ RxJava์ Project Reactor์ ๋ํด ์์ ์ด ์๊ธฐ ๋๋ฌธ์ ๋ API๋ฅผ ๋ชจ๋ ์ฌ์ฉํ์ฌ ๋ณํ์ ๋์ดํ๋ ค๊ณ ํ์ต๋๋ค.
๋๊ตฐ๊ฐ ์ฌ๊ธฐ์์ ์ ํํ ๋ฌด์์ ์ ์ํ๊ณ ์๋์ง ๋ช ํํ ํ ์ ์์ต๋๊น?
R2DBC๋ JDBC ์์ ์๋ ๊ณ์ธต์ ๋๊น, ์๋๋ฉด ์์ฒด์ ์ธ ๊ฒ์ ๋๊น? Jdbi๋ ๊ทน๋จ์ ์ผ๋ก JDBC์ ๊ฒฐํฉ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
R2DBC๋ JDBC ์์ ์๋ ๋ ์ด์ด๊ฐ ์๋๋๋ค. R2DBC๋ SQL ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ก์ธ์คํ๊ธฐ ์ํ ๋น์ฐจ๋จ API์ด๋ฉฐ ๊ณ ์ ํ ๊ฒ์ ๋๋ค(R2DBC ๋๋ผ์ด๋ฒ๋ ์ผ๋ฐ์ ์ผ๋ก ๋น์ฐจ๋จ I/O ๊ณ์ธต์ ์ฌ์ฉํ์ฌ ๊ณต๊ธ์ ์ฒด๋ณ ์์ด์ด ํ๋กํ ์ฝ์ ๊ตฌํํ๋ ์ฒ์๋ถํฐ ์ฒ์๋ถํฐ ์์ฑ๋จ). ์ํ๋ค๋ฉด R2DBC๋ SQL ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํตํฉํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ฐ์ ์ฌ์์ ๋๋ค.
์ฌ๊ธฐ์ ์ ์์ Jdbi์ฒ๋ผ ๋ณด์ด๊ณ ์๋ํ์ง๋ง R2DBC ๋๋ผ์ด๋ฒ ์๋์์ ์ฌ์ฉํ๋ API๋ฅผ ๊ฐ๋ ๊ฒ์ ๋๋ค. API๋ ์ค์นผ๋ผ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ๋์ Reactive Streams ์ ํ์ ๋ฐํํฉ๋๋ค.
์ค๋ช ํด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ์ฌ๊ธฐ์์ ์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ R2DBC ์์ ์์ ์์ ๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ฃผ๋ ์ต์ํ์ PoC ์ญํ ์ ํ๋ Jdbi ํฌํฌ ๋๋ ๋ถ๊ธฐ์ ํ๋กํ ํ์ ์ ๋ง๋๋ ๊ฒ์ ๋๋ค. ๊ฑฐ๊ธฐ์์ ์ฐ๋ฆฌ๋ ๊ธฐ์กด JDBC ์ง์๊ณผ ๋ณํํ์ฌ ํตํฉ์ ํฅํ ๊ฒฝ๋ก๋ฅผ ๊ฒฐ์ ํ๊ฑฐ๋ ์ด๊ฒ์ด ํ๋ ํฌํฌ๋ก ๋ ๋์ ๊ฒ์์ ํ๋ฆฝํด์ผ ํฉ๋๋ค. ์์์ Matthew๊ฐ ์ง์ ํ๋ฏ์ด ์ฐ๋ฆฌ๋ ํ์ฌ JDBC์ ๋ฐ์ ํ๊ฒ ์ฐ๊ฒฐ๋์ด ์์ผ๋ฉฐ ์ด๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ ๋ง์ ๋ ธ๋ ฅ์ด ํ์ํ ๋ฟ๋ง ์๋๋ผ ์ ์ฌ์ ์ผ๋ก ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ด ํ์ํ ์ ์์ต๋๋ค.
ํ๋ก์ ํธ์ ์ฅ๊ธฐ์ ์ธ ๋ ์ด๋์ ์ด๊ฒ์ ํฌํจํ๊ฒ ๋์ด ๊ธฐ์ฉ๋๋ค. ๊ทธ๋ฌ๋ ์๋นํ ์ปค๋ฎค๋ํฐ ์ฐธ์ฌ ์์ด๋ ๋น ๋ฅด๊ฒ ์งํ๋ ๊ฒ์ผ๋ก ๊ธฐ๋ํ์ง ์์ต๋๋ค.
@stevenschlansker ์ฒ์์๋ JDBI ์์ ์๊ฐ์ ๋ฐ์ r2dbc
๋ชจ๋( jdbi-r2dbc
)์ R2DBC Client์ ๊ธฐ์ฌ๋ก JDBI์ ๋ค์ ๋์
ํ๋ pull ์์ฒญ/PoC์ ๋ํด ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์๊ฐํ์ญ๋๊น?
ConnectionFactory cf = โฆ;
Rdbi rdbi = new Rdbi(cf);
rdbi.inTransaction(handle ->
handle.execute("INSERT INTO test VALUES ($1)", 100))
.thenMany(rdbi.inTransaction(handle ->
handle.select("SELECT value FROM test")
.mapResult(result -> result.map((row, rowMetadata) -> row.get("value", Integer.class)))))
.subscribe(System.out::println);
์์ฃผ ๋ฉ์ ธ์. ์, ์์ ์ด ํฉ๋ฆฌ์ ์ผ๋ก ์ํํ๊ฒ ํตํฉ๋ ์ ์๋ค๋ฉด ๊ธฐ๊บผ์ด ๋ชจ๋์์ ๋ฐฐ์ํ ๊ฒ์ ๋๋ค!
Rdbi
api๊ฐ Jdbi
์์ "์จ" ๊ฒฝ์ฐ -- jdbi.installPlugin(...).registerRowMapper(...)
๋ฅผ ์ํํ ๋ Rdbi
์ธ์คํด์ค๊ฐ " "์์ Jdbi
๋ ๊ตฌ์ฑ์ ๊ฐ์ ธ์ต๋๋ค. ๋ํ <strong i="11">@SqlUpdate</strong> CompletableFuture<ResultType> doSomeWork(...);
๋๋ ์ ์ ํ ๋ฐ์ ์ ํ์ด ๋ฌด์์ด๋ ํ ์ ์๋ ๊ฒ์ด ์ข์ต๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ด ํฐ์ผ์ ๋ณด๋ ๋ฐ๊ฐ์ต๋๋ค.
R2DBC์ ์ํ๋ฅผ ๋ช ํํ ํ๊ธฐ ์ํด ๋ ๊ฐ์ง๋ฅผ ๋น ๋ฅด๊ฒ ์ญ์ ํ๊ณ ์ถ์์ต๋๋ค.
์ด์จ๋ R2DBC๋ Spring Data R2DBC, R2DBC Client(jdbi์์ ์์ด๋์ด๋ฅผ ๋น๋ ค์ฃผ๋ R2DBC SPI ์์ ์๋ ์์ ๋ํผ) ๋ฑ๊ณผ ๊ฐ์ ํด๋ผ์ด์ธํธ ๊ตฌํ์์ SPI๋ฅผ ์ ํํ๋ ๊ฒ์ ๋ชฉํ๋ก ํฉ๋๋ค.