<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Date on</title><link>https://taetaetae.github.io/tags/date/</link><description>Recent content in Date on</description><generator>Hugo</generator><language>en</language><lastBuildDate>Thu, 23 Mar 2017 11:16:05 +0000</lastBuildDate><atom:link href="https://taetaetae.github.io/tags/date/index.xml" rel="self" type="application/rss+xml"/><item><title>Oracle + Mybatis 환경에서의 Date 다루기</title><link>https://taetaetae.github.io/2017/03/23/oracle-mybatis-date/</link><pubDate>Thu, 23 Mar 2017 11:16:05 +0000</pubDate><guid>https://taetaetae.github.io/2017/03/23/oracle-mybatis-date/</guid><description>&lt;h2 id="상황">상황&lt;/h2>
&lt;ul>
&lt;li>Oracle, Java 8, mybatis3 환경&lt;/li>
&lt;li>Date컬럼에 데이터가 있는데 이를 select query로 조회하여 Model에 바인딩 시키고자 함.&lt;/li>
&lt;/ul>
&lt;!-- more -->
&lt;ul>
&lt;li>쿼리에 아무 기능을 추가하지 않고 Date 형태로 Model에 바인딩을 하면 시분초가 없어진 &lt;code>2017-01-01 00:00:00&lt;/code> 형태로 남게됨&lt;/li>
&lt;li>그래서 아래처럼 쿼리 작성할 때마다 TO_CHAR를 사용해서 포맷에 맞추어 형변환을 시키고 Date 또는 String으로 Model에 바인딩 하곤 했음.&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="k">SELECT&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="n">TO_CHAR&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">reg_ymdt&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;YYYY-MM-DD HH24:MI:SS&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">registDate&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">...&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>이렇게 하다보니 query 만들때마다 형변환하는 쿼리를 만들어줘야하고, 자칫 포맷형식을 다르게 적으면 엉뚱한 결과를 초래하거나, Date형을 그대로 받아 사용해야하는 상황에서는 다시 형변환하는 과정(&lt;code>String to Date&lt;/code>)을 해줘야만 함. .. &lt;code>귀차니즘의 시작 : 삽질&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="1-삽질의-시작">1. 삽질의 시작&lt;/h2>
&lt;h3 id="1-1-오라클의-date형--javasqldate-의-경우">1-1. &lt;code>오라클의 DATE형&lt;/code> → &lt;code>java.sql.Date&lt;/code> 의 경우&lt;/h3>
&lt;ul>
&lt;li>mybatis에서는 자동적으로 &lt;code>org.apache.ibatis.type.SqlDateTypeHandler&lt;/code>를 호출하게됨 &lt;a href="http://www.mybatis.org/mybatis-3/ko/configuration.html#typeHandlers" target="_blank" rel="noopener noreffer ">mybatis 3 문서 참고&lt;/a>&lt;/li>
&lt;li>해당 핸들러의 내부 데이터 변환 코드는 다음과 같음&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="nd">@Override&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Date&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">getNullableResult&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ResultSet&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">rs&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">columnName&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">throws&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">SQLException&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">rs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">getDate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">columnName&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;code>java.sql.ResultSet.getDate()&lt;/code>메소드를 호출하면 실제 &amp;lsquo;yyyy-mm-dd&amp;rsquo; 만 가져와 리턴하게됨 (여기서 디버깅 해보면 rs.getTimestamp(columnName)값은 시분초까지 다 들어가 있음)&lt;/li>
&lt;li>따라서 시간값이 없는 &lt;code>yyyy-mm-dd&lt;/code> 형태로 리턴이 됨&lt;/li>
&lt;/ul>
&lt;h3 id="1-2-오라클의-date형--javautildate-의-경우">1-2. &lt;code>오라클의 DATE형&lt;/code> → &lt;code>java.util.Date&lt;/code> 의 경우&lt;/h3>
&lt;ul>
&lt;li>mybatis에서는 자동적으로 &lt;code>org.apache.ibatis.type.DateOnlyTypeHandler&lt;/code>를 호출하게됨 &lt;a href="http://www.mybatis.org/mybatis-3/ko/configuration.html#typeHandlers" target="_blank" rel="noopener noreffer ">mybatis 3 문서 참고&lt;/a>&lt;/li>
&lt;li>해당 핸들러의 내부 데이터 변환 코드는 다음과 같음&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="nd">@Override&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Date&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">getNullableResult&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ResultSet&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">rs&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">columnName&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">throws&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">SQLException&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="n">java&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">sql&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">Date&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">sqlDate&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">rs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">getDate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">columnName&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="k">if&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sqlDate&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">!=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">null&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">		&lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">java&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">util&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">Date&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sqlDate&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">getTime&lt;/span>&lt;span class="p">());&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">null&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>위의 &lt;code>org.apache.ibatis.type.SqlDateTypeHandler&lt;/code> 변환코드에서 발생한 문제점과 같이 &lt;code>yyyy-mm-dd&lt;/code> 만 가져와서 java.sql.Date 객체를 만들고, 이 정보를 토대로 java.util.Date 객체를 만들게 되는데 앞서 시간값을 뺀 정보로 만들어졌기 때문에 결국 동일하게 &lt;code>yyyy-mm-dd&lt;/code> 형태로 리턴이 됨&lt;/li>
&lt;/ul>
&lt;h2 id="2-삽질완료-해결의-시작">2. 삽질완료, 해결의 시작&lt;/h2>
&lt;ul>
&lt;li>오라클 + mybatis 환경에서 Date타입을 다루기 위해서는 타입핸들러를 명시적으로 만들어줘야 한다는걸 알게됨.&lt;/li>
&lt;/ul>
&lt;h4 id="2-1-오라클의-date형--javasqldate-의-경우">2-1. &lt;code>오라클의 DATE형&lt;/code> → &lt;code>java.sql.Date&lt;/code> 의 경우&lt;/h4>
&lt;ul>
&lt;li>아래처럼 코드를 작성하여 커스텀 핸들러를 만들어 등록을 시켜준다.&lt;/li>
&lt;li>mybatis-config.xml&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-xml" data-lang="xml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;typeHandlers&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="nt">&amp;lt;typeHandler&lt;/span> &lt;span class="na">handler=&lt;/span>&lt;span class="s">&amp;#34;com.naver.dbill.admin.common.handler.CustomDateHandler&amp;#34;&lt;/span>&lt;span class="nt">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;/typeHandlers&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>CustomDateHandler.java&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="p">...&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="kn">import&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">java.sql.Date&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">...&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">class&lt;/span> &lt;span class="nc">CustomDateHandler&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">extends&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">BaseTypeHandler&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Date&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="p">...&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="nd">@Override&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Date&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">getNullableResult&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ResultSet&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">rs&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">columnName&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">throws&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">SQLException&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">		&lt;/span>&lt;span class="n">Timestamp&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">sqlTimestamp&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">rs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">getTimestamp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">columnName&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">		&lt;/span>&lt;span class="k">if&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sqlTimestamp&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">!=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">null&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">			&lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Date&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sqlTimestamp&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">getTime&lt;/span>&lt;span class="p">());&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">		&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">		&lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">null&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="p">...&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>위 코드를 작성하고 실행해보면 정상적으로 시분초 값이 있는 완전한 Date 형태를 볼수 있다.&lt;/li>
&lt;/ul>
&lt;h4 id="2-2-오라클의-date형--javautildate-의-경우">2-2. &lt;code>오라클의 DATE형&lt;/code> → &lt;code>java.util.Date&lt;/code> 의 경우&lt;/h4>
&lt;ul>
&lt;li>아래처럼 코드를 작성하여 커스텀 핸들러를 만들어 등록을 시켜준다.&lt;/li>
&lt;li>단, &lt;a href="http://www.mybatis.org/mybatis-3/ko/configuration.html#typeHandlers" target="_blank" rel="noopener noreffer ">mybatis 3 문서&lt;/a>를 보면 &lt;code>java.sql.Date&lt;/code> 와는 다르게 기본으로 설정된 typeHandler가 JDBC에 따라 3가지가 있다.&lt;/li>
&lt;li>따라서 작성한 커스텀 핸들러를 적용하기 위해서는 명시적으로 &lt;code>자바타입&lt;/code> 과 &lt;code>JDBC타입&lt;/code> 을 적어줘야 정상적으로 오버라이딩이 되어 해당 핸들러를 사용하게 된다.&lt;/li>
&lt;li>mybatis-config.xml&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-xml" data-lang="xml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;typeHandlers&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">		&lt;span class="nt">&amp;lt;typeHandler&lt;/span> &lt;span class="na">handler=&lt;/span>&lt;span class="s">&amp;#34;com.naver.dbill.admin.common.handler.CustomDateHandler&amp;#34;&lt;/span> &lt;span class="na">javaType=&lt;/span>&lt;span class="s">&amp;#34;java.util.Date&amp;#34;&lt;/span> &lt;span class="na">jdbcType=&lt;/span>&lt;span class="s">&amp;#34;DATE&amp;#34;&lt;/span>&lt;span class="nt">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;/typeHandlers&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>CustomDateHandler.java 는 위와 동일하다. ( import java.util.Date; 사용으로 변경 )&lt;/li>
&lt;/ul>
&lt;h3 id="삽질하며-알게된-보너스-지식">삽질하며 알게된 보너스 지식&lt;/h3>
&lt;ul>
&lt;li>&lt;code>java.sql.Date&lt;/code> 는 &lt;code>java.util.Date&lt;/code> 을 상속받았다.&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">class&lt;/span> &lt;span class="nc">Date&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">extends&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">java&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">util&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">Date&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>검색을 하다보면 알수있겠지만 &lt;code>java.sql.Date&lt;/code> 는 JDBC등을 이용해서 데이터베이스의 데이터를 사용하는데 적합하고, &lt;code>java.util.Date&lt;/code> 은 보다 범용적인 날짜나 시각정보를 다룰때 적합하다고 한다.&lt;/li>
&lt;li>toString 메소드의 리턴 Format 형태
&lt;ul>
&lt;li>&lt;code>java.sql.Date&lt;/code> : yyyy-mm-dd&lt;/li>
&lt;li>&lt;code>java.util.Date&lt;/code> : EEE MMM dd HH:mm:ss zzz yyyy&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>mybatis 에서 형변환은 &lt;a href="http://www.mybatis.org/mybatis-3/ko/configuration.html#typeHandlers" target="_blank" rel="noopener noreffer ">mybatis 3 문서&lt;/a>에 나와있는 자바타입과 JDBC타입이 일치할 경우에 해당 타입 핸들러를 기본으로 사용하게 된다.&lt;/li>
&lt;/ul>
&lt;h3 id="정상혁-님-조언---작성하신분-">정상혁 님 조언 ( &lt;a href="http://d2.naver.com/helloworld/645609" target="_blank" rel="noopener noreffer ">http://d2.naver.com/helloworld/645609&lt;/a> 작성하신분 )&lt;/h3>
&lt;ul>
&lt;li>Oracle의 JDBC 드라이버가 예상 밖으로 동작하네요. Oracle의 DATE 타입도 문서를 보니 시분초까지 저장하게 되어 있는데, Oracle JDBC 구현체가 DATE 타입의 철학을 오해한게 아닌가하는 생각도 듭니다.&lt;/li>
&lt;li>참고로 java.sql.Date, java.sql.TimeStamp는 잘못된 설계라는 비판이 많습니다.&lt;/li>
&lt;li>저도 Java의 날짜와 시간 API 라는 글에서 아래와 같이 적은 적이 있습니다.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>java.sql.Date 클래스는 상위 클래스인 java.util.Date 클래스와 이름이 같다. 이 클래스를 두고 Java 플랫폼 설계자는 클래스 이름을 지으면서 깜빡 존 듯하다는 조롱까지 나왔다.[24]&lt;/p></description></item><item><title>자바 8 Date</title><link>https://taetaetae.github.io/2017/01/10/java8-date/</link><pubDate>Tue, 10 Jan 2017 20:55:33 +0000</pubDate><guid>https://taetaetae.github.io/2017/01/10/java8-date/</guid><description>&lt;p>이제까지 내 기억으로는 Date 관련 클래스를 아래처럼 점차 바꿔써온걸로 기억이 난다.
&lt;code>java.util.Date&lt;/code> &amp;gt; &lt;code>java.util.Calendar&lt;/code> &amp;gt; &lt;code>org.joda.time&lt;/code>
그런데 java 8 버전에서 기존에 있었던 문제들을 개선해서 나왔다고 한다. (&lt;a href="http://d2.naver.com/helloworld/645609" target="_blank" rel="noopener noreffer ">네이버 HellowWorld 포스팅 참고&lt;/a>) &lt;code>JSR-310&lt;/code> 이라는 표준명세로.&lt;/p>
&lt;!-- more -->
&lt;p>지금부터는 JAVA 8 에서 제공하는 API로 날짜 연산을 어떻게 하는지에 대해 알아보고자 한다. (물론 수많은 날짜 연산 방법을이 있지만 자주 쓰이는 부분들 위주로 정리해보자.)&lt;/p>
&lt;ul>
&lt;li>Date &amp;gt; String (format)&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="n">LocalDateTime&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">now&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="na">format&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">DateTimeFormatter&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">ofPattern&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>String &amp;gt; Date (format)&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="n">LocalDateTime&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;2017-01-01 12:30:00&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">DateTimeFormatter&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">ofPattern&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;yyyy-MM-dd HH:mm:ss&amp;#34;&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>날짜/시간 증감&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="n">LocalDateTime&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">localDateTime&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">LocalDateTime&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">of&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">2017&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">1&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">1&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">10&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">0&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">0&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="n">localDateTime&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">plusDays&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">1&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// 일&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="n">localDateTime&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">plusMonths&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">1&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// 월&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="n">localDateTime&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">plusHours&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">1&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// 시간&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="n">localDateTime&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">plusWeeks&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">1&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// 주&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="n">localDateTime&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">minusYears&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">1&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// 년&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="n">localDateTime&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">minusMinutes&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">1&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// 분&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>더 다양한 내용들은 아래 URL 에서 확인이 가능하다.
&lt;a href="https://docs.oracle.com/javase/tutorial/datetime/iso/overview.html" target="_blank" rel="noopener noreffer ">https://docs.oracle.com/javase/tutorial/datetime/iso/overview.html&lt;/a>&lt;/p></description></item></channel></rss>