์‹œ๊ฐ„ ๊ฒฝ๊ณผ์— ๋”ฐ๋ฅธ ํ˜„์žฌ ์ƒํ™ฉ

JDBC๊ฐ€ ๋ฐœ๋ช…๋˜๊ณ  ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ํ‘œ์ค€ํ™”๋œ ์ดํ›„ 20๋…„์ด๋ผ๋Š” ์‹œ๊ฐ„์ด ํ˜๋ €๊ณ  ๊ทธ ์‚ฌ์ด ๋งŽ์€ ๊ฒƒ์ด ๋ณ€ํ–ˆ๋‹ค.

์ฒซ์งธ, ์„ธ๊ณ„๋Š” ๊ธ€๋กœ๋ฒŒํ™”๋˜์—ˆ์œผ๋ฉฐ ์ด์ œ ํ•˜๋‚˜์˜ ์„œ๋ฒ„๊ฐ€ ์ „ ์„ธ๊ณ„ ์‚ฌ์šฉ์ž์—๊ฒŒ ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธํ„ฐ๋„ท ์†๋„๊ฐ€ ๋นจ๋ผ์กŒ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ์œ ํ˜•์ด ์‹œ๊ฐ„๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋„๋ก SQL์— ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค . ์ด์ œ ์œ ํ˜•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • DATE - ๋‚ ์งœ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค: ๋…„, ์›”, ์ผ.
  • TIME - ์‹œ๊ฐ„ ์ €์žฅ: ์‹œ, ๋ถ„, ์ดˆ.
  • TIMESTAMP - ํŠน์ • ์‹œ์ (๋‚ ์งœ, ์‹œ๊ฐ„ ๋ฐ ๋ฐ€๋ฆฌ์ดˆ)์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • TIMESTAMP WITH TIME ZONE - TIMESTAMP ๋ฐ ์‹œ๊ฐ„๋Œ€(๊ตฌ์—ญ ์ด๋ฆ„ ๋˜๋Š” ์˜คํ”„์…‹).

๋‘˜์งธ, Java๋Š” ์ „์—ญ ์‹œ๊ฐ„ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด DateTime API๋ฅผ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํด๋ž˜์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋‚ ์งœ ๋ฐ ์‹œ๊ฐ„ :
    • ํ˜„์ง€ ๋‚ ์งœ
    • ํ˜„์ง€ ์‹œ๊ฐ
  • ์ •ํ™•ํ•œ ์ˆœ๊ฐ„ :
    • java.time.Instant
    • java.time.LocalDateTime
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime
  • ์‹œ๊ฐ„๋Œ€๊ฐ€ ํฌํ•จ๋œ ์‹œ๊ฐ„ :
    • java.time.OffsetDateTime
    • java.time.ZonedDateTime

์„ธ ๋ฒˆ์งธ ํฅ๋ฏธ๋กœ์šด ์ ์€ ๋งŽ์€ SQL ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ด๋ฏธ ๋กœ์ปฌ ์˜์—ญ์— ์žˆ๋Š” ์„œ๋ฒ„์—์„œ ์‹œ๊ฐ„์„ ๋ฐ›๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค . ๋ฌผ๋ก  ์ฆ‰์„์—์„œ ์‹œ๊ฐ„์„ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํŽธ๋ฆฌํ•˜์ง€ ์•Š๊ณ  ์‹ค์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์˜ค๋Š˜์˜ ๋ชจ๋“  ์ž‘์—…์„ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. SQL Server์—๋Š” ์ด๋ฅผ ์œ„ํ•œ CURDATE() ํ•จ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋งŒ ์„œ๋ฒ„๊ฐ€ ๋ฏธ๊ตญ์— ์žˆ๊ณ  ์ €๋Š” ์ผ๋ณธ์— ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” ๊ทธ๊ฐ€ "๊ทธ์˜ ์˜ค๋Š˜"์ด ์•„๋‹ˆ๋ผ "๋‚˜์˜ ์˜ค๋Š˜"์— ๋Œ€ํ•œ ๋ชจ๋“  ๊ธฐ๋ก์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ SQL ์„œ๋ฒ„๋Š” ๋‹ค๋ฅธ ์‹œ๊ฐ„๋Œ€์— ์žˆ๋Š” ํด๋ผ์ด์–ธํŠธ์™€๋„ ์Šค๋งˆํŠธํ•˜๊ฒŒ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ˜„๋Œ€ ๋ฌธ์ œ์—๋Š” ํ˜„๋Œ€์ ์ธ ์†”๋ฃจ์…˜์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค

