<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev_jo.log</title>
        <link>https://velog.io/</link>
        <description>To be a better developer!!</description>
        <lastBuildDate>Tue, 21 Feb 2023 08:27:11 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dev_jo.log</title>
            <url>https://velog.velcdn.com/images/dev_jo/profile/142ef638-fb73-4897-9fba-1c2af2b70e72/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dev_jo.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dev_jo" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[SQLP] index range scan이 불가능한 SQL은?]]></title>
            <link>https://velog.io/@dev_jo/SQLP-index-range-scan%EC%9D%B4-%EB%B6%88%EA%B0%80%EB%8A%A5%ED%95%9C-SQL%EC%9D%80</link>
            <guid>https://velog.io/@dev_jo/SQLP-index-range-scan%EC%9D%B4-%EB%B6%88%EA%B0%80%EB%8A%A5%ED%95%9C-SQL%EC%9D%80</guid>
            <pubDate>Tue, 21 Feb 2023 08:27:11 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.youtube.com/watch?v=wK5ROTXK4RE&amp;list=PLlCujDgOz8x4JN2wHKbmlM8bFan-WaKj5&amp;index=21">강의주소</a></p>
<blockquote>
<p>SQLP 문제 </p>
</blockquote>
<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/dev_jo/post/068c48af-5b90-478a-a4c8-9cbace5d703d/image.png" alt="">
emp_idx 인덱스는 deptno, job, ename 컬럼이 결합된 결합 인덱스로 이루어져있다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQLP] 드라이빙, 드리븐 테이블]]></title>
            <link>https://velog.io/@dev_jo/SQLP-%EB%93%9C%EB%9D%BC%EC%9D%B4%EB%B9%99-%EB%93%9C%EB%A6%AC%EB%B8%90-%ED%85%8C%EC%9D%B4%EB%B8%94</link>
            <guid>https://velog.io/@dev_jo/SQLP-%EB%93%9C%EB%9D%BC%EC%9D%B4%EB%B9%99-%EB%93%9C%EB%A6%AC%EB%B8%90-%ED%85%8C%EC%9D%B4%EB%B8%94</guid>
            <pubDate>Tue, 21 Feb 2023 06:00:27 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>드라이빙 테이블</p>
</blockquote>
<h3 id="드라이빙-드리븐-테이블이란">드라이빙, 드리븐 테이블이란</h3>
<p>데이터베이스에서 데이터를 가져올 때, 테이블 엑세스 순서에 따라 성능 차이가 발생하기도 한다.
여기서 두 테이블간의 조인시에 먼저 엑세스 되는 테이블을 드라이빙 테이블이라고 하고, 나중에 엑세스 되는 테이블을 드리븐 테이블 이라고한다.</p>
<p>드라이빙 테이블로 결정되는 것은 INDEX의 존재 및 우선순위 혹은 FROM 절에서의 TABLE 지정순서에 영향을 받으며 어느 TABLE이 먼저 엑세스 되느냐에 따라 속도의 차이가 크게 날 수 있으므로 매우 중요하다.</p>
<ul>
<li>테이블 A가 100건 테이블 B가 100만건인 경우</li>
<li>A 테이블을 드라이빙 시 -&gt; 100번 탐색</li>
<li>B 테이블을 드라이빙 시 -&gt; 100만번 탐색</li>
<li><strong>즉 레코드 수가 적은 테이블을 드라이빙 하는것이 유리하다.</strong></li>
</ul>
<h3 id="드라이빙-테이블-결정-규칙">드라이빙 테이블 결정 규칙</h3>
<p>JOIN이 되는 컬럼 중 한쪽에만 인덱스가 있는 경우 해당 테이블이 드라이빙 테이블이 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQLP] 뷰 머지를 막는 키워드]]></title>
            <link>https://velog.io/@dev_jo/SQLP-%EB%B7%B0-%EB%A8%B8%EC%A7%80%EB%A5%BC-%EB%A7%89%EB%8A%94-%ED%82%A4%EC%9B%8C%EB%93%9C</link>
            <guid>https://velog.io/@dev_jo/SQLP-%EB%B7%B0-%EB%A8%B8%EC%A7%80%EB%A5%BC-%EB%A7%89%EB%8A%94-%ED%82%A4%EC%9B%8C%EB%93%9C</guid>
            <pubDate>Tue, 21 Feb 2023 01:18:15 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.youtube.com/watch?v=n0kFM6Wi2Yc&amp;list=PLlCujDgOz8x4JN2wHKbmlM8bFan-WaKj5&amp;index=18">강의주소</a></p>
