<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Mybatis on</title><link>https://taetaetae.github.io/tags/mybatis/</link><description>Recent content in Mybatis on</description><generator>Hugo</generator><language>en</language><lastBuildDate>Sun, 21 Apr 2019 22:47:04 +0000</lastBuildDate><atom:link href="https://taetaetae.github.io/tags/mybatis/index.xml" rel="self" type="application/rss+xml"/><item><title>spring-boot에서 mybatis로 mysql 연동하기</title><link>https://taetaetae.github.io/2019/04/21/spring-boot-mybatis-mysql-xml/</link><pubDate>Sun, 21 Apr 2019 22:47:04 +0000</pubDate><guid>https://taetaetae.github.io/2019/04/21/spring-boot-mybatis-mysql-xml/</guid><description>&lt;p>실무에서 개발을 하다보면 과거 누군가 잘 구성해 놓은 밥상(legacy)에 숟가락만 얹는 느낌으로 &lt;code>로직 구현&lt;/code>만 할때가 있다. 그러다보면 각종 레이어가 어떻게 구성(설정)되어있는지도 모르고 &lt;!-- more --> 간혹 설정에서 문제가 발생하면 &amp;ldquo;아 내가 이것도 모르고 이제까지 개발을 해왔나&amp;rdquo; 하는 자괴감이 들며 몇시간을 삽질하는 경우가 있다. 그게 지금의 필자인것 같다. (눙물&amp;hellip;)&lt;/p>
&lt;figure>&lt;a class="lightgallery" href="https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/mung.jpg" title="/images/spring-boot-mybatis-mysql-xml/mung.jpg" data-thumbnail="/images/spring-boot-mybatis-mysql-xml/mung.jpg" data-sub-html="&lt;h2>출처 : http://blog.naver.com/PostView.nhn?blogId=ondo_h&amp;logNo=221437452142&lt;/h2>">
 &lt;img
 class="lazyload"
 src="https://taetaetae.github.io/svg/loading.min.svg"
 data-src="https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/mung.jpg"
 data-srcset="https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/mung.jpg, https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/mung.jpg 1.5x, https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/mung.jpg 2x"
 data-sizes="auto"
 alt="/images/spring-boot-mybatis-mysql-xml/mung.jpg" width="30%" />
 &lt;/a>&lt;figcaption class="image-caption">출처 : &lt;a href="http://blog.naver.com/PostView.nhn?blogId=ondo_h&amp;amp;logNo=221437452142" target="_blank" rel="noopener noreffer ">http://blog.naver.com/PostView.nhn?blogId=ondo_h&amp;logNo=221437452142&lt;/a>&lt;/figcaption>
 &lt;/figure>
&lt;p>사이드 프로젝트 초기셋팅을 하며 호기롭게 spring boot 최신버전에서 db를 연동하려 했는데 막상 완전 바닥부터 해본 경험이 적다보니 (spring boot 2 버전에서는 더욱더&amp;hellip;) 어디서부터 뭘 설정을 해야할지&amp;hellip; 그리고 &lt;code>이럴때 보는&lt;/code> 도큐먼트를 봐도 잘 이해가 안되어 삽질을 해가며 당황하기 일쑤였다.
이번 포스팅에서는 아래와 같은 구성을 하는데 목표를 두고자 한다.&lt;/p>
&lt;ul>
&lt;li>Spring Boot 2 프로젝트를 처음 만들고&lt;/li>
&lt;li>mybatis 를 사용해서&lt;/li>
&lt;li>mysql 을 연동하는것 (AWS 의 RDS를 사용, 추후 RDS사용법에 대해 블로깅 예정)&lt;/li>
&lt;/ul>
&lt;p>위와 같은 상황을 처음 접하는 분들께 도움이 되었으면 하는 바램으로 짧게나마 필자의 삽질기를 여행해보자.&lt;/p>
&lt;h2 id="spring-boot-2-프로젝트-만들기">Spring boot 2 프로젝트 만들기&lt;/h2>
&lt;p>필자는 IntelliJ를 사용하고 있어서 새로 프로젝트를 만들려고 할때 클릭 몇번만으로 dependency 설정까지 다 해주기 때문에 편하고 좋았다. 혹 이클립스나 다른 IDE를 사용하고 있다면 &lt;a href="https://start.spring.io/" target="_blank" rel="noopener noreffer ">https://start.spring.io/&lt;/a> 을 참고하면 도움이 될것같다. 여기서도 클릭 몇번으로 IntelliJ 에서 해주는 것처럼 내가 사용할 모듈을 선택하고 generate 를 누르면 프로젝트가 생성되어 다운로드 받아진다. (참 좋은 세상&amp;hellip;)
우선 File → New → Project 를 눌러서 아래 창을 열어보자. 그리고 뭔가 다 해줄것 같은 (개발도 해주면 안되나&amp;hellip;) &lt;code>Spring Initializr&lt;/code>을 선택후 아래와 같은 설정을 적어준 뒤 다음을 눌러준다.&lt;/p>
&lt;a class="lightgallery" href="https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/1.jpg" title="/images/spring-boot-mybatis-mysql-xml/1.jpg" data-thumbnail="/images/spring-boot-mybatis-mysql-xml/1.jpg">
 &lt;img
 class="lazyload"
 src="https://taetaetae.github.io/svg/loading.min.svg"
 data-src="https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/1.jpg"
 data-srcset="https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/1.jpg, https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/1.jpg 1.5x, https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/1.jpg 2x"
 data-sizes="auto"
 alt="/images/spring-boot-mybatis-mysql-xml/1.jpg" width="80%" />
 &lt;/a>
