Jdbi: ZonedDateTime์šฉ ๋‚ด์žฅ ๋งคํผ๋Š” ์‹œ๊ฐ„๋Œ€ ์ •๋ณด๋ฅผ ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2017๋…„ 12์›” 21์ผ  ยท  43์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: jdbi/jdbi

ZonedDateTime ๋‚ด์žฅ๋œ ๋งคํผ๊ฐ€ ์žˆ๋Š”๋ฐ SQL์˜ TIMESTAMP WITH TIME ZONE ๊ฐ€ ์ง์ ‘ ์ง€์›๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ๋งคํผ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์˜์—ญ์„ ์ธ์‹ํ•˜์ง€ ๋ชปํ•˜๋Š” ์˜์—ญ ์ธ์‹ ์œ ํ˜•์— ๋Œ€ํ•ด ๋งคํผ๋ฅผ ๋…ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•์ด ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

bug feature improvement

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

์†”์งํžˆ ๋งํ•ด์„œ ๋‚˜๋Š” jdbi๊ฐ€ ์ง€์†๋˜์ง€ ์•Š๋Š” ์‹œ๊ฐ„๋Œ€/์˜คํ”„์…‹๊ณผ ๊ฐ™์ด ์‹ค์ œ๋กœ ์ •ํ™•ํ•˜๊ฒŒ ๋งคํ•‘๋  ์ˆ˜ ์—†๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๋งคํผ๋ฅผ ์ œ๊ณตํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๊ณ  ๋งํ•œ @findepi์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค... ์—ฌ๊ธฐ์—์„œ "ํƒ€ํ˜‘"์ด๋ผ๋Š” ์•„์ด๋””์–ด๋Š” ๋งค์šฐ ์œ„ํ—˜ํ•˜๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ์ €์—๊ฒŒ - ์ €๋Š” ํ•ญ์ƒ ์ „์ฒด ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ๋ชจ๋“  ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ€์žฅ ๋†’์€ ์šฐ์„  ์ˆœ์œ„ ์ค‘ ํ•˜๋‚˜๋กœ ๊ฐ„์ฃผํ•ด ์™”์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ๋‹ค์‹œ ํ™•์ธํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

jdbi์—์„œ ์ œ๊ณตํ•˜๋Š” ๋งคํผ๊ฐ€ ๋ชฐ๋ž˜ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ๋ฅผ ์•„๋Š” ๊ฒƒ๋ณด๋‹ค jdbi๊ฐ€ ์ฃผ์–ด์ง„ ์œ ํ˜•์— ๋Œ€ํ•œ ๋งคํผ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ค‘์— ๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ๋กœ ์•Œ์•„๋‚ธ ๋‹ค์Œ ์ง์ ‘ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋‚ด ๋ฐ์ดํ„ฐ.

db ์ž์ฒด(hsqldb)์™€ jdbi ๋ชจ๋‘์—์„œ ๊ตฌํ˜„ ์ •ํ™•์„ฑ/๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ์œ ํ˜•์˜ ๊ฐ’์„ ์“ฐ๊ณ  ์ฝ๋Š” ๋Œ€๊ทœ๋ชจ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ๋ชจ๋“  ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด jdbi ๋งคํผ/์ธ์ˆ˜๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” hsqldb๊ฐ€ ํ˜„์žฌ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ทธ๋ ‡๊ฒŒ ๋งํ•˜๋Š” ์‚ฌ์–‘์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  java.time์„ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—(๊ฑฐ๋Œ€ํ•œ ๋ฒ„๊ทธ) ๋ช‡ ๊ฐ€์ง€๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์•„์ง ๋‚ด ์‹œ์Šคํ…œ์ด ์•„๋‹Œ ๋‹ค๋ฅธ ์˜์—ญ/์˜คํ”„์…‹์œผ๋กœ java.time ๊ฐ์ฒด๋ฅผ ํ…Œ์ŠคํŠธํ•  ์ƒ๊ฐ์„ ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ƒฅ ํ–ˆ๊ณ , ์ถฉ๋ถ„ํžˆ ํ™•์‹คํžˆ, ๊ทธ๊ฒƒ๋“ค์€ ๋ชจ๋‘ ์‹œ์Šคํ…œ ๊ฐ’์œผ๋กœ ๋ฆฌ์…‹๋œ ์˜คํ”„์…‹/์˜์—ญ์œผ๋กœ ๋Œ์•„์˜ค์ง€๋งŒ jdbi์˜ ๋งคํ•‘์œผ๋กœ ์ธํ•ด hsqldb ๋ฒ„๊ทธ ๋•Œ๋ฌธ์ด ์•„๋‹ˆ๋ผ Timestamp๋กœ.