<blockquote>
<p>뷰 머지를 막는 키워드</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/dev_jo/post/1349e718-9ee2-45dc-b625-5c25d35674aa/image.png" alt=""></p>
<ul>
<li>ROWNUM</li>
<li>ORDER BY</li>
<li>DISITINCT</li>
<li>GROUP Functions</li>
<li>WINDOW Functions</li>
<li>SET Operator</li>
<li>CONNECT BY</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQLP] SQL Trace]]></title>
            <link>https://velog.io/@dev_jo/SQLP-SQL-Trace-un0cvgmu</link>
            <guid>https://velog.io/@dev_jo/SQLP-SQL-Trace-un0cvgmu</guid>
            <pubDate>Thu, 16 Feb 2023 05:17:44 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.youtube.com/watch?v=5RB-T1a4ztU&amp;list=PLlCujDgOz8x4JN2wHKbmlM8bFan-WaKj5&amp;index=12">강의링크</a></p>
<blockquote>
<p>SQL Trace</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/dev_jo/post/39e6f630-1646-4b99-9b51-4c2c76df6709/image.png" alt=""></p>
<h3 id="trace의-각-항목">Trace의 각 항목</h3>
<p>1) call</p>
<ul>
<li>Parse : SQL문이 파싱되는 단계에 대한 통계 </li>
<li>Execute :  SQL문의 실행단계에 대한 통계 (주로 UPDATE, INSERT, DELETE 문들에 대한 결과가 나타남)</li>
<li>Fetch : SQL문이 실행되면서 Fetch된 통계</li>
</ul>
<p>2) count : Parse, Execute, Fetch 각 단계가 수행된 횟수</p>
<p>3) cpu : Parse, Execute, Fetch에 실제로 사용된 CPU 시간 (0.01초 단위)</p>
<p>4) elapsed : Parse, Excecute, Fetch에 실제로 소요된 시간</p>
<p>5) disk : 디스크에서 읽어 들인 블록 수</p>
<p>6) query : 메모리에서 읽어 들인 블록 수 </p>
<p>7) current : 현재 세션에서 작업한 내용을 commit 하지않아 자신에게만 유효한 dirty blcok 수</p>
<p>8) rows : 각 단계에서 읽거나 변경된 ROW 수 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQLP] SQL을 서로 다르게 인식하는 경우]]></title>
            <link>https://velog.io/@dev_jo/SQLP-SQL%EC%9D%84-%EC%84%9C%EB%A1%9C-%EB%8B%A4%EB%A5%B4%EA%B2%8C-%EC%9D%B8%EC%8B%9D%ED%95%98%EB%8A%94-%EA%B2%BD%EC%9A%B0</link>
            <guid>https://velog.io/@dev_jo/SQLP-SQL%EC%9D%84-%EC%84%9C%EB%A1%9C-%EB%8B%A4%EB%A5%B4%EA%B2%8C-%EC%9D%B8%EC%8B%9D%ED%95%98%EB%8A%94-%EA%B2%BD%EC%9A%B0</guid>
            <pubDate>Thu, 16 Feb 2023 02:16:29 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.youtube.com/watch?v=4olmxQfQAFU&amp;list=PLlCujDgOz8x4JN2wHKbmlM8bFan-WaKj5&amp;index=11">강의링크</a>
<img src="https://velog.velcdn.com/images/dev_jo/post/dde0845e-1d85-4e19-8c57-ed4a0c04c46a/image.png" alt=""></p>
<h3 id="sql을-서로-다르게-인식하는-경우">SQL을 서로 다르게 인식하는 경우</h3>
<ol>
<li>공백 문자 또는 줄 바꿈</li>
<li>대.소문자 구분 </li>
<li>주석 (comment) 작성</li>
<li>테이블의 Owner를 명시한 경우</li>
<li>Hint 사용</li>
<li>WHERE 절에 다른 비교 값을 입력</li>
</ol>
<p>동일한 항목을 조회하더라도 SQL이 서로 다르게 인식되는 경우에는 각 SQL에 대해서 하드파싱이 일어난다.</p>
<h3 id="예제1">예제1</h3>
<p><img src="https://velog.velcdn.com/images/dev_jo/post/11c53690-e1dc-4ece-b2e1-038cc0b693ac/image.png" alt=""></p>
<p>1번, 2번, 3번 쿼리 결과값은 모두 동일하다.
하지만 각각의 쿼리는 다르게 인식되어 각 쿼리마다 하드파싱이 일어난다.
1번 경우 like가 소문자로 작성됬지만, 2번의 경우는 LIKE가 대문자로 작성되어 다르게 인식된다.
3번의 경우 고객조회라는 주석이 작성돼어 다르게 인식된다.</p>
<h3 id="예제2">예제2</h3>
<p><img src="https://velog.velcdn.com/images/dev_jo/post/c1324978-85b1-4aec-bf68-dff8cd56bb86/image.png" alt=""></p>
<p>1) 공백문자 작성으로 다르게 인식된다.
2) 대.소문자 구분으로 인해 다르게 인식된다.
3) 주석 작성으로 인해 다르게 인식된다.
4) 테이블 Owner 명시로 인해 다르게 인식된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQLP] 소프트 파싱, 하드 파싱]]></title>
            <link>https://velog.io/@dev_jo/SQLP-%EC%86%8C%ED%94%84%ED%8A%B8-%ED%8C%8C%EC%8B%B1-%ED%95%98%EB%93%9C-%ED%8C%8C%EC%8B%B1</link>
            <guid>https://velog.io/@dev_jo/SQLP-%EC%86%8C%ED%94%84%ED%8A%B8-%ED%8C%8C%EC%8B%B1-%ED%95%98%EB%93%9C-%ED%8C%8C%EC%8B%B1</guid>
            <pubDate>Thu, 16 Feb 2023 01:59:29 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.youtube.com/watch?v=4olmxQfQAFU&amp;list=PLlCujDgOz8x4JN2wHKbmlM8bFan-WaKj5&amp;index=11">강의링크</a></p>