์›์น™์ ์œผ๋กœ Java DateTime API์˜ ์ƒˆ ์œ ํ˜•๊ณผ SQL์˜ ์œ ํ˜•์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ๋งคํ•‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Java์—์„œ DATE ์œ ํ˜•์„ ๋‚˜ํƒ€๋‚ด๋ ค๋ฉด JDK 8 DateTime API์˜ java.time.LocalDate ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค .

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ TIME ์œ ํ˜•์€ Java์˜ ๋‘ ๊ฐ€์ง€ ์œ ํ˜•์ธ java.time.LocalTime ๋ฐ java.time.OffsetTime ์œผ๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค . ๋ณต์žกํ•œ ๊ฒƒ๋„ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ TIMESTAMP ์œ ํ˜• ์œผ๋กœ ํ‘œ์‹œ๋˜๋Š” ํŠน์ • ์‹œ์ ์€ Java์—์„œ 4๊ฐ€์ง€ ์œ ํ˜•์œผ๋กœ ํ‘œ์‹œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • java.time.Instant
  • java.time.LocalDateTime
  • java.time.OffsetDateTime
  • java.time.ZonedDateTime

๋งˆ์ง€๋ง‰์œผ๋กœ TIMESTAMP WITH TIME ZONE์€ ๋‘ ๊ฐ€์ง€ ์œ ํ˜•์œผ๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • java.time.OffsetDateTime
  • java.time.ZonedDateTime

์ด๋ฏธ DateTime API์— ์ต์ˆ™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฌธ์ œ๋ฅผ ๊ธฐ์–ตํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ต์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค :)

ํ‘œ ํ˜•์‹์œผ๋กœ ์ž‘์„ฑํ•˜๋ฏ€๋กœ ๋” ์‰ฌ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

SQL ์œ ํ˜• ์ž๋ฐ” ์œ ํ˜•
๋‚ ์งœ java.time.LocalDate
์‹œ๊ฐ„ java.time.LocalTime
java.time.OffsetTime
ํƒ€์ž„์Šคํƒฌํ”„ java.time.Instant
java.time.LocalDateTime
java.time.OffsetDateTime
java.time.ZonedDateTime
์‹œ๊ฐ„๋Œ€๊ฐ€ ์žˆ๋Š” ํƒ€์ž„์Šคํƒฌํ”„ java.time.OffsetDateTime
_

๋‚ ์งœ ๋ฐ›๊ธฐ

์ข‹์€ ์†Œ์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋žœ๋งŒ์—. java.sql ๋‚ ์งœ ์œ ํ˜•์„ ๋ฐ˜ํ™˜ํ•˜๋Š” getDate() ๋ฉ”์„œ๋“œ ์˜ ํ•œ๊ณ„๋ฅผ ๊ทน๋ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค .

์š”์ ์€ ๊ฐœ์ฒด๊ฒฐ๊ณผ ์ง‘ํ•ฉ๋˜ ๋‹ค๋ฅธ ํฅ๋ฏธ๋กœ์šด ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค - getObject() . ์ด ๋ฉ”์„œ๋“œ๋Š” ์—ด๊ณผ ์œ ํ˜•์˜ ๋‘ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ง€์ •๋œ ์œ ํ˜•์œผ๋กœ ๋ณ€ํ™˜๋œ ์—ด์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฐฉ๋ฒ•์˜ ์ผ๋ฐ˜์ ์ธ ํ˜•์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ClassName Name = getObject(column, ClassName);

๊ทธ๋ฆฌ๊ณ  DATE ์œ ํ˜•์„ java.time.LocalDate ์œ ํ˜• ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

LocalDate localDate = results.getObject(4, LocalDate.class);

๊ทธ๋ฆฌ๊ณ  ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋“  TIMESTAMP๋Š” ์—ฌ๋Ÿฌ ์œ ํ˜•์œผ๋กœ ๋ณ€ํ™˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

java.time.Instant instant = results.getObject(9, java.time.Instant.class);
java.time.LocalDateTime local = results.getObject(9, java.time. LocalDateTime.class);
java.time.OffsetDateTime offset = results.getObject(9, java.time. OffsetDateTime.class);
java.time.ZonedDateTime zoned = results.getObject(9, java.time. ZonedDateTime.class);

์ค‘์š”ํ•œ! ์ด ์ฝ”๋“œ๋Š” ์˜ค๋ž˜๋œ MySQL JDBC ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค . pom.xml์— ์ž‘์„ฑ๋˜์—ˆ๊ฑฐ๋‚˜ ํ”„๋กœ์ ํŠธ ์„ค์ •์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ถ”๊ฐ€๋œ "mysql-connector-java" ๋ฒ„์ „์— ์ฃผ์˜ํ•˜์‹ญ์‹œ์˜ค.

๊ทธ๊ฑด ๊ทธ๋ ‡๊ณ , ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๊ธฐ๋ณธ ์œ ํ˜•์— ๋Œ€ํ•ด null์„ ์ €์žฅํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์ด๋ธ” ์—ด์ด INT ์œ ํ˜•์ธ ๊ฒฝ์šฐ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ null์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