๊ฒฐํ•จ์ด ์žˆ๋Š” ๋งคํผ๋ฅผ jdbi3์—์„œ ์ œ๊ฑฐํ•˜๊ณ  ํ•ด๋‹น ๊ตฌํ˜„์ด ์™„์ „ํžˆ ์ˆ˜์ •๋  ์ˆ˜ ์žˆ๋Š” ๊ณต๊ธ‰์—…์ฒด๋ณ„ ์•„ํ‹ฐํŒฉํŠธ(jdbi3-hsqldb ๋ฐ ๊ธฐํƒ€)๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์–ด์จŒ๋“  ์ด๋ฏธ ๋‚ด ์ž์‹ ์˜ ํ”„๋กœ์ ํŠธ์— ํ•„์š”ํ•œ ๋ชจ๋“  ๋งคํผ์™€ ์ธ์ˆ˜๋ฅผ ์ž‘์„ฑํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— jdbi-hsqldb๋ฅผ ์ง์ ‘ ๊ธฐ์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

๋‹น์‹ ์ด ์˜ณ์•˜์ง€๋งŒ ์ด๊ฒƒ์ด ํ˜„์žฌ 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 ์ดํ›„ ์„ธ๊ณ„์—์„œ ๋‚ ์งœ/์‹œ๊ฐ„ ๊ฐ’์„ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•œ ์‚ฌ์‹ค์ƒ์˜ ํ‘œ์ค€์ด ๋ถ€์ƒํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค๋Š” ๊ฒƒ์„ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค.

๋จผ์ € ๋ฐฐ๊ฒฝ์ด ์กฐ๊ธˆ ๋” ์žˆ์Šต๋‹ˆ๋‹ค.

  • JDBI์˜ TIMESTAMP WITH TIME ZONE ZonedDateTime ๋กœ์˜ ๋ณ€ํ™˜์— ๋Œ€ํ•ด ์ด ๋ฌธ์ œ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์‹œ๊ฐ„๋Œ€ ์ •๋ณด๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
  • ๋ชจ๋“  JDBC API์—๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด TIMESTAMP , DATE , TIME ๊ฐ์ฒด๊ฐ€ ๊ฒ€์ƒ‰๋˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ฆ‰, java.sql.{Timestamp,Date,Time} ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค๋Š” ๋ชจ๋‘ java.util.Date ์—์„œ ํ™•์žฅ๋ฉ๋‹ˆ๋‹ค. Calendar ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋„์ž…๋˜์—ˆ๊ณ  java.util.Date ์˜ ๋ฉ”์†Œ๋“œ๊ฐ€ ๋…„/์›”/์ผ/์‹œ/๋ถ„/์ดˆ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š”์ง€ ๊ธฐ์–ตํ•˜๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋Ÿด๋งŒํ•œ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค( Calendar ๊ฐ€ ๋ชจ๋“  ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ๋‹ค๋Š” ์˜๋ฏธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค).

    • _JVM ์‹œ๊ฐ„๋Œ€_๊ฐ€ ํ˜„์ง€ ์‹œ๊ฐ„์„ ์ค€์ˆ˜ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ 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์„ ๋ฆด๋ฆฌ์Šคํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ž˜๋ชป ์œ ์ง€ํ•˜๋ฉด ๋ธŒ๋ ˆ์ดํ‚น ์ฒด์ธ์ง€์ผ ๋ฟ์ž…๋‹ˆ๋‹ค... ;)