<blockquote>
<p>소프트 파싱, 하드 파싱</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/dev_jo/post/51093c1f-ad52-49f4-b285-06a0e8459662/image.png" alt=""></p>
<h3 id="sql의-파싱-과정">SQL의 파싱 과정</h3>
<ol>
<li>Syntax Error 확인</li>
<li>Dictionary Cache에서 Object 및 권한 확인</li>
<li>Library Cache에 SQL과 실행계획이 있는지 탐색</li>
<li>SQL과 실행계획이 있는 경우 바로 실행 단계로 넘어간다. (소프트 파싱)</li>
<li>SQL과 실행계획이 없는 경우 SQL 최적화 후 실행 단계로 넘어간다. (하드 파싱)</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spread / Rest 문법 ]]></title>
            <link>https://velog.io/@dev_jo/Spread-Rest-%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@dev_jo/Spread-Rest-%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Thu, 09 Feb 2023 08:37:26 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>객체나 배열 가공을 쉽게 할 수 있도록 도와주는 Spread, Rest 문법을 알아보자</p>
</blockquote>
<h2 id="spread">Spread</h2>
<p>이 문법을 이용하면 객체나 배열을 합치는데 유용하다.
기존 객체를 건드리지않고 새로운 객체를 만들 때 사용한다.</p>
<h3 id="사용예시">사용예시</h3>
<pre><code class="language-javascript">// 객체 사용 예시
let name = {
    name : &#39;hongGilDong&#39;
};

let address = {
    address : &#39;incheon&#39;
};

let user = {
    ...name, 
      ...address, 
      age: 13
}; // Spread 문법으로 객체 합체

console.log(user); // {name: &#39;hongGilDong&#39;, address: &#39;incheon&#39;, age: 13}

// 배열 사용 예시
let number1 = [1,2,3];
let number2 = [4,5,6];

let number3 = [...number1, ...number2]; // Spread 문법으로 배열 합체

console.log(number3); // [1, 2, 3, 4, 5, 6]</code></pre>
<h2 id="rest">Rest</h2>
<p>이 문법을 사용할때 구조 분해 할당 문법이 함께 사용된다.
하나의 배열이나 객체를 둘 이상으로 나누고 싶을 때 사용한다.</p>
<h3 id="사용예시-1">사용예시</h3>
<pre><code class="language-javascript">// 객체 사용 예시
let user = {
    name : &#39;hongGilDong&#39;,
      address : &#39;incheon&#39;,
    age : 13
};

let { name, ...rest1 } = user; // user 객체의 name속성과 그 나머지 속성으로 나눔. 


console.log(name); // hongGilDong
console.log(rest1); // {address: &#39;incheon&#39;, age: 13}

// 배열 사용 예시
let numbers = [1, 2, 3, 4, 5, 6];

let [ number1, ...rest2 ] = numbers; 
// numbers 배열의 첫번째 요소와 첫번째를 제외한 나머지 요소로 나눔

console.log(number1); // [1]
console.log(rest2); // [2, 3, 4, 5, 6]

let [ number2, number3, ...rest3 ] = numbers; 
// numbers 배열의 첫번째, 두번째 요소와 그머지 요소로 나눔

console.log(number2); // [1]
console.log(number3); // [2]
console.log(rest3); // [3, 4, 5, 6]

