<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>junjun-creator.log</title>
        <link>https://velog.io/</link>
        <description>Web Backend 개발자</description>
        <lastBuildDate>Fri, 19 Feb 2021 14:01:23 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>junjun-creator.log</title>
            <url>https://images.velog.io/images/junjun-creator/profile/8e4adcd9-b615-44a3-a686-6042b973d60b/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. junjun-creator.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/junjun-creator" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[TIL(Web)-2021.02.10(Spring Boot-transaction)]]></title>
            <link>https://velog.io/@junjun-creator/Spring-Boot-transaction</link>
            <guid>https://velog.io/@junjun-creator/Spring-Boot-transaction</guid>
            <pubDate>Fri, 19 Feb 2021 14:01:23 GMT</pubDate>
            <description><![CDATA[<h3 id="transaction--논리적인-실행-단위">Transaction : 논리적인 실행 단위</h3>
<ul>
<li>(반드시) 한번에 수행되어야 할 명령들의 집합</li>
<li>반대 &gt; 물리적인 실행 단위 : update 등</li>
<li>논리적 실행단위 : 계좌이체</li>
<li>물리적 실행단위 : update 2회</li>
<li>하나의 논리적인 실행을 위해 물리적 실행이 2회 일어나야하는데 둘 중 하나라도 처리되지 않을 경우, 트랜잭션이 깨졌다 라고 할 수 있다.</li>
<li>spring에서는 DAO에서 jdbc 실행시마다 각각 connection이 연결, 해제 되는 작업이 실행된다.</li>
<li>이러면 대용량 트래픽이 있는경우 원치 않는 데이터가 수정되거나, 원치 않는 데이터를 참조하게 되는 문제가 발생할 수 있다.(물리적인 실행 도중 에러가 발생 할 수 있음)</li>
<li>이를 해결하기위해 하나의 논리적인 실행 단위에서 발생하는 모든 connection을 하나로 묶어서 모두 성공하여 commit 되었을때 connection이 해제되도록(트랜잭션 완료) 하여 트랜잭션을 관리하게 한다.</li>
</ul>
<h3 id="transaction">@Transaction</h3>
<ul>
<li>service 단에서 논리적인 업무로직(transaction)을 처리하게 된다.
<img src="https://images.velog.io/images/junjun-creator/post/ccf0b87a-232a-4d94-a7d1-59392a402a46/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-29%20%EC%98%A4%ED%9B%84%203.03.33.png" alt=""></li>
<li>위의 예제에서 atom() 업무에 insert가 2번 수행된다. 둘다 성공하지 않는다면 이 트랜잭션은 실패된다.</li>
</ul>
<h3 id="propagation">Propagation</h3>
<ul>
<li>트랜잭션 내부에서 또다른 트랜잭션 처리가 필요하다면 propagation을 활용해 처리할 수 있다.</li>
<li>나를 호출한 아이가 transaction을 갖고있다면, 그 트랜잭션이 깨지지 않도록 도와줄게! - SUPPORTS</li>
<li>requires_new : 나를 호출한 아이가 transaction을 갖고있든 없든 새로운 트랜잭션을 만들어서 먼저 처리할거야!</li>
<li>등등 </li>
</ul>
<h3 id="isolation">Isolation</h3>
<ul>
<li>read uncommitted<ul>
<li>dirty reads are allowed</li>
<li>2개 이상의 스레드가 실행되는 환경에서 다른 스레드에서 수정한 데이터를 commit(or rollback)전에 참조가능한 경우(lock이 없음)</li>
<li>lock을 걸지 않고 수행 될 수 있게 하기때문에 성능은 좋아짐</li>
<li>중간에 데이터가 변경되도 상관 없는경우에 사용
<img src="https://images.velog.io/images/junjun-creator/post/7a39f10e-da5a-4c07-8b94-26c54ccae3e9/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-29%20%EC%98%A4%ED%9B%84%203.59.22.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/21f5393d-c80f-4330-a58b-69575ad3b4c5/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-29%20%EC%98%A4%ED%9B%84%203.59.29.png" alt=""></li>
</ul>
</li>
<li>read committed<ul>
<li>non-repeatable reads phenomenon may occur</li>
<li>사용중인 레코드가 중간에 다른 스레드에서 변경하여 commit한 경우 허용. 다시 그 원래 값을 얻을 수 없다는(non-repeatable) 특징</li>
</ul>
</li>
<li>repeatable_read<ul>
<li>사용중인 레코드는 모두 lock 걸어버림(그동안 다른스레드에서 변경 불가)</li>
<li>기본 설정</li>
</ul>
</li>
<li>serialization<ul>
<li>사용중인 테이블 전체를 lock 걸어버림</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.02.09(spring boot-security)]]></title>
            <link>https://velog.io/@junjun-creator/security</link>
            <guid>https://velog.io/@junjun-creator/security</guid>
            <pubDate>Mon, 15 Feb 2021 10:02:00 GMT</pubDate>
            <description><![CDATA[<h3 id="로그인-컨트롤러">로그인 컨트롤러</h3>
<ul>
<li>로그인을 위한 컨트롤러
<img src="https://images.velog.io/images/junjun-creator/post/22c48f5e-fe87-4316-b052-71801c5fa0b9/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-14%20%EC%98%A4%ED%9B%84%204.18.16.png" alt=""></li>
</ul>
<h3 id="tiles-설정view">Tiles 설정(view)</h3>
<ul>
<li>login은 왜 home.*.*인가?<ul>
<li>root 디렉토리이지만, 이것을 그냥 *.*으로 설정할 경우, 다른 tiles도 모두 호출되어 문제가 발생할 수 있어으므로 루트 디렉토리의 것만 호출한다는 의미로만 home을 붙인다.(의미상으로 추가한것)
<img src="https://images.velog.io/images/junjun-creator/post/36051f0d-9515-4b49-8f52-0000164d53fe/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-14%20%EC%98%A4%ED%9B%84%204.19.14.png" alt=""></li>
</ul>
</li>
</ul>
<h3 id="spring-security-라이브러리-추가">spring security 라이브러리 추가</h3>
<ul>
<li>spring-boot-starter-security
<img src="https://images.velog.io/images/junjun-creator/post/3a91753c-6ff4-4b41-b530-e7bb6ed14cb6/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-14%20%EC%98%A4%ED%9B%84%204.24.25.png" alt=""></li>
</ul>
<h3 id="보안이-필요한-페이지-설정">보안이 필요한 페이지 설정</h3>
<p>  <img src="https://images.velog.io/images/junjun-creator/post/90ee2560-d0e3-47cb-a5ec-9cc43dab53ae/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%ED%9B%84%202.59.55.png" alt=""></p>
<ul>
<li><p>누군 되고 누군 안되는지?</p>
<ul>
<li>auth.ldap<ul>
<li>DC도메인 컨트롤러에서 WebServer에 유저 정보를 전달하는 프로토콜</li>
</ul>
</li>
<li>auth.jdbcAuthentication<ul>
<li>데이터베이스에서 유저정보 가져다 쓸때</li>
</ul>
</li>
<li>auth.inMemoryAuthentication<ul>
<li>유저의 폭이 좁을때. 메모리에 추가해서 사용하는 방식<ul>
<li>password에 {noop}을 붙임으로써 비밀번호 인코딩을 제거
<img src="https://images.velog.io/images/junjun-creator/post/22f64965-32d1-4c4d-906c-711f29f96109/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%ED%9B%84%203.00.37.png" alt=""></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>어떤건 되고 어떤건 안되는지</p>
<ul>
<li>http.authorizeRequests()<ul>
<li>인증요청을 해야하는 url 매핑 정의</li>
</ul>
</li>
<li>antMatchers(&quot;url&quot;)<ul>
<li>security를 적용하고자 하는 url</li>
<li>주의사항 : /admin/** &gt;&gt; resouces root 디렉토리까지 모두 탐색함.(그냥 /admin/ 으로 하면 /admin/ 을 포함하는 모든 디렉토리가 해당됨)</li>
</ul>
</li>
<li>permitAll()<ul>
<li>권한 없어도 모두가 접근가능(anonymous까지)</li>
</ul>
</li>
<li>hasAnyRole()<ul>
<li>해당 권한을 갖고 있는 사람만 접근 가능</li>
</ul>
</li>
<li>anthenticated()<ul>
<li>인증이 되어야(로그인) 접근 가능</li>
</ul>
</li>
<li>formLogin()<ul>
<li>loginPage(&quot;url&quot;) : 인증을 필요로 할때 redirect 할 로그인 페이지 설정</li>
<li>loginProcessingUrl(&quot;url&quot;) : 로그인이 진행중인 URL. 즉, 로그인을 위한 form 데이터를 전송한 url</li>
<li>defaultSuccessUrl(&quot;url&quot;) : 필터에 걸려서 로그인 페이지로 간 것이 아닌, 로그인 페이지로 직접 이동하여 로그인을 한 경우, 로그인 성공시 redirect 되는 기본 url</li>
</ul>
</li>
<li>logout()<ul>
<li>logoutUrl(&quot;url&quot;) : 로그아웃 요청이 들어간 url</li>
<li>logoutSuccessUrl(&quot;url&quot;) : 로그아웃 성공시 redirect되는 url</li>
<li>invalidateHttpSession(true/false) : session 초기화 여부</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/bbb8c938-be61-4655-b5c3-3885559fbd64/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%ED%9B%84%205.29.22.png" alt=""></p>
<h3 id="cross-site-request-forgery">Cross Site Request Forgery</h3>
</li>
<li><p>get요청을 통해 form을 받고, form 전송을 통해 post요청을 하는데, form을 받아온 사이트와, post요청을 보낼 사이트가 다른경우.</p>
</li>
<li><p>해결</p>
<ul>
<li>get요청에대한 응답을 보낼때 key생성 &gt; post요청시 key 검사</li>
<li>또는 csrf().disable();<ul>
<li>위의 사진 참고</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="메인페이지-controller-mapping--tiles-정의">메인페이지 controller mapping &amp; tiles 정의</h3>
<ul>
<li><p>controller mapping
<img src="https://images.velog.io/images/junjun-creator/post/63edd6e5-621f-4f15-bef9-04324d8313f2/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%ED%9B%84%205.46.51.png" alt=""></p>
</li>
<li><p>tiles 정의
<img src="https://images.velog.io/images/junjun-creator/post/065c4be7-607c-484a-a5ba-8d95a8f38f3f/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%ED%9B%84%205.47.14.png" alt=""></p>
</li>
</ul>
<h3 id="로그인-로그아웃-버튼-설정">로그인 로그아웃 버튼 설정</h3>
<ul>
<li><p>spring-security-taglabs 라이브러리 추가
<img src="https://images.velog.io/images/junjun-creator/post/18deb4e3-e98e-4f8c-a089-5dbe15f56168/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%ED%9B%84%205.37.19.png" alt=""></p>
</li>
<li><p>jsp 태그라이브러리 추가
<img src="https://images.velog.io/images/junjun-creator/post/edeaafb9-c6bd-4493-bbd6-8529fb54d48a/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%ED%9B%84%205.36.45.png" alt=""></p>
</li>
<li><p>spring이 제공하는 expression-based access control 사용하여 ui 조건 검사</p>
<ul>
<li>isAnonymous() : 비인증된 상태인지?</li>
<li>isAuthenticated() : 인증된 상태인지?
<img src="https://images.velog.io/images/junjun-creator/post/22cc3b01-65d3-4533-96a3-b1e8831b30b1/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%ED%9B%84%205.37.33.png" alt=""></li>
</ul>
</li>
</ul>
<h3 id="jdbcauthentication">jdbcAuthentication()</h3>
<ul>
<li>spring이 지정한 계정정보 : id, password, disabled</li>
<li>spring이 지정한 권한정보 : id, roleId<ul>
<li>roleId는 무조건 ROLE_*** 형식으로 DB에서 가져와야함</li>
</ul>
</li>
<li>비밀번호가 BCrypt 인코딩 되있다면 검사할때도 같은 인코딩으로 검사 해야함.</li>
</ul>
<pre><code>@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //누군 되고 누군 안되는지?
        auth .jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery(&quot;select uid id, pwd password, 1 enabled from Member where uid=?&quot;)
                .authoritiesByUsernameQuery(&quot;select uid id, &#39;ROLE_ADMIN&#39; roleId from Member where uid=?&quot;)
                .passwordEncoder(new BCryptPasswordEncoder());

    }</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 DI란?]]></title>
            <link>https://velog.io/@junjun-creator/%EC%8A%A4%ED%94%84%EB%A7%81-DI%EB%9E%80</link>
            <guid>https://velog.io/@junjun-creator/%EC%8A%A4%ED%94%84%EB%A7%81-DI%EB%9E%80</guid>
            <pubDate>Tue, 26 Jan 2021 06:49:48 GMT</pubDate>
            <description><![CDATA[<h3 id="spring-이란">Spring 이란?</h3>
<ul>
<li>DI 도구<ul>
<li>dependency(의존성) : 사용하는 부품/모듈/클래스/개체<ul>
<li>객체가 다른 객체를 참조하고 있는 경우 의존성을 가짐</li>
</ul>
</li>
</ul>
</li>
<li>왜 DI가 필요한가?<ul>
<li>인터페이스 : 분리를 위한 도구<ul>
<li>간접적으로 사용하게 하는 도구</li>
</ul>
</li>
<li>분리를 통해 인터페이스만 지켜준다면, 원래 본체가 바뀌어도 상관 없음.(두번째 이유)</li>
<li>인터페이스는 병렬적으로 작업이 가능하게끔 해준다.(구현 영역 분리)</li>
<li>인터페이스의 등장으로 병렬작업이 가능한 장점이지만, dependency를 꽂아주기 위해서는 더 상위에서 넣어주는 작업을 해줘야한다.<ul>
<li>이를 쉽게 할수 있기 위해서 Spring 이 등장을 했다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="spring-di-방법">Spring DI 방법</h3>
<ul>
<li>지시서 : 객체를 만들어서 컨테이너에 넣어주세요<del>, 그리고 조립도 해주세요</del><ul>
<li>xml방식</li>
<li>Annotation 방식</li>
</ul>
</li>
</ul>
<h3 id="현재-spring">현재 Spring</h3>
<ul>
<li>엔터프라이즈 애플리케이션을 만들기 위한 플랫폼으로 성장</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.25~26(Spring Boot - preparer, successhandler)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2021.01.25Spring-Boot-preparer-successhandler</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2021.01.25Spring-Boot-preparer-successhandler</guid>
            <pubDate>Mon, 25 Jan 2021 07:51:35 GMT</pubDate>
            <description><![CDATA[<p>오늘은 Tiles Preparer, AuthenticationSuccessHandler에 대해서 학습하였습니다.</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>Tiles Preparer</li>
<li>AuthenticationSuccessHandler</li>
</ul>
<h3 id="tiles-preparer">Tiles Preparer</h3>
<ul>
<li>레이아웃의 공통된 부분을 준비하는데 사용</li>
<li>main영역은 컨트롤러를 통해 데이터를 가져오지만, header, aside등과같은 영역은 컨트롤러가 없다.</li>
<li>이런 영역에서 필요한 데이터가 있다면?<ul>
<li>Preparer를 활용
<img src="https://images.velog.io/images/junjun-creator/post/ed9b0ccc-4db8-411f-96fc-e3aeeba4756f/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-25%20%EC%98%A4%ED%9B%84%203.46.43.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/fbc7adee-5182-4458-93cc-063d2c3a85a3/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-25%20%EC%98%A4%ED%9B%84%203.47.02.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/fe2bfc45-9342-435a-ba3b-f28ad00e4f08/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-25%20%EC%98%A4%ED%9B%84%203.47.25.png" alt=""></li>
</ul>
</li>
</ul>
<h3 id="사용자-정보를-사용하는-방법은">사용자 정보를 사용하는 방법은?</h3>
<ul>
<li><p>세션활용</p>
</li>
<li><p>하지만, 기존과 달리 로그인 처리를 우리가 직접 하는 것이 아니라 spring security에서 제공하는 기능을 사용한다</p>
</li>
<li><p>spring security에 session정보를 넣는 방법이 필요</p>
<ul>
<li>WebSecurityConfigurer에서 successHandler 활용<ul>
<li>AuthenticationSuccessHandler
<img src="https://images.velog.io/images/junjun-creator/post/4bd49201-f99b-44c1-9887-2644b59efe4c/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-25%20%EC%98%A4%ED%9B%84%204.45.22.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/94c8c7d0-dfac-42c6-9e89-99cc0eb9280b/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-25%20%EC%98%A4%ED%9B%84%204.47.46.png" alt=""></li>
</ul>
</li>
</ul>
</li>
<li><p>주의사항</p>
<ul>
<li>successHandler를 통해 로그인시 세션정보 등록을 완료하고, 원래 이동해야할 페이지로 redirect를 꼭 해줘야 한다.<ul>
<li>스프링은 returnURL 정보를 세션에 저장해둔다.<ul>
<li>saved request</li>
</ul>
</li>
<li>세션에서 returnURL정보를 꺼내서 redirect 해주면 됨
<img src="https://images.velog.io/images/junjun-creator/post/4820f64d-2f16-4243-861d-a308354848e6/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-26%20%EC%98%A4%ED%9B%84%206.42.24.png" alt=""></li>
</ul>
</li>
<li>로그인 한 사용자의 권한에 따라 페이지 redirect 하기
<img src="https://images.velog.io/images/junjun-creator/post/077782cc-0dd1-4c89-b3dc-7bd8d199a90b/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%ED%9B%84%203.23.54.png" alt=""></li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.25~02.03(NodeJS)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2021.01.25NodeJS</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2021.01.25NodeJS</guid>
            <pubDate>Mon, 25 Jan 2021 05:36:10 GMT</pubDate>
            <description><![CDATA[<p>오늘은 NodeJS를 학습하였습니다.</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>NodeJS 등장</li>
<li>NodeJS core</li>
</ul>
<h3 id="nodejs-등장">NodeJS 등장</h3>
<ul>
<li><p>스크립트가 웹에서만 동작하는 것이 아닌, 외부에서 동작할수 있는 v8 엔진 개발</p>
<ul>
<li>탈 브라우저</li>
</ul>
</li>
<li><p>브라우저가 아닌 터미널에서 스크립트 인터프리터를 작동 시킬 수 있음</p>
</li>
<li><p>이를 이용하여 서버 구현이 가능해짐</p>
</li>
<li><p>스크립트는 비동기 형식의 단일 스레드 구조</p>
<ul>
<li>실행속도가 아주 빠름</li>
</ul>
</li>
<li><p>모듈 단위로 설계</p>
<ul>
<li>기존 : commonJS module</li>
<li>10버전 이후 : ES module</li>
<li>모듈의 고립성을 유지한 채로, 허가된 것만 가져다 쓸 수 있음
<img src="https://images.velog.io/images/junjun-creator/post/7290e5d0-792d-4c4a-83fd-b185bf2171f6/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-25%20%EC%98%A4%EC%A0%84%2011.49.11.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/ff7b7215-262f-4a14-9891-c86d9d980643/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-25%20%EC%98%A4%EC%A0%84%2011.49.24.png" alt=""></li>
</ul>
</li>
<li><p>파일 시스템(fs)</p>
<ul>
<li>내장모듈</li>
<li>fs.readFile(&quot;파일경로&quot;,&quot;인코딩방식&quot;,콜백)
<img src="https://images.velog.io/images/junjun-creator/post/742443fc-fbc7-4294-8cda-e33f3848bafe/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-25%20%EC%98%A4%ED%9B%84%2012.01.47.png" alt=""></li>
</ul>
</li>
</ul>
<h3 id="nodejs-core-모듈">NodeJS core 모듈</h3>
<ul>
<li>http 모듈 : 웹에서 입출력을 할 수 있음</li>
<li>fs 모듈 : 파일을 읽어올 수 있음
<img src="https://images.velog.io/images/junjun-creator/post/c6d12af1-8852-4b3b-b03e-3b2e39e086b7/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-25%20%EC%98%A4%ED%9B%84%202.33.20.png" alt=""></li>
</ul>
<h3 id="사용자-입력을-받아-요청을-제공">사용자 입력을 받아 요청을 제공</h3>
<ul>
<li>request 객체 속성<ul>
<li>url</li>
<li>header 등등</li>
<li>여기서 디렉토리를 읽어서 서버를 구현한다는것은 너무 맨땅에 헤딩</li>
</ul>
</li>
<li>connect framework(middleware 프레임워크)<ul>
<li>http갖고있는것 중에서 파일을 읽어서 출력</li>
<li>요청시 파일을 알아서 읽어줌</li>
<li>라우팅도 알아서 해줌</li>
<li>인증, 인코딩 등 수행을 위한 코드 추가/삭제</li>
<li>마치 서블릿에서 필터처럼 사용자에게 view를 제공해주기 전에 보안, 인증 등을 수행하게끔 함</li>
</ul>
</li>
<li>express(출력)<ul>
<li>현재 우리가 사용하고있는 mvc 모델을 그대로 구현해놓은것</li>
</ul>
</li>
</ul>
<h3 id="connect-모듈을-이용한-웹-서버-구현">Connect 모듈을 이용한 웹 서버 구현</h3>
<ul>
<li><p>extensible HTTP server framework for node using plugins</p>
</li>
<li><p>npm 설치</p>
<ul>
<li>maven같은 아이, 패키지에서 사용하는 모듈들을 관리해주는 역할을 함</li>
<li>node package manager</li>
<li>메이븐 저장소에서 dependency들을 다운받듯이 npm 노드 패키지 저장소가 있음. 거기서 모듈을 가져와서 사용</li>
<li>$ <span style="color:red;">npm i connect</span><ul>
<li>connect 모듈 다운로드</li>
<li>connect 모듈이 사용하는 모듈들도 자동으로 설치됨</li>
</ul>
</li>
<li>package.json<ul>
<li>자동으로 설치되는줄 알았으나, 따로 해줘야함...!! 주의!!</li>
<li>설치한 dependency들의 목록을 관리함.</li>
<li>메이븐처럼 dependency 추가 및 관리 가능
<img src="https://images.velog.io/images/junjun-creator/post/74a1160a-e1d9-4650-8d3e-467293f14bfa/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-27%20%EC%98%A4%ED%9B%84%2011.53.36.png" alt=""></li>
</ul>
</li>
</ul>
</li>
<li><p>connect 모듈 사용하기</p>
<ul>
<li>서버 연결
<img src="https://images.velog.io/images/junjun-creator/post/f90df464-322c-4e70-b2de-c6b59be49fb2/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%EC%A0%84%2012.03.40.png" alt=""></li>
<li>connect().use()를 사용하여 url 매핑<ul>
<li>req : 응답 정보</li>
<li>res : 결과 정보</li>
<li>next : 미들웨어 로직 연결해주는 역할(filter chain처럼)
<img src="https://images.velog.io/images/junjun-creator/post/cbedd3d3-81a7-4e7b-a288-5aa13a925b5a/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%EC%A0%84%2012.29.17.png" alt=""></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="express-모듈을-사용하여-서버-구현">express 모듈을 사용하여 서버 구현</h3>
<ul>
<li>HTTP<ul>
<li>networking</li>
<li>request, response</li>
<li>event</li>
<li>listening</li>
</ul>
</li>
<li>CONNECT<ul>
<li>middleware</li>
<li>static file</li>
<li>badyParser</li>
</ul>
</li>
<li>EXPRESS <ul>
<li>routing</li>
<li>template view engine</li>
<li>웹 개발하는데 사용되는 모든 기능들이 여기에 들어있음(web framework)<ul>
<li>파일 업로드</li>
<li>인증</li>
<li>기타 등등</li>
</ul>
</li>
</ul>
</li>
<li>connect(압축, 인코딩, csrf 공격, static 파일에대한 내용 꽂아넣기) + view 엔진 + routing 기능 포함</li>
<li>java + tomcat의 관계와 같음<ul>
<li>백엔드단(api 제공)</li>
</ul>
</li>
<li>view 엔진<ul>
<li>모델의 데이터를 view에 꽂아주는 역할</li>
</ul>
</li>
<li>express 모듈 설치<ul>
<li>$ <span style="color:red;">npm i express</span></li>
</ul>
</li>
<li>서버 실행
<img src="https://images.velog.io/images/junjun-creator/post/70f8f5b3-acfe-470f-8a68-e2c9c04eb824/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%EC%A0%84%201.03.44.png" alt=""></li>
<li>url 매핑
<img src="https://images.velog.io/images/junjun-creator/post/61f39f18-b437-4c80-8130-b3619145285f/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%EC%A0%84%201.09.21.png" alt=""></li>
<li>express 만을 사용하여 서버를 만들 경우, 온전한 http의 기능을 쓰는것이 아닌 express를 통해서 쓰는것이 됨<ul>
<li>http를 온전히 쓰는것이 아닌 express로 wrapping된 기능만 사용하는 것이 됨</li>
<li>이 경우엔 express를 통해 네트워킹을 하고있음</li>
<li>네트워크 설정을 위해 express와 http를 분리한뒤 나중에 결합해서 사용하는 방식 사용</li>
<li>이 방식을 통해 http의 기능을 맨땅으로 사용 가능하고 + express에 추가된 기능들도 사용할 수 있다.</li>
</ul>
</li>
<li>routing<ul>
<li>스프링에서 컨트롤러가 url매핑과 관련된 작업을 했다면, router를 이용해 url 매핑을 컨트롤러처럼 구현할 수 있다
<img src="https://images.velog.io/images/junjun-creator/post/2ee57f1b-e696-4447-b4e7-88e2ed0c660f/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%EC%A0%84%2011.13.12.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/8cf2cb8a-6427-45b4-aed2-4c6e2a21e2f4/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%EC%A0%84%2011.13.28.png" alt=""></li>
</ul>
</li>
<li>express view 엔진<ul>
<li>ejs : 짜여진 html 코드에 el태그처럼 값을 꽂아넣을 수 있음</li>
<li>다른 view 엔진(jade, pug 등)<ul>
<li>기존 html코드에 값을 끼워넣는게 아니고, html코드를 쉽게 generating 해서 값을 꽂아서 사용하는 방식...</li>
<li>대용량 view를 구현하는데 효율적이지 못해보임.</li>
</ul>
</li>
</ul>
</li>
<li>ejs 설치(view 엔진)<ul>
<li>$ <span style="color:red;">npm i ejs</span></li>
</ul>
</li>
<li>view 렌더링<ul>
<li>.ejs view 파일 생성
<img src="https://images.velog.io/images/junjun-creator/post/82ffe52e-e75f-4af7-a745-832dea4dbc5b/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%EC%A0%84%2011.53.50.png" alt=""></li>
<li>expres가 사용할 view 경로 설정<ul>
<li>express().set()
<img src="https://images.velog.io/images/junjun-creator/post/2d680c3c-d421-476a-bbef-a86cefa1ea3a/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%EC%A0%84%2011.54.32.png" alt=""></li>
</ul>
</li>
<li>렌더링
<img src="https://images.velog.io/images/junjun-creator/post/998c5c27-6a71-48e7-a387-9df07bfb3f3c/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%EC%A0%84%2011.55.13.png" alt=""></li>
</ul>
</li>
<li>view 데이터 binding
<img src="https://images.velog.io/images/junjun-creator/post/d12904a0-b871-4020-a6bb-e23121a6a697/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%ED%9B%84%2012.06.45.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/e8c5a9a5-11ac-4dd0-8962-b81beaeb666d/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%ED%9B%84%2012.16.18.png" alt=""></li>
<li>라우터를 활용하여 json 객체를 반환하는 api 만들기
<img src="https://images.velog.io/images/junjun-creator/post/32857202-fdfa-4bd6-bc85-81c837c2944e/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%ED%9B%84%2012.24.25.png" alt=""></li>
</ul>
<h3 id="express-generator">express generator</h3>
<ul>
<li>nodejs + express를 활용하여 웹 개발을 할때 기본적인 설정을 해둔 상태로 그것을 모듈로 제공한다면? 편리할 것이다.</li>
<li>http, path, express 등 모듈들의 기본 세팅</li>
<li>그것을 제공하는 것이 express generator이다.</li>
<li>$ <span style="color:red;">npx express-generator [--view=view엔진명] [폴더이름]</span><ul>
<li>현재 디렉토리에 있는 모듈들을 설치해야함<ul>
<li>$ <span style="color:red;">npm i</span></li>
</ul>
</li>
</ul>
</li>
<li>package.json의 scripts에 간편 명령어들을 정의할 수 있다.<ul>
<li>start : 서버 실행을 위한 명령어</li>
</ul>
</li>
<li>주의사항<ul>
<li>Root 디렉토리(/)의 경우엔 express가 static 문서들을 먼저 참조한다면 index.html을 먼저 찾게됨.</li>
<li>라우터를 먼저 연결해주고 static을 연결 해주면 해결됨
<img src="https://images.velog.io/images/junjun-creator/post/813e1ad8-991f-4e70-ab6e-8e764ed72c00/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-29%20%EC%98%A4%EC%A0%84%2010.52.26.png" alt=""></li>
</ul>
</li>
</ul>
<h3 id="url-매핑-및-view-rendering">url 매핑 및 view rendering</h3>
<ul>
<li>controller(router) 만들기
<img src="https://images.velog.io/images/junjun-creator/post/7186556e-d9ae-4c76-8be7-af4a502a3560/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-29%20%EC%98%A4%EC%A0%84%2011.26.16.png" alt=""></li>
<li>express가 해당 controller 사용하게 하기(app.js에서)
<img src="https://images.velog.io/images/junjun-creator/post/3e2e09ce-0785-4b86-ae74-c2bb4fbde289/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-29%20%EC%98%A4%EC%A0%84%2011.27.18.png" alt=""></li>
<li>controller(router)에서 url 매핑 및 렌더링 설정하기
<img src="https://images.velog.io/images/junjun-creator/post/c6ff9faf-e3ed-44d6-b2ce-6a4c2836f632/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-29%20%EC%98%A4%EC%A0%84%2011.28.07.png" alt=""></li>
</ul>
<h3 id="database-모듈-사용">database 모듈 사용</h3>
<ul>
<li>모듈 설치<ul>
<li>$ <span style="color:red;">npm i mysql</span></li>
</ul>
</li>
<li>connection 객체를 통해 query 실행
<img src="https://images.velog.io/images/junjun-creator/post/3b5850ca-9a6b-4fba-9efd-26f83e322cf4/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-29%20%EC%98%A4%ED%9B%84%2012.27.50.png" alt=""></li>
<li>view에 값 넣기
<img src="https://images.velog.io/images/junjun-creator/post/3ff59ce4-8200-4831-bed0-43c6dc54c9c5/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-29%20%EC%98%A4%ED%9B%84%2012.28.49.png" alt=""></li>
</ul>
<h3 id="데이터베이스-모듈-분리">데이터베이스 모듈 분리</h3>
<ul>
<li>매 라우터마다 데이터베이스 모듈을 사용하는 코드가 있다면 비효율적이다.</li>
<li>집중화하여 필요한 곳에 꺼내 쓸 수 있도록 구성한다.
<img src="https://images.velog.io/images/junjun-creator/post/df032a4b-1aa8-49b7-b887-728bd84e0847/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-01%20%EC%98%A4%EC%A0%84%2010.13.00.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/f7f3d5a2-ba04-49dc-b0bb-ab0da0cca0fd/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-01%20%EC%98%A4%EC%A0%84%2010.13.13.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/6d63d572-951c-425c-b7dc-9fc9fd8c7931/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-01%20%EC%98%A4%EC%A0%84%2010.13.28.png" alt=""></li>
</ul>
<h3 id="nodejs와-reactapp-연동">nodeJS와 ReactApp 연동</h3>
<ul>
<li>Node &gt; ReactApp &gt; Babel &gt; Module(X):WebPack &gt; bundle(배포본) &gt; pure js</li>
<li>페이지를 컴포넌트 단위로 쪼개서 갈아끼우는 형식으로 SPA 구현<ul>
<li>App.js에 각각에 컴포넌트들을 끼워넣고 조립된 것을 리턴
<img src="https://images.velog.io/images/junjun-creator/post/2aa6be59-5eb4-42da-8019-987be01e8ef0/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-01%20%EC%98%A4%ED%9B%84%2012.37.49.png" alt=""></li>
<li>index.js에서 그 조립된 App을 사용
<img src="https://images.velog.io/images/junjun-creator/post/32876a63-72bf-4301-82fb-fed9d1f863e5/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-01%20%EC%98%A4%ED%9B%84%2012.38.59.png" alt=""></li>
</ul>
</li>
</ul>
<h3 id="페이지-switching">페이지 switching</h3>
<ul>
<li>컴포넌트를 url에 따라서 switching 해줘야 한다.</li>
<li>라우팅 필요<ul>
<li>$ <span style="color:red;">npm i react-router-dom</span></li>
</ul>
</li>
<li>헤더에 라우팅 링크 설정
<img src="https://images.velog.io/images/junjun-creator/post/80413f2b-9eeb-4c41-8594-2f7da40b2777/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-02%20%EC%98%A4%EC%A0%84%2010.19.22.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/2e20b6e2-b942-4493-ac3b-da42d9ce8163/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-02%20%EC%98%A4%EC%A0%84%2010.19.47.png" alt=""></li>
<li>각 컴포넌트 라우팅(App.js)
<img src="https://images.velog.io/images/junjun-creator/post/cc559267-f9dd-4c6d-9941-64ee979dccf0/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-02%20%EC%98%A4%EC%A0%84%2010.21.56.png" alt=""></li>
<li>Detail 페이지 설정<ul>
<li>list 영역과 detail 영역을 switching 하면 됨
<img src="https://images.velog.io/images/junjun-creator/post/858c5951-c22a-490c-a1c6-56253135adc4/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-02%20%EC%98%A4%EC%A0%84%2011.50.09.png" alt=""></li>
</ul>
</li>
<li>list 영역 데이터 서버에서 불러오기<ul>
<li>서버와 클라이언트가 모두 실행중인 상태에서 서버측에 데이터를 요청한다</li>
<li>서버에서 cors 허가가 있어야 서로 다른 도메인에 있는 데이터를 가져올 수 있다. </li>
<li>서버단에 cors 모듈 설치 및 사용(app.js)<ul>
<li>$ <span style="color:red;">npm i cors</span>
<img src="https://images.velog.io/images/junjun-creator/post/9c61b986-313f-40af-a314-ec541495e0e8/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-02%20%EC%98%A4%ED%9B%84%2012.14.45.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/f8f875f9-2aea-460c-9325-ae3a4d625d18/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-02%20%EC%98%A4%ED%9B%84%2012.14.53.png" alt=""></li>
</ul>
</li>
<li>서버단에서 cors를 허용하고싶은 도메인이 따로 있다면 객체 형태로 전송해주면 됨<ul>
<li>app.use(cors({origin : &quot;도메인주소&quot;});</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="각-detail-페이지-정보-불러오기">각 detail 페이지 정보 불러오기</h3>
<ul>
<li>서버 api 설정(NoticeController.js)
<img src="https://images.velog.io/images/junjun-creator/post/22cf0cd5-b22d-446b-a432-149cb6b63833/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-02%20%EC%98%A4%ED%9B%84%2012.20.31.png" alt=""></li>
<li>detail 페이지를 불러오기위한 Link 설정
<img src="https://images.velog.io/images/junjun-creator/post/09716a53-071e-4613-beef-c6cb01196ba0/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-03%20%EC%98%A4%EC%A0%84%2010.01.10.png" alt=""></li>
<li>detail api를 통해 데이터를 가져오기<ul>
<li>Route의 path 정보가 마치 스프링에서 PathVariable처럼 전달된다.</li>
<li>props로 전달됨
<img src="https://images.velog.io/images/junjun-creator/post/be167baf-fa16-4d7e-bf40-e2fd2eecdeb1/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-03%20%EC%98%A4%EC%A0%84%2010.02.50.png" alt=""></li>
</ul>
</li>
</ul>
<h3 id="login">login</h3>
<ul>
<li>입력하는 값 &gt; ref로 current value 가져다 쓰기
<img src="https://images.velog.io/images/junjun-creator/post/9f179aac-da72-4432-b951-81da7b3cf178/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-03%20%EC%98%A4%EC%A0%84%2011.39.39.png" alt=""></li>
<li>비밀번호 검증<ul>
<li>bcrypt로 비밀번호 검증
<img src="https://images.velog.io/images/junjun-creator/post/9b09b780-0889-437d-b0d5-8d0bfd79dff0/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-04%20%EC%98%A4%EC%A0%84%209.36.50.png" alt=""></li>
</ul>
</li>
<li>로그인 성공시 페이지 이동
<img src="https://images.velog.io/images/junjun-creator/post/e93e61ed-06ba-498f-8fc8-733292937d5e/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-02-04%20%EC%98%A4%EC%A0%84%209.41.22.png" alt=""></li>
</ul>
<h3 id="인증이-필요한-url-인터셉터-설정">인증이 필요한 url 인터셉터 설정</h3>
<ul>
<li>AuthorizedRoute 컴포넌트를 구현하여 전역변수에 로그인 정보가 있는지를 검사 한 후 라우트 하게끔</li>
</ul>
<h3 id="상태정보-유지하기">상태정보 유지하기</h3>
<ul>
<li>state와 같은 전역변수 사용</li>
<li>Redux 사용</li>
</ul>
<h3 id="commonjs-vs-es6-module">commonJS vs ES6 module</h3>
<ul>
<li>package.json에서 type 설정</li>
<li>module.exports vs export &amp; import</li>
<li>외부 모듈을 사용할때 왜 ES6 module을 안쓰고 commonJS를 쓰나?<ul>
<li>호환성 문제</li>
<li>환경변수(__dirname 등), 등 모듈이 사용하고 있는 기능들이 commonJS를 사용하고 있어서 호환성 문제가 생김 </li>
</ul>
</li>
</ul>
<h3 id="react-app-생성">React app 생성</h3>
<ul>
<li>$ <span style="color:red;">npx create-react-app my-app</span></li>
<li>node로 서버 실행 후 react와 연동 가능</li>
<li>질문 사항<ul>
<li>어떻게 서버가 실행되고 리액트 app과 연동되서 view를 구성하는지?</li>
</ul>
</li>
</ul>
<h3 id="번외">번외</h3>
<ul>
<li>모듈을 설치하기 전, 꼭 package.json 파일 만들어야함<ul>
<li>$ <span style="color:red;">npm init</span></li>
<li>만든 다음 모듈 설치하기</li>
</ul>
</li>
<li>모듈을 다른곳에서 쓰고싶을때??<ul>
<li>package.json만 옮겨서 install 해주면 됨</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.21(React-5)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2021.01.21React-5</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2021.01.21React-5</guid>
            <pubDate>Fri, 22 Jan 2021 06:06:41 GMT</pubDate>
            <description><![CDATA[<p>오늘은 React 5번째 시간입니다.</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>검색 기능</li>
<li>페이저 기능</li>
</ul>
<h3 id="검색기능">검색기능</h3>
<ul>
<li><p>검색 field와 query 값 설정</p>
<ul>
<li><p>this.field, query</p>
<ul>
<li><p>DOM 객체 사용하지 않고, React.createReg() 사용하여 현재 값 가져오기</p>
<pre><code>constructor(props){
super(props);
this.state={
    list:[
        {&quot;id&quot;:92032472,&quot;title&quot;:&quot;eff&quot;,&quot;writerId&quot;:&quot;newlec&quot;,&quot;content&quot;:&quot;af&quot;}
    ],
    count:0
};

this.queryInput = React.createRef();
this.fieldInput = React.createRef();

this.page=1;
this.field = &quot;title&quot;;
this.query = &quot;&quot;;
</code></pre></li>
</ul>
</li>
</ul>
<p>}
```</p>
</li>
<li><p>설정된 field와 query값을 통해 데이터 바인딩</p>
<pre><code>dataBind(){
    fetch(`/api/notice/list?p=${this.page}&amp;f=${this.field}&amp;q=${this.query}`)
    .then((response)=&gt;{
        return response.json();
    })
    .then((data)=&gt;{

        this.setState(data);
    });
}</code></pre></li>
<li><p>검색 form</p>
<pre><code>&lt;form className=&quot;table-form&quot;&gt;
                                &lt;fieldset&gt;
                                    &lt;legend className=&quot;hidden&quot;&gt;공지사항 검색 필드&lt;/legend&gt;
                                    &lt;label className=&quot;hidden&quot;&gt;검색분류&lt;/label&gt;
                                    &lt;select ref={this.fieldInput} name=&quot;f&quot;&gt;
                                        &lt;option  value=&quot;title&quot;&gt;제목&lt;/option&gt;
                                        &lt;option  value=&quot;writerId&quot;&gt;작성자&lt;/option&gt;
                                    &lt;/select&gt; 
                                    &lt;label className=&quot;hidden&quot;&gt;검색어&lt;/label&gt;
                                    &lt;input type=&quot;text&quot; name=&quot;q&quot; ref={this.queryInput}/&gt;
                                    &lt;input className=&quot;btn btn-search&quot; type=&quot;submit&quot; value=&quot;검색&quot; onClick={(e)=&gt;{this.search(e);}}/&gt;
                                &lt;/fieldset&gt;
                            &lt;/form&gt;</code></pre></li>
<li><p>onClick 이벤트</p>
</li>
</ul>
<pre><code>search(e){
        e.preventDefault();
        this.query = this.queryInput.current.value;
        this.field = this.fieldInput.current.value;

        this.dataBind();
    }</code></pre><h3 id="페이저-기능">페이저 기능</h3>
<ul>
<li><p>패이저를 위한 controller 설정</p>
<ul>
<li>list</li>
<li>count
<img src="https://images.velog.io/images/junjun-creator/post/1653e033-4571-4557-a773-b6d8a1a597e9/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-22%20%EC%98%A4%ED%9B%84%202.29.45.png" alt=""></li>
</ul>
</li>
<li><p>페이저 start number 설정</p>
<pre><code>constructor(props){
    super(props);
    this.state={
        list:[
            {&quot;id&quot;:92032472,&quot;title&quot;:&quot;eff&quot;,&quot;writerId&quot;:&quot;newlec&quot;,&quot;content&quot;:&quot;af&quot;}
        ],
        count:0
    };

    this.queryInput = React.createRef();
    this.fieldInput = React.createRef();

    this.page=1;
    this.field = &quot;title&quot;;
    this.query = &quot;&quot;;
    let offset = (this.page -1)%5;
    this.startNum = this.page-offset;
}</code></pre></li>
<li><p>페이저 ui</p>
<pre><code>&lt;ul className=&quot;-list- center&quot; onClick={(e)=&gt;{this.pageClickHandler(e);}}&gt;
{
    [0,1,2,3,4].map((i)=&gt;&lt;li key={i+this.startNum}&gt;&lt;a className=&quot;-text-  &quot; href=&quot;?p={i}&amp;f=&amp;q=&quot;&gt;{i+this.startNum}&lt;/a&gt;&lt;/li&gt;)
}
</code></pre></li>
</ul>
</ul>
```

<ul>
<li>이전 버튼<pre><code>&lt;div&gt;
{
    this.startNum==1?
    &lt;span className=&quot;btn btn-prev&quot; onClick={(e)=&gt;{alert(&#39;이전 페이지가 없습니다.&#39;)}}&gt;이전&lt;/span&gt;
    :&lt;a className=&quot;btn btn-prev&quot; href=&quot;?p=&amp;f=&amp;q=&quot;&gt;이전&lt;/a&gt;
}
&lt;/div&gt;</code></pre></li>
</ul>
<h3 id="정리">정리</h3>
<ul>
<li>react는 2way 바인딩이 없다.<ul>
<li>1 way
<img src="https://images.velog.io/images/junjun-creator/post/47e332a2-1edb-48d2-8295-8571fa58960e/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-28%20%EC%98%A4%EC%A0%84%209.59.57.png" alt=""></li>
</ul>
</li>
<li>component간 데이터 전송<ul>
<li>props</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.21(Spring Boot- 목록 삭제)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2021.01.21Spring-Boot-%EB%AA%A9%EB%A1%9D-%EC%82%AD%EC%A0%9C</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2021.01.21Spring-Boot-%EB%AA%A9%EB%A1%9D-%EC%82%AD%EC%A0%9C</guid>
            <pubDate>Thu, 21 Jan 2021 09:56:07 GMT</pubDate>
            <description><![CDATA[<h3 id="detail-페이지에서-목록-삭제">detail 페이지에서 목록 삭제</h3>
<ul>
<li><p>view 페이지 delete 버튼과 컨트롤러 매핑</p>
<ul>
<li>주의사항<ul>
<li>삭제버튼 클릭시 바로 삭제요청이 되는것이 아니라 확인창이 뜨게끔 만들어줘야함(script로 구현)
<img src="https://images.velog.io/images/junjun-creator/post/23fde018-448d-47ef-9c98-449c3b65cac0/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-21%20%EC%98%A4%ED%9B%84%205.52.34.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/b61f2e65-4197-4131-a3fe-520c18f666e9/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-21%20%EC%98%A4%ED%9B%84%205.52.50.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/7545433d-86ee-4de6-8f8e-4d5b6ec683ef/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-21%20%EC%98%A4%ED%9B%84%205.52.57.png" alt=""></li>
</ul>
</li>
</ul>
</li>
<li><p>서비스, DAO 구현 및 MyBatisMapper 작성
<img src="https://images.velog.io/images/junjun-creator/post/7df6b227-98cf-430c-872d-47a34d6cd630/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-21%20%EC%98%A4%ED%9B%84%205.54.13.png" alt=""></p>
</li>
</ul>
<h3 id="목록-페이지에서-일괄-삭제">목록 페이지에서 일괄 삭제</h3>
<ul>
<li><p>일괄삭제, 일괄공개 버튼 구별하기</p>
<ul>
<li>submit 버튼에 name값을 주고, value를 서버로 전달시켜서 사용
<img src="https://images.velog.io/images/junjun-creator/post/12782424-5f01-4e92-b96c-34d4f015d24b/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-21%20%EC%98%A4%ED%9B%84%206.02.57.png" alt=""></li>
</ul>
</li>
<li><p>체크박스에 value값을 줘서 삭제하고자 하는 아이템의 id값을 전달
<img src="https://images.velog.io/images/junjun-creator/post/aaeffb94-baec-4176-b3f5-4dbde72474ca/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-21%20%EC%98%A4%ED%9B%84%206.04.21.png" alt=""></p>
</li>
<li><p>controller, service, dao 구현
<img src="https://images.velog.io/images/junjun-creator/post/7471d0ff-a058-4850-a9f9-b4b35fa5cc32/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-21%20%EC%98%A4%ED%9B%84%206.39.07.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/3822f139-33fb-485b-bee9-3b22df7565ca/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-21%20%EC%98%A4%ED%9B%84%206.39.55.png" alt=""></p>
</li>
<li><p>dao 구현을 위한 MyBatisMapper구현</p>
<ul>
<li>쿼리의 where 절에 사용할 값으로 배열을 받고있음<ul>
<li>mybatis가 제공하는 foreach 문을 활용</li>
<li>where id in (1,2,3,4,5)와 같은 형태로 만듬
<img src="https://images.velog.io/images/junjun-creator/post/79771d07-085d-4a37-b799-31e2381e6138/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-21%20%EC%98%A4%ED%9B%84%206.40.08.png" alt=""></li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.21(React-3)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2021.01.21React-3</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2021.01.21React-3</guid>
            <pubDate>Thu, 21 Jan 2021 08:49:47 GMT</pubDate>
            <description><![CDATA[<p>오늘은 React 3번째 시간입니다.</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>React를 활용한 list 페이지 만들기</li>
</ul>
<h3 id="react를-활용한-list-페이지-만들기">React를 활용한 list 페이지 만들기</h3>
<ul>
<li><p>기존에 jsp에서 만들던 view에서 react component로 옮길때 jstl, el 태그는 다 지워줘야함</p>
<ul>
<li>jstl , el 모두가 백단에서 jasper가 인식하고 처리하는건데 컴포넌트로 빼서 프론트에서 작업하면 jsx가 jstl, el을 처리할수 없음</li>
<li>서버는 문서를 처리하는 작업을 하지 않음. 그저 js, css 파일만 제공</li>
<li>서버는 데이터를 제공하는 api 만 제공</li>
</ul>
</li>
<li><p>주의사항</p>
<ul>
<li>class &gt; className</li>
<li>onclick=&#39;string&#39; &gt; onClick={()=&gt;{실행하고자 하는 로직}}</li>
<li>input &gt; value 값을 넣을때는 onChange or read-only 필수.  </li>
</ul>
</li>
<li><p>Ajax로 서버 데이터 가져오기(list)
<img src="https://images.velog.io/images/junjun-creator/post/95977dad-879c-48b5-b333-132b314bf3ef/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-21%20%EC%98%A4%EC%A0%84%2010.51.22.png" alt=""></p>
</li>
<li><p>state 설정하기</p>
<ul>
<li>실행순서를 잘 고려해야함<ul>
<li>constructor &gt; render &gt; DidMount<pre><code>constructor(props){
super(props);
this.state={
    list:[
        {&quot;id&quot;:92032472,&quot;title&quot;:&quot;eff&quot;,&quot;writerId&quot;:&quot;newlec&quot;,&quot;content&quot;:&quot;af&quot;}
    ],
    count:0,
    page:1
};
}
</code></pre></li>
</ul>
</li>
</ul>
<p>componentDidMount(){</p>
<pre><code>fetch(`/api/notice/list?p=${this.state.page}`)
.then((response)=&gt;{
    return response.json();
})
.then((list)=&gt;{
    this.setState({list});
});</code></pre><p>}</p>
<pre><code></code></pre></li>
<li><p>map()을 활용하여 state값 rendering 하기</p>
<ul>
<li>jsx 코드 안에 스크립트 코드를 넣기 위해 {} 블록을 사용</li>
<li>map<ul>
<li>값을 순회하면서 지정한 값으로 변경하여 새로운 객체를 생성하여 반환<pre><code>{
this.state.list.map(notice=&gt;&lt;tr key={notice.id}&gt;
        &lt;td&gt;{notice.id}&lt;/td&gt;
        &lt;td className=&quot;title indent text-align-left&quot;&gt;&lt;a href={notice.id}&gt;{notice.title}&lt;/a&gt;[{notice.cmtCount}]&lt;/td&gt;
        &lt;td&gt;{notice.writerId}&lt;/td&gt;
        &lt;td&gt;{notice.regdate}&lt;/td&gt;
        &lt;td&gt;{notice.hit}&lt;/td&gt;
    &lt;/tr&gt;)
}</code></pre></li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.20(React-2)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2021.01.20React-2</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2021.01.20React-2</guid>
            <pubDate>Wed, 20 Jan 2021 05:33:46 GMT</pubDate>
            <description><![CDATA[<p>오늘은 React 2번째 시간입니다.</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>dfdf</li>
</ul>
<h3 id="덧셈-계산기-만들기-예제">덧셈 계산기 만들기 예제</h3>
<ul>
<li>만들고자 하는 ui component 단위로 나누기<ul>
<li>input value = 0으로 초기화<pre><code>function app(){
ReactDOM.render(
    &lt;section&gt;
       &lt;h1&gt;계산기&lt;/h1&gt;
       &lt;div&gt;
          &lt;input type=&quot;text&quot; dir=&quot;rtl&quot; value={0}/&gt;
          &lt;input type=&quot;text&quot; dir=&quot;rtl&quot; value={0}/&gt;
          &lt;input type=&quot;button&quot; value=&quot;계산&quot;/&gt;
          &lt;input type=&quot;text&quot; dir=&quot;rtl&quot; value={0}/&gt;
       &lt;/div&gt;
    &lt;/section&gt;
  , document.querySelector(&quot;#app&quot;) 
);
}
app();</code></pre></li>
</ul>
</li>
<li>VDOM 부분을 Calc라는 컴포넌트로 분리해서 작성(using function)<pre><code>function Calc(){
return &lt;section&gt;
         &lt;h1&gt;계산기&lt;/h1&gt;
         &lt;div&gt;
            &lt;input type=&quot;text&quot; dir=&quot;rtl&quot; value={0}/&gt;
            &lt;input type=&quot;text&quot; dir=&quot;rtl&quot; value={0}/&gt;
            &lt;input type=&quot;button&quot; value=&quot;계산&quot;/&gt;
            &lt;input type=&quot;text&quot; dir=&quot;rtl&quot; value={0} /&gt;
         &lt;/div&gt;
      &lt;/section&gt;;
}
</code></pre></li>
</ul>
<p>function app(){
    ReactDOM.render(
          <Calc />
        , document.querySelector(&quot;#app&quot;) 
    );
}
app();</p>
<pre><code>  - VDOM 부분을 Calc라는 컴포넌트로 분리해서 작성(using class)</code></pre><p>class Calc extends React.Component{
    render(){
        return <section>
             <h1>계산기</h1>
             <div>
                <input type="text" dir="rtl" value={0}/>
                <input type="text" dir="rtl" value={0}/>
                <input type="button" value="계산"/>
                <input type="text" dir="rtl" value={0} />
             </div>
          </section>; 
    }
}</p>
<pre><code>  - state를 이용해서 model값 저장하기
    - 주의사항
      - 닫는 태그 꼭 확인하기
      - 값을 넣을때는 문자열을 빼야함
      - JSX가 지정하는 속성명 사용 (ex. class &gt; className)
      - 1 way 모델링을 준수하기
        - 기존에 mvc 모델에서는 input의 value를 view에서 변경하면 model의 값도 변경이 됬다. 
        - flux(react)는 이런 2 way를 지원하지 않는다. 값이 변경이 되면, 차음으로 다시 돌아와서 model을 변경시켜야 함.
        - 그래서 onChange와 같은 이벤트를 등록해줘야 함</code></pre><p>class Calc extends React.Component{
    constructor(props){
        super(props);
        this.state = {x:0, y:0,result:0};
    }</p>
<pre><code>componentDidMount(){

}

componentWillUnmount(){

}

btnClick(){
    //console.log(this.state.x);
    let {x,y} = this.state;
    this.setState({result:x*1+y*1});
}

render(){
    return &lt;section&gt;
         &lt;h1&gt;계산기&lt;/h1&gt;
         &lt;div&gt;
            &lt;input type=&quot;text&quot; dir=&quot;rtl&quot; value={this.state.x} onChange={(e)=&gt;{this.setState({x:e.target.value})}}/&gt;
            &lt;input type=&quot;text&quot; dir=&quot;rtl&quot; value={this.state.y} onChange={(e)=&gt;{this.setState({y:e.target.value})}}/&gt;
            &lt;input type=&quot;button&quot; value=&quot;계산&quot; onClick={this.btnClick.bind(this)}/&gt;
            &lt;input type=&quot;text&quot; dir=&quot;rtl&quot; value={this.state.result} readOnly/&gt;
         &lt;/div&gt;
      &lt;/section&gt;; 
}</code></pre><p>}</p>
<p>```</p>
<h3 id="react를-활용한-list-페이지-만들기">React를 활용한 list 페이지 만들기</h3>
<ul>
<li>기존에 jsp에서 만들던 view에서 react component로 옮길때 jstl, el 태그는 다 지워줘야함<ul>
<li>jstl , el 모두가 백단에서 jasper가 인식하고 처리하는건데 컴포넌트로 빼서 프론트에서 작업하면 jsx가 jstl, el을 처리할수 없음</li>
<li>서버는 문서를 처리하는 작업을 하지 않음. 그저 js, css 파일만 제공</li>
<li>서버는 데이터를 제공하는 api 만 제공</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2012.01.19(React-1)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2012.01.19React-1</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2012.01.19React-1</guid>
            <pubDate>Tue, 19 Jan 2021 05:50:23 GMT</pubDate>
            <description><![CDATA[<p>react 학습내용입니다.</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>react 라이브러리</li>
<li>react state</li>
</ul>
<h3 id="react-라이브러리-추가하기">react 라이브러리 추가하기</h3>
<ul>
<li><p>CDN 추가.</p>
<pre><code>&lt;script src=&quot;https://unpkg.com/@babel/standalone/babel.min.js&quot;&gt;&lt;/script&gt;
&lt;script crossorigin src=&quot;https://unpkg.com/react@17/umd/react.development.js&quot;&gt;&lt;/script&gt;
&lt;script crossorigin src=&quot;https://unpkg.com/react-dom@17/umd/react-dom.development.js&quot;&gt;&lt;/script&gt;</code></pre></li>
<li><p>Virtual DOM rendering</p>
<ul>
<li>주의사항 : render안에 들어오는 엘리먼트는 무조건 root 여야함. 2개의 root node가 들어올 수 없음<pre><code>function tick(){
</code></pre></li>
</ul>
<p>ReactDOM.render(</p>
<pre><code>&lt;section&gt;
    &lt;h1&gt;세계 시간&lt;/h1&gt;
    &lt;section&gt;
        &lt;h1&gt;America/Toronto&lt;/h1&gt;
        &lt;span&gt;It is {new Date().toLocaleString(&quot;en-US&quot;,{timeZone:&quot;America/Toronto&quot;})}&lt;/span&gt;
    &lt;/section&gt;
    &lt;section&gt;
        &lt;h1&gt;Asia/Seoul&lt;/h1&gt;
        &lt;span&gt;It is {new Date().toLocaleString(&quot;ko-KR&quot;,{timeZone:&quot;Asia/Seoul&quot;})}&lt;/span&gt;
    &lt;/section&gt;
&lt;/section&gt;</code></pre><p>,document.querySelector(&#39;#root&#39;));
}</p>
</li>
</ul>
<p>setInterval(tick,1000);</p>
<pre><code>
  - 궂이 이걸 쓰는게 무슨 이득이 있나? 
    - 자바스크립트 : 행위만 신경
    - react : ui+행위
    - react는 component 기반으로 이루어져있다.
      - ui별로 component 단위로 나누어서 구현할 수 있다.</code></pre><p>function Clock(){
    return <section>
                <h1>America/Toronto</h1>
                <span>It is {new Date().toLocaleString(&quot;en-US&quot;,{timeZone:&quot;America/Toronto&quot;})}</span>
        </section>;
}</p>
<p>function tick(){</p>
<pre><code>ReactDOM.render(
    &lt;section&gt;
        &lt;h1&gt;세계 시간&lt;/h1&gt;

        &lt;Clock /&gt;
        &lt;Clock /&gt;
    &lt;/section&gt;

,document.querySelector(&#39;#root&#39;));</code></pre><p>}</p>
<p>setInterval(tick,1000);</p>
<pre><code>  - 하나의 ui 모양으로 여러개를 만들고자 한다면?
    - 들어가는 내용만 전달해서 바꿔주는 식으로 사용
    - 불러오는 태그에서는 태그스럽게 값을 전달(속성)
    - 그걸 읽어들이는 함수는 함수스럽게 값을 받음
      - 매개변수명은 props로 하는게 좋음.</code></pre><p>function Clock(props){
    let time = new Date().toLocaleString(props.locale,{timeZone:props.timeZone});
    return <section>
                <h1>{props.timeZone}</h1>
                <span>It is {time}</span>
        </section>;
}</p>
<p>function tick(){</p>
<pre><code>ReactDOM.render(
    &lt;section&gt;
        &lt;h1&gt;세계 시간&lt;/h1&gt;
        &lt;hr /&gt;
        &lt;Clock locale=&quot;en-US&quot; timeZone=&quot;America/Toronto&quot;/&gt;
        &lt;hr /&gt;
        &lt;Clock locale=&quot;ko-KR&quot; timeZone=&quot;Asia/Seoul&quot;/&gt;
    &lt;/section&gt;

,document.querySelector(&#39;#root&#39;));</code></pre><p>}</p>
<p>setInterval(tick,1000);</p>
<pre><code>  - 조금 더 객체지향스럽게 class로 component 정의하기
    - 생성자 유무에 따른 차이
      - 생성자를 직접 생성 : props를 인자로 받아 직접 사용하므로 this 필요없음
      - 생성자를 사용 X : 해당 클래스로 생성된 객체의 속성을 참조해야하므로 해당 객체라는것을 명확히 짚어줘야함. 그래서 this 꼭 써줘야함</code></pre><p>/*
class Clock extends React.Component{//객체지향적인 캡슐화 가능
    #time;
    constructor(props){
        super(props);//필수 무조건 react.Component에 보내줘야함
        this.#time = new Date().toLocaleString(props.locale,{timeZone:props.timeZone});
    }</p>
<pre><code>render(){
    return &lt;section&gt;
            &lt;h1&gt;{this.props.timeZone}&lt;/h1&gt;
            &lt;span&gt;It is {this.#time}&lt;/span&gt;
    &lt;/section&gt;;
}</code></pre><p>}*/</p>
<p>class Clock extends React.Component{//객체지향적인 캡슐화 가능
    render(){
        let time = new Date().toLocaleString(this.props.locale,{timeZone:this.props.timeZone});
        return <section>
                <h1>{this.props.timeZone}</h1>
                <span>It is {time}</span>
        </section>;
    }
}</p>
<pre><code>  - 직접 props를 사용하면 좋은 방법이 아니다.
  - 이를 해결하기 위해 state라는 store(버퍼화된 model)의 개념이 나온다.
    - flux의 순서 : dispatcher &gt; store &gt; view 단방향
  - 변화되는 모든 내용들은 state로 관리
    - state가 처음 생성될 때만 &#39;=&#39;연산자로 값을 넣어줄 수 있음.
    - 그 다음부터는 set을 통해서 데이터를 쌓아가야함
      - 개인적인 생각으로는 마운트 될때만 state를 새로 생성 가능하고, 그 뒤에는 set으로 쌓아줘야하는 것 같음.
      - 마운트는 처음 생성할때만 됨.
  - setInterval을 통해 렌더링이 수행될 때, 처음에는 객체를 생성하지만, 그 뒤에 실행될때는 render() 메소드만 계속 실행된다.
  - 초기화 작업
    - 생성자
      - 메모리에 올라갈때 초기화 
    - 마운트
      - onload시에 초기화
  - State를 왜 쓰나??
    - 데이터를 1way로 효율적으로 관리하기 위해?

### state를 활용한 예제</code></pre><p>class Clock extends React.Component{//객체지향적인 캡슐화 가능
    constructor(props){
        super(props);//필수 무조건 react.Component에 보내줘야함</p>
<pre><code>    let time = new Date().toLocaleString(this.props.locale,{timeZone:this.props.timeZone});
    let timeZone = props.timeZone;

    this.state = {time,timeZone};

}

tick(){
    let time = new Date().toLocaleString(this.props.locale,{timeZone:this.props.timeZone});
    let timeZone = this.props.timeZone;

    this.setState({time,timeZone});
}

componentDidMount(){//mount 된 후
/*
    setInterval(function tick(){
        let time = new Date().toLocaleString(this.props.locale,{timeZone:this.props.timeZone});
        let timeZone = this.props.timeZone;

        this.setState({time,timeZone});
    }.bind(this),1000);
*/
    setInterval(()=&gt;{this.tick();},1000);
}

componentWillUnmount(){//mount 해제 전
    console.log(&quot;will unmount&quot;);
}

render(){
    return &lt;section&gt;
            &lt;h1&gt;{this.state.timeZone}&lt;/h1&gt;
            &lt;span&gt;It is {this.state.time}&lt;/span&gt;
    &lt;/section&gt;;
}</code></pre><p>}</p>
<p>function tick(){</p>
<pre><code>ReactDOM.render(
    &lt;section&gt;
        &lt;h1&gt;세계 시간&lt;/h1&gt;
        &lt;hr /&gt;
        &lt;Clock locale=&quot;en-US&quot; timeZone=&quot;America/Toronto&quot;/&gt;
        &lt;hr /&gt;
        &lt;Clock locale=&quot;ko-KR&quot; timeZone=&quot;Asia/Seoul&quot;/&gt;
    &lt;/section&gt;

,document.querySelector(&#39;#root&#39;));</code></pre><p>}
tick();</p>
<p>```</p>
<ul>
<li>코드 분석<ul>
<li>ReactDOM.render()를 통해 컴포넌트 렌더링</li>
<li>렌더링시 props로 전달한 값을 통해 생성자에서 state 설정.</li>
<li>설정된 state객체 정보를 이용하여 값을 삽입하고 컴포넌트 랜더링</li>
<li>componentDidMount : 컴포넌트가 마운트 된 뒤에 실행되는 메소드 --&gt; 컴포넌트 마운트 후에 state의 변화가 필요할 경우 이 메소드에서 로직을 구현한다.</li>
<li>state의 변화는 setState 메소드를 통해 수행</li>
<li>setState 메소드는 해당 컴포넌트의 re-rendering을 발생시킴</li>
</ul>
</li>
<li>주의사항<ul>
<li>예제와 같이 setInterval에서 setState를 실행시키기 위해서는 해당 컴포넌트의 this를 통해서 실행해야함.</li>
<li>하지만 일반 function으로는 bind 해주지 않으면 해당 컴포넌트 this에 접근이 안됨.</li>
<li>이를 해결하기 위해서는 bind를 해주거나, ES6 Arrow function을 사용해야함.<ul>
<li>arrow function은 함수가 실행될 때 this를 새로 정의하지 않음. 바깥 함수 또는 클래스의 this 값을 사용함.</li>
</ul>
</li>
</ul>
</li>
<li>component, state, attribute</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.18(Web Socket)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2021.01.18Web-Socket</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2021.01.18Web-Socket</guid>
            <pubDate>Mon, 18 Jan 2021 03:30:57 GMT</pubDate>
            <description><![CDATA[<p>오늘은 채팅을 구현하기 위한 web socket을 학습하였습니다.</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>Web Socket</li>
</ul>
<h3 id="web-socket">Web Socket</h3>
<ul>
<li><p>Web Socket URL mapping을 위한 config 클래스 생성
<img src="https://images.velog.io/images/junjun-creator/post/0b851fc0-0d88-419e-acc3-6aa532d9a438/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%EC%A0%84%2011.33.41.png" alt=""></p>
</li>
<li><p>mapping된 소켓을 다루기 위한 Handler 클래스 생성
<img src="https://images.velog.io/images/junjun-creator/post/653be2fb-56d2-477d-a3ab-2a7d2e93862d/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%EC%A0%84%2011.34.46.png" alt=""></p>
</li>
<li><p>간단한 ui 구현
<img src="https://images.velog.io/images/junjun-creator/post/947b6acb-6843-4f4d-8bd3-ac8ed717e634/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%EC%A0%84%2011.36.52.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/5494fc35-7b06-4687-a4c6-f571f79020b2/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%EC%A0%84%2011.37.14.png" alt=""></p>
</li>
<li><p>소켓 연결 설정
<img src="https://images.velog.io/images/junjun-creator/post/613d4803-8f9f-42be-9358-24f59bec1e6f/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%EC%A0%84%2011.37.49.png" alt=""></p>
</li>
<li><p>텍스트만 처리하기 위한 WebSocketHandler 클래스 정의</p>
<ul>
<li>인터페이스를 구현하여 사용하는 것이 아닌 텍스트만을 처리 하기 위한 어댑터를 상속받아 사용함
<img src="https://images.velog.io/images/junjun-creator/post/2c16ae74-47a5-439b-b53e-1f2fecfd4dcd/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%EC%A0%84%2011.43.43.png" alt=""></li>
</ul>
</li>
<li><p>접속 인원이 여러명일때?</p>
<ul>
<li>각 세션을 모두 가지고 있는 상태로 메시지를 다루어야한다.</li>
<li>thread에 안전하고, thread lock기능을 내포하고 있는 arraylist 사용<ul>
<li>CopyOnWriteArrayList()
<img src="https://images.velog.io/images/junjun-creator/post/152e7910-9ecb-4653-86ae-96b2f1fc40f3/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%EC%A0%84%2011.53.03.png" alt=""></li>
</ul>
</li>
</ul>
</li>
<li><p>json형식으로 메시지 데이터 전송</p>
<ul>
<li>서버에서 json파일을 처리 또는 미러링
<img src="https://images.velog.io/images/junjun-creator/post/d9a1d37c-0cb0-4199-bb2c-7efe6c605e5f/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-18%20%EC%98%A4%ED%9B%84%2012.22.55.png" alt=""></li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.15(MVC & FLUX)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2021.01.15MVC-FLUX</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2021.01.15MVC-FLUX</guid>
            <pubDate>Fri, 15 Jan 2021 13:29:07 GMT</pubDate>
            <description><![CDATA[<p>오늘은 웹 프론트 개발에 있어서 다양한 framework들을 살펴보았습니다.</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>Front-end Framework 필요성</li>
<li>MVC &lt;&gt; FLUX</li>
<li>Vue</li>
<li>React</li>
</ul>
<h3 id="front-end-framework-필요성">Front-end Framework 필요성</h3>
<ul>
<li><p>promise를 활용한 Ajax 통신</p>
<ul>
<li>결과로 promise 객체를 반환함. =&gt; then()을 활용하여 데이터 조작 가능
<img src="https://images.velog.io/images/junjun-creator/post/61173e85-406f-4435-b6ee-fc4c2c713d5e/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-15%20%EC%98%A4%EC%A0%84%2010.18.56.png" alt=""></li>
</ul>
</li>
<li><p>json 데이터 뽑아내기
<img src="https://images.velog.io/images/junjun-creator/post/35104753-6307-4017-8641-f419395f7c2f/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-15%20%EC%98%A4%EC%A0%84%2010.21.47.png" alt=""></p>
</li>
<li><p>Ajax를 통한 페이지 전환
<img src="https://images.velog.io/images/junjun-creator/post/862db31f-0a5e-47aa-a8d6-8986aeddc842/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-15%20%EC%98%A4%EC%A0%84%2010.53.48.png" alt=""></p>
</li>
<li><p>중복이 너무 많다... 해결할 방법은?</p>
<ul>
<li>AngularJS(MISKO)</li>
<li>ajax를 통해 가져온 데이터를 DOM 조작할 때 많은 코드라인이 중복이 됨. 이를 해결하기위해 등장</li>
<li>MVW(Whatever) 라고 불리움</li>
<li>노드를 조작하는 코드를 제거할 수 있다.</li>
</ul>
</li>
<li><p>프론트 영역에서 MVC 패턴으로 구현하자!</p>
</li>
</ul>
<h3 id="mvc--flux">MVC &lt;&gt; FLUX</h3>
<ul>
<li>mvc : 양방향<ul>
<li>개발자는 모델까지만 신경쓰고 작업하면 됨.</li>
<li>사용자가 view에 변화를 주면 그 view의 변화가 model의 변화를 가져오고, controller는 model의 변화를 인지할 수 있다.</li>
<li>angular,vue</li>
</ul>
</li>
<li>flux : 단방향<ul>
<li>action -&gt; dispatcher -&gt; store -&gt; view</li>
<li>view의 변화가 stort을 직접 변경시키지 않음</li>
<li>view의 변화는 새로운 action을 낳음(throw)</li>
<li>store의 저장소가 다 소진되면 다음 store가 진행되는 방식으로 충돌이 생기지 않음.</li>
<li>react</li>
</ul>
</li>
</ul>
<h3 id="vue">Vue</h3>
<ul>
<li>mvc 패턴 구현</li>
<li>DOM 조작을 직접 할 필요 없음.
<img src="https://images.velog.io/images/junjun-creator/post/d374be7b-4443-458a-a029-e0ff22b5f5e6/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-15%20%EC%98%A4%ED%9B%84%203.23.31.png" alt=""></li>
</ul>
<h3 id="react">React</h3>
<ul>
<li><p>Flux</p>
</li>
<li><p>Virtual DOM : render
<img src="https://images.velog.io/images/junjun-creator/post/08d674ce-d492-484b-b947-c875a8becf88/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-15%20%EC%98%A4%ED%9B%84%204.07.11.png" alt=""></p>
<ul>
<li>render로 삽입할때, html 태그 사용하기<ul>
<li>babelJS 사용
<img src="https://images.velog.io/images/junjun-creator/post/1faf38e7-1d8b-4dbc-8914-2d3a77b60c92/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-15%20%EC%98%A4%ED%9B%84%204.17.06.png" alt=""></li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.14(Spring Boot-상세페이지)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2021.01.14Spring-Boot-%EC%83%81%EC%84%B8%ED%8E%98%EC%9D%B4%EC%A7%80</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2021.01.14Spring-Boot-%EC%83%81%EC%84%B8%ED%8E%98%EC%9D%B4%EC%A7%80</guid>
            <pubDate>Thu, 14 Jan 2021 07:27:58 GMT</pubDate>
            <description><![CDATA[<p>오늘은 spring boot 상세페이지 작성을 학습하였습니다.</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>detail page</li>
</ul>
<h3 id="detail-페이지-controller">detail 페이지 controller</h3>
<ul>
<li><p>상세 페이지에 사용할 모델 저장하기</p>
<ul>
<li>get()<ul>
<li>상세 페이지에 표현할 아이템</li>
</ul>
</li>
<li>getPrev()<ul>
<li>이전글 정보</li>
</ul>
</li>
<li>getNext()<ul>
<li>다음글 정보
<img src="https://images.velog.io/images/junjun-creator/post/d8eeb14c-f41c-4ab3-817d-a27cf3616950/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-14%20%EC%98%A4%ED%9B%84%203.27.14.png" alt=""></li>
</ul>
</li>
</ul>
</li>
<li><p>쿼리문 작성(mapper)</p>
<ul>
<li>get, getPrev, getNext<ul>
<li>getPrev : 이전글. 즉, 현재 날짜보다 이전에 적혀진 글 중에서 최 상단에 있는 글을 뽑으면 됨</li>
<li>getNext : 다음글. 즉, 현재 날짜보다 다음에 적혀진 글 중에서 최 하단에 있는 글을 뽑으면 됨<ul>
<li>최하단의 글을 뽑는 방법 : 정렬을 뒤집어서 최상단을 뽑으면 됨</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/83717fb3-1381-473a-accd-e87e225f5e93/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-14%20%EC%98%A4%ED%9B%84%203.29.21.png" alt=""></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.13(ES6-Modal)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2021.01.13ES6-Modal</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2021.01.13ES6-Modal</guid>
            <pubDate>Wed, 13 Jan 2021 03:41:29 GMT</pubDate>
            <description><![CDATA[<p>오늘은 modal 페이지를 만들어보았습니다.</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>Modal</li>
</ul>
<h3 id="modal">Modal</h3>
<ul>
<li>alert, confirm과 같은 창을 window가 아닌 새롭게 디자인한 modal 페이지로 만들고자 한다.</li>
<li>한번 만들어두면 재사용하기 쉽게 만들 예정</li>
</ul>
<h3 id="클래스-객체-생성을-통한-modal-box-생성">클래스 객체 생성을 통한 modal box 생성</h3>
<ul>
<li><p>modal box 생성을 위한 클래스 정의</p>
<p><img src="https://images.velog.io/images/junjun-creator/post/6b9bba4f-e8af-4114-8844-aa1aef24977b/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%EC%A0%84%2010.30.10.png" alt=""></p>
</li>
<li><p>정의된 클래스로 객체 생성 후 modal box 생성</p>
<p><img src="https://images.velog.io/images/junjun-creator/post/b2257605-3734-4029-8435-efa9fe2f22e6/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%EC%A0%84%2010.31.15.png" alt=""></p>
</li>
</ul>
<h3 id="클래스의-전역함수를-통한-modal-box-생성">클래스의 전역함수를 통한 modal box 생성</h3>
<ul>
<li><p>constructor와 클래스 내부의 공통분모들을 제거하고, 필요한 기능만을 제공</p>
</li>
<li><p>클래스 정의</p>
<p><img src="https://images.velog.io/images/junjun-creator/post/27a8b3a4-bf6b-4480-9c95-65443387f85f/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%EC%A0%84%2010.33.57.png" alt=""></p>
<ul>
<li>클래스의 static 메소드 호출을 통한 modal box 생성</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/90bb3b2c-4223-4801-9d0f-3b5c382f6e5e/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%EC%A0%84%2010.35.16.png" alt=""></p>
</li>
</ul>
<h3 id="modal-box-확인취소-버튼-기능">modal box 확인/취소 버튼 기능</h3>
<ul>
<li><p>modal box가 열리자마자 값을 리턴하게 하면 안됨</p>
</li>
<li><p>그렇다고 결과를 받기까지 메인 스레드를 멈출 수도 없음</p>
</li>
<li><p>버튼을 누른 뒤에 결과를 활용하기 위해 callback함수를 전달하고, 완료 후에 전송된 callback을 실행하는 방법을 사용한다.</p>
<ul>
<li>promise를 활용하자!</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/f917b14a-8474-455a-bbc6-87d09bcffee7/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%EC%A0%84%2010.56.58.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/27182580-c2c7-4472-bd82-fe2c69675d99/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%EC%A0%84%2010.57.20.png" alt=""></p>
</li>
</ul>
<h3 id="modal-box-등장-effect-부여">Modal box 등장 effect 부여</h3>
<ul>
<li><p>뒷배경이 서서히 어두워지게 하기</p>
<ul>
<li>자바스크립트는 실행시 동일 속성들을 모두 모아서 뒤에 적용된 아이만을 실행하는 특성이 있다.</li>
<li>예를들어 같은 함수를 호출하는 경우 내용이 같은건 덮어 씌우기 해서 한번에 실행해버림.<ul>
<li>setTimeout에 시간을 설정하지 않으면 비동기적으로 연결을 끊어서 서로 다르게 작동하게 만들 수 있음
<img src="https://images.velog.io/images/junjun-creator/post/e57f3895-951c-49b4-91ca-8d279bb7246a/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%EC%A0%84%2011.10.19.png" alt=""></li>
<li>이 경우에 먼저 위의 set 함수를 실행하고, opacity가 transition을 가지고 변경된다.</li>
</ul>
</li>
</ul>
</li>
<li><p>뒷배경이 어두워진 뒤에 modal box 나타나게 하기</p>
<ul>
<li><p>배경의 transition이 종료된 후에 나타나게 만들기</p>
<ul>
<li>addEvent : transitionend</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/7b9a2a03-c657-4c30-8f9e-ee05a0a3926a/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%EC%A0%84%2011.14.32.png" alt=""></p>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.11~2021.01.14(ES6-Drag&Drop)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2021.01.11ES6-dragdrop</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2021.01.11ES6-dragdrop</guid>
            <pubDate>Mon, 11 Jan 2021 03:37:12 GMT</pubDate>
            <description><![CDATA[<p>오늘은 ES6 Drag&amp;Drop 시간입니다</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>Drag and Drop</li>
<li>Upload를 위한 Drag Drop 박스</li>
</ul>
<h3 id="drag-and-drop">Drag and Drop</h3>
<p><img src="https://images.velog.io/images/junjun-creator/post/6ae09106-00e3-42c9-9fd2-a89d19e738ea/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-11%20%EC%98%A4%EC%A0%84%2010.53.31.png" alt=""></p>
<ul>
<li><p>드래그 드랍을 위한 박스 2개 만들고, 마우스가 큰 박스 안에서 움직일때 작은박스가 커서와 함께 움직이도록 이벤트 달아주기</p>
<p><img src="https://images.velog.io/images/junjun-creator/post/86e5a022-86c1-4dc2-b43e-f7fe7b21f564/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-11%20%EC%98%A4%EC%A0%84%2010.54.00.png" alt=""></p>
</li>
<li><p>클릭시에만 작은 상자가 커서를 따라다니도록 설정</p>
<p><img src="https://images.velog.io/images/junjun-creator/post/de16bf53-da04-42ff-a3b5-83fa58a008ae/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-11%20%EC%98%A4%EC%A0%84%2010.55.06.png" alt=""></p>
</li>
<li><p>상자에서 클릭한 위치 유지한채 드래그 하게 설정하기</p>
<ul>
<li>offset활용(이벤트 객체)</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/625c0fa0-dd00-435b-a6f7-2d958964434b/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-11%20%EC%98%A4%EC%A0%84%2011.27.46.png" alt=""></p>
</li>
<li><p>스크롤바 내릴 시, 스크롤바 만큼 위치가 달라지는 문제 해결 방법</p>
<ul>
<li>큰 컨테이너 안에서 상대위치 사용하기</li>
<li>천테이너의 offset 위치를 얻어서 box위치를 추가 보정하는 방법</li>
<li>첫번째 방식으로 해결해보자.</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/d369aad2-b86e-41b6-9b5b-12c3da9f0762/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-12%20%EC%98%A4%EC%A0%84%2010.34.27.png" alt=""></p>
</li>
<li><p>컨테이너가 2개 이상일 때 박스 선택에 따른 드래그 설정</p>
<p><img src="https://images.velog.io/images/junjun-creator/post/f91b1c0e-a7d0-4311-aa8b-85b7c3b8a792/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-12%20%EC%98%A4%EC%A0%84%2010.35.31.png" alt=""></p>
</li>
</ul>
<h3 id="재사용가능한-캡슐화">재사용가능한 캡슐화</h3>
<p><img src="https://images.velog.io/images/junjun-creator/post/a2106459-e225-47c2-83b1-e64de309b049/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-12%20%EC%98%A4%EC%A0%84%2011.11.01.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/eeff12a5-bc9c-4b99-b90a-178adbe67a78/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-12%20%EC%98%A4%EC%A0%84%2011.11.10.png" alt=""></p>
<ul>
<li><p>주의사항</p>
<ul>
<li>외부에서 내부 this값을 사용하려 할때는 this를 전달해줘야함.</li>
<li>현재 예시에서는 mouseHandler()가 호출될때 this가 무엇인지를 모름. 그래서 그걸 알려줘야함<ul>
<li>bind(this)</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/2b9e3582-5227-49fe-b369-414ce2c1c53b/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-12%20%EC%98%A4%EC%A0%84%2011.31.18.png" alt=""></p>
</li>
</ul>
<h3 id="upload를-위한-drag-drop-박스">Upload를 위한 Drag Drop 박스</h3>
<ul>
<li><p>HTML 드래그 앤 드롭 API</p>
</li>
<li><p>사용자로부터 입력을 받기 위한 행위이다.</p>
<p><img src="https://images.velog.io/images/junjun-creator/post/9aebc409-9bc7-402e-8126-15bf7bebd458/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%EC%A0%84%2011.31.25.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/4bfff3cb-038a-44c4-b2a6-ff5fa5260f51/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%EC%A0%84%2011.34.05.png" alt=""></p>
</li>
<li><p>드래그 해오는 파일의 정보</p>
<ul>
<li>e.dataTransfer</li>
<li>이 정보를 통해 드래그 파일이 적합한지 유무 검사 가능</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/e8388c3a-00df-44ab-9b0d-e95a4d633b82/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%ED%9B%84%2012.04.30.png" alt=""></p>
</li>
<li><p>파일 전송을 위한 ajax</p>
<ul>
<li><p>form태그에서 사용하던 multipart로 파일 전송하기</p>
<ul>
<li>직접적으로 form태그를 사용하는것이아니기 때문에 api사용<ul>
<li>FormData API
<img src="https://images.velog.io/images/junjun-creator/post/1f44ef43-5277-4231-8435-cc54f05adb41/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%ED%9B%84%2012.35.39.png" alt=""></li>
</ul>
</li>
</ul>
</li>
<li><p>서버단에서 전송한 formData 처리하기</p>
<ul>
<li>MultipartFile객체를 통해 FormData로 전송한 파일들을 읽어오기
<img src="https://images.velog.io/images/junjun-creator/post/97331e98-0c71-461e-9bd6-9bed684687af/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%ED%9B%84%2012.36.55.png" alt=""></li>
</ul>
</li>
<li><p>전송 진척도 출력하는 코드 작성하기</p>
<ul>
<li>request.upload.addEventListener(&quot;progress&quot;)
<img src="https://images.velog.io/images/junjun-creator/post/52af4fbd-936a-4479-ab2c-d33ae49a9d9a/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-14%20%EC%98%A4%EC%A0%84%2010.12.10.png" alt=""></li>
</ul>
</li>
<li><p>전송파일 최대 크기 설정방법</p>
<ul>
<li>개별 최대 크기, 전체 최대 크기 설정</li>
<li>resources/application.properties
<img src="https://images.velog.io/images/junjun-creator/post/cf7b43e6-4e2d-4b0c-a40d-a7d1283e48a6/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-14%20%EC%98%A4%EC%A0%84%2010.18.08.png" alt=""></li>
</ul>
</li>
<li><p>전송정보 출력하기</p>
<ul>
<li>status
<img src="https://images.velog.io/images/junjun-creator/post/519cc352-e357-4f2b-8621-7a24ae225fbf/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-14%20%EC%98%A4%EC%A0%84%2010.15.10.png" alt=""></li>
</ul>
</li>
<li><p>서버로 전송된 파일 저장</p>
<ul>
<li>파일 전송 경로 설정</li>
<li>전송 경로의 realPath 설정</li>
<li>해당 경로의 존재 유무 파악<ul>
<li>존재하지 않을 시 생성</li>
</ul>
</li>
<li>업로드 될 파일위치 설정</li>
<li>업로드 될 파일 위치 설정 후 해당 경로로 File객체 생성</li>
<li>클라이언트로부터 전송된 파일을 uploadedFile로 저장
<img src="https://images.velog.io/images/junjun-creator/post/4750a8a5-d6aa-4ac3-823b-2897ef7a1130/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-14%20%EC%98%A4%EC%A0%84%2011.07.57.png" alt=""></li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.08~2021.01.13(Spring Boot-pager)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2020.01.08Spring-Boot-8</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2020.01.08Spring-Boot-8</guid>
            <pubDate>Fri, 08 Jan 2021 07:29:09 GMT</pubDate>
            <description><![CDATA[<p>오늘은 Spring Boot로 pager기능을 넣어보는 시간입니다.</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>검색기능 + 페이저</li>
</ul>
<h3 id="검색기능">검색기능</h3>
<ul>
<li>queryString과 기본값을 통한 검색<ul>
<li>기본값 설정을 통해 값이 전달되지 않아도 정상적인 쿼리를 실행할 수 있도록 세팅</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/db9f409c-3af5-4aa1-92b5-824032c71f74/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%ED%9B%84%203.23.43.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/4ab9a52c-b9bf-4807-97d1-1f3dc9adec9f/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%ED%9B%84%203.24.21.png" alt=""></p>
<ul>
<li>기본값을 사용하지 않고, MyBatis가 제공하는 조건절을 사용하여 쿼리 수행하기<ul>
<li>전달된 값이 없는데도 궂이 기본값을 통해서 조회하는 일을 방지</li>
<li>Dynamic Query( 동적 쿼리 )</li>
<li>이럴경우 requestParam으로 값을 받는것이 required=false가 되야한다. (default가 true라서 필수)</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/d5add0a5-ee7b-4b2d-ac12-1a452dd58e0b/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%ED%9B%84%203.54.38.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/92763e0a-5df2-42f8-9948-e3dd6a7f867e/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%ED%9B%84%203.54.49.png" alt=""></p>
<ul>
<li>검색카테고리가 많은 경우 &lt;where&gt;를 사용하여 발생될 수 있는 문제들을 해결할 수 있다<ul>
<li>where만 남겨지는 문제</li>
<li>where and 와 같은 쿼리가 되는 문제</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/7200a031-8cf0-4cde-9465-1249af461a64/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%ED%9B%84%203.59.58.png" alt=""></p>
<h3 id="페이저">페이저</h3>
<ul>
<li>전체 페이지 수 불러오기</li>
<li>Math.ceil(count/size);</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/352a9bb2-200f-4505-b0b7-1b813a7ad65f/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-11%20%EC%98%A4%ED%9B%84%203.52.42.png" alt=""></p>
<ul>
<li>검색어 유지하면서 페이지 이동</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/8dc3fb74-e944-4438-8020-6e6176a4fbfc/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%ED%9B%84%203.50.10.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/e67bedec-32c7-41fc-b1dc-9190da3302d1/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%ED%9B%84%203.50.50.png" alt=""></p>
<ul>
<li>다음, 이전페이지</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/687ec5b1-5a65-4297-a033-27c69158dd2f/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%ED%9B%84%204.39.50.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/eed3815b-68ab-4496-8785-fbff18cb794e/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%ED%9B%84%204.40.02.png" alt=""></p>
<ul>
<li>페이저 갯수 max 페이지까지만 출력하게 하기</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/9582824f-e1aa-43a1-acab-80eb2eb44477/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-13%20%EC%98%A4%ED%9B%84%204.42.51.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.07(Spring Boot-7)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2020.01.07Spring-Boot-7</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2020.01.07Spring-Boot-7</guid>
            <pubDate>Thu, 07 Jan 2021 07:28:10 GMT</pubDate>
            <description><![CDATA[<p>오늘은 Spring Boot 7번째 시간입니다.</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>xml방식의 MyBatis rowMapping</li>
</ul>
<h3 id="xml방식의-mybatis-rowmapping">xml방식의 MyBatis rowMapping</h3>
<ul>
<li>2가지 방법<ul>
<li>select문에서 별칭사용하기</li>
<li>resultMap 사용하기(resultMap 정의하고 resultType대신 사용)</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/3c17b65b-37d4-4764-a3b6-0abc89c03a8a/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-07%20%EC%98%A4%ED%9B%84%202.43.29.png" alt=""></p>
<h3 id="날짜-포맷">날짜 포맷</h3>
<p><img src="https://images.velog.io/images/junjun-creator/post/cc621a7b-a2d3-44b6-9e90-0ed53ba8b333/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-07%20%EC%98%A4%ED%9B%84%202.48.58.png" alt=""></p>
<h3 id="view-만들기">View 만들기</h3>
<ul>
<li>view entity와 데이터베이스 컬럼을 mapping시켜서 세팅해주면 됨</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/40f225ad-3d27-4a65-9509-5df6680c122b/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-07%20%EC%98%A4%ED%9B%84%203.03.05.png" alt=""></p>
<ul>
<li>MyBatis는 오버로드를 지원하지 않음<ul>
<li>인자가 가장 많은 메소드를 구현하고, 나머지는 구현된 메소드를 기본값으로 채워서 사용하는 방식으로 활용</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/b35c8696-e560-4707-bba9-e2dd2de849f2/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-07%20%EC%98%A4%ED%9B%84%203.49.20.png" alt=""></p>
<ul>
<li><p>그렇다면 전달된 인자는 어떻게 MyBatis에서 읽어들이는것인가?</p>
<ul>
<li><p>RTTI Reflection</p>
<ul>
<li>객체의 메모리(class)를 통해 객체의 상태(정보)를 얻어오는 것<ul>
<li>.class 또는 getClass()</li>
</ul>
</li>
</ul>
</li>
<li><p>파라미터 이름 &gt; getter</p>
<ul>
<li>객체로 파라미터가 전달 될 때에는 getter를 통해 인식하게 된다.</li>
<li>전달되는 이름은 AA, BB이지만 이는 사실 getAA, getBB로 인식</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/2f903236-4e54-4072-92d3-33968c88dad5/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-07%20%EC%98%A4%ED%9B%84%204.06.28.png" alt=""></p>
<ul>
<li>하지만 우리는 이것을 약속처럼 param1,2,...으로 사용할 수 있다.</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/34ad9c10-6499-4a29-9f47-df2607b974cb/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-07%20%EC%98%A4%ED%9B%84%204.05.09.png" alt=""></p>
</li>
</ul>
<h3 id="querystring을-이용한-페이저-만들기">QueryString을 이용한 페이저 만들기</h3>
<ul>
<li>queryString을 이용한 파라미터 전달 및 컨트롤러 적용<ul>
<li>@RequestParam(name=&quot;전달된 변수명&quot;, defaultValue=&quot;초기값&quot;) Integer 사용할변수명</li>
<li>Request로 전달된 파라미터를 꺼내는 방법이다.</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/ad09136d-ad2d-4b1a-b5c1-a4457bc1d478/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-07%20%EC%98%A4%ED%9B%84%204.26.07.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.07~2021.01.08(ES6-7,8)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2020.01.07ES6-7</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2020.01.07ES6-7</guid>
            <pubDate>Thu, 07 Jan 2021 03:24:11 GMT</pubDate>
            <description><![CDATA[<p>ES6 7번째 시간입니다.</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>async, await</li>
<li>promise - then, catch</li>
<li>ES Module</li>
</ul>
<h3 id="async-await">async, await</h3>
<ul>
<li>비동기로 수행되는 함수를 호출하면서 동기적으로 일을 수행하고 싶을때(얼마 안걸릴거같으니 비동기 끝나면 다음거 수행하자) await 키워드를 통해 기다리게 할 수 있다.</li>
<li>이 await를 사용하기 위해서는, 해당 비동기 함수를 호출하는 함수가 비동기형이라는것을 명시해줘야한다(async)</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/3f6dc6d7-ff2f-4382-814d-a71c3b08be20/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-07%20%EC%98%A4%EC%A0%84%209.53.11.png" alt=""></p>
<h3 id="promise-then">promise-then</h3>
<ul>
<li>then(func1,func2)를 통해 각각 resolve와 reject 결과로 실행 되게끔 해주면 된다.</li>
<li>성공과 실패시 각각 인자로 전달된 함수가 실행된다.</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/6c450426-9c9b-4a48-ba4c-7561c6c19b65/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-07%20%EC%98%A4%EC%A0%84%2010.12.59.png" alt=""></p>
<ul>
<li>꼬리에 꼬리를 무는 then<ul>
<li>then을 활용하여 변환코드, 분쇄코드, 인코딩 코드 등을 수행하고, 그 결과를 출력하는 로직을 만들 수 있다.</li>
<li>then을 통해 수행된 결과를 다음 then에게 return으로 넘겨주게 되면, 그 결과를 then으로 호출되는 함수의 인자로 전달한다.</li>
<li>만일 리턴값이 또다른 비동기함수를 호출할 경우, 또다시 promise를 통해 성공 또는 실패에 따라 해당 함수가 실행된다.</li>
<li>에러(예외)를 반환할 경우, 그 다음 then은 reject가 실행되며, catch가 있다면 catch가 실행된다.</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/76cac706-891f-489b-9d13-c8c6b0fbbf8f/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-07%20%EC%98%A4%EC%A0%84%2010.21.47.png" alt=""></p>
<ul>
<li>then이 리턴이 없다면<ul>
<li>undefined value를 가지고 then을 resolve</li>
</ul>
</li>
</ul>
<h3 id="promise-all">promise all</h3>
<ul>
<li>여러개의 비동기 처리를 한번에 수행하고 싶을때 사용<ul>
<li>모두 성공해야 then(resolve) 실행</li>
<li>하나라도 reject 되면 then(reject)실행</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/24c75c7a-5710-4e9e-8a83-498f63ace957/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%EC%A0%84%2010.58.50.png" alt=""></p>
<h3 id="es-module">ES Module</h3>
<ul>
<li>부품 + isolation(고립성)<ul>
<li>다른 부품에 영향을 미쳐선 안됨.</li>
<li>자바스크립트는 어디서든 사용 가능했었음...</li>
</ul>
</li>
<li>모듈을 동적으로 로드하는 방법이 없다.<ul>
<li>load 기능이 생기고, 각 모듈별 충돌을 제어할 수 있는 방법이 생김</li>
<li>그게 바로 ES 모듈</li>
</ul>
</li>
<li>과거버전 모듈 불러오기<ul>
<li>함수이름이 충돌되면 뒤에 불려온 모듈의 함수로 적용됨</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/fcb6e654-adaf-4a60-bb97-a78278ae27f2/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-07%20%EC%98%A4%ED%9B%84%2012.08.54.png" alt=""></p>
<ul>
<li>import<ul>
<li>함수가 한두개도 아니고, 그 함수가 리턴하는것이 다양함.<ul>
<li>단순히 import만을 가지고 함부로 가져다 쓸수 없음(고립화)</li>
</ul>
</li>
<li>허가를 위해서 가져오고자 하는 모듈이 export 설정을 해줘야 함.</li>
<li>import하는 모듈이 html에서 호출될때 type을 모듈이라고 설정해줘야함.</li>
<li>또한 import하고자 하는 모듈의 경로를 절대 또는 상대경로로 꼭 지정해줘야함</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/be0e571a-503f-4ca8-b1f3-5c9db7751a37/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-07%20%EC%98%A4%ED%9B%84%2012.20.17.png" alt=""></p>
<ul>
<li>그렇다면 모듈이 변경되거나, 모듈 내의 다른 함수를 import해오고 싶을 때는 어떻게 해야하나?<ul>
<li>export default, export<ul>
<li>import t1,{test2,test1} from &#39;./module1.js&#39;;</li>
<li>module1.js에서 export default 된 메소드를 t1이라는 이름으로 import.(이름 임의 변경 가능)</li>
<li>module1.js에서 test2,test1이름의 export 함수를 가져옴(이름 임의 변경 불가)<ul>
<li>이름 변경을 위해 as로 명명 해줘야함</li>
<li>import {test as m2test} from &#39;./module2.js&#39;;</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/3f4866b1-d4f0-4511-ad83-0cfcf1c216d6/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%EC%A0%84%2011.29.59.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/66c2559a-d697-4ff2-a6ae-e44f2642d8b3/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%EC%A0%84%2011.30.05.png" alt=""></p>
<ul>
<li>클래스 export &amp; import<ul>
<li>클래스답게 new 생성자를 통해 생성하고 사용할 수 있음</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/c125e7ee-55dd-40d4-9fec-97f902837240/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%EC%A0%84%2011.35.02.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/ab8f10c6-a05a-4907-aee5-b99d3aff3835/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%EC%A0%84%2011.35.09.png" alt=""></p>
<ul>
<li>객체 자체를 노출<ul>
<li>전역객체화</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/c890556e-8896-4205-a7bb-f01010cbacf4/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%EC%A0%84%2011.57.29.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/3ac5e799-288d-4622-bab2-abea37aa5fd5/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%EC%A0%84%2011.57.38.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/ccd629a0-8158-4f43-92e7-c80546eb4706/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%EC%A0%84%2011.57.45.png" alt=""></p>
<ul>
<li>고립화가 아닌 공개scope에 두고 원할때 꺼내 쓸수 있게 끔 하려면<ul>
<li>import는 로드시 무조건 가져오게 되는 것</li>
<li>원할때 특정 모듈을 가져오려면?<ul>
<li>import(&quot;./json.js&quot;) 함수</li>
<li>서버상에 동적으로 데이터를 요청할 수 있음 (ajax없이)<ul>
<li>import(./api/notice/list)</li>
</ul>
</li>
</ul>
</li>
<li>import() 메소드로 호출된 것은 모두 scope에 들어가게 됨.<ul>
<li>고립화가 존재하지 않음.</li>
<li>그저 가져와서 실행하는 것 뿐</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/bd2b90e6-2aee-482f-b0ce-a17af0cad150/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%ED%9B%84%2012.07.18.png" alt=""></p>
<ul>
<li>그렇다면 원하는 함수만 원하는 시점에 가져와서 쓰고싶을 때는 어떻게하나?<ul>
<li>await import();(with async())</li>
<li>기본적으로 import 함수는 비동기형이다.(메인함수를 잠식시킨채로 다른 함수를 가져와서 실행할 수 없으므로)</li>
</ul>
</li>
</ul>
<h3 id="await와-then">await와 then</h3>
<ul>
<li>기본적으로 await와 then을 활용하기 위해서는 함수가 promise객체를 반환해야한다.</li>
<li>async/await를 사용할 경우<ul>
<li>promise가 await에게 넘겨지면 await은 promise가 fulfill되기를 기다렸다가 해당 값(resolve될 값)을 리턴한다.</li>
<li>만약 promise가 reject되면, reject된 값이 throw됨.</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/7afcf905-3265-4e69-bda4-2069aea2b5b8/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%ED%9B%84%201.55.24.png" alt=""><img src="https://images.velog.io/images/junjun-creator/post/f126636e-980f-4f05-ac3d-298ea3769abe/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%ED%9B%84%201.56.52.png" alt=""></p>
<ul>
<li>await는 비동기함수가 실행을 마칠때까지 기다리는 동기화 작업을 한다.</li>
<li>promise가 await에 넘겨지게 되면, resolve또는 rejecte될 값을 반환(또는 throw)하게 된다</li>
<li>이렇게 반환된 값을 then, catch 할 수도 있다.</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/cb854ba3-7255-41c5-aa24-8ff15e58a12f/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-08%20%EC%98%A4%ED%9B%84%202.01.03.png" alt=""></p>
<ul>
<li>결론<ul>
<li>await는 비동기함수가 실행을 마칠때까지 기다린다.</li>
<li>await를 통해 resolve될 값(객체 등)을 반환 받을 수 있다.</li>
<li>then은 promise를 통해서 비동기적으로 값을 반환 받고 그 반환된 값을 이용하고자 할 때 사용한다.</li>
<li>비동기함수의 결과를 사용하기 위해 기존에는 함수를 인자로서 전달하여 위임하는 방식으로 비동기 결과를 통해 얻은 것을 비동기 함수 내에서 사용하곤 했다.</li>
<li>위임을 하는것이 아닌 그 비동기 결과가 나온 뒤에 그 값을 이용하여 어떤 함수를 처리하고자 할때, Promise/then을 사용하는 것이다.</li>
<li>결국, then과, await 모두 비동기 함수 실행결과를 return 받는것은 동일하나, await은 값의 형태로 전달 받고, then은 resolve(또는 reject) 함수의 인자로 전달 받는 차이가 있다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.06(Spring Boot-6)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2020.01.06Spring-Boot-6</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2020.01.06Spring-Boot-6</guid>
            <pubDate>Wed, 06 Jan 2021 08:59:49 GMT</pubDate>
            <description><![CDATA[<p>오늘은 Spring Boot 6번째 시간입니다</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>PathVariable</li>
<li>MyBatis - xml 활용</li>
<li>의존성 주입(DI) 3가지 방법</li>
</ul>
<h3 id="pathvariable">PathVariable</h3>
<ul>
<li>queryString을 사용하지 않고, 값으로 경로를 바로 지정할 수 있다.</li>
<li>매핑은 @RequestMapping(&quot;{id}&quot;) 과같은 방식으로 설정한다<ul>
<li>함수내에서는 id라는 이름으로 전달된 pathvariable 값을 사용하기 위해 이름을 일치시켜야한다</li>
<li>@PathVariable(&quot;id&quot;) Integer id</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/1f59f14a-4fe2-4f6e-90c3-0ad0512dc1b2/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-06%20%EC%98%A4%ED%9B%84%203.34.53.png" alt=""></p>
<h3 id="mybatis---xml-활용">MyBatis - xml 활용</h3>
<ul>
<li>인터페이스에 어노테이션을 덕지덕지 붙여서 구현하는것이 간편하고 좋지만, 만약 MyBatis가 아닌 JDBC를 함께 이용할 경우 해당 인터페이스를 따로 구현해야하고, @Mapper 어노테이션과 같은 MyBatis설정을 다 제거해줘야한다.</li>
<li>또한, 인터페이스 함수가 많고, select구문이 복잡해질 경우 코드가 난잡해진다.</li>
<li>그래서 인터페이스를 분리 시켜서 구현하는 방법을 쓰기도 한다.<ul>
<li>xml에 sql과 인터페이스 함수를 매핑 하는 정보를 저장하는 방식</li>
</ul>
</li>
<li>xml 설정 방법<ul>
<li>namespace : 구현할 인터페이스 경로 지정</li>
<li>resultMap : 컬럼과 엔티티의 속성 매핑 정보 저장</li>
<li>select id : 구현하고자 하는 인터페이스 함수명</li>
</ul>
</li>
<li>xml 장점<ul>
<li>쿼리 수정이 쉬움</li>
<li>쿼리가 아무리 길어도 텍스트형식으로 작성되므로 쉬움</li>
<li>인터페이스를 따로 분리시켜둘수 있어서 본래의 취지에 맞음</li>
</ul>
</li>
<li>xml 단점<ul>
<li>인터페이스 함수명, 리턴타입 등 수정이 생기면 바꿔야 할 것이 많아짐</li>
</ul>
</li>
<li>@mapper, XML 어떤 방식을 이용하든 MyBatis는 인터페이스 구현체를 저장하고 있는 저장공간을 갖고있음<ul>
<li>저장소 : factory</li>
<li>factory에서 구현체를 가져다 쓸수 있는 도구 : SqlSession<ul>
<li>&#39;나 지금 뭐 필요해&#39; 하면 전달해줌</li>
<li>getMapper(&quot;&quot;) 매퍼를 꺼내서 반환</li>
<li>IoC에 담겨져 있음(MyBatis가 담아둠)</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/06c6ee24-5c04-40f0-b73f-2465aed43a90/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-06%20%EC%98%A4%ED%9B%84%204.58.37.png" alt=""></p>
<ul>
<li>Dao 인터페이스 구현체에서는 매퍼를 통해 구현한 구현체를 session을 통해 반환 받아서 구현해주면 된다.</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/95b6aad4-31fb-465f-9b5f-46dce9843d92/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-06%20%EC%98%A4%ED%9B%84%205.02.59.png" alt=""></p>
<h3 id="의존성-주입di-3가지-방법">의존성 주입(DI) 3가지 방법</h3>
<ul>
<li>Field DI<ul>
<li>멤버변수에서 바로 의존성 주입</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/0bc001b8-61eb-4109-aafa-d6eafa3ace55/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-06%20%EC%98%A4%ED%9B%84%205.44.27.png" alt=""></p>
<ul>
<li>Setter DI<ul>
<li>setter 메소드에서 의존성 주입</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/b4c54430-50d6-4826-a0f7-9eb75a087a91/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-06%20%EC%98%A4%ED%9B%84%205.46.19.png" alt=""></p>
<ul>
<li>Constructor DI<ul>
<li>생성자에서 의존성 주입</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/43339e60-f251-446c-aebb-b91eb4848292/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-06%20%EC%98%A4%ED%9B%84%205.48.10.png" alt=""></p>
<ul>
<li>Autowired는 의존성 주입을 위한 Spring이 제공하는 기능이다.</li>
<li>의존성 주입을 위해 IoC에서 해당 객체를 알아서 탐색하고 의존성 주입을 하게된다.</li>
<li>이때, spring은 mybatis가 IoC에 넣어둔 SqlSession 객체를 찾아서 DI를 해준다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL(Web)-2021.01.06(ES6-6)]]></title>
            <link>https://velog.io/@junjun-creator/TILWeb-2020.01.06ES6-6</link>
            <guid>https://velog.io/@junjun-creator/TILWeb-2020.01.06ES6-6</guid>
            <pubDate>Wed, 06 Jan 2021 04:37:13 GMT</pubDate>
            <description><![CDATA[<p>오늘은 ES6 6번째 시간입니다</p>
<blockquote>
<h2 id="today-i-learned">Today I Learned</h2>
</blockquote>
<ul>
<li>Symbol</li>
<li>Promise</li>
</ul>
<h3 id="symbol">Symbol</h3>
<ul>
<li>내장 객체 클래스</li>
<li>고유한 값을 생성</li>
<li>왜 만들었나?<ul>
<li>다형성 : 자바스크립트는 태생이 다형성을 갖고있어서 인터페이스를 구현하지 않음</li>
<li>자바스크립트는 함수로 어디든 꽂아서 쓸 수 있음</li>
<li>약속된 &#39;로직을 꽂아서&#39; 사용하기 위해 만듬(인터페이스를 구현하는 목적 처럼)</li>
</ul>
</li>
<li>약속된 로직으로서 인터페이스와 같은 역할을 할 수 있게끔 하기 위해 만듬</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/b1339b6e-7aa5-464a-b8b6-43b2c58b0b50/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-06%20%EC%98%A4%EC%A0%84%2010.26.08.png" alt=""></p>
<ul>
<li>Symbol 정리<ul>
<li>자바스크립트 내에서 마치 라이브러리를 만드는 것 처럼</li>
<li>약속된 함수를 구현해야만 사용할 수 있는 기능이 있다면?</li>
<li>그 약속을 정의하는 것이 Symbol</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/f6990c55-81fd-465b-8289-8dc84effbcf7/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-06%20%EC%98%A4%ED%9B%84%201.25.03.png" alt=""></p>
<h3 id="promise">Promise</h3>
<ul>
<li>자바스크립트는 비동기 작업을 함수의 중첩으로 해결한다.</li>
<li>이것을 콜백 지옥이라고 하는데 이로부터 해방될 방법이 없을까?</li>
<li>이것이 Promise가 등장한 이유이다.</li>
<li>먼저 기존 중첩형식을 보자.</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/253c96bb-47e7-42bb-a635-167ffa6bde96/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-06%20%EC%98%A4%ED%9B%84%201.28.22.png" alt=""></p>
<ul>
<li>마치 DB에서 데이터를 가져오는데 오랜 시간이 걸리는 것 처럼 예제를 만들어주기 위해 비동기 함수인 setTimeout을 사용하였다.<ul>
<li>결과 : &quot;get요청 이루어짐&quot; &gt; &quot;메인 스레드~&quot; &gt; (10초뒤)&quot;공지사항 1&quot; 순서로 실행됨</li>
</ul>
</li>
<li>10초뒤에 콜백함수가 실행되게 하기 위하여 함수 전체를 인자로 전달하고, 함수의 중첩으로 이를 실행하고 있는 모습을 볼 수 있다.</li>
<li>우리는 이를 통해, 인자로 함수를 전달하는 것과, 함수의 중첩을 제거하고 싶은 욕심이 생긴다.</li>
</ul>
<p><img src="https://images.velog.io/images/junjun-creator/post/03c6c0f8-ce35-444b-b442-219c835b1f59/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-01-06%20%EC%98%A4%ED%9B%84%201.32.43.png" alt=""></p>
<ul>
<li>Promise는 비동기작업의 완료(실패)의 결과를 알려주는 객체이다.<ul>
<li>위임함수(인자로 함수가 전달되는것)를 제거 할 수 있다.</li>
</ul>
</li>
<li>비동기 작업 처리 완료시 resolve, 실패시 reject 메소드를 실행하게 되는데, 이는 각각 then,catch로 전달된 함수가 실행된다.</li>
<li>then과 catch를 활용하여 비동기함수들을 연결하여 실행할 수 도 있다.<ul>
<li>then의 결과로 다음 비동기 함수를 return하는 경우, 실행 결과에 따라 그 다음에 위치한 then 또는 catch가 실행된다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>