&lt;p>사용할 모듈을 선택해주자. 필자는 이것저것(?)을 도와주는 &lt;code>lombok&lt;/code>과 &lt;code>Mybatis&lt;/code>, &lt;code>MySQL&lt;/code>을 선택하고 프로젝트를 생성하였다. 그러면 이쁜(?) pom.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;dependencies&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="nt">&amp;lt;dependency&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">		&lt;span class="nt">&amp;lt;groupId&amp;gt;&lt;/span>org.mybatis.spring.boot&lt;span class="nt">&amp;lt;/groupId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">		&lt;span class="nt">&amp;lt;artifactId&amp;gt;&lt;/span>mybatis-spring-boot-starter&lt;span class="nt">&amp;lt;/artifactId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">		&lt;span class="nt">&amp;lt;version&amp;gt;&lt;/span>2.0.1&lt;span class="nt">&amp;lt;/version&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="nt">&amp;lt;/dependency&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="nt">&amp;lt;dependency&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">		&lt;span class="nt">&amp;lt;groupId&amp;gt;&lt;/span>mysql&lt;span class="nt">&amp;lt;/groupId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">		&lt;span class="nt">&amp;lt;artifactId&amp;gt;&lt;/span>mysql-connector-java&lt;span class="nt">&amp;lt;/artifactId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="nt">&amp;lt;/dependency&amp;gt;&lt;/span>	
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="nt">&amp;lt;dependency&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">		&lt;span class="nt">&amp;lt;groupId&amp;gt;&lt;/span>org.projectlombok&lt;span class="nt">&amp;lt;/groupId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">		&lt;span class="nt">&amp;lt;artifactId&amp;gt;&lt;/span>lombok&lt;span class="nt">&amp;lt;/artifactId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">		&lt;span class="nt">&amp;lt;optional&amp;gt;&lt;/span>true&lt;span class="nt">&amp;lt;/optional&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="nt">&amp;lt;/dependency&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;/dependencies&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;a class="lightgallery" href="https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/2.jpg" title="/images/spring-boot-mybatis-mysql-xml/2.jpg" data-thumbnail="/images/spring-boot-mybatis-mysql-xml/2.jpg">
 &lt;img
 class="lazyload"
 src="https://taetaetae.github.io/svg/loading.min.svg"
 data-src="https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/2.jpg"
 data-srcset="https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/2.jpg, https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/2.jpg 1.5x, https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/2.jpg 2x"
 data-sizes="auto"
 alt="/images/spring-boot-mybatis-mysql-xml/2.jpg" width="80%" />
 &lt;/a>
