<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Oracle on</title><link>https://taetaetae.github.io/tags/oracle/</link><description>Recent content in Oracle on</description><generator>Hugo</generator><language>en</language><lastBuildDate>Tue, 04 Apr 2017 11:41:28 +0000</lastBuildDate><atom:link href="https://taetaetae.github.io/tags/oracle/index.xml" rel="self" type="application/rss+xml"/><item><title>mybatis insert/update 쿼리실행후 결과 가져오기</title><link>https://taetaetae.github.io/2017/04/04/mybatis-use-generated-keys/</link><pubDate>Tue, 04 Apr 2017 11:41:28 +0000</pubDate><guid>https://taetaetae.github.io/2017/04/04/mybatis-use-generated-keys/</guid><description>&lt;p>&lt;code>Select&lt;/code>문이 아닌 다른 &lt;code>SQL Query&lt;/code>(insert, update 등) 를 실행하고서 결과를 봐야하는 상황이 생긴다. 정확히 잘 수행되었나에 대한 확인. 어떻게 쿼리가 잘 수행되었나를 확인하는 방법은 다음과 같다.
※ 참고 url : &lt;a href="http://www.mybatis.org/mybatis-3/ko/sqlmap-xml.html" target="_blank" rel="noopener noreffer ">http://www.mybatis.org/mybatis-3/ko/sqlmap-xml.html&lt;/a>&lt;/p>
&lt;h2 id="usegeneratedkeys-keyproperty-옵션">useGeneratedKeys, keyProperty 옵션&lt;/h2>
&lt;p>사용하는 데이터베이스가 자동생성키를 지원한다면(mySql 같은) 해당옵션을 이용해 결과를 리턴 받을수 있다.
예로들어 파라미터로 아래 모델객체를 넘긴다고 가정하고&lt;/p>
&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="n">Student&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="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">id&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">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">name&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">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">email&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">Date&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">regist_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;/code>&lt;/pre>&lt;/div>&lt;p>아래 mybatis 구문으로 insert를 시도하게되면, 파라미터로 넘긴 Student 객체의 id값에 insert 했을때의 key값(id)이 들어오게 된다.&lt;/p>
&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">Student&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">student&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&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">Student&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">student&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">setName&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">bla&lt;/span>&lt;span class="err">&amp;#39;&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">student&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">setEmail&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">bla&lt;/span>&lt;span class="nd">@naver.com&lt;/span>&lt;span class="err">&amp;#39;&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>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="n">mapper&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">insertStudents&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">student&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">student&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">getId&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;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;insert&lt;/span> &lt;span class="na">id=&lt;/span>&lt;span class="s">&amp;#34;insertStudents&amp;#34;&lt;/span> &lt;span class="na">useGeneratedKeys=&lt;/span>&lt;span class="s">&amp;#34;true&amp;#34;&lt;/span> &lt;span class="na">keyProperty=&lt;/span>&lt;span class="s">&amp;#34;id&amp;#34;&lt;/span> &lt;span class="na">parameterType=&lt;/span>&lt;span class="s">&amp;#34;Student&amp;#34;&lt;/span>&lt;span class="nt">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> insert into Students ( name, email )
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> values ( #{name}, #{email} )
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;/insert&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="selectkey-옵션">selectKey 옵션&lt;/h2>
&lt;p>Oracle 같은 경우는 Auto Increment 가 없고 Sequence를 사용해야만 하기 때문에 위 옵션을 사용할수가 없다. 하지만 다른 우회적인(?) 방법으로 위와같은 효과를 볼수가 있다.
파라미터의 모델이나 java구문은 위와 동일하고 xml 쿼리 부분만 아래와 같이 설정해주면 된다.&lt;/p>
&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;insert&lt;/span> &lt;span class="na">id=&lt;/span>&lt;span class="s">&amp;#34;insertStudents&amp;#34;&lt;/span> &lt;span class="na">parameterType=&lt;/span>&lt;span class="s">&amp;#34;Student&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;selectKey&lt;/span> &lt;span class="na">keyProperty=&lt;/span>&lt;span class="s">&amp;#34;id&amp;#34;&lt;/span> &lt;span class="na">resultType=&lt;/span>&lt;span class="s">&amp;#34;int&amp;#34;&lt;/span> &lt;span class="na">order=&lt;/span>&lt;span class="s">&amp;#34;BEFORE&amp;#34;&lt;/span>&lt;span class="nt">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> select SEQ_ID.nexyval FROM DUAL
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;/selectKey&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> insert into Students
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (id, name , email)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> values
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (#{id}, #{name}, #{email})
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;/insert&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>위와같은 코드에서 쿼리가 실행되기 전에 id값에 Sequence에 의해 값을 셋팅하게 되고, 자동적으로 해당 값을 Student의 id에 set하게 되서 동일한 결과를 볼수가 있다.&lt;/p>
&lt;p>항상 테이블의 key값에만 해당하는것이 아니다. key값과는 전혀 상관없는 값도 &lt;code>selectKey&lt;/code> 구문으로 리턴할수가 있는데 &lt;code>order&lt;/code>옵션을 &lt;code>AFTER&lt;/code>로 주고 리턴하고자 하는 값을 명시해주면 된다.
아래 코드에서는 입력할시 id값을 Sequence에서 가져오는게 아니라 수동으로 넣어주고, 입력했던 id에 맞는 regist_date 값을 리턴받아 위에서처럼 동일하게 값를 가져올수 있다.&lt;/p>
&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;insert&lt;/span> &lt;span class="na">id=&lt;/span>&lt;span class="s">&amp;#34;insertStudents&amp;#34;&lt;/span> &lt;span class="na">parameterType=&lt;/span>&lt;span class="s">&amp;#34;Student&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;selectKey&lt;/span> &lt;span class="na">keyProperty=&lt;/span>&lt;span class="s">&amp;#34;regist_date&amp;#34;&lt;/span> &lt;span class="na">resultType=&lt;/span>&lt;span class="s">&amp;#34;java.util.Date&amp;#34;&lt;/span> &lt;span class="na">order=&lt;/span>&lt;span class="s">&amp;#34;AFTER&amp;#34;&lt;/span>&lt;span class="nt">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> select regist_date FROM students WHERE id = #{id}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;/selectKey&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> insert into Students
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (id, name , email, regist_date)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> values
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (#{id}, #{name}, #{email}, syadate)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;/insert&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><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></channel></rss>