๋‚ด๊ฐ€ ๋“ฃ๊ณ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฌ๋Š” ๊ฒƒ์„ ์žฌ์ƒํ•˜๋ ค๋ฉด :

  • ๊ธฐ์กด ๋‚ด์žฅ java.time ๋งคํผ๋ฅผ ๋ณ„๋„์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค( YoloTimePlugin ์ข‹์•„์š”).
  • java.sql ์œ ํ˜•์—์„œ ๋ณ€ํ™˜ํ•˜๋Š” ๋Œ€์‹  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โ„ข์— ๋ฌผ๊ฑด์„ ์›ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด (์‹ค์ œ๋กœ ํ•˜๋Š” ํ•œ) ์•„๋ฌด๊ฒƒ๋„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  • Jdbi ์ธ์Šคํ„ด์Šค์— ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ชจ๋“  ๋งคํผ/์ธ์ˆ˜๋ฅผ ์ง€์šฐ์‹ญ์‹œ์˜ค(ํด๋ฆฐ ์Šฌ๋ ˆ์ดํŠธ).
  • ์šฐ๋ฆฌ๊ฐ€ ์ˆ˜๋™์œผ๋กœ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ˜„์žฌ ๋‚ด์žฅ ๋งคํผ/์ธ์ˆ˜ impl์„ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  • ์ˆ˜์š”๊ฐ€ ์ฆ๊ฐ€ํ•  ๋•Œ ํ•ต์‹ฌ ์•„ํ‹ฐํŒฉํŠธ์— ๋Œ€์ฒด ๋งคํผ impls๋ฅผ ๊ณ„์† ์ถ”๊ฐ€ํ•˜๊ณ  ์‚ฌ๋žŒ๋“ค์ด ์Šค์Šค๋กœ ์„ค์น˜ํ•˜๋„๋ก ํ•˜์—ฌ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ฒƒ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ๋‚˜๋Š” 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() ์ง€์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
  • ๋‚ด์žฅ ๋งคํผ, ์ธ์ˆ˜ ๋ฐ ์ˆ˜์ง‘๊ธฐ๋ฅผ ๊ณต๊ฐœํ•˜๋Š” ๊ฒƒ์ด ์•ฝ๊ฐ„ ์ฃผ์ €ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋“ค ์ค‘ ์ผ๋ถ€๋Š” ๋‚ด๋ถ€์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๊ฐ€ ๋ฌด์‹œํ•˜๋Š” ์ด์ƒํ•œ ์ด๋ฆ„์ด๋‚˜ ๋””์ž์ธ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. API์˜ ์ผ๋ถ€๋กœ ๋งŒ๋“ค๊ธฐ ์ „์— ์ผ๋ถ€๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • ๋ฐฑ์„œ๊ฐ€ ์ •๋ง ํ•„์š”ํ•œ์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. Jdbi์˜ ๋ชจ๋“  ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ํด๋ž˜์Šค๋Š” last-registered-wins ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ํ•ญ์ƒ ์ฆ‰์‹œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋™์ž‘์„ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ์˜๋ฏธ์—์„œ ๋ฐฑ์ง€ ์ƒํƒœ๋Š” ์•ฝ๊ฐ„ ๊ณผํ•œ ๋Š๋‚Œ์ž…๋‹ˆ๋‹ค.

@jdbi/contributors ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๊ด€์‹ฌ์„ ๊ฐ€์งˆ๋งŒํ•œ ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” ๋‹น์‹ ์ด ์„ ํƒํ•œ ๊ฒƒ์„ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ์„ ์žŠ์—ˆ์„ ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ ์‹ค์ˆ˜๋กœ ๊ธฐ๋ณธ ๋งคํผ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๋นˆ ์Šฌ๋ ˆ์ดํŠธ ์•„์ด๋””์–ด๋ฅผ ํฌํ•จ์‹œ์ผฐ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ impl๋ณด๋‹ค NotImplementedException์ด ๋” ๋‚ซ์Šต๋‹ˆ๋‹ค. ์ตœํ›„์˜ ์Šน์ž๋Š” ํ›Œ๋ฅญํ•˜์ง€๋งŒ ์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ๋ฌดํšจํ™”ํ•ด์•ผ ํ•˜๋Š” ์ŠนํŒจ๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค.

๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ์•„ํ”ˆ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๊ทธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด clear ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฉฐ ์•„๋ฌด ๊ฒƒ๋„ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์ด ์—†๋Š” ์ž‘์—… ๋ฐฉ์‹์„ ์„ ํ˜ธํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ธฐ์กด ๋งคํผ๋ฅผ ๊ณต๊ฐœํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๊นจ๋—ํ•œ ์Šฌ๋ ˆ์ดํŠธ ์˜ต์…˜์„ ์ œ๊ณตํ•˜๊ธฐ๋กœ ์„ ํƒํ•œ ๊ฒฝ์šฐ ๋งคํผ์™€ ๋ฐ”์ธ๋”๋ฅผ ํ•ฉ๋ฆฌ์ ์ธ Plugin ์ฒญํฌ, PrimitivesPlugin , BoxedPrimitivesPlugin , CollectionsPlugin , ๋ฌด์—‡์ด๋“  ๋ฒˆ๋“ค๋กœ ๋ฌถ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ตฌ์„ฑ์ด ์ „ํ˜€ ์—†๋Š” "๊ธฐ๋ณธ" jdbi์— ๋Œ€ํ•œ ์ƒˆ ํŒฉํ† ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๊ธฐ์กด ํŒฉํ† ๋ฆฌ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  WholeJdbiEnchiladaPlugin ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ง์…ˆ์œผ๋กœ ๋นŒ๋“œํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์—†๋‹ค๋ฉด ์ €๋Š” 'clear'์— ๋Œ€ํ•ด ๋‹ค์†Œ ๋ฐ˜๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ฒŒ๋Š” ์ฝ”๋“œ ๋ƒ„์ƒˆ์ฒ˜๋Ÿผ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค.