&lt;p>우선 여기까지 잘 되었는제 확인해보기 위해 Controller 에 현재시간을 출력하는걸 만들어 보고&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="nd">@RestController&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">ApiController&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>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="nd">@GetMapping&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">path&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;/helloWorld&amp;#34;&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="n">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">helloWorld&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="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">ISO_LOCAL_DATE_TIME&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;p>톰켓을 실행해보면 정상적으로 접속과 출력이 되는것을 확인할 수 있다.&lt;/p>
&lt;a class="lightgallery" href="https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/3.jpg" title="/images/spring-boot-mybatis-mysql-xml/3.jpg" data-thumbnail="/images/spring-boot-mybatis-mysql-xml/3.jpg">
 &lt;img
 class="lazyload"
 src="https://taetaetae.github.io/svg/loading.min.svg"
 data-src="https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/3.jpg"
 data-srcset="https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/3.jpg, https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/3.jpg 1.5x, https://taetaetae.github.io/images/spring-boot-mybatis-mysql-xml/3.jpg 2x"
 data-sizes="auto"
 alt="/images/spring-boot-mybatis-mysql-xml/3.jpg" width="80%" />
 &lt;/a>
&lt;h2 id="mysql-연동하기">MySQL 연동하기&lt;/h2>
&lt;p>필자가 허둥지둥 했던점 중 하나는 MyBatis와 MySQL을 동시에 연동하려고 하다보니 문제가 발생해도 어디서의 문제인지를 제대로 파악하지 못하고 삽질했다는 점이다. 여기서 정확히 짚고 넘어가면 우선 데이터를 연결해주는 ORM인 MyBatis를 셋팅해준 다음 MySQL을 연동해주는 식으로 분리해서 설정을 하면 햇갈리지 않고 (돌아가지 않고) 보다 빠르게 설정이 가능할것 같다. (여기서 순서는 중요하지 않고 별도로 설정해야 한다는 관점이 중요한것 같다.)
우선 &lt;code>src/main/resources&lt;/code>폴더에 있는 &lt;code>application.properties&lt;/code> 에 다음처럼 작성해주자.&lt;/p>
&lt;pre tabindex="0">&lt;code>spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.jdbc-url=jdbc:mysql://{url}:{port}/{db}
spring.datasource.hikari.username={id}
spring.datasource.hikari.password={password}
&lt;/code>&lt;/pre>&lt;p>위의 jdbc-url 항목에서 AWS에서 제공하는 RDS를 사용하는 경우 RDS에서 제공해주는 엔드포인트와 포트를 적어주면 된다. (추후 AWS - RDS에 대해 블로깅 예정이다.)
Spring Boot 2.0 이후부터 기본적으로 사용되는 커넥션 풀이 HikariCP로 변경되었다고 한다. (&lt;a href="https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes#hikaricp" target="_blank" rel="noopener noreffer ">링크&lt;/a>) 커넥션 풀 종류중 성능이 좋다고 하는데 &lt;a href="https://github.com/brettwooldridge/HikariCP" target="_blank" rel="noopener noreffer ">링크&lt;/a>를 가보면 다른 커넥션 풀 라이브러리와 성능을 비교한 벤치마크 결과를 확인할 수 있다.
위처럼 &lt;code>spring.datasource.hikari&lt;/code> 가 prefix로 붙고 각종 정보들을 적어주어 config 에서 인식될수 있도록 해주자. 그 다음 DataSource 설정을 해준다.&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="nd">@Slf4j&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">@Configuration&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">@PropertySource&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;classpath:/application.properties&amp;#34;&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">DatabaseConfiguration&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="nd">@Bean&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">@ConfigurationProperties&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">prefix&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;spring.datasource.hikari&amp;#34;&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="n">HikariConfig&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">hikariConfig&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">HikariConfig&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>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="nd">@Bean&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">DataSource&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">dataSource&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="n">DataSource&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">dataSource&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">HikariDataSource&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">hikariConfig&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">log&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">info&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;datasource : {}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">dataSource&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">dataSource&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;p>위 내용은 DataSource 를 hikariConfig에서 설정한 정보로 만들어 준다는 의미이다. 이렇게만 하고 프로젝트를 다시 실행시켜보면 logger 에 의해 datasource 의 정보를 볼수가 있다.&lt;/p></description></item><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>