Integer id1 = results.getObject(8, Integer.class);    	 // this will work
Integer id2 = results.getObject(8, int.class);                 //this will also work
int id3 = results.getObject(8,  Integer.class);            	//method will return null, JVM will throw NPE
int id4 = results.getObject(8,  int.class);                    	//method will return null, JVM will throw NPE

MySQL์˜ ์‹œ๊ฐ„๋Œ€ ์„ค์ •

MySQL์—์„œ๋„ ๋งŽ์€ ํฅ๋ฏธ๋กœ์šด ์ผ๋“ค์ด ์ผ์–ด๋‚ฌ์Šต๋‹ˆ๋‹ค. ์•„์‹œ๋‹ค์‹œํ”ผ MySQL ์—ฐ๊ฒฐ์„ ์ƒ์„ฑํ•  ๋•Œ ๋‹ค์–‘ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค .
mysql://localhost:3306/db_scheme?Name=meaning&Name=meaning

๋”ฐ๋ผ์„œ MySQL์—์„œ ์‹œ๊ฐ„๋Œ€ ์ž‘์—…์„ ์œ„ํ•ด ์„ธ ๊ฐœ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•  ๋•Œ ์ด๋Ÿฌํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜์—์„œ ๋‚˜๋Š” ๊ทธ๋“ค๊ณผ ํ•จ๊ป˜ ํ‘œ๋ฅผ ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค :

๋ชจ์ˆ˜ ๊ฐ€์น˜ ๊ธฐ๋ณธ๊ฐ’
์—ฐ๊ฒฐ ์‹œ๊ฐ„๋Œ€ ์ง€์—ญ | ์„œ๋ฒ„ | ์‚ฌ์šฉ์ž ์˜์—ญ ์„ฌ๊ธฐ๋Š” ์‚ฌ๋žŒ
forceConnectionTimeZoneToSession ์‚ฌ์‹ค | ๊ฑฐ์ง“ ์ง„์‹ค
๋ณด์กด ์ธ์Šคํ„ด์Šค ์‚ฌ์‹ค | ๊ฑฐ์ง“ ๊ฑฐ์ง“

connectionTimeZone ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  ์š”์ฒญ์ด ์‹คํ–‰๋  ์‹œ๊ฐ„๋Œ€(์‹œ๊ฐ„๋Œ€)๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์˜ ๊ด€์ ์—์„œ ์„œ๋ฒ„๋Š” ์ง€์ •๋œ ์‹œ๊ฐ„๋Œ€๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

forceConnectionTimeZoneToSession ๋งค๊ฐœ๋ณ€์ˆ˜ ๋กœ ์ธํ•ด ์„ธ์…˜ time_zone ๋ณ€์ˆ˜๊ฐ€ ๋ฌด์‹œ๋˜๊ณ  connectionTimeZone์œผ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ, preserveInstants ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” JVM์˜ timeZone๊ณผ connectionTimeZone ์‚ฌ์ด์˜ ์ •ํ™•ํ•œ ์‹œ๊ฐ„ ๋ณ€ํ™˜์„ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๊ตฌ์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • connectionTimeZone=LOCAL & forceConnectionTimeZoneToSession=false - useLegacyDatetimeCode=true์ธ ์ด์ „ MySQL JDBC ๋“œ๋ผ์ด๋ฒ„ ๋ฒ„์ „ 5.1์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

  • connectionTimeZone=LOCAL & forceConnectionTimeZoneToSession=true๋Š” ๋‚ ์งœ ๋ฐ ์‹œ๊ฐ„ ๊ฐ’์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฐ€์žฅ ์ž์—ฐ์Šค๋Ÿฌ์šด ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ชจ๋“œ์ž…๋‹ˆ๋‹ค.

  • connectionTimeZone=SERVER & preserveInstants=true - useLegacyDatetimeCode=false์ธ ์ด์ „ MySQL JDBC ๋“œ๋ผ์ด๋ฒ„ ๋ฒ„์ „ 5.1์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

  • connectionTimeZone=user_defined & preserveInstants=true - ์„œ๋ฒ„์˜ ํ‘œ์ค€ ์‹œ๊ฐ„๋Œ€๊ฐ€ CET/CEST์™€ ๊ฐ™์€ ์ผ๋ฐ˜ ์•ฝ์–ด๋กœ ์„ค์ •๋˜์–ด ์ปค๋„ฅํ„ฐ์—์„œ ์ธ์‹ํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์„ ๊ทน๋ณตํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ, ๋‚ ์งœ๋Š” ํฅ๋ฏธ๋กœ์šด ์ฃผ์ œ์ด๋ฉฐ ๋งŽ์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์†๋‹ด์ฒ˜๋Ÿผ : ๋ฌผ๋ก  ๋ฌด์„ญ์ง€ ๋งŒ ํ™”๋„ ์•ˆ๋‚˜์š”! :)