</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[인텔리제이 디버그 모드 진입이 안될 때]]></title>
            <link>https://velog.io/@dev_jo/%EC%9D%B8%ED%85%94%EB%A6%AC%EC%A0%9C%EC%9D%B4-%EB%94%94%EB%B2%84%EA%B7%B8-%EB%AA%A8%EB%93%9C-%EC%A7%84%EC%9E%85%EC%9D%B4-%EC%95%88%EB%90%A0-%EB%95%8C</link>
            <guid>https://velog.io/@dev_jo/%EC%9D%B8%ED%85%94%EB%A6%AC%EC%A0%9C%EC%9D%B4-%EB%94%94%EB%B2%84%EA%B7%B8-%EB%AA%A8%EB%93%9C-%EC%A7%84%EC%9E%85%EC%9D%B4-%EC%95%88%EB%90%A0-%EB%95%8C</guid>
            <pubDate>Wed, 08 Feb 2023 01:52:57 GMT</pubDate>
            <description><![CDATA[<p><a href="https://developer0513.tistory.com/166">https://developer0513.tistory.com/166</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 둘만의 암호]]></title>
            <link>https://velog.io/@dev_jo/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%91%98%EB%A7%8C%EC%9D%98-%EC%95%94%ED%98%B8</link>
            <guid>https://velog.io/@dev_jo/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%91%98%EB%A7%8C%EC%9D%98-%EC%95%94%ED%98%B8</guid>
            <pubDate>Sat, 04 Feb 2023 08:38:02 GMT</pubDate>
            <description><![CDATA[<h2 id="문제">문제</h2>
<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42583">둘만의 암호</a></p>
</blockquote>
<h3 id="문제풀이">문제풀이</h3>
<pre><code class="language-javascript">function solution(s, skip, index) {
    var answer = &#39;&#39;;
    let sArr = [];
    let skipArr = [];

    // 알파벳 to 아스키코드 
    for (let i = 0; i &lt; s.length; i++) {
        sArr.push(s.charCodeAt(i) % 97)
    }

    // 알파벳 to 아스키코드 
     for (let i = 0; i &lt; skip.length; i++) {
        skipArr.push(skip.charCodeAt(i) % 97)
    }


    for (let i = 0; i &lt; sArr.length; i++) {
        for (let k = 0; k &lt; index; k++) {
            do {
                sArr[i]++;  
                if (sArr[i] == 26) sArr[i] = 0;
            } while (skipArr.includes(sArr[i])); // skip에 등록된 단어인 경우 계속 반복  
        }
        answer += String.fromCharCode(sArr[i] + 97);
    }


    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로미스 패턴]]></title>
            <link>https://velog.io/@dev_jo/%ED%94%84%EB%A1%9C%EB%AF%B8%EC%8A%A4-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@dev_jo/%ED%94%84%EB%A1%9C%EB%AF%B8%EC%8A%A4-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Fri, 03 Feb 2023 07:12:52 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>자바스크립트 비동기 호출을 하는 소스를 작성할 때 가독성 높은 코드로 작성할 수 있다.</p>
</blockquote>
<h2 id="프로미스promise">프로미스(Promise)</h2>
<p>자바스크립트에서 비동기 처리를 하는 코드를 작성할 때 사용하게 되는 객체이다.
비동기로 동작하지만 순차적으로 처리해야하는 경우 프로미스 패턴을 이용해 간결한 코드를 작성할 수 있다.</p>
<p><del>콜백지옥 예시</del></p>
<pre><code class="language-javascript">function a () {
    function b () {
        function c () {
            function d () {
              //...
            }
        }
    }
}</code></pre>
<p>콜백 지옥이라는 말이 있다. 위 코드는 a, b, c, d.. 함수가 비동기로 동작한다는 가정하에 작성해보았다. 소스를 보는 사람도 소스를 수정해야 하는 사람도 가독성이 떨어지는 코드를 보며 어려움을 겪을 것 이다. 또한 만약 처리 도중 특정 메소드에서 오류가 발생하는 경우, 그 원인을 찾기가 어렵다. </p>
<p>이때 프로미스가 필요하다. 
<br></p>
<h2 id="promise의-3가지-상태">Promise의 3가지 상태</h2>
<p>프로미스의 상태란 프로세스 처리과정을 의미한다.
프로미스 객체를 생성하고 종료될 때 까지 3가지 상태를 갖게 되는데 대기, 이행, 실패 단계가 존재한다.</p>
<ul>
<li>Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태</li>
<li>Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태</li>
<li>Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태</li>
</ul>
<h3 id="대기-상태">대기 상태</h3>
<p>new Promise() 메소드를 통해 호출하는 순간 Pending(대기) 상태가 된다.
비동기 처리가 끝날 때 까지 Pending(대기) 상태가 유지된다.</p>
<pre><code class="language-javascript">new Promise(function(resolve, reject) {
  // ...
});</code></pre>
<h3 id="이행-상태">이행 상태</h3>
<p>비동기 처리가 다 끝난 후 resolve 함수가 콜백된다.
이때를 이행 상태라 하는데, 이 시점에서 .then() 메소드를 통해 결과 값을 받을 수 있다.</p>
<pre><code class="language-javascript">new Promise(function(resolve, reject) {
    resolve();
});</code></pre>
<h3 id="실패-상태">실패 상태</h3>
<p>비동기 처리가 실패한 경우 reject 함수가 콜백된다.
이때를 실패 상태라 하고, 이 시점에서 .catch() 메소드를 통해 실패한 이유를 알 수 있다.</p>
<pre><code class="language-javascript">new Promise(function(resolve, reject) {
  reject();
});</code></pre>
<br>

<h2 id="프로미스-사용-방법">프로미스 사용 방법</h2>
<p>프로미스는 말 그대로 약속이다. 비동기 처리에 대한 약속된 결과를 반환한다. 이때 약속값을 통해 개발자는 해당 함수의 종료시점을 알 수 있으며, 종료시점 이후 로직을 작성할 수 있다.</p>
<h3 id="1-프로미스-객체-생성-및-리턴">1. 프로미스 객체 생성 및 리턴</h3>
<pre><code class="language-javascript">function promiseTest () {
     return new Promise(function(resolve, reject) {
          if (resolve) {
            resolve({test : &#39;success&#39;});
        }
          else if (reject) {
              reject(new Error(&quot;error occured!!&quot;));
        } 
    });
}
</code></pre>
<p>비동기 호출이 성공과 실패의 경우에 대해서 각각 resolve, reject에 할당한다.</p>
<h3 id="2-프로미스-체이닝">2. 프로미스 체이닝</h3>
<pre><code class="language-javascript">function callPromiseTest () {
     promiseTest().then(response =&gt; {
          console.log(response.test); // success
    }).catch(error =&gt; {
          console.log(error); //error occured!!
    });
}</code></pre>
<p>비동기 작업이 정상적으로 처리된 경우에 then 메소드를 통해 처리된 값을 인자로 전달 받을 수 있다. 비동기 작업이 실패한 경우 catch 메소드를 통해 실패한 이유를 분석한다.</p>
<p>프로미스를 쓰면 비동기 처리에 많은 편리함이 있다. 
then과 catch를 통해 성공과 실패를 제어하기 편하며, 여러 비동기 함수를 작성할때도 하나의 비동기가 끝나고 리턴되는 시점인 .then() 메소드 안에 소스를 작성하면 되므로 가독성이 뛰어나다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[var, let, const 차이]]></title>
            <link>https://velog.io/@dev_jo/var-let-const-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@dev_jo/var-let-const-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Mon, 30 Jan 2023 08:04:06 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>var, let, const의 차이점</p>
</blockquote>
<h2 id="개요">개요</h2>
<p>var, let, const를 설명할 때 크게 2가지로 분류할 수 있다.
첫번째는 스코프 범위, 두번째는 재할당이다.
심화적으로 더 들어가면 호이스팅 개념도 등장한다.</p>
<h3 id="1-스코프-범위">1. 스코프 범위</h3>
<p>스코프 범위란, 자바스크립트에서 변수에 접근할 수 있는 범위를 뜻한다.
var와 let, const는 접근할 수 있는 범위가 다르다.</p>
<p>1) var의 스코프 범위
var는 함수안에서면 어디서든 접근가능하다. (function scope)</p>
<p>예제 소스를 보며 이해해보자.</p>
<pre><code class="language-javascript">function fnAccess () {
  if (true) {
    var foo = &#39;scope&#39;;
    console.log(foo);
  }

  console.log(foo);
}</code></pre>
<p>if(true) 안에서 선언된 foo변수는 if 밖에서도 접근이 가능하다. 
함수안에서 선언된 변수는 어디서든 유효하다.
<br></p>
<p>2) let의 스코프 범위
let은 스코프 범위가 블럭{} 단위이다. (block scope)</p>
<pre><code class="language-javascript">function fnAccess () {
  if (true) {
    let foo = &#39;scope&#39;;
    console.log(foo);
  }

  console.log(foo);
}</code></pre>
<p>1)번과 동일하게 작성하고, 단지 var를 let으로 바꾸면 어떻게 될까?</p>
<p><img src="https://velog.velcdn.com/images/dev_jo/post/c1ed92d9-c8b3-4421-a9a4-e93bf882d614/image.png" alt="">
위 이미지와 같이 에러메서지가 뜬다. 
foo라는 변수는 지역변수로 선언되서 if (true){} 안에서만 유효한데, 유효범위 밖에서 접근하려고 했기때문에 에러가 뜨는 것이다.
즉, 여기서 알 수 있는건 지역변수로 선언된 let은 해당 블럭{}안에서만 유효하다는 것 이다.</p>
<h3 id="2-재할당">2. 재할당</h3>
<p>1) 재할당
재할당이란, 선언된 변수에 새로운 값을 대입하는 것을 말한다.
var와 let은 변수여서 재할당이 가능하지만 const는 상수이기 때문에 재할당이 불가능하다.</p>
<pre><code class="language-javascript">const foo = &#39;foo&#39;;
foo = &#39;foo1&#39;;</code></pre>
<p>해당 소스는 오류가 뜬다. const로 선언된 foo 변수에 &#39;foo1&#39; 값을 재할당하려고 했기때문이다.
<img src="https://velog.velcdn.com/images/dev_jo/post/1133f0c9-bc3d-4edf-a560-58dd43dcd74e/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[LWC] Lightning Message Service]]></title>
            <link>https://velog.io/@dev_jo/LWC-Lightning-Message-Service</link>
            <guid>https://velog.io/@dev_jo/LWC-Lightning-Message-Service</guid>
            <pubDate>Mon, 30 Jan 2023 07:21:14 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[[LWC] Custom Event]]></title>
            <link>https://velog.io/@dev_jo/LWC-Custom-Event</link>
            <guid>https://velog.io/@dev_jo/LWC-Custom-Event</guid>
            <pubDate>Thu, 26 Jan 2023 05:53:27 GMT</pubDate>
            <description><![CDATA[<blockquote>
</blockquote>
<span style="font-size:12px">
  CustomEvent란?<br>
Custom Event는 자바스크립트에서 DOM을 조작할 때 기본적으로 지원하는 이벤트가 아닌 직접 원하는 때에 이벤트를 발생하고 싶을 때 사용된다.<br>
LWC도 마찬가지로 Custom Event를 통해 사용자가 원하는 이벤트를 만들 수 있다.

<p><br><br></p>
<ol>
<li><p>이벤트 생성 </p>
<pre><code class="language-javascript">let customEvent = new CustomEvent(&#39;next&#39;);</code></pre>
<p>new 키워드를 통해 Custom Event 객체를 생성해준다.
필자는 next라는 이벤트 이름으로 Custom Event를 생성하였다.
<br><br></p>
<ol start="2">
<li>이벤트 트리거<pre><code class="language-javascript">this.dispatchEvent(customEvent);</code></pre>
dispatchEvent 메소드를 통해 이벤트를 발생시킨다.
<br><br></li>
<li>이벤트 등록<pre><code class="language-html">&lt;template&gt;
&lt;c-sample-component onnext={hanldEvent}&gt; &lt;/c-sample-component&gt;
&lt;/template&gt;</code></pre>
<pre><code class="language-javascript">function handleEvent() {
console.log(&#39;이벤트 호출됨.&#39;);
}</code></pre>
on키워드를 통해 event를 등록한다.
1) 위에서 next라는 이벤트를 생성했으므로 on키워드 뒤에 next를 붙여서 작성하고 해당 이벤트가 트리거 됬을 때, 실행할 함수를 등록해 주었다.
2) handleEvent 함수는 dispatchEvent를 통해 이벤트가 트리거 될 때 호출된다.
<br><br></li>
<li>이벤트를 통해 값 넘겨받기<pre><code class="language-html">&lt;!-- childComponent.html --&gt;
&lt;template&gt;
&lt;lightning-layout&gt;
  &lt;lightning-layout-item&gt;
      &lt;lightning-button
              label=&quot;이름&quot;
              onclick={nameHandler}
      &gt;&lt;/lightning-button&gt;
      &lt;lightning-button
              label=&quot;주소&quot;
              onclick={addressHandler}
      &gt;&lt;/lightning-button&gt;
&lt;/lightning-layout&gt;
&lt;/template&gt;</code></pre>
<pre><code class="language-javascript">// childComponent.js
function nameHandler() {
let nameEvent = new CustomEvent(&#39;name&#39;, {detail:{first:&#39;kim&#39;, last:&#39;jangHoon&#39;}});
this.dispatchEvent(nameEvent);
}
</code></pre>
</li>
</ol>
<p>function addressHandler() {
 let addressEvent = new CustomEvent(&#39;address&#39;, {detail:&#39;incheon&#39;});
 this.dispatchEvent(addressEvent);
}</p>
<pre><code>childComponent에서 각 버튼이 눌리면 해당 Custom Event가 발생한다.
CustomEvent의 detail 프로퍼티에 원하는 값을 넣어서 전달 할 수 있다.
&lt;br&gt;

전달받는 방법에는 2가지가 있다. on 키워드를 통한 방법, 혹은 eventListener를 통한 이벤트 방법이 있다.
&lt;br&gt;
1) on 키워드를 통한 방법
```html
&lt;!-- parentComponent.html --&gt;
&lt;template&gt;
   &lt;c-child-component onname={nameHandle} onaddress={addressHandle}&gt; 
 &lt;/c-child-component&gt;
&lt;/template&gt;</code></pre><pre><code class="language-javascript">// parentComponent.js
function nameHandle(event) {
   console.log(&#39;FirstName : &#39; + event.detail.first);
   console.log(&#39;LastName : &#39; + event.detail.last);
}

function addressHandle(event) {
   console.log(&#39;Address : &#39; + event.detail);
}</code></pre>
<p>parentComponent에서는 자식에서 이벤트가 발생하면, 부모 컴퍼넌트에 등록해논 함수의 event 객체에 child에서 전달한 값을 받을 수 있다.</p>
</li>
</ol>
</span>
  <br>

<p>  2) EventListener를 통한 방법</p>
<pre><code class="language-html">  &lt;!-- parentComponent.html --&gt;
  &lt;template&gt;
      &lt;c-child-component&gt; 
    &lt;/c-child-component&gt;
  &lt;/template&gt;</code></pre>
<pre><code class="language-javascript">  // parentComponent.js
  constructor() {
      super();
      /*
      this.template.addEventListener(&#39;name&#39;, evt =&gt; {
          console.log(evt.detail.name);
      });
      this.template.addEventListener(&#39;address&#39;, evt =&gt; {
          console.log(evt.detail.address);
      });
      */  
      this.template.addEventListener(&#39;name&#39;, this.nameHandler);
    this.template.addEventListener(&#39;address&#39;, this.addressHandler);
  }

  function nameHandler (event) {
    console.log(&#39;FirstName : &#39; + event.detail.first);
    console.log(&#39;LastName : &#39; + event.detail.last);  
  }

  function addressHandler (event) {
      console.log(&#39;Address : &#39; + event.detail);
 }</code></pre>
<p>  원리는 1번 방법과 동일하다. 
  작성방법만 조금 다른데, on키워드가 아닌 부모 컴퍼넌트의 LWC 생성자(constructor) 안에 받을 이벤트를 등록해준다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[localhost 외부에서 접근가능하게 해주기]]></title>
            <link>https://velog.io/@dev_jo/localhost-%EC%99%B8%EB%B6%80-%EC%A0%91%EC%86%8D-%ED%97%88%EC%9A%A9</link>
            <guid>https://velog.io/@dev_jo/localhost-%EC%99%B8%EB%B6%80-%EC%A0%91%EC%86%8D-%ED%97%88%EC%9A%A9</guid>
            <pubDate>Sat, 10 Dec 2022 06:59:04 GMT</pubDate>
            <description><![CDATA[<p><a href="https://localtunnel.github.io/www/">https://localtunnel.github.io/www/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[OAUTH 2.0 ]]></title>
            <link>https://velog.io/@dev_jo/OAUTH-2.0</link>
            <guid>https://velog.io/@dev_jo/OAUTH-2.0</guid>
            <pubDate>Wed, 07 Dec 2022 03:22:27 GMT</pubDate>
            <description><![CDATA[<p>OAUTH 2.0 FLOW
<a href="https://min5k-619.tistory.com/40">https://min5k-619.tistory.com/40</a></p>
<p>OAUTH + SPRING BOOT
<a href="https://docfriends.github.io/DevStrory/2021-10-08/spring-boot-security-jwt-social/">https://docfriends.github.io/DevStrory/2021-10-08/spring-boot-security-jwt-social/</a></p>
<p>OUATH 실제구현 사례
<a href="https://data-jj.tistory.com/53">https://data-jj.tistory.com/53</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[LWC] 데코레이터란?]]></title>
            <link>https://velog.io/@dev_jo/%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0%EB%9E%80</link>
            <guid>https://velog.io/@dev_jo/%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0%EB%9E%80</guid>
            <pubDate>Tue, 06 Dec 2022 07:56:40 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="데코레이터란">데코레이터란?</h3>
<pre><code>Lightning 웹 구성 요소 프로그래밍 모델의 속성 또는 함수 기능</code></pre></blockquote>
<p>**  종류로는 @api, @wire, @track으로 총 3개가 있다.  **</p>
<h3 id="1-api">1. @api</h3>
<p>  <span style="font-size:12px; font-family:'맑은고딕'">@api 데코레이터는 컴퍼넌트 내 변수 또는 함수에 지정 가능하다.
  @api 데코레이터를 활용도는 2가지가 있다.</p>
<ol>
<li><p>(해당 화면이 레코드 페이지인 경우) 레코드 Id를 가져올 때 사용한다.</p>
</li>
<li><p>A 컴퍼넌트 안에 B 컴퍼넌트가 있는 있는 경우, B에서 변수값을 A로부터 상속 받을 때 사용한다.
1) 레코드를 가져올 때는 아래와 같이 지정해주면 된다.</p>
</span>
```java
export default class RecordPageComponent extends LightningElement {
@api recordId;
}
```
<span style="font-size:12px; font-family:'맑은고딕'">
<br>
2) 하위(자식) 컴퍼넌트의 변수 값을 상위(부모) 컴퍼넌트로 부터 상속받을 때 아래와 같이 지정한다.
</span>

<p>```java</p>
</li>
</ol>
<p>  *부모-자식관의 관계에 있는 컴퍼넌트의 경우 
  (ex: A 컴퍼넌트안에 B 컴퍼넌트가 포함된 경우, A는 부모 B는 자식의 관계에 있다고 표현한다.) 
  자식 Component에서 변수에 @api 데코레이터를 지정하여, 부모 Component의 값을 상속 받을 수 있다.</p>
<pre><code>```html
ParentComponent.html
&lt;template&gt;
    &lt;c-child-Component child-label={value}&gt;&lt;/c-child-Component&gt;
&lt;/template&gt;</code></pre><pre><code class="language-java">ParentComponent.js
export default class ParentComponent extends LightningElement {
    value = &#39;child label&#39;;

} </code></pre>
<pre><code class="language-html">ChildComponent.html
&lt;template&gt;
  childLabel : {childLabel}
&lt;/template&gt;</code></pre>
<pre><code class="language-java">ChildComponent.js
export default class ChildComponent extends LightningElement {
    @api childLabel;

}</code></pre>
<h3 id="2-track">2. @track</h3>
  <span style="font-size:12px; font-family:'맑은고딕'">
  track 데코레이터는 배열 변수에 지정한다.<BR>
  LWC에서 배열의 경우 push 메소드를 통해 요소가 추가 되거나, pop을 통해 요소가 제거되더라도 renderCallback 호출을 하지 않아 화면상에 반영되지 않는다.
<BR> 
@track 데코레이터를 걸어주면 배열 요소가 변경되는 것을 인식하여 <span style = "font-weight:bold";>renderCallback을 호출. 즉, 배열에 대한 변경상황을 화면에 정상적으로 렌더링이 가능하다. 
  </span>
  </span>


<p><img src="https://velog.velcdn.com/images/dev_jo/post/862beffa-a8c6-4c49-a4e8-850c1feb0ded/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[sql 트랜잭션 격리수준 (Isolation level)]]></title>
            <link>https://velog.io/@dev_jo/sql-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B2%A9%EB%A6%AC%EC%88%98%EC%A4%80-Isolation-level</link>
            <guid>https://velog.io/@dev_jo/sql-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B2%A9%EB%A6%AC%EC%88%98%EC%A4%80-Isolation-level</guid>
            <pubDate>Tue, 01 Nov 2022 02:00:08 GMT</pubDate>
            <description><![CDATA[<p>트랜잭션 격리 수준 종류에 대한 이해하기 쉬운 설명</p>
<p><a href="https://private-space.tistory.com/97">https://private-space.tistory.com/97</a>
<a href="https://zzang9ha.tistory.com/381">https://zzang9ha.tistory.com/381</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQLD] NULL 관련 함수들]]></title>
            <link>https://velog.io/@dev_jo/SQLD-NULL-%EA%B4%80%EB%A0%A8-%ED%95%A8%EC%88%98%EB%93%A4</link>
            <guid>https://velog.io/@dev_jo/SQLD-NULL-%EA%B4%80%EB%A0%A8-%ED%95%A8%EC%88%98%EB%93%A4</guid>
            <pubDate>Mon, 31 Oct 2022 05:27:13 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/dev_jo/post/eb1b8897-2912-4182-af5e-0165a112d651/image.png" alt=""></p>
<p>[출처] <a href="https://www.youtube.com/watch?v=NYc18lS6FtQ&amp;list=PLlCujDgOz8x4JN2wHKbmlM8bFan-WaKj5&amp;index=14">https://www.youtube.com/watch?v=NYc18lS6FtQ&amp;list=PLlCujDgOz8x4JN2wHKbmlM8bFan-WaKj5&amp;index=14</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[sql drop vs truncate vs delete 차이]]></title>
            <link>https://velog.io/@dev_jo/sql-drop-vs-truncate-vs-delete-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@dev_jo/sql-drop-vs-truncate-vs-delete-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Mon, 31 Oct 2022 00:51:57 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/dev_jo/post/55bc7f67-e546-45b4-8ff9-6e6ab4c1e20b/image.png" alt=""></p>
<p>[출처] <a href="https://yurimac.tistory.com/34">https://yurimac.tistory.com/34</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQLD] Foriegn key와 관련된 설정]]></title>
            <link>https://velog.io/@dev_jo/Foriegn-key%EC%99%80-%EA%B4%80%EB%A0%A8%EB%90%9C-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@dev_jo/Foriegn-key%EC%99%80-%EA%B4%80%EB%A0%A8%EB%90%9C-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Thu, 27 Oct 2022 07:16:38 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/dev_jo/post/38506c6d-0446-4e03-8bbf-119fd2b3fada/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_jo/post/a35255ba-93cb-4d32-b929-595f6de35714/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_jo/post/64231c49-4d01-470e-9454-87c2bb63e718/image.png" alt=""></p>
<p>[출처] <a href="https://www.youtube.com/watch?v=mMoOok9eLQ4&amp;list=PLlCujDgOz8x4JN2wHKbmlM8bFan-WaKj5&amp;index=11">https://www.youtube.com/watch?v=mMoOok9eLQ4&amp;list=PLlCujDgOz8x4JN2wHKbmlM8bFan-WaKj5&amp;index=11</a></p>
]]></description>
        </item>
    </channel>
</rss>