๋ง์…ˆ์œผ๋กœ ๋นŒ๋“œํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์—†๋‹ค๋ฉด ์ €๋Š” 'clear'์— ๋Œ€ํ•ด ๋‹ค์†Œ ๋ฐ˜๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ฒŒ๋Š” ์ฝ”๋“œ ๋ƒ„์ƒˆ์ฒ˜๋Ÿผ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค.

๋ณ„๋„์˜ ์‚ฌ์ „ ๊ตฌ์„ฑ์ด ์—†๋Š” jdbi ํŒฉํ† ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์ถ”๊ฐ€๋กœ ๋นŒ๋“œํ•˜๋Š” ๊ฒƒ์ด ์–ด๋ ต์ง€ ์•Š์œผ๋ฏ€๋กœ ์‹ค์ œ๋กœ clear()๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋งž์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์—ฌ๊ธฐ์— ๋™์˜ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” clear() ์Šคํƒ€์ผ๋ณด๋‹ค ์ƒˆ๋กœ์šด "๊นจ๋—ํ•œ" ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์„ ํ˜ธ๋„๋ฅผ ํ‘œํ˜„ํ•œ ๊ฒƒ ๋ฟ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ๋ชจ๋“  ์‚ฌ๋žŒ์˜ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๊นŒ? ๊ฐœ์ธ์ ์œผ๋กœ ๊ณ„ํš์ด ๊ฝค ์„น์‹œํ•˜๊ฒŒ ๋“ค๋ฆฐ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

  • Jdbi no-defaults๋กœ ์„ค์ •(๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ์— ์˜ˆ์™ธ๋ฅผ ๋˜์ง)
  • ๋ชจ๋“  ๊ธฐ์กด ๋งคํผ์™€ ๋ฐ”์ธ๋”(๋ฐ tx ํ•ธ๋“ค๋Ÿฌ ๋“ฑ)๋ฅผ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ฒˆ๋“ค ๋ฐ ๊ฐœ๋ณ„ ํด๋ž˜์Šค๋กœ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐ€๋Šฅ( PrimitivesPlugin , BoxedPrimitivesPlugin ๋“ฑ)
  • ๋ช‡ ๊ฐ€์ง€ ๋Œ€์ฒด ๊ตฌํ˜„ ์ œ๊ณต( UTCJavaTimePlugin vs LocalJavaTimePlugin vs ConvertJavaTimeToUtilDatePlugin , GetObjectMapper.forClasses(Class... cs) , SetObjectArgumentFactory.forClasses(Class... cs) , NullsToDefaultsPrimitivesPlugin vs NullThrowsExceptionPrimitivesPlugin ) ๋ฐ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ(ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ฐ ๊ฐœ๋ณ„์ ์œผ๋กœ) ๋…ธ์ถœํ•˜์—ฌ ์‚ฌ๋žŒ๋“ค์ด ์›ํ•˜๋Š” ๊ฒƒ์„ ์ •ํ™•ํžˆ ์ทจํ•˜์—ฌ ์›ํ•˜๋Š” ์ „์ฒด ๋งคํ•‘ ๋…ผ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถˆ๋ฒ• null ๋˜๋Š” ๋ˆ„๋ฝ๋œ ์‹œ๊ฐ„๋Œ€ ๋ฐ ๊ธฐํƒ€ ๊ฐ€๋Šฅํ•œ ๋ถˆ์ผ์น˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ์ „๋žต๊ณผ ๊ฐ™์ด ์—ฌ๊ธฐ์— ์ž ์žฌ์ ์œผ๋กœ ๋งŽ์€ ๋งคํผ ๊ตฌ์„ฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • db ์ „์šฉ ๋ฒˆ๋“ค ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ธ๊ธฐ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค + ๋ฒ„์ „์„ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž๋Š” ๊ตฌ์„ฑ ์—†์Œ Jdbi ์—์„œ ์‹œ์ž‘ํ•˜๊ณ  db ( HsqlDb2_4_0Plugin )์— ๋Œ€ํ•ด ์•Œ๋ ค์ง„ ์ข‹์€ ๋งคํ•‘ ์ฒด๊ณ„๋ฅผ ํ•œ ์ค„๋กœ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ์ „๋žต์— ๋Œ€ํ•œ ๊ตฌ์„ฑ ์˜ต์…˜ ํฌํ•จ
  • ํ˜„์žฌ ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ๊ฐ€ no-config ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ์™€ ํ•จ๊ป˜ ํ˜„์žฌ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‚ฌ์ „ ๊ตฌ์„ฑ( 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์ด ์ฒ˜๋ฆฌ ๋  ๋•Œ๊นŒ์ง€ ์ด๊ฒƒ์œผ๋กœ ๊ธฐ๋‹ค๋ฆฌ์‹ญ์‹œ์˜ค. ๋™์‹œ์— ๋„ˆ๋ฌด ๋งŽ์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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