<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>JmPark.log</title>
        <link>https://velog.io/</link>
        <description>동료를 소중히 생각하는 개발자입니다.</description>
        <lastBuildDate>Sat, 04 Feb 2023 13:54:17 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. JmPark.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jaemin_0820" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Docker] 명령어 정리]]></title>
            <link>https://velog.io/@jaemin_0820/Docker-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@jaemin_0820/Docker-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sat, 04 Feb 2023 13:54:17 GMT</pubDate>
            <description><![CDATA[<ol>
<li>도커 이미지 목록</li>
</ol>
<ul>
<li>docker images</li>
</ul>
<ol start="2">
<li>도커 이미지 내려받기</li>
</ol>
<ul>
<li>docker pull 이미지명</li>
</ul>
<ol start="3">
<li>현재 컨테이너에서 실행중인 이미지 확인</li>
</ol>
<ul>
<li>docker ps</li>
<li>docker ps -a (실행, 종료 포함하는 전체 프로세스)</li>
</ul>
<ol start="4">
<li>도커 이미지 삭제 명령어</li>
</ol>
<ul>
<li>docker rmi 이미지명</li>
</ul>
<ol start="5">
<li>컨테이너에 실행중(PS-메모리할당)인 이미지 삭제</li>
</ol>
<ul>
<li>docker stop</li>
<li>docker rmi  이미지명</li>
</ul>
<ol start="6">
<li>종료된 컨테이너 이미지 삭제</li>
</ol>
<ul>
<li>docker stop → rmi 해보고 안될 경우 아래와 같이 진행</li>
<li>docker ps -a → docker rm 이미지명</li>
</ul>
<ol start="7">
<li>docker run -d 이미지명 </li>
</ol>
<ul>
<li>백그라운드에서 실행하는 명령어</li>
<li>이미지의 해시 코드(주소)만 뜬다</li>
<li>docker ps (-a)를 하면 정상적으로 프로세스 실행이 되는 것을 확인 할 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[git 명령어 정리 및 에러 발생 시 상황별 처리 ]]></title>
            <link>https://velog.io/@jaemin_0820/git-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC-%EB%B0%8F-%EC%97%90%EB%9F%AC-%EB%B0%9C%EC%83%9D-%EC%8B%9C-%EC%83%81%ED%99%A9%EB%B3%84-%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@jaemin_0820/git-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC-%EB%B0%8F-%EC%97%90%EB%9F%AC-%EB%B0%9C%EC%83%9D-%EC%8B%9C-%EC%83%81%ED%99%A9%EB%B3%84-%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Mon, 19 Dec 2022 15:19:07 GMT</pubDate>
            <description><![CDATA[<p>회사에서 Svn에서 Git으로 변경하여 관리중인데 다들 혼란이 심히오셨다. 그래서 상황 발생 시 대응 하는 명령어를 정리하였다. </p>
<p>master / developer</p>
<p>상황이 다들 다르고 제가 틀린 부분도 있을 수 있기 때문에 참고만 하시고 틀린 부분은 지적 부탁드립니다.</p>
<p> <strong>오류 없는 상황에서 보통의 git 처리</strong></p>
<ul>
<li><p>git pull origin 브랜치명</p>
</li>
<li><p>git commit</p>
</li>
<li><p>git push </p>
</li>
</ul>
<p> <strong>untracked files 지우기</strong></p>
<ul>
<li><p>git clean -f (파일만)</p>
</li>
<li><p>git clean -fd(디렉토리)</p>
</li>
</ul>
<p><strong>상위 브랜치(master)에서 하위 브랜치(developer) 작업 내용 merge</strong></p>
<ul>
<li><p>git stash (master 작업물 임시 저장소로 이관)</p>
</li>
<li><p>git merge developer</p>
</li>
<li><p>git stash pop (master 작업물 임시 저장소에서 꺼내오기)</p>
</li>
</ul>
<p><strong>merge → git stash pop 하다가 conflict 발생 시 처리</strong></p>
<ul>
<li><p>git reset HEAD [해당 파일명] , 해당 파일명을 안쓰면 모든 파일 </p>
</li>
<li><p>다시 git merge 실행</p>
</li>
<li><p>그래도 error: Merging is not possible because you have unmerged files. 문구 발생이 된다면</p>
</li>
<li><p>git reset --hard origin/(현재 체크 아웃 된 브랜치명) —&gt; 최근 push된 상황으로 되돌아 간다. </p>
</li>
<li><p>다시 git merge를 실행한다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Mybatis <selectKey> 사용법]]></title>
            <link>https://velog.io/@jaemin_0820/Mybatis-selectKey</link>
            <guid>https://velog.io/@jaemin_0820/Mybatis-selectKey</guid>
            <pubDate>Mon, 19 Dec 2022 14:55:18 GMT</pubDate>
            <description><![CDATA[<p>Mybatis 벌크 연산 쿼리를 작성 중 A테이블의 PK를 B테이블에 같이 INSERT를 진행하는 상황이 생겼다. </p>
<h1 id="insert-이전-사용">INSERT 이전 사용</h1>
<p>그래서 <code>&lt;selectKey&gt;</code> 를 사용하여 wm_dep_m테이블 INSERT이전에 키 값을 조회해서 INSERT를 하도록 쿼리를 작성했다. </p>
<pre><code>  &lt;insert id=&quot;insExp&quot; parameterType=&quot;map&quot;&gt;

  &lt;selectKey order=&quot;BEFORE&quot; keyProperty=&quot;exp_no&quot; resultType=&quot;int&quot;&gt;
          select INS_EXP_NO() FROM 테이블명
  &lt;/selectKey&gt;

    insert into wm_exp_m(no,exp_nm,exp_ct,start_dt,end_dt,reg_id)
    values(#{exp_no},#{exp_nm},#{exp_ct},#{start_dt},#{end_dt},#{reg_id}) 
    &lt;/insert&gt;</code></pre><p>여기서 INS_EXP_NO() MYSQL에서 사용자 함수를 만들어 AUTO_INCREMENT의 역할을 하는 것으로 생각하면 된다.</p>
<h1 id="insert-이후-사용">INSERT 이후 사용</h1>
<pre><code>  &lt;insert id=&quot;insExp&quot; parameterType=&quot;map&quot;&gt;
    insert into wm_exp_m(no,exp_nm,exp_ct,start_dt,end_dt,reg_id)
    values(#{exp_no},#{exp_nm},#{exp_ct},#{start_dt},#{end_dt},#{reg_id}) 

    &lt;selectKey order=&quot;AFTER&quot; keyProperty=&quot;exp_no&quot;  keyColumn=&quot;exp_no&quot; resultType=&quot;int&quot;&gt;
        select INS_EXP_NO() FROM dual
&lt;/selectKey&gt;
    &lt;/insert&gt;</code></pre><h1 id="select-key-엘리먼트-속성">select key 엘리먼트 속성</h1>
<ul>
<li><p>keyProperty: selectKey구문의 결과가 셋팅될 대상 프로퍼티.</p>
</li>
<li><p>keyColumn: 리턴되는 결과셋의 칼럼명은 프로퍼티에 일치한다. 여러개의 칼럼을 사용한다면 칼럼명의 목록은 콤마를 사용해서 구분한다.</p>
</li>
<li><p>resultType: 결과의 타입. 마이바티스는 이 기능을 제거할 수 있지만 추가하는게 문제가 되지는 않을것이다. 마이바티스는 String을 포함하여 키로 사용될 수 있는 간단한 타입을 허용한다.</p>
</li>
<li><p>order: BEFORE 또는 AFTER를 셋팅할 수 있다. BEFORE로 설정하면 키를 먼저 조회하고 그 값을 keyProperty 에 셋팅한 뒤 insert 구문을 실행한다. AFTER로 설정하면 insert 구문을 실행한 뒤 selectKey 구문을 실행한다. </p>
</li>
<li><p>statementType: STATEMENT, PREPARED 또는 CALLABLE중 하나를 선택할 수 있다. 마이바티스에게 Statement, PreparedStatement 또는 CallableStatement를 사용하게 한다. 디폴트는 PREPARED 이다.</p>
</li>
</ul>
<p>[참조링크] : <a href="https://deeplify.dev/back-end/spring/select-key">https://deeplify.dev/back-end/spring/select-key</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링부트 2.7 이상 QueryDsl build.gradle 설정 방법]]></title>
            <link>https://velog.io/@jaemin_0820/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-2.7-%EC%9D%B4%EC%83%81-QueryDsl-build.gradle-%EC%84%A4%EC%A0%95-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@jaemin_0820/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-2.7-%EC%9D%B4%EC%83%81-QueryDsl-build.gradle-%EC%84%A4%EC%A0%95-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Sat, 26 Nov 2022 06:22:11 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/jaemin_0820/post/1836f0fd-fe3e-4c4d-8455-d5b5f70d5c99/image.png" alt=""></p>
<pre><code>buildscript {
  ext {
      queryDslVersion = &quot;5.0.0&quot;
  }
}


plugins {
  id &#39;org.springframework.boot&#39; version &#39;2.7.5&#39;
  id &#39;io.spring.dependency-management&#39; version &#39;1.0.15.RELEASE&#39;
  id &#39;java&#39;
  id &#39;war&#39;
  id &#39;com.ewerk.gradle.plugins.querydsl&#39; version &#39;1.0.10&#39;
}


apply plugin: &#39;com.ewerk.gradle.plugins.querydsl&#39;
group = &#39;toy.tiering&#39;
version = &#39;0.0.1-SNAPSHOT&#39;
sourceCompatibility = &#39;11&#39;

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {

    implementation &quot;com.querydsl:querydsl-jpa:${queryDslVersion}&quot;

    implementation &quot;com.querydsl:querydsl-apt:${queryDslVersion}&quot;

}

tasks.named(&#39;test&#39;) {
    useJUnitPlatform()
}

def querydslDir = &quot;$buildDir/generated/querydsl&quot;

querydsl {
    jpa = true
    querydslSourcesDir = querydslDir
}
sourceSets {
    main.java.srcDir querydslDir
}
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
    querydsl.extendsFrom compileClasspath
}
compileQuerydsl {
    options.annotationProcessorPath = configurations.querydsl
}

compileQuerydsl.doFirst {
    if(file(querydslDir).exists() )
        delete(file(querydslDir))
}</code></pre><ul>
<li>참조
<a href="https://dkswnkk.tistory.com/593">https://dkswnkk.tistory.com/593</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[@Slf4j 사용시 log cannot be resolved 에러 처리]]></title>
            <link>https://velog.io/@jaemin_0820/Slf4j-%EC%82%AC%EC%9A%A9%EC%8B%9C-log-cannot-be-resolved-%EC%97%90%EB%9F%AC-%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@jaemin_0820/Slf4j-%EC%82%AC%EC%9A%A9%EC%8B%9C-log-cannot-be-resolved-%EC%97%90%EB%9F%AC-%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Thu, 13 Jan 2022 06:48:45 GMT</pubDate>
            <description><![CDATA[<ol>
<li><p>STS 또는 이클립스 Maven Dependencies 에서 lombok-1.18.8.jar 파일을 찾는다.</p>
</li>
<li><p>lombok-1.18.8.jar 파일을 우클릭 -&gt; run as -&gt; java application -&gt; 프로세스 진행</p>
</li>
<li><p>lombok jar 파일이 실행되며 install 창이 표시된다.</p>
</li>
<li><p>specify location -&gt; 이클립스 위치의 eclipse.ini 를 선택 -&gt; install/update 진행</p>
</li>
<li><p>install 이 정상적으로 실행 된다.</p>
</li>
<li><p>STS 또는 이클립스로 돌아와 프로젝트를 clean -&gt; restart 한다.</p>
</li>
<li><p>log 관련 에러가 사라진다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Security 로그아웃 에러 핸들링 ("Status" : 999)]]></title>
            <link>https://velog.io/@jaemin_0820/Spring-Security-%EB%A1%9C%EA%B7%B8%EC%95%84%EC%9B%83-%EC%97%90%EB%9F%AC-%ED%95%B8%EB%93%A4%EB%A7%81-Status-999</link>
            <guid>https://velog.io/@jaemin_0820/Spring-Security-%EB%A1%9C%EA%B7%B8%EC%95%84%EC%9B%83-%EC%97%90%EB%9F%AC-%ED%95%B8%EB%93%A4%EB%A7%81-Status-999</guid>
            <pubDate>Thu, 22 Jul 2021 03:10:23 GMT</pubDate>
            <description><![CDATA[<p>Spring Security 회원가입 / 로그인 - 로그아웃 구현 후 테스트를 하다가 로그아웃 할 때 아래와 같은 에러가 발생하였다.</p>
<p><img src="https://images.velog.io/images/jaemin_0820/post/4c3fc2ab-b31d-48fd-98e7-74f869f53d33/image.png" alt=""></p>
<p>처음 생각했을 때 이전에 로그인한 세션이 남아 있는 상황에서 로그인을 하려고하니 위와 같은 에러페이지가 발생하는 것 같아
아래와 같이 세션 초기화 처리도 했지만 소용이 없었다
<img src="https://images.velog.io/images/jaemin_0820/post/ec8f3952-4c70-4b69-bbb9-40bd84d277cd/image.png" alt=""></p>
<p>그러나 문제 해결은 너무나 쉽게 해결되었다. 구글링을 통해 접속하여 대략 확인해보니 로그인을 성공한 후 이동할 페이지에 접근이 불가한 상태라는 것 같아 아래처럼 정적 페이지는 인증을 안해도 접근을 허용하게 하여 해결(&quot;/error&quot;를 추가)
<a href="https://stackoverflow.com/questions/61029340/spring-security-redirects-to-page-with-status-code-999/61029341">https://stackoverflow.com/questions/61029340/spring-security-redirects-to-page-with-status-code-999/61029341</a>
<img src="https://images.velog.io/images/jaemin_0820/post/3902ca93-e249-423a-bb5a-636b1c8f4185/image.png" alt=""> </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[var, let, const 비교 ]]></title>
            <link>https://velog.io/@jaemin_0820/var-let-const-%EB%B9%84%EA%B5%90</link>
            <guid>https://velog.io/@jaemin_0820/var-let-const-%EB%B9%84%EA%B5%90</guid>
            <pubDate>Mon, 05 Jul 2021 13:38:21 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트의 기본 변수 선언시 사용 하는 var, let, const의 비교를 하고자 한다.</p>
<ol>
<li>var</li>
</ol>
<pre><code class="language-js">var variable = &quot;변수1&quot;
console.log(variable) // 변수1

var variable = &quot;변수2&quot;
console.log(variable) // 변수2</code></pre>
<ul>
<li>var는 변수 선언을 여러 번해도 에러 없이 각각의 값을 출력</li>
<li>필요할 때 마다 변수를 사용할 수 있다는 장점이 있지만, 같은 변수명을 남용하는 문제가 있기에 단점이 많아 ES6부터 let, const가 추가 됨</li>
</ul>
<ol start="2">
<li>let<pre><code class="language-js">let variable = &quot;변수1&quot;
console.log(variable) // 변수1
</code></pre>
</li>
</ol>
<p>variable =&quot;변수2&quot;
console.log(variable) // 변수2</p>
<p>let variable = &quot;변수3&quot;
console.log(variable)// 변수3</p>
<pre><code> - let은 변수 재할당은 가능하지만 var처럼 재 선언은 되지 않음

 ![](https://images.velog.io/images/jaemin_0820/post/00e32fb3-f1d6-4279-99c0-c53bec0e1c17/image.png)
 - 실제로 위에처럼 재 선언 후 크롬 개발자 도구에서 확인하면 에러 문구가 뜸.


 3. const

```js
const variable = &quot;변수1&quot;

console.log(variable) // 변수1

variable = &quot;변수2&quot;
console.log(variable) // 변수2(에러)

const variable = &quot;변수3&quot;
console.log(variable) // 변수3(에러)
</code></pre><ul>
<li>const의 경우 한 번만 선언하고 또 값을 재 할당을 통해 바꿀수 없음</li>
</ul>
<p>[결론]</p>
<ul>
<li><p>재 할당이 필요 없는 경우, const(상수, 객체)를 사용해 불 필요한 변수의 재 사용을 방지하고, 재 할당이 필요한 경우 let을 사용하는 것이 좋음.</p>
</li>
<li><p>변수의 스코프는 최대한 좁게 만드는 것이 좋음.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바 Static이란?]]></title>
            <link>https://velog.io/@jaemin_0820/%EC%9E%90%EB%B0%94-Static%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@jaemin_0820/%EC%9E%90%EB%B0%94-Static%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Sat, 03 Jul 2021 08:39:08 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/jaemin_0820/post/695617bb-67e3-4740-ad32-54f3ec618164/image.png" alt=""></p>
<ol>
<li>Static이란?</li>
</ol>
<ul>
<li>Static이란 고정된 의미</li>
<li>Static이라는 키워드를 사용하여 Static변수와 메서드를 만들수 있음</li>
<li>정적 필드 + 정적 메서드 = 정적 멤버(클래스 멤버)</li>
<li>정적 필드와 메서드는 객체에 소속된 멤버가 아니라 클래스에 고정된 멤버 </li>
<li>클래스를 로딩해서 메서드 메모리 영역에 적재할 때 클래스별로 관리</li>
<li>따라서, 클래스의 로딩이 끝나는 즉시 바로 사용 </li>
</ul>
<ol start="2">
<li>정적(Static) 멤버 생성</li>
</ol>
<ul>
<li>Static 키워드를 통해 생성된 정적 멤버들은 Heap 영역이 아닌 Static 영역에 할당</li>
<li>Static 영역에 할당 된 메모리는 모든 객체가 공유하여 하나의 멤버를 어디서든지 참조</li>
<li>다만, Garbage Collector의 관리 영역 밖에 존재 하기에 Static영역에 있는 멤버들은 프로그램 종료시 까지 메모리가 할당된 채로 존재 =&gt; Static을 많이 사용하면 시스템 성능이 떨어짐</li>
</ul>
<ol start="3">
<li><p>정적(Static) 멤버 선언</p>
<ul>
<li>필드와 메서드를 생성 시 인스턴스 VS 정적으로 생성할 것인지 판단 기준은 공용으로 사용 여부로 나뉨</li>
<li>그냥 생성 한다면 자동으로 인스턴스로 생성되며, 정적으로 생성하려면 필드와 메서드 선언 시 Static이라는 키워드를 추가하면 됨</li>
</ul>
</li>
<li><p>정적 메서드 사용 예시</p>
</li>
</ol>
<pre><code class="language-java">class Player{
    static void print() { //클래스 메소드
    System.out.println(&quot;야구선수 이승엽입니다.&quot;);
    }

    void print2() { //인스턴스 메소드
    System.out.println(&quot;야구선수 이대호입니다.&quot;);
    }
}

public class Static_ex {

    public static void main(String[] args) {
        Player.print(); //인스턴스를 생성하지 않아도 호출이 가능

        Player player = new Player(); //인스턴스 생성
        player.print2(); //인스턴스를 생성하여야만 호출이 가능
    }
}</code></pre>
<ul>
<li>정적 메서드는 클래스가 메모리에 올라갈 때 정적 메서드가 자동적으로 생성</li>
<li>정적 메서드는 인스턴스를 생성하지 않아도 호출 가능</li>
<li>정적 메서드는 공통적으로 사용 가능한(유틸리티) 함수를 만드는데 유용</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[디자인패턴 - 생성패턴] 추상팩토리 패턴]]></title>
            <link>https://velog.io/@jaemin_0820/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-%EC%83%9D%EC%84%B1%ED%8C%A8%ED%84%B4-%EC%B6%94%EC%83%81%ED%8C%A9%ED%86%A0%EB%A6%AC-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@jaemin_0820/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-%EC%83%9D%EC%84%B1%ED%8C%A8%ED%84%B4-%EC%B6%94%EC%83%81%ED%8C%A9%ED%86%A0%EB%A6%AC-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Sat, 03 Jul 2021 06:48:36 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/jaemin_0820/post/2e271ae8-556c-4385-a5d6-d70dd9f68edb/image.png" alt=""></p>
<ul>
<li>생성 패턴 중에 하나인 추상 팩토리 패턴에 대해 정리</li>
</ul>
<p>[팩토리 메서드 패턴]</p>
<ul>
<li>객체의 생성을 팩토리 클래스로 위임하여 객체를 생성하는 패턴</li>
</ul>
<p>[추상 팩토리 패턴]</p>
<ul>
<li>팩토리를 추상화해서 관련있는 객체의 집합을 생성 할 수 있는 팩토리를 만들고 조건에 따라 팩토리를 생성해서 서로 관련된 객체를 생성하는 패턴</li>
</ul>
<p>예제</p>
<p>1) Shape 인터페이스 생성</p>
<pre><code class="language-java">public interface Shape {
    void draw();
}</code></pre>
<p>2) Shape 인터페이스를 구현하는 구상 클래스 생성</p>
<p>[RoundedRectangle]</p>
<pre><code class="language-java">public class RoundedRectangle implements Shape {
   @Override
   public void draw() {
      System.out.println(&quot;Inside RoundedRectangle::draw() method.&quot;);
   }
}</code></pre>
<p>[RoundedSquare]</p>
<pre><code class="language-java">public class RoundedSquare implements Shape {
   @Override
   public void draw() {
      System.out.println(&quot;Inside RoundedSquare::draw() method.&quot;);
   }
}</code></pre>
<p>[Rectangle]</p>
<pre><code class="language-java">public class Rectangle implements Shape {
   @Override
   public void draw() {
      System.out.println(&quot;Inside Rectangle::draw() method.&quot;);
   }
}</code></pre>
<p>3) 추상 클래스를 생성하여 객체를 생성할 수 있는 추상 팩토리 패턴을 만듬.</p>
<p>[AbstractFactory]</p>
<pre><code class="language-java">public abstract class AbstractFactory {
   abstract Shape getShape(String shapeType) ;
}</code></pre>
<p>4) AbstractFactory를 상속받아 구상클래스의 객체를 생성</p>
<p>[ShapeFactory]</p>
<pre><code class="language-java">public class ShapeFactory extends AbstractFactory {
   @Override
   public Shape getShape(String shapeType){    
      if(shapeType.equalsIgnoreCase(&quot;RECTANGLE&quot;)){
         return new Rectangle();         
      }else if(shapeType.equalsIgnoreCase(&quot;SQUARE&quot;)){
         return new Square();
      }     
      return null;
   }
}</code></pre>
<p>[RoundedShapeFactory]</p>
<pre><code class="language-java">public class RoundedShapeFactory extends AbstractFactory {
   @Override
   public Shape getShape(String shapeType){    
      if(shapeType.equalsIgnoreCase(&quot;RECTANGLE&quot;)){
         return new RoundedRectangle();         
      }else if(shapeType.equalsIgnoreCase(&quot;SQUARE&quot;)){
         return new RoundedSquare();
      }     
      return null;
   }
}</code></pre>
<p>5) FactoryProducer클래스를 생성하여 Shape 인터페이스의 정보를 사용할 수 있도록 함.</p>
<p>[FactoryProducer]</p>
<pre><code class="language-java">public class FactoryProducer {
   public static AbstractFactory getFactory(boolean rounded){   
      if(rounded){
         return new RoundedShapeFactory();         
      }else{
         return new ShapeFactory();
      }
   }
}</code></pre>
<p>6) FactoryProducer를 사용하여 각 도형 객체의 정보를 가져 올 수 있음.</p>
<p>[AbstractFactoryPatternDemo]</p>
<pre><code class="language-java">public class AbstractFactoryPatternDemo {
   public static void main(String[] args) {

      AbstractFactory shapeFactory = FactoryProducer.getFactory(false);

      Shape shape1 = shapeFactory.getShape(&quot;RECTANGLE&quot;);

      shape1.draw();

      Shape shape2 = shapeFactory.getShape(&quot;SQUARE&quot;);

      shape2.draw();

      AbstractFactory shapeFactory1 = FactoryProducer.getFactory(true);

      Shape shape3 = shapeFactory1.getShape(&quot;RECTANGLE&quot;);

      shape3.draw();

      Shape shape4 = shapeFactory1.getShape(&quot;SQUARE&quot;);

      shape4.draw();

   }
}</code></pre>
<p>7) 출력 결과</p>
<pre><code class="language-java">Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside RoundedRectangle::draw() method.
Inside RoundedSquare::draw() method.</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[@Controller와 @RestController의 차이]]></title>
            <link>https://velog.io/@jaemin_0820/Controller%EC%99%80-RestController%EC%9D%98-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@jaemin_0820/Controller%EC%99%80-RestController%EC%9D%98-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Thu, 01 Jul 2021 12:55:05 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/jaemin_0820/post/8cf197ee-037c-4a1b-8c6e-c713d3f4a05d/image.png" alt=""></p>
<p>[개요]</p>
<ul>
<li><p>MVC 패턴에서 @RestController은 @Controller와 @ResponseBody의 조합</p>
</li>
<li><p>Spring 프레임 워크에서 RESTful 서비스를 보다 쉽개 개발 할 수 있도록 Spring 4.0에서 추가</p>
</li>
<li><p>@Controller의 역할은 Model 객체를 만들어 데이터를 담고 View를 찾는 것이지만, @RestController는 단순히 객체만을 반환하고 객체 데이터를 JSON 또는 XML형식으로 HTTP 응답에 담아서 전송</p>
</li>
<li><p>@Controller + @ResponseBody를 사용하여 만들 수 있지만 이러한 방식은 RESTful 웹 서비스의 기본 동작이기 때문에 Spring은 @Controller와 @ResponseBody의 동작을 조합한 @RestController를 도입</p>
</li>
</ul>
<p>[Spring에서 @Controller와 @RestController의 역할은 무엇인가?]</p>
<ul>
<li><p>@Controller는 view에 표시될 데이터가 있는 Model 객체를 만들고 view를 선택함</p>
</li>
<li><p>@ResponseBody를 사용하여 HTTP ResponseBody에 데이터를 담아 요청을 완료할 수 있음</p>
</li>
<li><p>HTTP ResponseBody에 데이터를 담는 것은 RESTful 웹 서비스에 대한 응답에 유용 
-&gt; 왜냐하면 view를 반환하는 대신 데이터를 반환하기 때문</p>
</li>
</ul>
<p>[Spring에서 @RestController와 @Controller의 차이점]</p>
<ul>
<li>@Controller는 클래스를 MVC 컨트롤러로 표시하는데 사용하며, @RestController는 RESTful 서비스에서 사용 되는 @Controller + @ResponseBody와 동일</li>
</ul>
<p>[결론]</p>
<ul>
<li>RESTful 서비스를 만드는 경우 @Controller + @ResponseBody대신 @RestController를 사용하는 것이 좋다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모놀리식과 마이크로서비스 아키텍처 비교]]></title>
            <link>https://velog.io/@jaemin_0820/%EB%AA%A8%EB%86%80%EB%A6%AC%EC%8B%9D%EA%B3%BC-%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%EB%B9%84%EA%B5%90</link>
            <guid>https://velog.io/@jaemin_0820/%EB%AA%A8%EB%86%80%EB%A6%AC%EC%8B%9D%EA%B3%BC-%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%EB%B9%84%EA%B5%90</guid>
            <pubDate>Tue, 29 Jun 2021 13:10:42 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/jaemin_0820/post/d7412b66-66d3-403c-a29b-088de2c50216/image.png" alt=""></p>
<p>1) 모놀리식 아키텍처 (Monolithic Architecture)</p>
<p>장점</p>
<ul>
<li><p>어떤 기능(서비스)이든지 개발되어있는 환경이 같아서 복잡 하지 않음</p>
</li>
<li><p>쉽게 고 가용성 서버 환경을 만들 수 있음. ( 같은 어플리케이션으로 하나더 만들면 됨)</p>
</li>
<li><p>End-to-End 테스트가 용이하다. (MSA의 경우 테스트에 필요한 서비스들을 모두 동작 시켜야함)
 
단점</p>
</li>
<li><p>한 프로젝트의 덩치가 너무 커져서 어플리케이션 구동 시간이 늘어나고 빌드,배포 시간도 길어진다.</p>
</li>
<li><p>조그마한 수정 사항이 있어도 전체를 다시 빌드 하고 배포 해야함.</p>
</li>
<li><p>많은 양의 코드가 몰려있어 개발자가 모두를 이해 할 수 없고 유지 보수도 힘듬.</p>
</li>
<li><p>일부분의 오류가 전체에 영향을 미침.</p>
</li>
<li><p>기능 별로 알 맞는 기술, 언어, 프레임워크를 선택하기가 까다로움</p>
</li>
</ul>
<p>2)마이크로 서비스 아키텍처 (MicroService Architecture)</p>
<p>장점</p>
<ul>
<li>기능 별로 마이크로 서비스를 개발하고, 작업 할당을 서비스 단위로 하면 개발자가 해당 부분을 온전히 이해</li>
<li>새로 추가되거나 수정 사항이 있는 마이크로 서비스만 빠르게 빌드, 배포가 가능</li>
<li>해당 기능에 맞는 기술, 언어 등을 선택하여 사용할 수 있음</li>
<li>일부분의 오류가 있으면 해당 기능에만 오류가 발생하고 그 부분만 빠르게 고쳐서 정상화가 가능</li>
</ul>
<p>단점</p>
<ul>
<li>무엇보다 관리가 힘듬. 작은 여러 서비스들이 분산 되어있기 때문에 모니터링이 힘들다.</li>
<li>서로를 호출하여 전체 서비스가 이루어지기 때문에 무조건 다른 서비스를 호출하는 코드가 추가되는데 이 부분이 모놀리식 아키텍쳐의 개발보다 조금 까다로움.</li>
<li>통신 관련 오류가 잦을 수 있음. 마이크로 서비스들 끼리 계속 서로 통신을 하다 보니 모놀리식 아키텍쳐에 비해 통신 관련 오류가 잦음.</li>
<li>테스트가 불편하다. 예로 End-to-End 테스트를 위해 UI, Gateway 등등 여러 개의 마이크로 서비스를 구동 시켜야 함.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS EC2 초기 설정 pem 생성]]></title>
            <link>https://velog.io/@jaemin_0820/AWS-EC2-%EC%B4%88%EA%B8%B0-%EC%84%A4%EC%A0%95-pem-%EC%83%9D%EC%84%B1</link>
            <guid>https://velog.io/@jaemin_0820/AWS-EC2-%EC%B4%88%EA%B8%B0-%EC%84%A4%EC%A0%95-pem-%EC%83%9D%EC%84%B1</guid>
            <pubDate>Tue, 15 Jun 2021 14:13:03 GMT</pubDate>
            <description><![CDATA[<p>AWS EC2 pem을 생성하기 위해 AWS EC2로 가서 인스턴스를 생성해야한다.</p>
<ol>
<li>인스턴스 시작</li>
</ol>
<ul>
<li>Ubuntu로 18.04로 실행한다. os에 맞게 선택하고 다음으로 넘어간다
<img src="https://images.velog.io/images/jaemin_0820/post/149a36ff-3e87-477d-8ed7-784c0732b04d/image.png" alt=""></li>
</ul>
<ol start="2">
<li><p>단계 2 
그냥 default인 상태로 두고 다음으로 넘어간다.
<img src="https://images.velog.io/images/jaemin_0820/post/181437a5-5dfb-4bf1-8a2f-06e5e97ea494/image.png" alt=""></p>
</li>
<li><p>단계 5까지 그냥 넘어가고 단계 6에서 아래와 같이 설정 한다.</p>
</li>
</ol>
<ul>
<li>지정 해서 ip잡아주는게 좋지만 여기선 위치 무관으로 했다.</li>
<li>인스턴스 생성 후 ipv4 퍼블릭 ip로 톰켓 실행 시 접속이 안될 경우가 있는데 그 경우는 HTTPS랑 HTTP를 추가해주면 해결 된다. </li>
</ul>
<p><img src="https://images.velog.io/images/jaemin_0820/post/27fb7c12-9564-490b-bab8-71964166b497/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/jaemin_0820/post/87f3f3ef-d68f-4cf8-b947-fe3013b67a32/image.png" alt=""></p>
<ol start="4">
<li>단계 7에서 기존 키 페어 선택 또는 새 키 페어 생성에서 &#39;새 키 페어 생성 후 페어 이름을 지정하고 
&#39;키 페어 다운로드&#39;를 클릭하면 pem 파일이 저장된다. 다운로드 후  인스턴스 시작을 누르면 인스턴스가 생성된다. </li>
</ol>
<p><img src="https://images.velog.io/images/jaemin_0820/post/6e4efc2f-199d-45d2-8c53-df6bbc15ef87/image.png" alt=""></p>
<ol start="5">
<li>생성되고 ipv4 퍼블릭 ip와 pem을 확인 후 putty 설정을 하러 가야한다. </li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS 배포용 war 파일 추출(Spring Boot)]]></title>
            <link>https://velog.io/@jaemin_0820/AWS-%EB%B0%B0%ED%8F%AC%EC%9A%A9-war-%ED%8C%8C%EC%9D%BC-%EC%B6%94%EC%B6%9CSpring-Boot</link>
            <guid>https://velog.io/@jaemin_0820/AWS-%EB%B0%B0%ED%8F%AC%EC%9A%A9-war-%ED%8C%8C%EC%9D%BC-%EC%B6%94%EC%B6%9CSpring-Boot</guid>
            <pubDate>Tue, 15 Jun 2021 13:38:31 GMT</pubDate>
            <description><![CDATA[<p>팀 프로젝트를 AWS에 배포 하기 위한 과정으로 인텔리제이서 war파일로 추출하기 위한 과정을 정리</p>
<p>1) 빌드 설정</p>
<p>좌측 상단 메뉴바 -&gt; Project Structure -&gt; Artifacts -&gt; + -&gt; Web Application :Archive</p>
<ul>
<li>Web Application :Archive 선택 후 For &#39;Gradle ... war(exploded)를 선택하고 OK를 누른다</li>
</ul>
<p>2) 빌드 실행</p>
<ul>
<li>상단 Build 클릭 Build Artifacts 누른 후 위에 ok를 했던 war 파일을 찾아 클릭 후 Action에서 Build를 누른다.</li>
</ul>
<p>3) war파일이 생성 되면 복사본을 만들어 추후 filezilia에서 사용할 예정이다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring MVC Model, ModelAndView]]></title>
            <link>https://velog.io/@jaemin_0820/Spring-MVC-Model-ModelAndView</link>
            <guid>https://velog.io/@jaemin_0820/Spring-MVC-Model-ModelAndView</guid>
            <pubDate>Sat, 10 Apr 2021 05:48:09 GMT</pubDate>
            <description><![CDATA[<p><strong>1. Model과 ModelAndView의 차이점</strong></p>
<ul>
<li><p>Model은 데이터만 저장하고 ModelAndView는 데이터와 이동하고자 하는 View Page를 같이 저장</p>
</li>
<li><p>컨트롤러 처리 후 응답할 view와 view에 전달할 값을 저장</p>
</li>
</ul>
<p><strong>2. 생성자 유형</strong></p>
<ul>
<li>ModelAndView(String viewName) : 응답할 view 설정</li>
<li>ModelAndView(String viewName, Map values) : 응답할 view와 view로 전달할 값들을 저장한 Map 객체
ModelAndView(String viewName, String name, Object value) : 응답할 view 이름, view로 넘길 객체의 name-value</li>
</ul>
<pre><code>@GetMapping(&quot;content.do&quot;)
public ModelAndView read(long seq) {

    Board board = boardService.read(seq);

    ModelAndView mv = new ModelAndView(&quot;board/content&quot;, &quot;board&quot;, board);

    return mv;

}</code></pre><p>&quot;board/content&quot; -&gt; 응답할 view의 이름(jsp)
&quot;board&quot; -&gt; name
 board-&gt; view로 넘길 객체의 name-value</p>
<p><strong>3. 자주 사용하는 메소드</strong></p>
<ul>
<li>setViewName(String view): 응답할 view 이름을 설정</li>
<li>addObject(String name, Object value) : view에 전달할 값을 설정</li>
<li>addAllObject(Map values) : view에 전달할 값을 Map에 name-value로 저장하여 한번에 설정</li>
</ul>
<pre><code>@GetMapping(&quot;list.do&quot;)
    public ModelAndView list() {
        List&lt;Address&gt; list = addressService.listS();
            ModelAndView mv = new ModelAndView();
        mv.setViewName(&quot;address/list&quot;); //View의 경로
        mv.addObject(&quot;list&quot;, list); //Model(변수 이름, 데이터 값


        return mv; // return을 ModelAndView 객체를 반환
    }</code></pre><ul>
<li>ModelAndView 객체 생성 후 아래 메소드를 사용한다.</li>
<li>setViewName을 통해 view의 이름을 설정하여 addObject메소드를 통해 view에 전달할 값을 설정</li>
</ul>
<p>위 코드를 ModelAndView 생성자로 만들면 아래와 같다</p>
<pre><code>ModelAndView mv = new ModelAndView(&quot;address/list&quot;, &quot;list&quot;, &quot;list&quot;)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[DAO]]></title>
            <link>https://velog.io/@jaemin_0820/DAO</link>
            <guid>https://velog.io/@jaemin_0820/DAO</guid>
            <pubDate>Thu, 08 Apr 2021 09:57:37 GMT</pubDate>
            <description><![CDATA[<p>1)DAO</p>
<ul>
<li>Data Access Object의 약자로 실제로 DB에 접근하는 객체</li>
<li>프로젝트의 서비스 모델과 실제 DB를 연결하는 역할</li>
<li>CRUD를 실행하는 메서드는 JDBC등을 이용하여 DB에 접근해서 쿼리를 실행</li>
<li>객체로 반환해주는 것(ORM)</li>
<li>객체 &lt;-&gt; 관계 맵핑 &lt;-&gt; DB 연동</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[테스트 클래스를 생성하여 오라클 db 연동 여부 확인(STS4 - Oracle - mybatis 연동 설정 포함)]]></title>
            <link>https://velog.io/@jaemin_0820/%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%81%B4%EB%9E%98%EC%8A%A4%EB%A5%BC-%EC%83%9D%EC%84%B1%ED%95%98%EC%97%AC-%EC%98%A4%EB%9D%BC%ED%81%B4-db-%EC%97%B0%EB%8F%99-%EC%97%AC%EB%B6%80-%ED%99%95%EC%9D%B8STS4-Oracle-mybatis-%EC%97%B0%EB%8F%99-%EC%84%A4%EC%A0%95-%ED%8F%AC%ED%95%A8</link>
            <guid>https://velog.io/@jaemin_0820/%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%81%B4%EB%9E%98%EC%8A%A4%EB%A5%BC-%EC%83%9D%EC%84%B1%ED%95%98%EC%97%AC-%EC%98%A4%EB%9D%BC%ED%81%B4-db-%EC%97%B0%EB%8F%99-%EC%97%AC%EB%B6%80-%ED%99%95%EC%9D%B8STS4-Oracle-mybatis-%EC%97%B0%EB%8F%99-%EC%84%A4%EC%A0%95-%ED%8F%AC%ED%95%A8</guid>
            <pubDate>Thu, 08 Apr 2021 03:40:00 GMT</pubDate>
            <description><![CDATA[<p>(1) Spring 설정</p>
<p> 1) pom.xml</p>
<pre><code>   &lt;dependency&gt;
    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
    &lt;artifactId&gt;spring-jdbc&lt;/artifactId&gt;
    &lt;version&gt;${org.springframework-version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
    &lt;artifactId&gt;spring-tx&lt;/artifactId&gt;
    &lt;version&gt;${org.springframework-version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;com.zaxxer&lt;/groupId&gt;
    &lt;artifactId&gt;HikariCP&lt;/artifactId&gt;
    &lt;version&gt;2.7.8&lt;/version&gt;
&lt;/dependency&gt;</code></pre><p> 2) root-context.xml </p>
<pre><code>    &lt;bean id=&quot;hikariConfig&quot; class=&quot;com.zaxxer.hikari.HikariConfig&quot;&gt;
    &lt;property name=&quot;driverClassName&quot;
        value=&quot;net.sf.log4jdbc.sql.jdbcapi.DriverSpy&quot;&gt;&lt;/property&gt;
    &lt;property name=&quot;jdbcUrl&quot;
        value=&quot;jdbc:log4jdbc:oracle:thin:@localhost:1521:JAVA&quot;&gt;&lt;/property&gt;
    &lt;property name=&quot;username&quot; value=&quot;scott&quot;&gt;&lt;/property&gt;
    &lt;property name=&quot;password&quot; value=&quot;tiger&quot;&gt;&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id=&quot;dataSource&quot; class=&quot;com.zaxxer.hikari.HikariDataSource&quot;
    destroy-method=&quot;close&quot;&gt;
    &lt;constructor-arg ref=&quot;hikariConfig&quot; /&gt;
&lt;/bean&gt;</code></pre><p>   3) pom.xml </p>
<pre><code>    &lt;dependency&gt;
   &lt;groupId&gt;com.oracle.database.jdbc&lt;/groupId&gt;
   &lt;artifactId&gt;ojdbc6&lt;/artifactId&gt;
   &lt;version&gt;11.2.0.4&lt;/version&gt;
&lt;/dependency&gt;</code></pre><p>4) DataSourceTests.java </p>
<p><img src="https://images.velog.io/images/jaemin_0820/post/7afa860a-5dae-4d57-9b4b-68bc73adb790/image.png" alt=""></p>
<p>   5) pom.xml </p>
<pre><code>   &lt;dependency&gt;
    &lt;groupId&gt;org.bgee.log4jdbc-log4j2&lt;/groupId&gt;
    &lt;artifactId&gt;log4jdbc-log4j2-jdbc4&lt;/artifactId&gt;
    &lt;version&gt;1.16&lt;/version&gt;
&lt;/dependency&gt;</code></pre><p>   6) log4jdbc.log4j2.properties</p>
<p>   <img src="https://images.velog.io/images/jaemin_0820/post/35cdbb26-988a-4004-a90f-a0d665237b25/image.png" alt=""></p>
<p>7) web.xml </p>
<pre><code>   &lt;filter&gt;
    &lt;filter-name&gt;encoding&lt;/filter-name&gt;
    &lt;filter-class&gt;org.springframework.web.filter.CharacterEncodingFilter&lt;/filter-class&gt;
    &lt;init-param&gt;
        &lt;param-name&gt;encoding&lt;/param-name&gt;
        &lt;param-value&gt;UTF-8&lt;/param-value&gt;
    &lt;/init-param&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
    &lt;filter-name&gt;encoding&lt;/filter-name&gt;
    &lt;servlet-name&gt;appServlet&lt;/servlet-name&gt;
&lt;/filter-mapping&gt;</code></pre><p> (2) mybatis 설정</p>
<p>   1) pom.xml </p>
<pre><code>&lt;dependency&gt;
    &lt;groupId&gt;org.mybatis&lt;/groupId&gt;
    &lt;artifactId&gt;mybatis&lt;/artifactId&gt;
    &lt;version&gt;3.4.6&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.mybatis&lt;/groupId&gt;
    &lt;artifactId&gt;mybatis-spring&lt;/artifactId&gt;
    &lt;version&gt;1.3.2&lt;/version&gt;
&lt;/dependency&gt;</code></pre><p>2) root-context.xml</p>
<pre><code>&lt;bean id=&quot;sqlSessionFactory&quot;
    class=&quot;org.mybatis.spring.SqlSessionFactoryBean&quot;&gt;
    &lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot;&gt;&lt;/property&gt;
    &lt;property name=&quot;configLocation&quot;
         value=&quot;classpath:/mybatis-config.xml&quot;/&gt;
&lt;/bean&gt;</code></pre><p>3) mybatis-config.xml</p>
<pre><code> &lt;configuration&gt;
   &lt;typeAliases&gt;
       &lt;typeAlias alias=&quot;Address&quot; type=&quot;soo.md.domain.Address&quot;/&gt;
   &lt;/typeAliases&gt;
   &lt;mappers&gt;
       &lt;mapper resource=&quot;soo/md/mapper/AddressMapper.xml&quot;/&gt;
   &lt;/mappers&gt;
 &lt;/configuration&gt;</code></pre><p>4) AddressMapper.xml ( 참조: <a href="https://mybatis.org/mybatis-3/ko/sqlmap-xml.html">https://mybatis.org/mybatis-3/ko/sqlmap-xml.html</a> )</p>
<p>5) AddressMapper.java</p>
<p>6) 컴포넌트 스켄 
         &lt;context:component-scan base-package=&quot;soo.md.mapper&quot;/&gt;
         &lt;mybatis-spring:scan base-package=&quot;soo.md.mapper&quot;/&gt;</p>
<p>7) AddressMapperTests.java </p>
<p>(3) DBMS별 dataSource 설정 </p>
<p> 1) Oracle </p>
<p>   1)-1 root-context.xml</p>
<pre><code>&lt;bean id=&quot;hikariConfig&quot; class=&quot;com.zaxxer.hikari.HikariConfig&quot;&gt;
    &lt;property name=&quot;driverClassName&quot;
        value=&quot;net.sf.log4jdbc.sql.jdbcapi.DriverSpy&quot;&gt;&lt;/property&gt;
    &lt;property name=&quot;jdbcUrl&quot;
        value=&quot;jdbc:log4jdbc:oracle:thin:@localhost:1521:JAVA&quot;&gt;&lt;/property&gt;
    &lt;property name=&quot;username&quot; value=&quot;scott&quot;&gt;&lt;/property&gt;
    &lt;property name=&quot;password&quot; value=&quot;tiger&quot;&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id=&quot;dataSource&quot; class=&quot;com.zaxxer.hikari.HikariDataSource&quot;
    destroy-method=&quot;close&quot;&gt;
    &lt;constructor-arg ref=&quot;hikariConfig&quot; /&gt;
&lt;/bean&gt;</code></pre><p>1)-2 pom.xml</p>
<pre><code>&lt;dependency&gt;
    &lt;groupId&gt;com.oracle.database.jdbc&lt;/groupId&gt;
    &lt;artifactId&gt;ojdbc6&lt;/artifactId&gt;
    &lt;version&gt;11.2.0.4&lt;/version&gt;
&lt;/dependency&gt;</code></pre><p>미리 만든 mapper클래스와 domain을 통해 오라클db와 연결이 되는지 테스트 클래스를 작성</p>
<p><img src="https://images.velog.io/images/jaemin_0820/post/5f0fd8f2-6d25-4717-b874-7736f8f98985/image.png" alt=""></p>
<p>[테스트 클래스 작성]</p>
<p>1) @RunWith
-현재 테스트 코드가 스프링을 실행하는 역할을 할 것이라는 것을 의미</p>
<p>2) @ContextConfiguration
-단위 테스트에서 가장 중요한 어노테이션으로 속성 값이 중요</p>
<p>-지정된 클래스나 문자열을 통해 필요한 객체들을 스프링 내에 객체로 등록 ---&gt; 스프링의 빈(Bean)으로 등록된다고 표현</p>
<ul>
<li>XML의 경우 &#39;classpath :&#39; 또는 &#39;file :&#39;을 이용할 수 있으므로 툴에서 자동 생성된 root-context.xml의 경로를 지정</li>
</ul>
<p>-JAVA의 경우 &#39;classes&#39;를 이용해 root-context.xml의 역할을 대신하는 RootCofig 경로를 지정
---&gt;  </p>
<pre><code>@ContextConfiguration(classes={RootConfig.class})</code></pre><p>[XML]</p>
<p><img src="https://images.velog.io/images/jaemin_0820/post/26f0bf07-0b50-45a4-820c-dc10c93d1d80/image.png" alt=""></p>
<p>3) @Test</p>
<ul>
<li><p>JUnit에서 테스트 대상을 표시하는 어노테이션,  헤당 메서드를 선택하고 Junit Test 기능을 실행</p>
</li>
<li><p>테스트 실행 결과 (테스트는 오라클 연동 확인을 위해 insert로 실행)</p>
</li>
</ul>
<p><img src="https://images.velog.io/images/jaemin_0820/post/8d858f6f-e204-4dff-903a-1362d1390da4/image.png" alt=""></p>
<p>console창에 데이터가 저장됐음 보여주고 테스트 코드도 문제 없이 실행</p>
<p><img src="https://images.velog.io/images/jaemin_0820/post/ec56be74-f7b4-4ca1-b0f3-b4651c5a605d/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/jaemin_0820/post/01686564-4810-41e3-b74b-06d60f0ba0fc/image.png" alt=""></p>
<p>오라클 db에 저장이 되었다</p>
<p><img src="https://images.velog.io/images/jaemin_0820/post/29fb5e62-58e8-402b-950a-54a4224bdab7/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[EL (Expression Language)]]></title>
            <link>https://velog.io/@jaemin_0820/EL-Expression-Language</link>
            <guid>https://velog.io/@jaemin_0820/EL-Expression-Language</guid>
            <pubDate>Thu, 08 Apr 2021 01:43:18 GMT</pubDate>
            <description><![CDATA[<p>&lt;1&gt; 모양 : ${}</p>
<p> &lt;2&gt; 기능 
   1&gt; 객체의 속성값을 얻어온다.
   2&gt; 배열의 값을 얻어온다. 
   3&gt; List 값을 얻어온다. 
   4&gt; Map 값을 얻어온다.</p>
<p> &lt;3&gt; EL의 내장 객체(11개)
   1&gt; param 
      paramValues
      
   2&gt; header
      headerValues </p>
<p>   3&gt; pageContext - &quot;EL에서 JSP디폴트객체 접근시 사용&quot; </p>
<p>   4&gt; pageScope
      requestScope  
      sessionScope 
      applicationScope </p>
<p>app &gt; session &gt; request &gt; page (범위 순서)</p>
<p>---&gt; 범위가 작을수록 강력한 힘을 갖기 때문에 아래 스코프 이름을 생략할 경우 범위가 작은 Request가 먼저 출력 되고 Session Scope의 처음 값인 홍길동이 출력 된다</p>
<p><img src="https://images.velog.io/images/jaemin_0820/post/bc2750cc-9927-4af2-b19d-323bebe9c125/image.png" alt="">
<img src="https://images.velog.io/images/jaemin_0820/post/d188984d-a08a-4f41-8d9a-30d90b87a916/image.png" alt=""></p>
<p>--- &gt;   범위가 넓은 부분이 먼저 출력이 되게 하려면 스코프 이름을 생략 하지 말고 직접 쓰면 Session Scope가 먼저 출력하게 된다. </p>
<p><img src="https://images.velog.io/images/jaemin_0820/post/ae788583-a533-40a7-9e97-8f4bed737013/image.png" alt="">
<img src="https://images.velog.io/images/jaemin_0820/post/624e9d3f-7dd8-409c-852a-a34a6072f733/image.png" alt=""></p>
<p>   5&gt; cookie </p>
<p>   6&gt; initParam - &quot;ServletContext에 대한 initParam&quot; </p>
<p> &lt;4&gt; EL 함수 </p>
<p> &lt;5&gt; EL 연산자 
   1&gt; useELOperation </p>
<p>   2&gt; EL 연산자의 종류 </p>
<pre><code>  [1] 산술 연산자 
     ex) +, -, * , / 와 div, %와 mod 
     cf1)/와 div사용시 0으로 나눌 수 있다(infinity)
     cf2)%와 mod사용시 0으로 나눌 수 없다.(오류)

  [2] 논리 연산자 
     ex) &amp;&amp;와 and, ||와 or, !와 not

  [3] 관계 연산자 
     ex) ==와 eq, !=과 ne, &lt;와 lt, &gt;와 gt, 
        &lt;=와 le, &gt;=와 ge 

  [4] empty 
     -&gt; 비어있거나 null 일 경우 true 리턴 

 cf1) jsp의 변수(멤버/지역)는 EL에서 인식하지 못함
 cf2) 정의되지 않은 변수/값(null)일 경우 표현처리 
   case1) 공백 처리 (ex: ${str} )
   case2) 0 으로 처리 (ex: ${str + 10})
   case3) false 로 처리 (ex: ${true and str})</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[JSP Default 9가지 객체]]></title>
            <link>https://velog.io/@jaemin_0820/JSP-Default-9%EA%B0%80%EC%A7%80-%EA%B0%9D%EC%B2%B4</link>
            <guid>https://velog.io/@jaemin_0820/JSP-Default-9%EA%B0%80%EC%A7%80-%EA%B0%9D%EC%B2%B4</guid>
            <pubDate>Thu, 08 Apr 2021 01:39:50 GMT</pubDate>
            <description><![CDATA[<p>(1) 설명 : 객체를 따로 생성하지 않고 스크립트렛 즉, 
       &lt;%%&gt; 사이에서 사용 가능한 객체를 의미 
      
(2) 종류 
   &lt;1&gt; out 객체 ( type : JspWriter )
      -&gt; 클라이언트 브라우져와 연결된 출력 객체 
      
   &lt;2&gt; request 객체 ( type : HttpServletRequest )
      -&gt; 클라이언트 요청정보를 가진 객체/공간[객체]
      ex) scope/requestTest.jsp</p>
<p>   &lt;3&gt; response 객체 ( type : HttpServletResponse )
      -&gt; 서버의 답변정보를 가진 객체  </p>
<p>   &lt;4&gt; session 객체 ( type : HttpSession )
      -&gt; 클라이언트측 브라우져에 할당된 서버측 공간[객체]
       ( JSessionId라는 label 표식 소유 )
      ex) scope/sessionTest.jsp</p>
<pre><code>  cf1) 세션 변수 ( 속성 == Attribute) 
     -&gt; session 객체안에 들어가는 객체(속성값 Object)
         의 주소를 참조하는 변수 (type : String) 

  cf2) 세션 변수값 (속성값 ==  Attribute Value)
     -&gt; session 객체안에 들어가는 객체(type : Object)

  ex1) &lt;jsp:useBean id=&quot;login&quot; class=&quot;soo.loginBean&quot; 
              scope=&quot;session&quot;/&gt; 
  ex2) session.setAttribute(&quot;id&quot;, &quot;tiger&quot;);

    # 세션변수는 &quot;login&quot; 과 &quot;id&quot; 를 의미 
    # 세션변수값 new soo.loginBean() 과 &quot;tiger&quot;를 의미 
    # 세션객체가 없어지면, 그 안의 세션변수와 세션변수값
      도 함께 사라진다.</code></pre><p>   &lt;5&gt; application 객체 ( type : ServletContext ) 
      -&gt; WebApplication 전체에 공유되는 공간[객체]
       ex) scope/applicationTest.jsp</p>
<pre><code>   cf) application 변수(속성)/application 변수값(속성값)
   application.setAttribute(application변수, application 변수값);</code></pre><p>   &lt;6&gt; page 객체 ( type : Object )
      -&gt; JSP 페이지 자신을 의미하는 객체 
       ex) scope/pageTest.jsp</p>
<p>   &lt;7&gt; pageContext 객체 ( type : PageContext ) 
      -&gt; 다른 디폴트객체들을 접근(가져)할 수 있는 method
      -&gt; 모든 scope에 들어있는 속성(변수)들을 접근할 수 
         있는 method가 존재 
         - setAttribute(String name, Object value, int scope)
         - getAttribute(String name, int scope) 
         - findAttribute(String name)
      -&gt; page scope 영역도 핸들링이 가능함
         ex) scope/pageTest.js</p>
<p>   &lt;8&gt; config 객체 ( type : ServletConfig )
      -&gt; DD(web.xml)에서 서블릿의 구성정보를 접근할 수 있는 객체
         ex) servletConfigContext/
          ConfigTest.java,ConfigTest.jsp(참조 불가),
          ContextTest.java, contextTest.jsp</p>
<pre><code>     cf1) web.xml의 수정 (한글이 깨지지 않음)
      &lt;?xml version=&quot;1.0&quot; encoding=&quot;euc-kr&quot;?&gt;
     cf2) jsp페이지에서는 DD(web.xml)설정된 
             init-param를 참조할 수 없음
     cf3) DD(Deployment Descriptor)</code></pre><p>   &lt;9&gt; exception 객체 ( type : Throwable )
      -&gt; 예외 처리 관련 객체<strong>텍스트</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JSP 구성요소]]></title>
            <link>https://velog.io/@jaemin_0820/JSP-%EA%B5%AC%EC%84%B1%EC%9A%94%EC%86%8C</link>
            <guid>https://velog.io/@jaemin_0820/JSP-%EA%B5%AC%EC%84%B1%EC%9A%94%EC%86%8C</guid>
            <pubDate>Thu, 08 Apr 2021 01:38:22 GMT</pubDate>
            <description><![CDATA[<p><strong>1. Fixed Template Data</strong></p>
<ul>
<li>html / xml</li>
</ul>
<p><strong>2. JSP Elements</strong></p>
<ul>
<li><p>&lt;%@%&gt;  - &gt; Direct Element 지시어
   ex) &lt;%@ page %&gt;</p>
</li>
<li><p>Scripting Elements - &gt; 
        &lt;% %&gt; scriptlet 스크립트렛 ( 자바 코드를 실행-메서드 호출) - &gt; 서블릿 서비스 
     ex) &lt;% public void service(){} %&gt;</p>
</li>
</ul>
<p>        &lt;%! %&gt; declaration선언(자바 클래스 작성)
       ex) &lt;% class{} %&gt;</p>
<pre><code>&lt;%= %&gt; expression 식(값을 출력) - &gt; 서비스
ex) &lt;% out.println(str); %&gt;   ==     &lt;%= str%&gt;
     </code></pre><p><strong>3. <jsp :  xxx /> : jsp 액션 (표준 태그)=== jsp</strong></p>
<p><strong>4. ${}  : expression language(el)</strong> (스크립트 요소를 사용하면 복잡해지는 코드를 간결하게 사용할 수 있음)</p>
<p><strong>5. &lt;c:XXX / &gt; : JSTL</strong></p>
<pre><code>cf) custom tag lib(CTL) </code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[React Hook(useEffect)]]></title>
            <link>https://velog.io/@jaemin_0820/React-HookuseEffect</link>
            <guid>https://velog.io/@jaemin_0820/React-HookuseEffect</guid>
            <pubDate>Thu, 08 Apr 2021 01:35:42 GMT</pubDate>
            <description><![CDATA[<p><strong>[useEffect]</strong></p>
<ul>
<li>useEffect를 사용하면 컴포넌트를 화면에 그린 후 실행될 함수를 정의</li>
</ul>
<p><strong>[사용방법]</strong></p>
<p>![]
(<a href="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrnEbF%2Fbtq1sByJtEY%2FaFRKBeWDpQ5tpZuq9o1OU1%2Fimg.png">https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrnEbF%2Fbtq1sByJtEY%2FaFRKBeWDpQ5tpZuq9o1OU1%2Fimg.png</a>)</p>
<p> useEffect는 2개의 매개변수를 가지는데 첫 번째는 컴포넌트 레이아웃 배치와 화면 그리기가 끝난 후 실행될 함수, 두 번째는 의존성 배열</p>
<ul>
<li>첫 번째 인자의 내부는 effect 함수, 첫 번째 인자가 반환하는 함수는 clean-up 함수라고 부른다. </li>
</ul>
<ul>
<li><p>useEffect는 첫 번째 인자로 주어진 함수를 실행하기 전에 의존성 배열의 원소가 변경됐는지 확인</p>
</li>
<li><p>비교는 useState와 동일하게 Object.is 메소드를 사용하고 만약 하나도 변경되지 않았으면 렌더링 시점에선 useEffect를 실행하지 않음</p>
</li>
<li><p>하지만 의존성 배열의 원소가 하나라도 변경됐으면 useEffect를 실행</p>
</li>
<li><p>의존성 배열을 빈 배열로 설정하면 useEffect의 함수는 컴포넌트를 마운트하는 시점과 언마운트하는 시점에만 실행(예)List - 목록 렌더링)</p>
</li>
</ul>
<p>![]
(<a href="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbidOSE%2Fbtq1sBlaQTz%2FTKPIcABaJQumwmcKiBPzrK%2Fimg.png">https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbidOSE%2Fbtq1sBlaQTz%2FTKPIcABaJQumwmcKiBPzrK%2Fimg.png</a>)</p>
<ul>
<li>useEffect가 함수 컴포넌트 생애주기에 관여하는 부분은 위 그림과 같고, useEffect는 항상 DOM 상태 변경과 레이아웃 배치, 화면 그리기가 모두 완료된 후 실행</li>
</ul>
<ul>
<li>컴포넌트는 기본적으로 마운트-&gt;업데이트(반복)-&gt;언마운트의 생애주기를 가진다</li>
</ul>
<ul>
<li>마운트 상태 : 컴포넌트 구조가 HTML DOM에 존재하는 상태(화면에 보이는 상태), 컴포넌트 DOM 구조나 내용이 변경될 때마다 업데이트 과정 </li>
</ul>
<ul>
<li>언마운트 상태 : 컴포넌트 구조가 HTML DOM에서 제거된 상태(화면에 안 보이는 상태)를 의미.</li>
</ul>
<p><strong>[effect 함수와 clean-up 함수]</strong></p>
<p>![]
(<a href="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfZRIs%2Fbtq1nHfCNQA%2FPIXivkC7aM33YkFrVuzhY1%2Fimg.png">https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfZRIs%2Fbtq1nHfCNQA%2FPIXivkC7aM33YkFrVuzhY1%2Fimg.png</a>)</p>
<ul>
<li>React 컴포넌트는 매 render 함수를 실행하는 과정에서 그 시점의 컴포넌트 props와 상태를 기반으로 컴포넌트 내부 변수와 함수를 다시 정의하고 계산 -&gt; 이 때 useEffect의 첫 번째 인수도 계산되어 위 그림에서 표현된 시점에 실행</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>