ZonedDateTime
๋ด์ฅ๋ ๋งคํผ๊ฐ ์๋๋ฐ SQL์ TIMESTAMP WITH TIME ZONE
๊ฐ ์ง์ ์ง์๋๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง ๋งคํผ๋ ๊ทธ๋ ์ง ์์ต๋๋ค.
์์ญ์ ์ธ์ํ์ง ๋ชปํ๋ ์์ญ ์ธ์ ์ ํ์ ๋ํด ๋งคํผ๋ฅผ ๋ ธ์ถํ๋ ๊ฒ์ ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ์ด ์๋๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๋น์ ์ด ์ณ์์ง๋ง ์ด๊ฒ์ด ํ์ฌ JDBC๊ฐ ์ง์ํ๋ ์ ๋ถ์ ๋๋ค. ๋ชจ๋ java.time ์ ํ์ ์๊ฐ๋/์คํ์ ๋ฐ์ดํฐ๊ฐ ์๋ java.util ๋๋ java.sql ์ ํ์ผ๋ก ๋ณํํด์ผ ํฉ๋๋ค.
ํธ๊ธฐ์ฌ์ Postgres๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๊น? TIMESTAMP WITH TIME ZONE์ด ์์๊ณผ ๋ค๋ฅด๊ฒ ์๋ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
Postgres๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๊น? TIMESTAMP WITH TIME ZONE์ด ์์๊ณผ ๋ค๋ฅด๊ฒ ์๋ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋๋ ์๊ณ ์๋ค. (๊ทธ๋ ์ง ์์ผ๋ฉด ๋งค์ฐ ํ์ค์ ์ค์ํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค btw์ ๋ํ ํฐ ์ค๋ง์ ๋๋ค.)
๋น์ ์ด ์ณ์์ง๋ง ์ด๊ฒ์ด ํ์ฌ JDBC๊ฐ ์ง์ํ๋ ์ ๋ถ์ ๋๋ค.
JDBI๊ฐ H2์ org.h2.api.TimestampWithTimeZone
๋ฅผ ์๋์ผ๋ก ์ํํ ํ์ ์์ด _์ด๋ค ๋ฐฉ์์ผ๋ก_ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๊ธฐ๋ํ์ต๋๋ค.
TIMESTAMP W/TZ ๊ฐ์ ๊ฐ์ ธ์ค๋ "ํด๋์ฉ"(๋ค๋ฅธ ๋๋ผ์ด๋ฒ์์ ์๋) ๋ฐฉ๋ฒ์ ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ์ง์ ํ ์๋ฃจ์
์ด ์์ต๋๋ค.
๊ทธ๋ฌ๋ ๋ชจ๋ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค์ง ์๋๋ค๋ฉด ๊ทธ๋ ๊ฒ ํ๋ ์ฒ ํด์๋ ์ ๋ฉ๋๋ค. ์ฆ, IMO์๋ ZonedDateTime
๋ํ ๋ด์ฅ ๋งคํผ๊ฐ ์์ด์ผ ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด Postgres์ฒ๋ผ ํ๊ณ ์์ต๋๋ค. ๋ด๊ฐ ๊ธฐ๋ํ ๊ฒ๊ณผ๋ ๋ค๋ฆ
๋๋ค.
์ฌ์ฉ์๊ฐ ZonedDateTime
๋ฅผ ์ฌ์ฉํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๊ฐ๋ ๋์ ์ฑ ์๋ฒ์ ์๊ฐ๋์์ ๋ฐํ๋๋ ๊ฒ์ ์ ๊ฒฝ ์ฐ์ง ์๋๋ค๋ฉด ์ฌ์ ํ ํธ๋ฆฌํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ทธ๊ฑด ๊ทธ๋ ๊ณ , Dropwizard๋ ์ฌ์ฉ์๊ฐ ๋ช ์์ ์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๊ฐ๋๋ฅผ ์ค์ ํ ์ ์๋ JDBI2์ฉ ๋ค๋ฅธ ๋ฒ์ ์ ๋งคํผ๋ฅผ ์ฌ์ฉํฉ๋๋ค. https://github.com/dropwizard/dropwizard/blob/master/dropwizard-jdbi/src/main/java /io/dropwizard/jdbi/args/ZonedDateTimeMapper.java
H2๋ก ZonedDateTime
๋ฅผ ๊ฐ์ ธ์ค๊ฑฐ๋ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์์ ์ฝ๋๋ฅผ ์ ๊ณตํ ์ ์๋ค๋ฉด ๊ธฐ๊บผ์ด ํ๋ฌ๊ทธ์ธ์ ์ถ๊ฐํ๊ฒ ์ต๋๋ค.
์ฌ์ฉ์๊ฐ ZonedDateTime์ ์ฌ์ฉํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๊ฐ๋ ๋์ ์ฑ ์๋ฒ์ ์๊ฐ๋์์ ๋ฐํ๋๋ ๊ฒ์ ์ ๊ฒฝ ์ฐ์ง ์๋๋ค๋ฉด ์ฌ์ ํ ํธ๋ฆฌํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
@arteam , ์ฌ์ฉ์๊ฐ ์ด๋ฌํ ์ ํ์ ํ๋ ๊ฒ์ ์๊ณ ์๋ค๋ฉด ๋์ํฉ๋๋ค.
๊ทธ๋ฌ๋ AFAIR https://github.com/jdbi/jdbi/blob/master/core/src/main/java/org/jdbi/v3/core/mapper/BuiltInMapperFactory.java#L182 ๋ H2์์๋ ์๋ํ์ง ์์ต๋๋ค. TS w TZ, rs.getTimestamp(..)
๋ ํด๋น ์ ํ์ ๋ํด ์ง์๋์ง ์์ต๋๋ค.
H2๋ก ZonedDateTime์ ๊ฐ์ ธ์ค๊ฑฐ๋ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์์ ์ฝ๋๋ฅผ ์ ๊ณตํ ์ ์๋ค๋ฉด ๊ธฐ๊บผ์ด ํ๋ฌ๊ทธ์ธ์ ์ถ๊ฐํ๊ฒ ์ต๋๋ค.
๋๋ ์ด์ ๊ฐ๋ฅํ ๋ฐฉ๋ฒ์ ๋ชจ๋ฆ
๋๋ค. ๋ด๊ฐ ์๋ ์ ์ผํ ๋ฐฉ๋ฒ์ (org.h2.api.TimestampWithTimeZone) rs.getObject(..)
์ด๊ณ ์๋ฅผ ๋ค์ด Oracle์ ๊ฒฝ์ฐ ๋น์ทํ์ง๋ง Oracle ์ ์ฉ ํด๋์ค๊ฐ ์์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก API์ ์ํด _๊ฐ์ _๋์ด ์ฌ๋ฐ๋ฅธ ๋ณํ( LocalDateTime
ํ์์คํฌํ)์ ์ฌ์ฉํ๊ณ ๋ช
์์ ์ผ๋ก "zone-ing"์ ์ถ๊ฐํ๋ ๊ฒ์ ์ ํธํฉ๋๋ค.
๋น์ ์ ๋์ํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ฆ, ์ด ๋ฌธ์ ๋ฅผ ๊ณ์ ์ด์ด๋ ํ์๊ฐ ์์ต๋๋ค.
์ฐ๋ฆฌ๊ฐ ์คํ์์ ์ํํ๋ ํ ๊ฐ์ง๋ ์ค์ ๋ก Java์ ์๊ฐ๋ == Postgres์ ์๊ฐ๋๋ผ๊ณ ์ฃผ์ฅํ๋ฉฐ, ์ด ๊ฒฝ์ฐ ๋ชจ๋ ๊ฒ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํฉ๋๋ค. ๋ถ์ผ์น๊ฐ ์๋ ๊ฒฝ์ฐ ๊ฒฝ๊ณ ๋ฅผ ํ์ํด์ผ ํฉ๋๊น? ์ฌ๋๋ค์ด ๊ธฐ๋ํ๋ ๊ธฐ๋ฅ์ ํ์ฑํํ๋ ๊ฒ๊ณผ TZ๋ฅผ ์ค์ํ๋ ๊ฒ ์ฌ์ด์์ ๊ด์ฐฎ์ ํํ์ด ๋ ๊น์?
์ ๊ทธ๋ ๊ฒ ๋นจ๋ฆฌ ๋ซ์๋์ง ๋ชจ๋ฅด๊ฒ ์ง๋ง, ๋ ๋ ผ์ํ ๊ฒ์ด ์๋ค๊ณ ๋๊ผ์ต๋๋ค.
๋ชจ๋ ๊ณต๊ธ์ ์ฒด์ ๋ํด ์ด ๋ฌธ์ ๋ฅผ ์ผ๋ฐ์ ์ผ๋ก ํด๊ฒฐํ ์๋ ์๋๋ผ๋ ๊ณต๊ธ์ ์ฒด๋ณ๋ก ์ด๋ฅผ ํ์คํ ์ง์ํ ์ ์์ต๋๋ค.
Jdbi์ ํจ๊ป ์ ๊ณต๋๋ ๋งคํผ ๋ฐ ์ธ์ ํฉํ ๋ฆฌ๋ ๋ค๋ฅธ ๋งคํผ/์ธ์๋ฅผ ๋ฑ๋กํ์ฌ ๊ฐ๋จํ ์ฌ์ ์ํ ์ ์์ต๋๋ค. ๋ง์ง๋ง ๋ฑ๋ก(์ ํ๋ณ)์ด ์ฐ์ ํฉ๋๋ค.
PostgresPlugin
์ ๋ํ ์์ค๋ฅผ ๋ณด๋ฉด LocalDate
, LocalTime
๋ํด LocalDate
ResultSet.getObject(Class)
๋ฅผ ์ฌ์ฉํ์ฌ ๋์ฒด ๋งคํผ๋ฅผ ์ ๊ณตํ๋ JavaTimeMapperFactory
๋ฅผ ๋ฑ๋กํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. LocalTime
, LocalDateTime
๋ฐ OffsetDateTime
, Postgres JDBC ๋๋ผ์ด๋ฒ์์ ์ง์ ์ง์ํฉ๋๋ค.
H2์ ์์ญ์ ์๋ตํ์ง ์๊ณ ZonedDateTime
๋ฅผ ์ ์ฅํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์ผ๋ฉด H2DatabasePlugin
๋ฅผ ์์ ํ์ฌ ์ฌ์ฉ์ ์ง์ ๋งคํผ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ง๊ธ์ ์ด๊ฒ์ ๋ค์ ์ด๊ฒ ์ต๋๋ค. ์ฌ๊ธฐ์ ์ข์ ํ ๋ก ์ด ์์ต๋๋ค. @findepi ์ฐ๋ฆฌ๋ ์ผ์ ์ฌ๋ฐ๋ฅด๊ฒ ํ๋ ๋ฐ ๋ง์ ๊ด์ฌ์ ๊ฐ์ง๊ณ ์์ต๋๋ค! ์ฐ๋ฆฌ๋ ๋ํ ์ค์ฉ์ ์ด๊ณ ์ฌ๋๋ค์ ์ค์ ๋ก ์๊ฐ ์ ํ์ ์ฌ์ฉํ ์ ์๊ธฐ๋ฅผ ๊ธฐ๋ํฉ๋๋ค...
์ด ๋ํ์์ jdbi ํ์ด ์๋ฅผ ๋ค์ด hsqldb์ ๋ํ ์ธ์์ ๋งคํผ๋ฅผ ์ ๊ณตํ๋ jdbi3-hsqldb subproject/artifact/...๋ฅผ ๊ฐ๋ ๋ฐ ๊ด์ฌ์ด ์๋ค๋ ๊ฒ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ดํดํ๊ณ ์์ต๋๊น? ๋ณํ)?
์ ์ ์ผ๋ก.
์์งํ ๋งํด์ ๋๋ jdbi๊ฐ ์ง์๋์ง ์๋ ์๊ฐ๋/์คํ์ ๊ณผ ๊ฐ์ด ์ค์ ๋ก ์ ํํ๊ฒ ๋งคํ๋ ์ ์๋ ๊ฒ์ ๋ํ ๋งคํผ๋ฅผ ์ ๊ณตํด์๋ ์ ๋๋ค๊ณ ๋งํ @findepi์ ๋์ํฉ๋๋ค... ์ฌ๊ธฐ์์ "ํํ"์ด๋ผ๋ ์์ด๋์ด๋ ๋งค์ฐ ์ํํ๊ฒ ๋ค๋ฆฝ๋๋ค. ์ ์๊ฒ - ์ ๋ ํญ์ ์ ์ฒด ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ๋ชจ๋ ํ๋ก์ ํธ์์ ๊ฐ์ฅ ๋์ ์ฐ์ ์์ ์ค ํ๋๋ก ๊ฐ์ฃผํด ์์ต๋๋ค. ์ฌ์ฉ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ๋ค์ ํ์ธํ ํ์๊ฐ ์์ต๋๋ค.
jdbi์์ ์ ๊ณตํ๋ ๋งคํผ๊ฐ ๋ชฐ๋ ๋ณ๊ฒฝ๋์์ ๋๋ฅผ ์๋ ๊ฒ๋ณด๋ค jdbi๊ฐ ์ฃผ์ด์ง ์ ํ์ ๋ํ ๋งคํผ๋ฅผ ์ ๊ณตํ์ง ์๋๋ค๋ ๊ฒ์ ํ ์คํธ ์คํ ์ค์ ๋ฐํ์ ์์ธ๋ก ์์๋ธ ๋ค์ ์ง์ ์์ฑํ๊ณ ์ถ์ต๋๋ค. ๋ด ๋ฐ์ดํฐ.
db ์์ฒด(hsqldb)์ jdbi ๋ชจ๋์์ ๊ตฌํ ์ ํ์ฑ/๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ํ์ธํ๊ธฐ ์ํด ์ฌ๋ฌ ์ ํ์ ๊ฐ์ ์ฐ๊ณ ์ฝ๋ ๋๊ท๋ชจ ๋จ์ ํ ์คํธ๊ฐ ์์ผ๋ฏ๋ก ๋ชจ๋ ๋ฌธ์ ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด jdbi ๋งคํผ/์ธ์๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ๋๋ hsqldb๊ฐ ํ์ฌ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ทธ๋ ๊ฒ ๋งํ๋ ์ฌ์์๋ ๋ถ๊ตฌํ๊ณ java.time์ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์(๊ฑฐ๋ํ ๋ฒ๊ทธ) ๋ช ๊ฐ์ง๋ฅผ ์์ฑํด์ผ ํ์ต๋๋ค. ๋๋ ์์ง ๋ด ์์คํ ์ด ์๋ ๋ค๋ฅธ ์์ญ/์คํ์ ์ผ๋ก java.time ๊ฐ์ฒด๋ฅผ ํ ์คํธํ ์๊ฐ์ ํ์ง ์์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฅ ํ๊ณ , ์ถฉ๋ถํ ํ์คํ, ๊ทธ๊ฒ๋ค์ ๋ชจ๋ ์์คํ ๊ฐ์ผ๋ก ๋ฆฌ์ ๋ ์คํ์ /์์ญ์ผ๋ก ๋์์ค์ง๋ง jdbi์ ๋งคํ์ผ๋ก ์ธํด hsqldb ๋ฒ๊ทธ ๋๋ฌธ์ด ์๋๋ผ Timestamp๋ก.
๊ฒฐํจ์ด ์๋ ๋งคํผ๋ฅผ jdbi3์์ ์ ๊ฑฐํ๊ณ ํด๋น ๊ตฌํ์ด ์์ ํ ์์ ๋ ์ ์๋ ๊ณต๊ธ์ ์ฒด๋ณ ์ํฐํฉํธ(jdbi3-hsqldb ๋ฐ ๊ธฐํ)๋ก ์ด๋ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ด์จ๋ ์ด๋ฏธ ๋ด ์์ ์ ํ๋ก์ ํธ์ ํ์ํ ๋ชจ๋ ๋งคํผ์ ์ธ์๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ jdbi-hsqldb๋ฅผ ์ง์ ๊ธฐ์ฌํ ์ ์์ต๋๋ค.
๋๋ ์๋ง๋ ๋ ํ๋ช ํ ๊ธธ์ด์์ ๊ฒ์ด๋ผ๋ ๋ฐ ๋์ํ์ง๋ง ์ด ์์ ์์ v3๊ฐ ์ถ์๋๊ณ ๊ณ ์์ด๋ ๊ฐ๋ฐฉ์์ ๋ฒ์ด๋ฌ์ต๋๋ค.
์ด๋ฌํ ๋งคํผ ๋๋ ์ธ์ ํฉํ ๋ฆฌ๋ฅผ ์ ๊ฑฐํ๋ฉด ์ด์ ์์กดํ๋ ๊ธฐ์กด ์ฌ์ฉ์๊ฐ ํฌ๊ฒ ๋ณ๊ฒฝ๋ฉ๋๋ค.
๋๊ตฐ๊ฐ๊ฐ ์ด๋ฏธ ๊ทธ๋ค์๊ฒ ์์กดํ๊ณ ์๋ค๋ฉด(๊ฒฐํจ์ ์๊ณ ์๋ ์๋ ) ํด๋น ์ฌ์ฉ์๊ฐ ๋ค์ ํจ์นํ๋ ๊ฒ์ด ์ถฉ๋ถํ ๊ฐ๋จํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋ณํ์ ๊ฑฐ์ ํ ์ค์ง๋ฆฌ์
๋๋ค. ๋ฐ๋ฉด์ ๊ทธ๊ฒ๋ค์ ์ ์งํ๋ ๊ฒ์ ๊ทธ๊ฒ์ด ์ ๊ณต๋๊ธฐ ๋๋ฌธ์ ์๋ํ๋ค๊ณ ๊ฐ์ ํ๋ ๋์ ๊ฐ์ ์ ์ ๋ ๋ง์ ์ฌ๋๋ค๋ก ์ด์ด์ง ๊ฒ์ด๋ฉฐ(์์งํ, ๋๊ฐ jdbc์ ํ์ค ์๊ฐ๋ ์ง์๊ณผ ๊ฐ์ ๋ชจ๋ ๊ธฐ์ ์ฌ์์ ๋ง์์ผ๋ก ์๊ณ ์์ต๋๊น?) ๊ทธ๋ด ์๋ ์๊ณ ์๋ ์๋ ์์ต๋๋ค. ๋์ค์ ๊ทธ๋ค์ ๋ฐ์ดํฐ๊ฐ ์๋ชป ์ฒ๋ฆฌ๋์๋ค๋ ๊ฒ์ ์๊ฒ ๋ฉ๋๋ค...
๊ธฐ๋ณธ์ ์ผ๋ก ๋๋ ๊ทธ๊ฒ๋ค์ ๊ทธ๋๋ก ๋์ด์ ์ ์ฌ์ ์ธ ๋ฏธ๋์ ํผํด๊ฐ ๊ทธ๊ฒ๋ค์ ์ ๊ฑฐํ์ฌ ์
๋ฐ์ดํธํ ์์์๊ฒ ์ง๊ธ ์
ํ ํผํด๋ณด๋ค ํจ์ฌ ๋ ํฌ๋ค๊ณ ์๊ฐํฉ๋๋ค.
@TheRealMarnes ์ ์๊ฐ์ ๊ธฐ๋ฅ์ ์ ๊ฑฐํ๋ ๊ฒ์ (์ฐ๋ฆฌ๊ฐ ๊ทธ๊ฒ์ด ์กด์ฌํ์ง ์์์ผ ํ๋ค๋ ๋ฐ ๋์ํ๋๋ผ๋) ๊ทธ๋ ๊ฒ ๊ฐ๋จํ์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ฌ๋๋ค์ ์๋ฏธ๋ก ์ ๋ฒ์ ๊ด๋ฆฌ๋ฅผ ๊ฐ์ ํ๋ ๊ฒฝํฅ์ด ์์ต๋๋ค(ํ๋ก์ ํธ๊ฐ ์ด๋ฅผ ๋ฐ๋ฅด๋ ๋ฐ๋ฅด์ง ์๋ ). ํ๋ก์ ํธ ๊ท์น์ ๋ชจ๋ฅด์ง๋ง ์ผ๋ฐ์ ์ผ๋ก v3์์ ๋ ์ด์ ์ฌ์ฉํ์ง ์์ ๊ฒ์ ๋๋ค(์ฌ์ฉ๋์ง ์๋ ๊ฒ์ผ๋ก ํ์ํ ์ ์๋ API ๋ฉ์๋๊ฐ ์๊ณ ๋ฌธ์ ๋ฐ ๋ก๊น ์ด ๋จ์ ์๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์ ์ฌ์ฉ ์ค๋จ์ ๊น๋ค๋กญ์ต๋๋ค). v4์์ ๊ธฐ๋ฅ์ ์ ๊ฑฐํฉ๋๋ค. , ์ฌ๋๋ค์ด ๋ฆด๋ฆฌ์ค ์ ๋ณด/๋ง์ด๊ทธ๋ ์ด์ ๊ฐ์ด๋๋ฅผ ์ฝ์ ๊ฒ์ผ๋ก ๊ธฐ๋ํฉ๋๋ค.
๋๋ ๊ทธ๋ฐ ์ผ์ด ๊ฒฐ์ฝ ๊ฐ๋จํ์ง ์๊ณ ํด๊ฒฐ์ฑ ์ด ํญ์ ๋๊ตฐ๊ฐ๋ฅผ ๋ถํํ๊ฒ ๋ง๋ค ๊ฒ์ด๋ผ๋ ๋ฐ ๋์ํ์ง๋ง, ๋๋ ๋ชฉ์ ์ด ์๋จ์ ์ ๋นํํ๊ณ ๊ฒฐํจ์ด ์๋ ์์คํ ์ ๋ ๋์ ์์คํ ์ผ๋ก ๊ต์ฒดํ๋ ๊ฒ์ ์ฅ๊ธฐ์ ์ผ๋ก ํญ์ ํ๋ฅผ ๋ผ ๊ฐ์น๊ฐ ์๋ค๊ณ ์๊ฐํ๋ ๊ฒฝํฅ์ด ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ๋๋ค์ด ๋ฆด๋ฆฌ์ค ๋ ธํธ/๋ง์ด๊ทธ๋ ์ด์ ๊ฐ์ด๋๋ฅผ ์ฝ์ ๊ฒ์ด๋ผ๊ณ ๊ธฐ๋ํ๋ ๊ฒ์ ๋นํฉ๋ฆฌ์ ์ด๋ผ๊ณ ์๊ฐํ์ง ์์ต๋๋ค... ์ ์ง ๊ด๋ฆฌ ๋ฐ ๋ง์ด๋ ์ ๋ฐ์ดํธ๋ ๋ฌผ๋ก ์ด์ง๋ง ์ฃผ์ ์ ๋ฐ์ดํธ๋ ์๋๋๋ค. Jdbi3 ์์ฒด๋ ์๋ก์ด ๊ฐ์ด๋๋ฅผ ์ฝ์ง ์๊ณ ๋ jdbi2์์ ์ค๋ ๊ฒ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋๋ ๊ทธ ๋งคํผ/์ธ์๋ฅผ ๋นํ์ฑํํ๋ ์๋ฃจ์ ์ ๋ค์์ ์ป์ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋จ ํ ์ค์ง๋ฆฌ๋ก ๋ณต์ํ๋ฉด ํด๋น ๋งคํผ๋ฅผ ํ๋ฌ๊ทธ์ธ์ผ๋ก ์ฎ๊ธธ ์ ์์ต๋๊น?
๊ณต๊ธ์
์ฒด์ ํ์ ๋์ง ์์ jdbi3-core-experimental
?
ํธ์ง: ๋ด ๋์, ๋น์ ์ jdbi.installPlugin(new ExperimentalMappersPlugin())
์ด๊ฒ์ด ์ค์ ๋ก '์คํ์ '์ธ ๊ฒ์ ์๋์ง๋ง ์์ด๋์ด๊ฐ ๋ ๊ฒ์ ๋๋ค.
TimezoneInsensitiveJavaTimeMappers ๋ค์ :P
๋งคํผ๋ฟ๋ง ์๋๋ผ ์ธ์ ํฉํ ๋ฆฌ์ด๊ธฐ๋ ํฉ๋๋ค.
JavaTimeYoloTZPlugin
์ด๋์?:์ํฌ:
๋ชจ๋ ๊ณต๊ธ์ ์ฒด์ ๋ํด ์ด ๋ฌธ์ ๋ฅผ ์ผ๋ฐ์ ์ผ๋ก ํด๊ฒฐํ ์๋ ์๋๋ผ๋ ๊ณต๊ธ์ ์ฒด๋ณ๋ก ์ด๋ฅผ ํ์คํ ์ง์ํ ์ ์์ต๋๋ค.
@qualidafial ์ ๋ ์ต๊ทผ์ Java8 ์ดํ ์ธ๊ณ์์ ๋ ์ง/์๊ฐ ๊ฐ์ ๊ฒ์ํ๊ธฐ ์ํ ์ฌ์ค์์ ํ์ค์ด ๋ถ์ํ๊ณ ์๋ ๊ฒ ๊ฐ๋ค๋ ๊ฒ์ ๋ฐฐ์ ์ต๋๋ค.
๋จผ์ ๋ฐฐ๊ฒฝ์ด ์กฐ๊ธ ๋ ์์ต๋๋ค.
TIMESTAMP WITH TIME ZONE
ZonedDateTime
๋ก์ ๋ณํ์ ๋ํด ์ด ๋ฌธ์ ๋ฅผ ๋ง๋ค์์ต๋๋ค. ์ด๋ ์๊ฐ๋ ์ ๋ณด๋ฅผ ์ญ์ ํฉ๋๋ค.TIMESTAMP
, DATE
, TIME
๊ฐ์ฒด๊ฐ ๊ฒ์๋๋ ๋ฐฉ์์
๋๋ค. ์ฆ, java.sql.{Timestamp,Date,Time}
ํด๋์ค๋ฅผ ์ฌ์ฉํฉ๋๋ค. ํด๋์ค๋ ๋ชจ๋ java.util.Date
์์ ํ์ฅ๋ฉ๋๋ค. Calendar
๊ฐ ์ด๋ป๊ฒ ๋์
๋์๊ณ java.util.Date
์ ๋ฉ์๋๊ฐ ๋
/์/์ผ/์/๋ถ/์ด๋ฅผ ์ฒ๋ฆฌํ๋์ง ๊ธฐ์ตํ๋ ์ฌ๋์ด ์์ต๋๊น? ๊ทธ๋ด๋งํ ์ด์ ๊ฐ ์์ต๋๋ค( Calendar
๊ฐ ๋ชจ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค๋ ์๋ฏธ๋ ์๋๋๋ค).java.sql.Timestamp
๋ฅผ ๊ฒ์ํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ฏธ๊ตญ์์ ์คํ๋๋ ์ฑ์ ์ผ๋ถ ๊ณต์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ 2017-03-26 02:30:00
์ ํ์์คํฌํ ๊ฐ(์์ญ ์์ด!)์ ์ ์ฅํ ์ ์์ง๋ง ์ ๋ฝ์์ ์คํ๋๋ ์ฑ(์: Europe/Berlin
์ JVM ์์ญ์ผ๋ก ์ฌ์ฉ)์ ์ ์ฅํ์ง ์์ต๋๋ค. ๋น์ ์ ๋ฝ์๋ DST๊ฐ ์์๊ธฐ ๋๋ฌธ์ ์ด ํ์์คํฌํ๋ฅผ ๊ฒ์ํ ์ ์์ต๋๋ค.java.sql.Date
์๋ ๋์ผํ๊ฒ ์ ์ฉ๋ฉ๋๋ค. java.sql.Date
๋ ์์ ์ java.sql.Timestamp
๊ฒ์ฒ๋ผ ๋ ์ง๋ฅผ ๋ํ๋ด์ง๋ง ์์ ์ด ์๋ ๊ฒฝ์ฐ๋ ์์ต๋๋ค. ์์ ์ DST๊ฐ ๋ณ๊ฒฝ๋๋ ๊ตฌ์ญ์ด ์์ต๋๋ค(ํ์ฌ ๋๋ ๊ณผ๊ฑฐ).java.sql.Time
๋ ๊ฒ์๋ ์๊ฐ์ 1970-01-01์ ํ์์คํฌํ๋ก ๋ํ๋ด๊ธฐ ๋๋ฌธ์ ์ด ๋ฌธ์ ๊ฐ ์๋ค๊ณ ์๊ฐํ์ญ๋๊น? ๋ถํํ๋ ํด๋น ๋ ์ง์ ์ ์ฑ
์ด ๋ณ๊ฒฝ๋ ๋งํผ ์ถฉ๋ถํ ์ข์ ์์ญ์ด ์๊ธฐ ๋๋ฌธ์(์: America/Bahia_Banderas
, America/Hermosillo
). JVM์ด ์ด๋ฌํ ์์ญ์ธ ๊ฒฝ์ฐ JDBC๋ฅผ ์ฌ์ฉํ๋ ํ๋ก๊ทธ๋จ์ ํน์ TIME
๊ฐ์ ๊ฒ์ํ ์ ์์ต๋๋ค.ํด๊ฒฐ์ฑ ์ JDBC ์ด์ API๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒ์ํ๊ณ ์ด๋ฅผ ์ ํด๋์ค๋ก ๋ณํํ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ์ผ๋ฐ์ ์ผ๋ก ์๋ชป๋์์ต๋๋ค.
resultSet.getTimestamp(col).toLocalDateTime()
~resultSet.getDate(col).toLocalDate()
~resultSet.getTime(col).toLocalTime()
~์ด๊ฒ์ ์์์ ์ค๋ช
ํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ง ๋ชปํ๋ค๋ ์ ์ ์ ์ธํ๊ณ ๋ ์ ์ปดํ์ผ๋๊ณ ์๋ํฉ๋๋ค(JVM ์์ญ์ด Pacific/Apia
์ด๊ณ ๊ฒ์๋ ๋ ์ง๊ฐ 2011-12-30
์ธ ๊ฒฝ์ฐ ๋ ์ง ๊ฒ์๋ ์๋ํ์ง ์์ ;)
์ด์ ๋ ์ค๋ฅด๋ ์๋ฃจ์
์ผ๋ก. ResultSet
์๋ JDBC ๋๋ผ์ด๋ฒ์ ์ ํ์ ๋ณํํ๋๋ก ์์ฒญํ ์ ์๋ ๋ ์ธ๊ธฐ ์๋ API๊ฐ ์์ต๋๋ค.
resultSet.getObject(col, LocalDateTime.class) // for TIMESTAMP
resultSet.getObject(col, LocalDate.class) // for DATE
resultSet.getObject(col, LocalTime.class) // for TIME
resultSet.getObject(col, ZonedDateTime.class) // for TIMESTAMP WITH TIME ZONE
์ด๊ฒ์ PostgreSQL, MySQL, Oracle ๋ฐ H2์ฉ JDBC ๋๋ผ์ด๋ฒ์ ํจ๊ป ์๋ํ๋ ๊ฒ์ผ๋ก ๋ณด์
๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ง์ ์ ์์์ ์ค๋ช
ํ "JVM ์์ญ์ ํํ ๋ถ๊ฐ๋ฅ์ฑ" ๋ฌธ์ ๋ฅผ ์ฐํํฉ๋๋ค.
์ด ๋ณํ์ด ์๋ฅผ ๋ค์ด SQL Server ๋๋ผ์ด๋ฒ์์ ์์ง ๊ตฌํ๋์ง๋ ์์์ง๋ง ์ด๊ฒ์ด JDBI๊ฐ ์ ๊ณตํ๋ Java ์๊ฐ ํด๋์ค์ ๋ํ ๊ธฐ๋ณธ ๋งคํ์ด ๋ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ฉ๋ชจ:
JDBC 4.2 ์ฌ์์ ๋๋ผ์ด๋ฒ๊ฐ ์ด๊ฒ์ ๊ตฌํํด์ผ ํ๋ค๊ณ ์๊ตฌํ์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ฌ์์์๋ PreparedStatement.setObject
๋ฐ RowSet.setObject
๊ฐ Java Time ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์๋ฝํ๊ณ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํด์ผ ํ๋ฏ๋ก ๋๋ผ์ด๋ฒ๋ ์ด์จ๋ ์ด๋ฌํ ํด๋์ค๋ฅผ ๋ช
์์ ์ผ๋ก ์ง์ํด์ผ ํฉ๋๋ค.
๋ฉ์ง๋ค! ๋ด ์ฃผ์ ๊ด์ฌ์ฌ๋ ์ด ์ ๊ทผ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝํ๋ฉด ๋ํดํ ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ๋ ์ฌ์ฉ์์๊ฒ ํดํ์ผ๋ก ๋ํ๋ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ๋ฆด๋ฆฌ์ค ๋ ธํธ์ ์ ์ ํ ๋ฉ์์ง๋ฅผ ์ ๋ฌํ๋ฉด ์ฌ๋ฐ๋ฅธ ๋ฐฉ์์ผ๋ก ์ผ์ ํ๋ค๋ ๋ช ๋ชฉ์ผ๋ก ๊ธฐ์ ์ ์ผ๋ก ์ด ์์ ๋ณํ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค...
@stevenschlansker ๋น์ ์ด ๋ง์ต๋๋ค. JDBI๊ฐ ์ ๊ณตํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ถ ๋ฒ์ ์ผ๋ก ์ ์งํฉ์๋ค, ์ฐ๋ฆฌ๋ ๋ฐฉ๊ธ 3์ ๋ฆด๋ฆฌ์คํ์ต๋๋ค. ์ด๊ฒ์ ์๋ชป ์ ์งํ๋ฉด ๋ธ๋ ์ดํน ์ฒด์ธ์ง์ผ ๋ฟ์ ๋๋ค... ;)
๋ด๊ฐ ๋ฃ๊ณ ์๋ ๊ฒ์ฒ๋ผ ๋ค๋ฆฌ๋ ๊ฒ์ ์ฌ์ํ๋ ค๋ฉด :
YoloTimePlugin
์ข์์).ResultSet.getObject(column, type)
๋ฅผ ์ฌ์ฉํ๋ ์ ๋ด์ฅ ๋งคํผ๋ฅผ ๋์ ์ถ๊ฐํฉ๋๋ค.์ด ๋ค์ ๊ฐ ์ ์์ต๋๋ค.
์ฐ๋ฆฌ๋ ์ฌ์ ํ ์ด๋ฌํ ๋ ์ง/์๊ฐ ๊ฐ์ฒด๋ฅผ ๋ฐ์ธ๋ฉํ๋ ๊ฒ์ ๋ํ ์ง๋ฌธ์ ๋๋ตํ์ง ์์์ต๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ธ๋ถ์ ๋งคํ ๊ฒฐ๊ณผ์ ๋ํด ๋ณ๊ฒฝํ๋ ๋ชจ๋ ๊ฒ์ ๋ ์ง/์๊ฐ ์ธ์๋ฅผ SQL ๋ฌธ์ ๋ฐ์ธ๋ฉํ๋ ๋ฐฉ์์ผ๋ก ๋ฏธ๋ฌ๋ง๋์ด์ผ ํฉ๋๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ฒฐ๊ณผ๋ฅผ ๋งคํํ๋ ๊ฒ๊ณผ ๊ด๋ จํ์ฌ ๋ณ๊ฒฝํ ๋ชจ๋ ์ฌํญ์ ๋ ์ง/์๊ฐ ์ธ์๋ฅผ SQL ๋ฌธ์ ๋ฐ์ธ๋ฉํ๋ ๋ฐฉ์์ผ๋ก ๋ฏธ๋ฌ๋ง๋์ด์ผ ํฉ๋๋ค.
@qualidafial , ์์ฃผ ์ข์ ์ง๋ฌธ์ ๋๋ค. ๋๋ ์ด๊ฒ์ ํ ์คํธํ์ง ์์๋ค. ์ด๊ฒ์ JDBC 4.2 ์ฌ์์์ ๋ช ์์ ์ผ๋ก ๋ค๋ฃจ๊ณ ์์ผ๋ฏ๋ก _์๋ํด์ผ ํฉ๋๋คโข_.
์ด๊ฒ์ JDBC 4.2 ์ฌ์์์ ๋ช ์์ ์ผ๋ก ๋ค๋ฃจ๊ณ ์์ผ๋ฏ๋ก _์๋ํด์ผ ํฉ๋๋คโข_.
์ด๊ฒ์ JDBC ๋๋ผ์ด๋ฒ ๊ตฌํ์๊ฐ ์ฌ์์ ์๋ฒฝํ๊ฒ ๋ฐ๋ฅธ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค. ๋ฒ๊ทธ๊ฐ ์๋ JDBC ๋๋ผ์ด๋ฒ ๊ตฌํ์ ์์ง ์ฐพ์ง ๋ชปํ์ต๋๋ค.
๋ชจ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํด ๋งคํผ๋ฅผ ํ๋ฌ๊ทธ์ธ์ ์ ๊ณตํ๊ณ ๋ฐ์ดํฐ ์ ํ์ ๋ํ ์ง์์ด ๋ค๋ฅธ ๋ค์ํ ๋ฒ์ ์ ์ ๊ณตํ๋ ๊ฒ์ ๋๋ฌด ์ฑ๊ฐ์ ์ผ์ด๋ผ๋ ์๊ฐ์ด ๋ญ๋๋ค. ์๋ง๋ ๋ ๋น ์ฌ๋ ์ดํธ ์ ๊ทผ ๋ฐฉ์์ด ์๋ํ ์ ์์ต๋๋ค. ๋ฏธ๋ฆฌ ์ค์น๋ ๋งคํผ๊ฐ ์๋ Jdbi ์ธ์คํด์ค๋ก ์์ํ๊ณ ํต์ฌ ์ํฐํฉํธ๋ ์๋์ผ๋ก ์ ํํ์ฌ ์ค์นํ ์ ์๋ ์ฌ๋ฌ ๋งคํผ๋ฅผ ์ ๊ณตํ๋ฉฐ ์ผ๋ถ๋ ๋์ผํ ๋ฐ์ดํฐ ์ ํ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๋ค๋ฅธ ๋ ผ๋ฆฌ๋ฅผ ๊ฐ์ต๋๋ค - get/ setObject, get/setX, ๋ค๋ฅธ ์ ํ์ผ๋ก์ ๋ณํ ๋ฑ. ๋ฐ์ดํฐ๋ฒ ์ด์ค(๋ฒ์ ) ๋ฐ ์์ฉ ํ๋ก๊ทธ๋จ ๋ ผ๋ฆฌ์ ๊ฐ์ฅ ์ ํฉํ ๋งคํผ๋ฅผ ์ค์ค๋ก ํ์ ํ๊ณ ๋จ์ ํ ์คํธ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ธํด์ผ ํฉ๋๋ค.
๊ทธ๊ฒ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ด๊ฐ ์ด๋ฏธ ๋ด ํ๋ก์ ํธ์์ ์ด๋ฏธ ํ๊ณ ์๋ ์ผ์ ๋๋ค. ๋ด db์์ ์๋ํ์ง ์๋ Jdbi์ ์ฌ์ ์ค์น๋ ์ผ๋ถ ๋งคํผ๊ฐ ์์ผ๋ฉฐ ์ง๊ธ์ ํ์ํ์ง ์์ผ๋ฏ๋ก UnsupportedOperationException์ ๋์ง๋ ์ธ์/๋งคํผ ํฉํ ๋ฆฌ๋ก ์ค์ ๋ก ์ฌ์ ์ํ์ต๋๋ค. ๊ตฌํ(์๋ ์ฐธ์กฐ).
์ด๊ฒ์ ๋ชจ๋ ๊ฒ์ด ์ ๋์ ์ผ๋ก ์๋ํ๋์ง ํ์ธํ๊ธฐ ์ํด ์์ ์ db์ ์น๋ฐํด์ง๊ณ ์ถ์ดํ๋ ์ฌ๋๋ค์ ์ํ ์๋ฃจ์ ์ด ๋ ๊ฒ์ด๋ฉฐ, Just Werkโข์ ๋ฌผ๊ฑด์ ์ํ๋ ์ฌ๋๋ค์ ์ํด (์ค์ ๋ก ํ๋ ํ) ์๋ฌด๊ฒ๋ ๋ณ๊ฒฝํ์ง ์์ ๊ฒ์ ๋๋ค.
์ด๋ ๊ฒ ํจ์ผ๋ก์จ ๋๋ hsqldb ๋๋ผ์ด๋ฒ์์ ๋๋ฌด ๋ง์ ์ง์ ์ ์ฐพ์์ต๋๋ค. hsqldb ๋๋ผ์ด๋ฒ์์ ์์ฒด ์ฌ์(์์ค์ ๋ณด๊ณ ๋๊ณ ์์ ๋์์ง๋ง ์ฌ์ ํ ์ ๋ฐ์ดํธ๋ ์ํฐํฉํธ๋ฅผ ๊ฒ์ํ๊ธฐ๋ฅผ ์ฌ์ ํ ๊ธฐ๋ค๋ฆฌ๊ณ ์์)์์ ๋ฒ์ด๋๊ณ ์์ ํ์ต๋๋ค. ์๋ํ๋ ๋งคํ ๋ ผ๋ฆฌ๋ฅผ ์ง์ ์ฐพ์ ์ด๋ฌํ ๊ฒฐํจ์ ํด๊ฒฐํฉ๋๋ค.
// I want strings handled differently
<strong i="13">@Component</strong>
public class CleanStringArgumentFactory extends AbstractArgumentFactory<String> {
protected CleanStringArgumentFactory() {
super(Types.VARCHAR);
}
<strong i="14">@Override</strong>
protected Argument build(String value, ConfigRegistry config) {
return (position, statement, ctx) -> statement.setString(position, StringUtils.trimToNull(value));
}
}
// no need for jdbi's built-in logic
<strong i="17">@Component</strong>
public class SetObjectArgumentFactory implements ArgumentFactory {
private static final Set<Type> SUPPORTED = ImmutableSet.of(UUID.class, LocalDateTime.class);
<strong i="18">@Override</strong>
public Optional<Argument> build(Type type, Object value, ConfigRegistry config) {
return SUPPORTED.contains(type)
? Optional.of(new LoggableArgument(value, (position, statement, context) -> statement.setObject(position, value)))
: Optional.empty();
}
}
// these built-ins don't work and I don't need them anyway
<strong i="21">@Component</strong>
public class UnsupportedArgumentFactory implements ArgumentFactory {
private static final Set<Type> UNSUPPORTED = ImmutableSet.of(ZonedDateTime.class, OffsetDateTime.class, OffsetTime.class);
<strong i="22">@Override</strong>
public Optional<Argument> build(Type type, Object value, ConfigRegistry config) {
if (UNSUPPORTED.contains(type)) {
throw new UnsupportedOperationException(type.getTypeName() + " is not supported at the moment");
} else {
return Optional.empty();
}
}
}
// voodoo
<strong i="25">@Inject</strong>
public JdbiConfiguration(
@Named("dataSource") DataSource dataSource,
Set<ArgumentFactory> arguments,
Set<ColumnMapper> mappers,
Set<ColumnMapperFactory> mapperFactories
) {
jdbi = Jdbi.create(dataSource);
jdbi.clearMappings();
jdbi.installPlugin(new SqlObjectPlugin());
arguments.forEach(jdbi::registerArgument);
mapperFactories.forEach(jdbi::registerColumnMapper);
mappers.forEach(jdbi::registerColumnMapper);
// ...
// Jdbi instance fine-tuned for my exact database and demands, without surprises and at my own responsibility
ํ๋ถ๋ค? ์๋ฅผ ๋ค์ด ํ์ฑํํด์ผ ํ๋ ํด๋์ค ์งํฉ์ผ๋ก ์ด๊ธฐํํด์ผ ํ๋ SetObjectArgumentFactory์ ๋ง์ ๋ฐ์ดํฐ ์ ํ์ ๋ํ ๋งคํ ๋ ผ๋ฆฌ์ ๋ชจ๋ ์ข ๋ฅ์ ๋ณํ์ ์ ๊ณตํ ์ ์์ผ๋ฉฐ ์ ์ฉ ๊ฐ๋ฅํ ๊ฒฝ์ฐ ๋ช ๊ฐ์ง ๊ตฌ์ฑ ๊ฐ๋ฅํ ๋์์ ์ ๊ณตํ ์ ์์ต๋๋ค. ๋ชจ๋๋ค ํ๋ณตํ์ธ์. ์ต์ข ์ฌ์ฉ์๋ก๋ถํฐ ์ฝ๊ฐ์ ์์ ์ด ํ์ํ์ง๋ง jdbi๊ฐ ๋ด๊ฐ ์ํ๋ ์์ ๊ณผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ง์ํ๋ ์์ ์ ์ ํํ ์ํํ๋ค๋ ์ฌ์ค์ ์๊ฒ ๋์ด ๊ธฐ๋ถ์ด ์ข์ต๋๋ค.
๋ชจ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํด ๋งคํผ๋ฅผ ํ๋ฌ๊ทธ์ธ์ ์ ๊ณตํ๊ณ ๋ฐ์ดํฐ ์ ํ์ ๋ํ ์ง์์ด ๋ค๋ฅธ ๋ค์ํ ๋ฒ์ ์ ์ ๊ณตํ๋ ๊ฒ์ ๋๋ฌด ์ฑ๊ฐ์ ์ผ์ด๋ผ๋ ์๊ฐ์ด ๋ญ๋๋ค.
๋ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ณต๊ธ์ ์ฒด๋ฅผ ์ํ ํ๋ฌ๊ทธ์ธ์ ๊ฐ๊ณ ์ถ์ต๋๋ค. ์ด๋ฆฌ ์์ ๋ชจ๋: ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฒค๋ ๋๋ ํด๋น JDBC ๋๋ผ์ด๋ฒ์ ํน์ฑ์ ๋ง๊ฒ Jdbi๋ฅผ ์กฐ์ ํ๊ธฐ ์ํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ช ๊ฐ์ง ์ฌ์ฉ์ ์ ์๊ฐ ํ์ํ๊ฑฐ๋ ์ํ๋ ๊ฒฝ์ฐ ์ด์ ๋ํด ๋ฃ๊ณ ์ถ์ต๋๋ค. ๋๋ ๋ ๋์ ์์ง, ์ฐ๋ฆฌ๋ pull ์์ฒญ์ ์ํฉ๋๋ค! :)
๊ทํ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ TravisCI์์ ์ง์ ์ง์๋๋ ๊ฒฝ์ฐ ๋ณด๋์ค ํฌ์ธํธ๋ก ์ค์ ๋ก ์ด์ ๋ํ ํ ์คํธ๋ฅผ ์คํํ ์ ์์ต๋๋ค: https://docs.travis-ci.com/user/database-setup/
๊ทํ์ "๋ฐฑ์ง" ์ ์๊ณผ ๊ด๋ จํ์ฌ ์ ๋ ์ฝ๊ฐ์ ์ด์๊ฐ ์์ต๋๋ค.
clearMappings()
์ง์ ์ ๋ฐฉ๋ฒ์ RowMappers
, ColumnMappers
, Arguments
๋ฐ JdbiCollectors
๋์ ์์ ์์
์ config (์ค์ ) Jdbi
, ์ด๋ฆ์ clear()
์ง์ ํ๊ฒ ์ต๋๋ค.@jdbi/contributors ๋ค๋ฅธ ์ฌ๋์ด ๊ด์ฌ์ ๊ฐ์ง๋งํ ์ฌ๋์ด ์์ต๋๊น?
๋๋ ๋น์ ์ด ์ ํํ ๊ฒ์ ๋ฑ๋กํ๋ ๊ฒ์ ์์์ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ ์ค์๋ก ๊ธฐ๋ณธ ๋งคํผ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ํผํ๊ธฐ ์ํด ๋น ์ฌ๋ ์ดํธ ์์ด๋์ด๋ฅผ ํฌํจ์์ผฐ์ต๋๋ค. ๊ธฐ๋ณธ impl๋ณด๋ค NotImplementedException์ด ๋ ๋ซ์ต๋๋ค. ์ตํ์ ์น์๋ ํ๋ฅญํ์ง๋ง ์ํ์ง ์๋ ๊ฒฝ์ฐ ๋ฌดํจํํด์ผ ํ๋ ์นํจ๋ฅผ ์ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
๊ฐ์ง๊ณ ์๋ ๊ฒ์ด ์ํ ๊ฒ์ ์๋๋๋ค. ์ฌ๋๋ค์ด ๊ทธ ์ ๊ทผ ๋ฐฉ์์ ์ํ์ง ์๋๋ค๋ฉด clear ๋ฉ์๋๋ฅผ ํธ์ถํ ํ์๊ฐ ์์ผ๋ฉฐ ์๋ฌด ๊ฒ๋ ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค. ๊ธฐ๋ณธ๊ฐ์ด ์๋ ์์ ๋ฐฉ์์ ์ ํธํ๋ ์ฌ๋๋ค์ ์ํ ๊ฒ์ ๋๋ค.
๊ธฐ์กด ๋งคํผ๋ฅผ ๊ณต๊ฐํด์๋ ์ ๋๋ค๋ ๋ฐ ๋์ํฉ๋๋ค. ๊นจ๋ํ ์ฌ๋ ์ดํธ ์ต์
์ ์ ๊ณตํ๊ธฐ๋ก ์ ํํ ๊ฒฝ์ฐ ๋งคํผ์ ๋ฐ์ธ๋๋ฅผ ํฉ๋ฆฌ์ ์ธ Plugin
์ฒญํฌ, PrimitivesPlugin
, BoxedPrimitivesPlugin
, CollectionsPlugin
, ๋ฌด์์ด๋ ๋ฒ๋ค๋ก ๋ฌถ์ด์ผ ํฉ๋๋ค.
๊ทธ๋ฐ ๋ค์ ๊ตฌ์ฑ์ด ์ ํ ์๋ "๊ธฐ๋ณธ" jdbi์ ๋ํ ์ ํฉํ ๋ฆฌ๋ฅผ ์ถ๊ฐํ๊ณ ์ด๋ฅผ ์ฌ์ฉํ๋๋ก ๊ธฐ์กด ํฉํ ๋ฆฌ๋ฅผ ์์ ํ๊ณ WholeJdbiEnchiladaPlugin
์ถ๊ฐํ ์ ์์ต๋๋ค.
๋ง์ ์ผ๋ก ๋น๋ํ๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ๋ฅผ ๋ณด์ฌ์ค ์ ์๋ค๋ฉด ์ ๋ 'clear'์ ๋ํด ๋ค์ ๋ฐ๋ํฉ๋๋ค. ์ ๊ฒ๋ ์ฝ๋ ๋์์ฒ๋ผ ๋๊ปด์ง๋๋ค.
๋ง์ ์ผ๋ก ๋น๋ํ๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ๋ฅผ ๋ณด์ฌ์ค ์ ์๋ค๋ฉด ์ ๋ 'clear'์ ๋ํด ๋ค์ ๋ฐ๋ํฉ๋๋ค. ์ ๊ฒ๋ ์ฝ๋ ๋์์ฒ๋ผ ๋๊ปด์ง๋๋ค.
๋ณ๋์ ์ฌ์ ๊ตฌ์ฑ์ด ์๋ jdbi ํฉํ ๋ฆฌ๋ฅผ ์ถ๊ฐํ๋ฉด ์ถ๊ฐ๋ก ๋น๋ํ๋ ๊ฒ์ด ์ด๋ ต์ง ์์ผ๋ฏ๋ก ์ค์ ๋ก clear()๊ฐ ํ์ํ์ง ์์ต๋๋ค.
๋ง์ต๋๋ค. ์ ๋ ์ฌ๊ธฐ์ ๋์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ ๋ clear()
์คํ์ผ๋ณด๋ค ์๋ก์ด "๊นจ๋ํ" ํฉํ ๋ฆฌ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๋ ์ ํธ๋๋ฅผ ํํํ ๊ฒ ๋ฟ์
๋๋ค.
๊ทธ๋ฌ๋ฉด ๋ชจ๋ ์ฌ๋์ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋ฉ๋๊น? ๊ฐ์ธ์ ์ผ๋ก ๊ณํ์ด ๊ฝค ์น์ํ๊ฒ ๋ค๋ฆฐ๋ค๊ณ ์๊ฐํฉ๋๋ค.
Jdbi
no-defaults๋ก ์ค์ (๊ฑฐ์ ๋ชจ๋ ๊ฒ์ ์์ธ๋ฅผ ๋์ง)PrimitivesPlugin
, BoxedPrimitivesPlugin
๋ฑ)UTCJavaTimePlugin
vs LocalJavaTimePlugin
vs ConvertJavaTimeToUtilDatePlugin
, GetObjectMapper.forClasses(Class... cs)
, SetObjectArgumentFactory.forClasses(Class... cs)
, NullsToDefaultsPrimitivesPlugin
vs NullThrowsExceptionPrimitivesPlugin
) ๋ฐ ๋์ผํ ๋ฐฉ์์ผ๋ก(ํ๋ฌ๊ทธ์ธ ๋ฐ ๊ฐ๋ณ์ ์ผ๋ก) ๋
ธ์ถํ์ฌ ์ฌ๋๋ค์ด ์ํ๋ ๊ฒ์ ์ ํํ ์ทจํ์ฌ ์ํ๋ ์ ์ฒด ๋งคํ ๋
ผ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค. ๋ถ๋ฒ null ๋๋ ๋๋ฝ๋ ์๊ฐ๋ ๋ฐ ๊ธฐํ ๊ฐ๋ฅํ ๋ถ์ผ์น๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๋ค์ํ ์ ๋ต๊ณผ ๊ฐ์ด ์ฌ๊ธฐ์ ์ ์ฌ์ ์ผ๋ก ๋ง์ ๋งคํผ ๊ตฌ์ฑ์ด ํ์ํฉ๋๋ค.Jdbi
์์ ์์ํ๊ณ db ( HsqlDb2_4_0Plugin
)์ ๋ํด ์๋ ค์ง ์ข์ ๋งคํ ์ฒด๊ณ๋ฅผ ํ ์ค๋ก ์ค์นํ ์ ์์ต๋๋ค. ๋ค์ํ ์ ๋ต์ ๋ํ ๊ตฌ์ฑ ์ต์
ํฌํจBuiltInGenericPreconfigurationPlugin
)์ ์ํํ๋๋ก ํ์ฌ ๋ชจ๋ ์ญํธํ์ฑ์ ๋ง๋ญ๋๋ค.
Jdbi
๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์ ํ์ง ์์
๋๋ ๋งค์ฐ ๊ฐํ ์๊ฒฌ์ ๊ฐ์ง๊ณ ์์ง ์์ง๋ง, ์ด ๋ชจ๋ ๊ฒ์ด ์ฌ์ฉ์ ๊ด์ ์์ ๋งค์ฐ ๋ณต์กํ๊ฒ ๋ค๋ฆฝ๋๋ค. ์ฌ์ฉ์๋ ์ฌ์ฉํ๋ ค๋ ์ ํ์ ๋ํด ๊ฐ๋ฅํ ๋ค์ํ ๋งคํ์ ์ดํดํ๊ณ ์ ์ ํ ๋งคํ์ ์ ํํด์ผ ํฉ๋๋ค. ์ด๊ฒ์ ์ด๋ ค์ด๋ฐ, ํนํ ์๊ฐ์ ์์๊ฐ ์์ฉํ ๋ ๊ฐ๋ฅํฉ๋๋ค. ๊ฐ๋ฅํ ๋ค๋ฅธ ์ต์ ์ ์ดํดํ๋ ๊ฒ์ ๊ฒฐ์ฝ ์ฌ์ด ์ผ์ด ์๋๋๋ค.
์ฌ์ฉ์๋ ์ฌ์ฉํ๋ ค๋ ์ ํ์ ๋ํด ๊ฐ๋ฅํ ๋ค์ํ ๋งคํ์ ์ดํดํ๊ณ ์ ์ ํ ๋งคํ์ ์ ํํด์ผ ํฉ๋๋ค.
์๋์, ๊ทธ๋ค์ด ์ํ ๋๋ง. ๊ธฐ์กด ํฉํ ๋ฆฌ ๋ฉ์๋๋ ํ์ฌ์ ๋๊ฐ์ ์ฌ์ ์ค์น๋ ๋งคํผ๋ฅผ ์ฌ์ฉํ์ฌ Jdbi
์ธ์คํด์ค๋ฅผ ๊ณ์ ์ถ๋ ฅํฉ๋๋ค. ์ฐ๋ฆฌ๋ ์ถ๊ฐ๋ก DIY ๊ตฌ์ฑ ํฉํ ๋ฆฌ ๋ฉ์๋๋ฅผ ์ป์ ๊ฒ์ด๋ฉฐ, ์ด๋ฅผ ์ ํํ๋ ์ฌ๋๋ค์ ๋งคํ์ ์น๋ฐ๋๋ฅผ ํ์
ํด์ผ ํ ๊ฒ์
๋๋ค. DIY ์ธ์คํด์ค๋ฅผ ์ป๊ณ YourDbAndVersionPlugin
์ค์นํ๊ณ ๋ฌด์์ ํ๋ ๋กค๋งํ๋ ์ค๊ฐ๋ ์์ ๊ฒ์
๋๋ค. ๋ด ๊ธด ์ค๋ช
์ ๊ธฐ์ค์ ์ด ์๋๋ผ ์ฃผ๋ก jdbi ๋ด๋ถ ๋ฐ ๊ณ ๊ธ ์ฌ์ฉ๋ฒ์ด์์ต๋๋ค.
TLDR: ์ฌ์ ํ Jdbi.create(dataSource)
๋ฅผ ํ ์ ์์ผ๋ฉฐ ์์ง ์ ๊ณตํ์ง ์์ ์ถ๊ฐ ํ์๋ฆฌ๋ฅผ ํ ํ์๊ฐ ์์ต๋๋ค. ๋ค๋ฅธ ์ฌ๋์ Jdbi.createBlank(dataSource).install(x).install(y).install(z)...
์ ๋ ๊ธฐ์กด ํฉํ ๋ฆฌ๋ฅผ ๋ ์ด์ ์ฌ์ฉํ์ง ์์์ผ ํ๋ค๊ณ ์๊ฐํ์ง ์๋๋ค๋ ์ ์ ์ ์ธํ๊ณ ๋ ์ฐธ์ฌํ๊ณ ์์ต๋๋ค. "์ฆ์ ์ฌ์ฉ ๊ฐ๋ฅํ" ๋์์ด ๊ฝค ์ข๊ธฐ ๋๋ฌธ์ ๋๋ถ๋ถ์ ์ฌ์ฉ์๊ฐ ๊ณ์ ์ฌ์ฉํ ๊ฒ์ด๋ผ๊ณ ๋ฏฟ์ต๋๋ค.
๊ทธ๋ด ์ ์์ง
@TheRealMarnes ์ด ์ ์ฒด ๋ํ๋ JDBC์์ ์ง์ ์ง์ํ์ง ์๋ JSR-310 ๋ฐ์ดํฐ ์ ํ์ ๋ค๋ฃจ๊ธฐ ์์ํ์ต๋๋ค.
์๋ชป๋ java.time ๋งคํผ์ ์ธ์๋ฅผ ์ ๊ฑฐํ๊ณ ๋ด์ฅ ๋์ ํ๋ฌ๊ทธ์ธ์ ๋ฃ๋ ๊ฒ์ ๋ํ ํฉ์๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์์ง๋ ๊ทธ๊ฒ์ ์ถ๊ตฌํ๊ณ ์ถ์ต๋๊น?
java.time ๊ฒ๋ค๋ง? ์๋ฐํ์ํ๋ฌ๊ทธ์ธ?
์, java.time ์ ํ ์ ์ฉ ํ๋ฌ๊ทธ์ธ์ด์ง๋ง ์ธ์์ ๋งคํผ๊ฐ @findepi์์ ์ค๋ช ํ ๋๋ก ์์งํ๊ณ ์์ค์ด ๋ง์ ๊ตฌํ
SimplisticJavaTimePlugin
?
๋ด ๋ค๋ฅธ PR์ด ์ฒ๋ฆฌ ๋ ๋๊น์ง ์ด๊ฒ์ผ๋ก ๊ธฐ๋ค๋ฆฌ์ญ์์ค. ๋์์ ๋๋ฌด ๋ง์ ๊ฒ์ ๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์์งํ ๋งํด์ ๋๋ jdbi๊ฐ ์ง์๋์ง ์๋ ์๊ฐ๋/์คํ์ ๊ณผ ๊ฐ์ด ์ค์ ๋ก ์ ํํ๊ฒ ๋งคํ๋ ์ ์๋ ๊ฒ์ ๋ํ ๋งคํผ๋ฅผ ์ ๊ณตํด์๋ ์ ๋๋ค๊ณ ๋งํ @findepi์ ๋์ํฉ๋๋ค... ์ฌ๊ธฐ์์ "ํํ"์ด๋ผ๋ ์์ด๋์ด๋ ๋งค์ฐ ์ํํ๊ฒ ๋ค๋ฆฝ๋๋ค. ์ ์๊ฒ - ์ ๋ ํญ์ ์ ์ฒด ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ๋ชจ๋ ํ๋ก์ ํธ์์ ๊ฐ์ฅ ๋์ ์ฐ์ ์์ ์ค ํ๋๋ก ๊ฐ์ฃผํด ์์ต๋๋ค. ์ฌ์ฉ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ๋ค์ ํ์ธํ ํ์๊ฐ ์์ต๋๋ค.
jdbi์์ ์ ๊ณตํ๋ ๋งคํผ๊ฐ ๋ชฐ๋ ๋ณ๊ฒฝ๋์์ ๋๋ฅผ ์๋ ๊ฒ๋ณด๋ค jdbi๊ฐ ์ฃผ์ด์ง ์ ํ์ ๋ํ ๋งคํผ๋ฅผ ์ ๊ณตํ์ง ์๋๋ค๋ ๊ฒ์ ํ ์คํธ ์คํ ์ค์ ๋ฐํ์ ์์ธ๋ก ์์๋ธ ๋ค์ ์ง์ ์์ฑํ๊ณ ์ถ์ต๋๋ค. ๋ด ๋ฐ์ดํฐ.
db ์์ฒด(hsqldb)์ jdbi ๋ชจ๋์์ ๊ตฌํ ์ ํ์ฑ/๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ํ์ธํ๊ธฐ ์ํด ์ฌ๋ฌ ์ ํ์ ๊ฐ์ ์ฐ๊ณ ์ฝ๋ ๋๊ท๋ชจ ๋จ์ ํ ์คํธ๊ฐ ์์ผ๋ฏ๋ก ๋ชจ๋ ๋ฌธ์ ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด jdbi ๋งคํผ/์ธ์๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ๋๋ hsqldb๊ฐ ํ์ฌ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ทธ๋ ๊ฒ ๋งํ๋ ์ฌ์์๋ ๋ถ๊ตฌํ๊ณ java.time์ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์(๊ฑฐ๋ํ ๋ฒ๊ทธ) ๋ช ๊ฐ์ง๋ฅผ ์์ฑํด์ผ ํ์ต๋๋ค. ๋๋ ์์ง ๋ด ์์คํ ์ด ์๋ ๋ค๋ฅธ ์์ญ/์คํ์ ์ผ๋ก java.time ๊ฐ์ฒด๋ฅผ ํ ์คํธํ ์๊ฐ์ ํ์ง ์์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฅ ํ๊ณ , ์ถฉ๋ถํ ํ์คํ, ๊ทธ๊ฒ๋ค์ ๋ชจ๋ ์์คํ ๊ฐ์ผ๋ก ๋ฆฌ์ ๋ ์คํ์ /์์ญ์ผ๋ก ๋์์ค์ง๋ง jdbi์ ๋งคํ์ผ๋ก ์ธํด hsqldb ๋ฒ๊ทธ ๋๋ฌธ์ด ์๋๋ผ Timestamp๋ก.
๊ฒฐํจ์ด ์๋ ๋งคํผ๋ฅผ jdbi3์์ ์ ๊ฑฐํ๊ณ ํด๋น ๊ตฌํ์ด ์์ ํ ์์ ๋ ์ ์๋ ๊ณต๊ธ์ ์ฒด๋ณ ์ํฐํฉํธ(jdbi3-hsqldb ๋ฐ ๊ธฐํ)๋ก ์ด๋ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ด์จ๋ ์ด๋ฏธ ๋ด ์์ ์ ํ๋ก์ ํธ์ ํ์ํ ๋ชจ๋ ๋งคํผ์ ์ธ์๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ jdbi-hsqldb๋ฅผ ์ง์ ๊ธฐ์ฌํ ์ ์์ต๋๋ค.