<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>공부한거 정리</title>
    <link>https://bacha.tistory.com/</link>
    <description>개발 관련 공부 정리 블로그</description>
    <language>ko</language>
    <pubDate>Fri, 3 Jul 2026 08:46:18 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>바차</managingEditor>
    <image>
      <title>공부한거 정리</title>
      <url>https://tistory1.daumcdn.net/tistory/4794006/attach/35ac922541b949a48ac603b4be46d781</url>
      <link>https://bacha.tistory.com</link>
    </image>
    <item>
      <title>[JavaScript] CodePen에서 javascript 코드 디버깅하기</title>
      <link>https://bacha.tistory.com/143</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;코딩 테스트 풀 때 디버깅하고 싶은 문제 크롬 개발자 도구에서 디버깅 하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codepen.io/pen/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://codepen.io/pen/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1713491608410&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Create a New Pen&quot; data-og-description=&quot;Behavior Auto Save If active, Pens will autosave every 30 seconds after being saved once. Auto-Updating Preview If enabled, the preview panel updates automatically as you code. If disabled, use the &amp;quot;Run&amp;quot; button to update. Format on Save If enabled, your co&quot; data-og-host=&quot;codepen.io&quot; data-og-source-url=&quot;https://codepen.io/pen/&quot; data-og-url=&quot;https://codepen.io/pen/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://codepen.io/pen/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codepen.io/pen/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Create a New Pen&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Behavior Auto Save If active, Pens will autosave every 30 seconds after being saved once. Auto-Updating Preview If enabled, the preview panel updates automatically as you code. If disabled, use the &quot;Run&quot; button to update. Format on Save If enabled, your co&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codepen.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;코드 예시&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;html&lt;/p&gt;
&lt;pre id=&quot;code_1713491744762&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;button id='btn'&amp;gt;button&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;js(프로그래머스 코딩 테스트 Lv2 - 124 나라의 숫자)&lt;/p&gt;
&lt;pre id=&quot;code_1713491773463&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function recursiveCalc(n) {
    if(n == 0) return 0;
    let quotient = Math.floor(n / 3);
    let remain = n % 3;
    return remain == 0 ? recursiveCalc(quotient - 1) * 10 + 4 : recursiveCalc(quotient) * 10 + remain;
}
const button = document.getElementById(&quot;btn&quot;);
button.addEventListener(&quot;click&quot;,  () =&amp;gt; {
  debugger;
  console.log(recursiveCalc(3));
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 'F12' 를 눌러 개발자 도구 진입&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버튼 눌러서 javascript 코드 디버깅 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간혹 debugging; 에 안 걸리고 넘어갈 때가 있는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자 도구 킨 상태에서 뒤로가기 버튼 우클릭 - 캐시 비우기 및 강력 새로고침 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbcWgB/btsGJpSR3qM/FipYRrKOanMS6vLQbN6nt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbcWgB/btsGJpSR3qM/FipYRrKOanMS6vLQbN6nt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbcWgB/btsGJpSR3qM/FipYRrKOanMS6vLQbN6nt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbcWgB%2FbtsGJpSR3qM%2FFipYRrKOanMS6vLQbN6nt0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;310&quot; height=&quot;141&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div id=&quot;simple-translate&quot;&gt;
&lt;div&gt;
&lt;div class=&quot;simple-translate-button isShow&quot; style=&quot;background-image: url('chrome-extension://mhncgbfifjnhlilpnccgbimimkjejada/icons/512.png'); height: 22px; width: 22px; top: 1476px; left: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;simple-translate-panel &quot; style=&quot;width: 300px; height: 200px; top: 0px; left: 0px; font-size: 13px; background-color: #ffffff;&quot;&gt;
&lt;div class=&quot;simple-translate-result-wrapper&quot; style=&quot;overflow: hidden;&quot;&gt;
&lt;div class=&quot;simple-translate-move&quot; draggable=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;simple-translate-result-contents&quot;&gt;
&lt;p class=&quot;simple-translate-result&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;simple-translate-candidate&quot; style=&quot;color: #737373;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>codepen</category>
      <category>javascirpt</category>
      <category>디버깅</category>
      <category>코딩테스트</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/143</guid>
      <comments>https://bacha.tistory.com/143#entry143comment</comments>
      <pubDate>Fri, 19 Apr 2024 11:02:36 +0900</pubDate>
    </item>
    <item>
      <title>에버노트에서 노션으로 가져오기, 마이그레이션 중 오류(무한 로딩) 해결법</title>
      <link>https://bacha.tistory.com/142</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;예전에 에버노트에서 노션으로 갈아타고자 기존 데이터를 옮기는 작업을 위해 노션의 가져오기 기능을 사용했으나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계속 노트들을 가져오다가 무한 로딩에 빠지게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;163&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEiDNL/btrLr2eHAPF/SERQG97ckyt1YFx3KBopm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEiDNL/btrLr2eHAPF/SERQG97ckyt1YFx3KBopm0/img.png&quot; data-alt=&quot;노션 - Evernote에서 노트북을 가져오는 중&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEiDNL/btrLr2eHAPF/SERQG97ckyt1YFx3KBopm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEiDNL%2FbtrLr2eHAPF%2FSERQG97ckyt1YFx3KBopm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;474&quot; height=&quot;163&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;163&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;노션 - Evernote에서 노트북을 가져오는 중&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 문제를 아무리 검색해봐도 해결 방법이 안나와서 그동안 노션으로 못 가고 있었는데 드디어 해결했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;[해결법]&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 먼저 가져올때 오류가 발생하는 노트북을 에버노트에서 &quot;노트북 내보내기&quot; 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;195&quot; data-origin-height=&quot;306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MA2RL/btrLqWlBN6H/f8iItWoTY4ttmc5bXu1Hp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MA2RL/btrLqWlBN6H/f8iItWoTY4ttmc5bXu1Hp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MA2RL/btrLqWlBN6H/f8iItWoTY4ttmc5bXu1Hp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMA2RL%2FbtrLqWlBN6H%2Ff8iItWoTY4ttmc5bXu1Hp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;195&quot; height=&quot;306&quot; data-origin-width=&quot;195&quot; data-origin-height=&quot;306&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. ENEX로 내보내고&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;649&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A8Sf2/btrLqXEQEAg/QwKQEk8qCnkUJQjVOpmnxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A8Sf2/btrLqXEQEAg/QwKQEk8qCnkUJQjVOpmnxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A8Sf2/btrLqXEQEAg/QwKQEk8qCnkUJQjVOpmnxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA8Sf2%2FbtrLqXEQEAg%2FQwKQEk8qCnkUJQjVOpmnxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;751&quot; height=&quot;649&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;649&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 내보낸 .enex 파일을 다시 에버노트로 가져온다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qauWS/btrLuA9G7Z6/2IEkOOIWqdA4pZ4EgLt8y1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qauWS/btrLuA9G7Z6/2IEkOOIWqdA4pZ4EgLt8y1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qauWS/btrLuA9G7Z6/2IEkOOIWqdA4pZ4EgLt8y1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqauWS%2FbtrLuA9G7Z6%2F2IEkOOIWqdA4pZ4EgLt8y1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;353&quot; height=&quot;318&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 기존 노트북이 아닌 가져온 노트북을 노션에서 Import하면 정상적으로 가져올 수 있다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>기타</category>
      <category>EverNote</category>
      <category>import</category>
      <category>Notion</category>
      <category>가져오기</category>
      <category>노션</category>
      <category>마이그래이션</category>
      <category>무한 로딩</category>
      <category>에버노트</category>
      <category>오류</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/142</guid>
      <comments>https://bacha.tistory.com/142#entry142comment</comments>
      <pubDate>Tue, 6 Sep 2022 12:40:48 +0900</pubDate>
    </item>
    <item>
      <title>JSONObject와 JSONArray 차이</title>
      <link>https://bacha.tistory.com/141</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- {}로 묶일때는 &lt;b&gt;JSONObject&lt;/b&gt;&lt;/b&gt;&lt;b&gt;&lt;b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- []로 묶일때는 &lt;b&gt;&lt;b&gt;JSONA&lt;/b&gt;rray&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;2.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;JSONObject&lt;/b&gt;&lt;/b&gt;&lt;b&gt;&amp;nbsp;: 하나 이상의 key-value 쌍을 { }의 중괄호를 이용하여 담고있는 객체 구조&lt;b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;JSONA&lt;/b&gt;rray : &lt;/b&gt;&lt;/b&gt;&lt;b&gt;요소로 문자열, 숫자, 배열, 객체 등을 담을 수 있다.&lt;b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;3.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;각각 HashMap VS List로 대입하여 비교&lt;br /&gt;&lt;b&gt;&lt;b&gt;JSONObject&lt;/b&gt;&lt;/b&gt;는 요소의 순서는 중요하지 않다. &lt;br /&gt;{id:&amp;nbsp;1,&amp;nbsp;name:&amp;nbsp;'B'}&amp;nbsp;==&amp;nbsp;{name:&amp;nbsp;'B',&amp;nbsp;id:&amp;nbsp;1} &lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;JSONA&lt;/b&gt;rray&lt;/b&gt;&lt;/b&gt;는 요소의 순서가 중요하다. &lt;br /&gt;[1,'value']&lt;span style=&quot;color: #3a3a3a;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; != &lt;/span&gt;&lt;/span&gt;['value',1]&lt;br /&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기타</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/141</guid>
      <comments>https://bacha.tistory.com/141#entry141comment</comments>
      <pubDate>Sat, 12 Mar 2022 19:48:18 +0900</pubDate>
    </item>
    <item>
      <title>C# - RichTextBox 자동 스크롤 하기</title>
      <link>https://bacha.tistory.com/140</link>
      <description>&lt;pre id=&quot;code_1645513199056&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (int i = 0; i &amp;lt; 10000; i++)
                {

                    richTextBox1.Invoke(new Action(delegate ()
                    {
                    	//richTextBox1 += i.ToString(); 로 작성시 자동 스크롤 안됨
                        richTextBox1.AppendText(i.ToString());
                        richTextBox1.ScrollToCaret();
                    }));

                }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.ScrollToCaret();를 적용하여도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;richTextBox1 += i.ToString();&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 작성하면 스크롤이 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자동 스크롤 기능을 구현하기 위해서는 AppendText()를 사용해줘야 한다는 것을 알게 됐다.&amp;nbsp;&lt;/p&gt;</description>
      <category>C#</category>
      <category>AppendText</category>
      <category>Auto Scroll</category>
      <category>c#</category>
      <category>richtextbox</category>
      <category>자동 스크롤</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/140</guid>
      <comments>https://bacha.tistory.com/140#entry140comment</comments>
      <pubDate>Tue, 22 Feb 2022 16:03:32 +0900</pubDate>
    </item>
    <item>
      <title>Visual Studio: Warning IDE0006 Error encountered while loading the project 경고 해결</title>
      <link>https://bacha.tistory.com/139</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[c# - 경고 IDE0006 프로젝트를로드하는 동안 오류가 발생했습니다.]&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Close Visual Studio&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Open a Visual Studio Developer Command Prompt&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Set environment variable &amp;ldquo;TraceDesignTime&amp;rdquo; to true (set TraceDesignTime=true)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Delete .vs directory/.suo file&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Restart VS from the command prompt you set the environment varaible (devenv)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Open the solution&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Check 'C:\Users\nitesh dandekar\AppData\Local\Temp\HelloWorld_*.designtime.log' and look for the failed tasks (FAILED)&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;해당 순서를 따라 가서 해결할 예정이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. .VS 파일 삭제&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;210&quot; data-origin-height=&quot;87&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tzlOu/btrs3agrDbD/7kIYGYFHXX0KXFoYSFgG8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tzlOu/btrs3agrDbD/7kIYGYFHXX0KXFoYSFgG8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tzlOu/btrs3agrDbD/7kIYGYFHXX0KXFoYSFgG8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtzlOu%2Fbtrs3agrDbD%2F7kIYGYFHXX0KXFoYSFgG8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;210&quot; height=&quot;87&quot; data-origin-width=&quot;210&quot; data-origin-height=&quot;87&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;.vs 파일은 해당 프로젝트 안에 숨김파일로 존재한다. &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이 폴더를 삭제 후 다음 단계를 진행한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 개발자 명령 프롬프트 열기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프롬프트를 실행하기 전에 이전에 열어놨던 Visual Studio는 닫아두도록 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l1p4V/btrsY7ednop/chKXKZXqoArIoJoHk6FKv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l1p4V/btrsY7ednop/chKXKZXqoArIoJoHk6FKv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l1p4V/btrsY7ednop/chKXKZXqoArIoJoHk6FKv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl1p4V%2FbtrsY7ednop%2FchKXKZXqoArIoJoHk6FKv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;245&quot; height=&quot;175&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;175&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개발자 명령 프롬프트를 연 후&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;cs&quot; data-ke-language=&quot;cs&quot;&gt;&lt;code&gt;set TRACEDESIGNTIME=true&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1644540287701&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;devenv&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;187&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ns5xi/btrs3VDkO3Y/DldAAyz8HC5f9axEF5Kvzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ns5xi/btrs3VDkO3Y/DldAAyz8HC5f9axEF5Kvzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ns5xi/btrs3VDkO3Y/DldAAyz8HC5f9axEF5Kvzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNs5xi%2Fbtrs3VDkO3Y%2FDldAAyz8HC5f9axEF5Kvzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;485&quot; height=&quot;187&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;187&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;두개의 명령어를 차례대로 입력한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 로그파일 확인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그러면 vscode 실행이 되고 이전처럼 빌드를 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다시 경고가 뜨게 되고 이번엔 사전에 설정한대로 로그파일에 해당 에러 정보가 저장되어 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;C:\Users\&amp;lt;username&amp;gt;\AppData\Local\Temp 에 로그파일들이 여러개 존재할 것이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;603&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clhRLd/btrs3Vi1dwv/eGjkhJP79ka8npp1PwsbWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clhRLd/btrs3Vi1dwv/eGjkhJP79ka8npp1PwsbWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clhRLd/btrs3Vi1dwv/eGjkhJP79ka8npp1PwsbWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclhRLd%2Fbtrs3Vi1dwv%2FeGjkhJP79ka8npp1PwsbWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;603&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;603&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;파일이 많아서 어지럽지만 우리가 원하는 파일은 프로젝트 명으로 적혀있기 때문에 쉽게 찾을 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정 찾기 힘들면 로그파일 지웠다가 위에 과정을 진행하면 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;로그파일을 열어서 가장 밑으로 내려보면 경고나 에러 내용이 나오게 되고 어디서 문제가 있는지 확인할 수 있다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;364&quot; data-origin-height=&quot;271&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cr11mD/btrs0Jc6D2y/BtlAQBy7AmcUPRuOwprGZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cr11mD/btrs0Jc6D2y/BtlAQBy7AmcUPRuOwprGZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cr11mD/btrs0Jc6D2y/BtlAQBy7AmcUPRuOwprGZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcr11mD%2Fbtrs0Jc6D2y%2FBtlAQBy7AmcUPRuOwprGZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;364&quot; height=&quot;271&quot; data-origin-width=&quot;364&quot; data-origin-height=&quot;271&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>C#</category>
      <category>c#</category>
      <category>error</category>
      <category>IDE0006</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/139</guid>
      <comments>https://bacha.tistory.com/139#entry139comment</comments>
      <pubDate>Fri, 11 Feb 2022 09:55:52 +0900</pubDate>
    </item>
    <item>
      <title>Invoke, BeginInvoke, 크로스 스레드 예외</title>
      <link>https://bacha.tistory.com/138</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span&gt;[Invoke]&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;- &lt;/span&gt;스레드를 따로 분리하지 않고 시간이 오래 걸리는 계산을 진행하면 &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그동안&lt;span&gt; UI &lt;/span&gt;핸들링을 담당하는&lt;span&gt; MainThread&lt;/span&gt;가&lt;span&gt; &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;UI &lt;/span&gt;컨트롤을 핸들링 하지 못하기 때문에&lt;span&gt;, &lt;/span&gt;&lt;/b&gt;&lt;b&gt;계산하는 동안 &lt;span&gt;UI&lt;/span&gt;가 멈추고&lt;span&gt;, &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;제어가 불가능 하며 응답 없음을 출력할 때도 있다&lt;span&gt;.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;- &lt;/span&gt;이를 해결하기위해&lt;span&gt; thread &lt;/span&gt;사용하게 되는데 코딩하여 실행하면 관련&lt;span&gt; Exception&lt;/span&gt;을 보게 된다&lt;span&gt;.&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;- &lt;/span&gt;메인 스레드가 아닌 다른 스레드에서 &lt;span&gt;ui &lt;/span&gt;컨트롤에 접근하려고 하기 때문이다&lt;span&gt;.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;942&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r2TQp/btrrDwksneR/MaRg22Mc2szH7gOX1e02r1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r2TQp/btrrDwksneR/MaRg22Mc2szH7gOX1e02r1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r2TQp/btrrDwksneR/MaRg22Mc2szH7gOX1e02r1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr2TQp%2FbtrrDwksneR%2FMaRg22Mc2szH7gOX1e02r1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;470&quot; height=&quot;471&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;942&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;- &lt;/span&gt;이 때&lt;span&gt; invoke &lt;/span&gt;를 사용하여 실행하려고 하는 메소드의 대리자&lt;span&gt;(delegate)&lt;/span&gt;를 실행시키면 해결할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;-&amp;gt; Control&lt;/span&gt;의&lt;span&gt; Invoke&lt;/span&gt;는 다른 스레드에서 직접 접근할 수 없는 윈폼 컨트롤 작업에 대해&lt;span&gt; Invoke&lt;/span&gt;를 통해 작업 자체를 대리자(delegate)로&amp;nbsp; 위임하여&lt;span&gt; MainThread&lt;/span&gt;가 해당 작업을 실행하게 한다&lt;span&gt;.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;Invoke&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;와 &lt;span&gt;BeginInvoke&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;-&amp;gt; Invoke&lt;/span&gt;의 경우&lt;span&gt;, &lt;/span&gt;컨트롤을 생성한 스레드에서 동기식으로 실행하고&lt;span&gt;, BeginInvoke&lt;/span&gt;는 비동기식으로 실행합니다&lt;span&gt;.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>C#</category>
      <category>BeginInvoke</category>
      <category>Invoke</category>
      <category>크로스 스레드 예외</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/138</guid>
      <comments>https://bacha.tistory.com/138#entry138comment</comments>
      <pubDate>Mon, 24 Jan 2022 16:36:48 +0900</pubDate>
    </item>
    <item>
      <title>C# - CancellationToken</title>
      <link>https://bacha.tistory.com/137</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span&gt;[CancellationToken]&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;- CancellationToken&lt;/span&gt;은 비동기 작업을 취소하는 용도로 사용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;- &lt;/span&gt;작업 취소와 관련된 타입은&lt;span&gt; CancellationTokenSource &lt;/span&gt;클래스와&lt;span&gt; CancellationToken &lt;/span&gt;구조체&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;- CancellationTokenSource &lt;/span&gt;클래스는&lt;span&gt; Cancellation Token&lt;/span&gt;을 생성하고&lt;span&gt; Cancel &lt;/span&gt;요청을&lt;span&gt; Cancellation Token&lt;/span&gt;들에게 보내는 일을 담당&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;- CancellationToken&lt;/span&gt;은 현재&lt;span&gt; Cancel &lt;/span&gt;상태를 모니터링하는 여러&lt;span&gt; Listener&lt;/span&gt;들에 의해 사용되는 구조체&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span&gt;[CancellationToken &lt;/span&gt;사용 절차]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;1. &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;CancellationTokenSource &lt;/span&gt;필드를 선언&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;-&amp;gt; private CancellationTokenSource cancelTokenSource;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;2.&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;CancellationTokenSource &lt;/span&gt;객체를 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;-&amp;gt; cancelTokenSource = new CancellationTokenSource();&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;3.&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;비동기 작업 메서드 안에서 작업이 취소되었는지를 체크하는 코드를 작성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;b&gt;if (cancelTokenSource.Token.IsCancellationRequested)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return null;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;4. &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;취소 버튼이 눌러지면&lt;span&gt; CancellationTokenSource&lt;/span&gt;의&lt;span&gt; Cancel() &lt;/span&gt;메서드를 호출해 작업 취소를 요청&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;private void btnCancel_Click(object sender, EventArgs e)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;{&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;cancelTokenSource.Cancel();&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;}&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고 &lt;span&gt;: &lt;a href=&quot;https://www.csharpstudy.com/Threads/taskOfT.aspx&quot;&gt;https://www.csharpstudy.com/Threads/taskOfT.aspx&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1643009439302&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Task Of T 클래스 - C# 프로그래밍 배우기 (Learn C# Programming)&quot; data-og-description=&quot;C# Task 클래스 Non-Generic 타입인 Task 클래스는 ThreadPool.QueueUserWorkItem()과 같이 리턴값을 쉽게 돌려 받지 못한다. 비동기 델리게이트(Asynchronous Delegate)와 같이 리턴값을 돌려 받기 위해서는 Task 클래&quot; data-og-host=&quot;www.csharpstudy.com&quot; data-og-source-url=&quot;https://www.csharpstudy.com/Threads/taskOfT.aspx&quot; data-og-url=&quot;https://www.csharpstudy.com/Threads/taskOfT.aspx&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.csharpstudy.com/Threads/taskOfT.aspx&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.csharpstudy.com/Threads/taskOfT.aspx&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Task Of T 클래스 - C# 프로그래밍 배우기 (Learn C# Programming)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;C# Task 클래스 Non-Generic 타입인 Task 클래스는 ThreadPool.QueueUserWorkItem()과 같이 리턴값을 쉽게 돌려 받지 못한다. 비동기 델리게이트(Asynchronous Delegate)와 같이 리턴값을 돌려 받기 위해서는 Task 클래&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.csharpstudy.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C#</category>
      <category>c#</category>
      <category>CancellationToken</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/137</guid>
      <comments>https://bacha.tistory.com/137#entry137comment</comments>
      <pubDate>Mon, 24 Jan 2022 16:33:38 +0900</pubDate>
    </item>
    <item>
      <title>Task와 async, await 비교/관계</title>
      <link>https://bacha.tistory.com/136</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.sysnet.pe.kr/3/0/5488&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.sysnet.pe.kr/3/0/5488&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1643008185415&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;C# 비동기 함수 async, await 와 Task의 관계에 대해 질문 드립니다.&quot; data-og-description=&quot;C# 비동기 함수 async, await 와 Task의 관계에 대해 질문 드립니다. [링크 복사], [링크+제목 복사] 조회: 1227 글쓴 사람 종범 (kjb_jh at naver.com) 홈페이지 첨부 파일 부모글 보이기/감추기 비동기 함수와 &quot; data-og-host=&quot;www.sysnet.pe.kr&quot; data-og-source-url=&quot;https://www.sysnet.pe.kr/3/0/5488&quot; data-og-url=&quot;https://www.sysnet.pe.kr/3/0/5488&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.sysnet.pe.kr/3/0/5488&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.sysnet.pe.kr/3/0/5488&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;C# 비동기 함수 async, await 와 Task의 관계에 대해 질문 드립니다.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;C# 비동기 함수 async, await 와 Task의 관계에 대해 질문 드립니다. [링크 복사], [링크+제목 복사] 조회: 1227 글쓴 사람 종범 (kjb_jh at naver.com) 홈페이지 첨부 파일 부모글 보이기/감추기 비동기 함수와&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.sysnet.pe.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;비슷한 의문점이 있어 찾아보다 발견하여 참고하였습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;[Task와 async, await]&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 기존 비동기 지원 방식 자체가 Delegate의 BeginInvoke 를 이용해 스레드 풀을 이용하는 것만 지원하고 있었기 때문에 비동기 작업 이후의 처리에 제약이 많았다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; 이러한 제약을 극복한 것이 Task&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; async/await이&amp;nbsp;어차피&amp;nbsp;비동기&amp;nbsp;호출이&amp;nbsp;완료된&amp;nbsp;후,&amp;nbsp;그&amp;nbsp;완료&amp;nbsp;이벤트를&amp;nbsp;받았을&amp;nbsp;때&amp;nbsp;계속&amp;nbsp;코드를&amp;nbsp;실행해야&amp;nbsp;하는&amp;nbsp;작업을&amp;nbsp;스레드&amp;nbsp;풀의&amp;nbsp;스레드가&amp;nbsp;담당하게&amp;nbsp;되는데&amp;nbsp;자연스럽게&amp;nbsp;Task로&amp;nbsp;그&amp;nbsp;작업을&amp;nbsp;맡기게&amp;nbsp;된&amp;nbsp;것&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; &lt;b&gt;async, await 보다 &lt;/b&gt;더욱 세밀하게 제어할 수 있도록 Task를 구현하여 제공&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 결국 async/await 역시 Task 의 기능을 사용하는 것이므로 결과적으로는 SynchronizationContext를 이용해 비동기 처리와 콜백 처리를 하게 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;- 둘 다 ThreadPool을 사용하는 것이므로 속도차이는 무시할 정도로 미미하거나 없다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;br /&gt;&lt;b&gt;- 어떤 것을 사용할 것인지는 개발자 취향.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>C#</category>
      <category>async</category>
      <category>Await</category>
      <category>Task</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/136</guid>
      <comments>https://bacha.tistory.com/136#entry136comment</comments>
      <pubDate>Mon, 24 Jan 2022 16:27:12 +0900</pubDate>
    </item>
    <item>
      <title>c# Error - NullReferenceException</title>
      <link>https://bacha.tistory.com/135</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;501&quot; data-origin-height=&quot;504&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/veR3f/btrrqlZHNkG/5F5WxPozg4splz8Yhmjn31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/veR3f/btrrqlZHNkG/5F5WxPozg4splz8Yhmjn31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/veR3f/btrrqlZHNkG/5F5WxPozg4splz8Yhmjn31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FveR3f%2FbtrrqlZHNkG%2F5F5WxPozg4splz8Yhmjn31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;501&quot; height=&quot;504&quot; data-origin-width=&quot;501&quot; data-origin-height=&quot;504&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;NullReferenceException was unhandled by user code&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;An&amp;nbsp;exception&amp;nbsp;of&amp;nbsp;type&amp;nbsp;'System.NullReferenceException'&amp;nbsp;occurred&amp;nbsp;in&amp;nbsp;FleckWebsocketServer.exe&amp;nbsp;but&amp;nbsp;was&amp;nbsp;not&amp;nbsp;handled&amp;nbsp;in&amp;nbsp;user&amp;nbsp;code &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Additional&amp;nbsp;information:&amp;nbsp;개체&amp;nbsp;참조가&amp;nbsp;개체의&amp;nbsp;인스턴스로&amp;nbsp;설정되지&amp;nbsp;않았습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;디버깅 도중 이런 오류가 떴다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이유는 간단했다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;45&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WLWxa/btrrumQ5vST/JDeNkt4KE9wnap3JkQx3b1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WLWxa/btrrumQ5vST/JDeNkt4KE9wnap3JkQx3b1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WLWxa/btrrumQ5vST/JDeNkt4KE9wnap3JkQx3b1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWLWxa%2FbtrrumQ5vST%2FJDeNkt4KE9wnap3JkQx3b1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;371&quot; height=&quot;45&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;45&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;if문에서 저 runLoop 변수를 초기화 해주지 않은 상태에서 값을 비교했었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1643004129869&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if(runLoop == null || runLoop.Status == TaskStatus.RanToCompletion)
                                {
                                    MessageBox.Show(&quot;loop 실행&quot;);
                                    Console.WriteLine(&quot;Run &quot; + message + &quot;...&quot;);
                                    allSockets.ToList().ForEach(s =&amp;gt; s.Send(&quot;Echo: Run &quot; + message + &quot;...&quot;));
                                    RunClientLoop();
                                }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Null 체크 하는 습관을 들여야겠다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>C#</category>
      <category>c#</category>
      <category>error</category>
      <category>Null 체크</category>
      <category>NullReferenceException</category>
      <category>System.NullReferenceException</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/135</guid>
      <comments>https://bacha.tistory.com/135#entry135comment</comments>
      <pubDate>Mon, 24 Jan 2022 15:04:10 +0900</pubDate>
    </item>
    <item>
      <title>C# - Managed DLL, Unmanaged DLL</title>
      <link>https://bacha.tistory.com/134</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Managed DLL과 Unmanaged DLL 대표적으로 나누면&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CLR이 제공하는 서비스를 제공 받느냐 못받느냐로 나눌 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이름 대로 Managed DLL은 제공 받고, Unmanaged DLL은 제공받지 못한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내용을 좀 더 조사해 보았다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;- Managed DLL은&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Common Language Runtime (&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;줄여서&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;CLR)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;환경에서&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;동작&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Managed DLL&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;은&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;CLR에 의해 제공되는 실행시의 각종 서비스 (보안 및 메모리 관련)를 받을 수 있는 것을 말한다. &lt;/b&gt;&lt;br /&gt;&lt;b&gt;- Managed DLL&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;은&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;CLR에 의해 해당 컴퓨터에 적합한 기계 언어를 능동적으로 생성하여 범용성을 높였다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Managed&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;DLL&lt;/b&gt;은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;Visual Basic .NET과&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;C# 컴파일러가 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- &lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;Unmanaged code&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;는&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Visual Studio .NET 2002&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;가&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;나오기&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;전에&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;만든&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;코드를&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;말한다&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Unmanaged DLL&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;은&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;실행시의 CLR이 제공하는 서비스를 제공받을 수 없다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;Unmanaged DLL&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;은 가비지&amp;nbsp;컬렉터가&amp;nbsp;없으므로&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;메모리&amp;nbsp;누수가&amp;nbsp;발생&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;- Unmanaged DLL&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;은&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;컴파일할때 컴퓨터의 환경에 적합한 기계어만 생성하므로 범용성이 매우 낮다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;- Managed Type 클래스는 힙에 생성되면 자동으로 메모리 수거가 이루어 지는 반면 Unmanaged Type 클래스는 사용자가 수거해야 한다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;</description>
      <category>C#</category>
      <category>c#</category>
      <category>Managed DLL</category>
      <category>Unmanaged DLL</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/134</guid>
      <comments>https://bacha.tistory.com/134#entry134comment</comments>
      <pubDate>Mon, 24 Jan 2022 12:34:03 +0900</pubDate>
    </item>
    <item>
      <title>C# - using문</title>
      <link>https://bacha.tistory.com/133</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/using-statement&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/using-statement&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1642990057741&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;using 문 - C# 참조&quot; data-og-description=&quot;using 문(C# 참조) 이 문서의 내용 --&amp;gt; IDisposable 개체의 올바른 사용을 보장하는 편리한 구문을 제공합니다. C# 8.0부터 using 문은 IAsyncDisposable 개체의 올바른 사용을 보장합니다. 예제 다음 예제에서&quot; data-og-host=&quot;docs.microsoft.com&quot; data-og-source-url=&quot;https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/using-statement&quot; data-og-url=&quot;https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/using-statement&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/using-statement&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/using-statement&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;using 문 - C# 참조&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;using 문(C# 참조) 이 문서의 내용 --&amp;gt; IDisposable 개체의 올바른 사용을 보장하는 편리한 구문을 제공합니다. C# 8.0부터 using 문은 IAsyncDisposable 개체의 올바른 사용을 보장합니다. 예제 다음 예제에서&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;using 문&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-IDisposable&amp;nbsp;개체의&amp;nbsp;올바른&amp;nbsp;사용을&amp;nbsp;보장하는&amp;nbsp;편리한&amp;nbsp;구문을&amp;nbsp;제공&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 관리되지 않는 리소스에 액세스 하는 클래스들을 사용한 후에 적절한 시기에 해제하여 해당 리소스를 다시 반납해야 하지만 사람이 수동적으로 하기에는 번거로운 점이 많다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- using문을 이용하면 해당 리소스 범위를 벗어나게 되면 자동으로 리소스(자원)을 해제(Dispose)하여 리소스관리를 용이하게 해주는 편리한 구문이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이전에 구현한 메모장 스크린샷 프로그램 일부이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;using문을 사용하고 나서 dispose&lt;/p&gt;
&lt;pre id=&quot;code_1642990389216&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Bitmap 클래스: 그래픽 이미지의 픽셀 데이터를 저장하는 클래스. 픽셀 단위로 데이터를 저장한다.
                using (Bitmap bmp = new Bitmap(rc.Width, rc.Height, pixelFormat))
                {
                    // Bitmap 이미지 변경을 위해 Graphics 객체 생성
                    //FromImage(): 지정된 Graphics에 대한 새 Image를 반환하는 메서드
                    using (Graphics gr = Graphics.FromImage(bmp))
                    {
                        //디바이스 컨텍스트에 대한 핸들을 가져온다.
                        IntPtr dc = gr.GetHdc();


                        bool success = PrintWindow(memoHandle, dc, 0);
                        gr.ReleaseHdc(dc);
                    }
                    bmp.Save(&quot;result.bmp&quot;);
                    MessageBox.Show(&quot;스냅샷 찰영 완료&quot;);
                }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>C#</category>
      <category>c#</category>
      <category>using 문</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/133</guid>
      <comments>https://bacha.tistory.com/133#entry133comment</comments>
      <pubDate>Mon, 24 Jan 2022 11:42:26 +0900</pubDate>
    </item>
    <item>
      <title>HTTP, AJAX, 폴링, 롱폴링 기법, 웹소켓</title>
      <link>https://bacha.tistory.com/132</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;HTTP 부터 웹 소켓 까지 각각의 배경, 사용 이유, 각 기능의 장단점을 알아보았다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[Http]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt;&amp;nbsp;HTTP는&amp;nbsp;서버와&amp;nbsp;클라이언트가&amp;nbsp;인터넷상에서&amp;nbsp;데이터를&amp;nbsp;주고받기&amp;nbsp;위한&amp;nbsp;프로토콜 &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt;&amp;nbsp;HTTP는&amp;nbsp;서버/클라이언트&amp;nbsp;모델 &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt;&amp;nbsp;Client가&amp;nbsp;요청을&amp;nbsp;보내는&amp;nbsp;경우에만&amp;nbsp;Server가&amp;nbsp;응답하는&amp;nbsp;단방향&amp;nbsp;통신.&amp;nbsp;Server로부터&amp;nbsp;응답을&amp;nbsp;받은&amp;nbsp;후에는&amp;nbsp;연결이&amp;nbsp;바로&amp;nbsp;종료 &lt;/b&gt;&lt;br /&gt;&lt;b&gt;--&amp;gt;&amp;nbsp;즉각적인&amp;nbsp;갱신을&amp;nbsp;요구하는&amp;nbsp;실시간&amp;nbsp;통신에서는&amp;nbsp;불리하다.&amp;nbsp;다수의&amp;nbsp;요청을&amp;nbsp;반복해서&amp;nbsp;보내야&amp;nbsp;하기때문에&amp;nbsp;리소스&amp;nbsp;낭비가&amp;nbsp;심함.&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[AJAX]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AJAX&amp;nbsp;:&amp;nbsp;비동기적으로&amp;nbsp;서버와&amp;nbsp;통신을&amp;nbsp;하면서,&amp;nbsp;동적으로&amp;nbsp;페이지를&amp;nbsp;변경하게&amp;nbsp;한다. &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt; http의 단점을 보완해, 웹페이지를 리로드하지 않고 데이터를 불러와 페이지를 부분적으로 변경시킬 수 있다.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt;&amp;nbsp;비동기&amp;nbsp;방식을&amp;nbsp;활용하여&amp;nbsp;필요한&amp;nbsp;부분만&amp;nbsp;불러와&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있으므로&amp;nbsp;큰&amp;nbsp;장점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; 단점으로, 어디까지나 일부 랜더링 문제이고, 결국 HTTP 자체를 벗어날 순 없었다. &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt; 즉 양방향 통신이 불가능 하다는 점이 단점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;&lt;b&gt;[폴링]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; 양방향 통신을 근접하게 구현하기 위한 방법들&lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt; 클라이언트가 서버에게 일정한 주기를 가지고 지속적으로 요청 후 응답을 받는 방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; 단점으로, 폴링의 주기가 짧으면 성능에 부담이 가고, 주기가 길면 실시간성능이 떨어진다. &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt;&amp;nbsp;서버에서&amp;nbsp;정보가&amp;nbsp;변하지&amp;nbsp;않으면&amp;nbsp;요청&amp;nbsp;응답&amp;nbsp;과정에서&amp;nbsp;리소스를&amp;nbsp;낭비하고,&amp;nbsp;오버헤드&amp;nbsp;트래픽이&amp;nbsp;발생한다. &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;&lt;b&gt;[롱폴링 기법]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt;&amp;nbsp;이러한&amp;nbsp;폴링의&amp;nbsp;문제점을&amp;nbsp;개선한&amp;nbsp;방식이다. &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt;&amp;nbsp;클라이언트가&amp;nbsp;요청을&amp;nbsp;보냈을&amp;nbsp;때&amp;nbsp;그&amp;nbsp;요청에&amp;nbsp;대한&amp;nbsp;연결을&amp;nbsp;서버가&amp;nbsp;이벤트가&amp;nbsp;발생할때까지&amp;nbsp;가지고&amp;nbsp;있는&amp;nbsp;것.&amp;nbsp; &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt;&amp;nbsp;즉&amp;nbsp;클라이언트에게&amp;nbsp;받은&amp;nbsp;요청을&amp;nbsp;가지고&amp;nbsp;있다가,&amp;nbsp;이벤트&amp;nbsp;발생시&amp;nbsp;응답. &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt;&amp;nbsp;변경이&amp;nbsp;빈번하다면&amp;nbsp;이&amp;nbsp;역시&amp;nbsp;얻을&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;이득이&amp;nbsp;크지&amp;nbsp;않다. &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;* 폴링 롱폴링 모두 서버측 푸시 기술을 구현하기 위한 대안이었지만 클라이언트의 요청을 통해야만 서버에게 데이터를 전송 받는다는 한계점 존재. &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt; 불필요한 헤더와 높은 트래픽을 야기한다는 단점.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;[웹소켓]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; http의 한계를 극복하고 실시간 서비스를 개발하기 위해 탄생함 &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt; 사용자의 웹 브라우저에서 서버로 영구 양방향, 전이중 tcp 연결을 위한 통신 프로토콜 &lt;/b&gt;&lt;br /&gt;&lt;b&gt;(양방향&amp;nbsp;통신&amp;nbsp;안에&amp;nbsp;전이중(쌍방이&amp;nbsp;동시&amp;nbsp;송신&amp;nbsp;가능),&amp;nbsp;반이중(한쪽이&amp;nbsp;송신하고&amp;nbsp;있는&amp;nbsp;동안은&amp;nbsp;수신)&amp;nbsp;이&amp;nbsp;있다.)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt; 서버와 클라이언트 사이에 웹소켓이 열리면 서버 또는 사용자 둘 중 하나가 세션을 닫을 때까지 언제든지 메시지를 보낼 수 있다. &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt; http 요청과 마찬가지로 80번 포트를 통해서 웹서버를 연결한다.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt; 웹소켓은 잘 알려진 기존 포트를 사용하기 때문에 추가로 방화벽을 열지 않고도 양방향 통신을 실현할 수 있다.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt; Client만 필요한 경우에 요청을 보낼 수 있는 Http 프로그래밍과 달리 Socket 프로그래밍은 Server 역시 Client로 요청을 보낼 수 있으며, 계속 연결을 유지하는 연결 지향형 방식이기 때문에 실시간 통신이 필요한 경우에 자주 사용.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt;&amp;nbsp;단점으로&amp;nbsp;웹소켓과&amp;nbsp;http&amp;nbsp;세션이&amp;nbsp;서로&amp;nbsp;다르다는&amp;nbsp;것.&amp;nbsp;주기적으로&amp;nbsp;웹소켓&amp;nbsp;세션과&amp;nbsp;서버에&amp;nbsp;저장하는&amp;nbsp;http&amp;nbsp;세션을&amp;nbsp;동기화하는&amp;nbsp;모듈을&amp;nbsp;구현해야&amp;nbsp;한다는&amp;nbsp;것. &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;gt; 대용량 트래픽에서는 서버가 클라이언트 수만큼의 연결을 유지해야 한다는 부담 존재.&lt;/b&gt;&lt;/p&gt;</description>
      <category>기타</category>
      <category>Ajax</category>
      <category>HTTP</category>
      <category>롱폴링</category>
      <category>웹소켓</category>
      <category>폴링</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/132</guid>
      <comments>https://bacha.tistory.com/132#entry132comment</comments>
      <pubDate>Mon, 24 Jan 2022 10:30:32 +0900</pubDate>
    </item>
    <item>
      <title>C# - Application 클래스란?</title>
      <link>https://bacha.tistory.com/131</link>
      <description>&lt;h2 data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Application]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MSDN의 설명으론&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://docs.microsoft.com/ko-kr/dotnet/api/system.windows.application?view=netcore-3.1&quot;&gt;https://docs.microsoft.com/ko-kr/dotnet/api/system.windows.application?view=netcore-3.1&lt;/a&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1642986393372&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Application Class (System.Windows)&quot; data-og-description=&quot;Encapsulates a Windows Presentation Foundation application.&quot; data-og-host=&quot;docs.microsoft.com&quot; data-og-source-url=&quot;https://docs.microsoft.com/ko-kr/dotnet/api/system.windows.application?view=netcore-3.1&quot; data-og-url=&quot;https://docs.microsoft.com/ko-kr/dotnet/api/system.windows.application&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b3mBhj/hyNb92apEP/iit5kfKPXACVgk8GTtLgF0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://docs.microsoft.com/ko-kr/dotnet/api/system.windows.application?view=netcore-3.1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.microsoft.com/ko-kr/dotnet/api/system.windows.application?view=netcore-3.1&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b3mBhj/hyNb92apEP/iit5kfKPXACVgk8GTtLgF0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Application Class (System.Windows)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Encapsulates a Windows Presentation Foundation application.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- WPF 응용 프로그램 관련 기능을 캡슐화 하는 클래스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 자기 자신(exe)을 래핑하고 제어하는 최상위 클래스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Application 클래스의 주로 사용하는 기능 두 가지&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 윈도우 응용 프로그램을 시작 (Application.Run())하고 종료(Application.Exit())시키는 메소드를 제공. &lt;br /&gt;- 윈도우 메시지를 처리.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C#</category>
      <category>Application</category>
      <category>c#</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/131</guid>
      <comments>https://bacha.tistory.com/131#entry131comment</comments>
      <pubDate>Mon, 24 Jan 2022 10:14:10 +0900</pubDate>
    </item>
    <item>
      <title>[STAThread] 란?</title>
      <link>https://bacha.tistory.com/130</link>
      <description>&lt;h2 data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;[STAThread] &lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;해당 메서드가 STA (Single Threaded Arpartment) Thread모델로 실행된다는 것으로 만약 이를 지우면 윈도우 프로그램에 문제가 생기는 경우가 있다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;인터넷에 나와있는 설명은&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;b&gt;어플리케이션의 COM 스레드모델이 단일스레드어파트먼트(STA: Single-Threaded Apartment)인 것&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;라고 설명하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;일단 여기서 COM이 무엇인지 모르겠어서 찾아보면,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Component Object Model 의 약자&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 현재는 .net 프레임워크로 지위가 넘어가는 상황&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- com 형식이란 com 객체를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- .net은 기본적으로 MTA(멀티스레드어파트먼트)로 동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 그런데 전통적으로 com 객체는 STAThread 기반이어서 이를 명시해줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 만약 명시하지 않고 단일쓰레드아파트먼트 기반인 com 객체를 사용시엔 런타임때 오류가 발생한다.&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;(위키피디아의 정확한 설명)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8_%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8_%EB%AA%A8%EB%8D%B8&quot;&gt;https://ko.wikipedia.org/wiki/%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8_%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8_%EB%AA%A8%EB%8D%B8&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;만약 Main 메소드에 STAThread 속성을 붙이지 않았으면, C#에서는, 멀티 스레드 어파트먼트(MTA: multithreaded apartment)가 되게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;본론으로 들어가서, C#의 Main 메소드에 STAThread가 그래서 필요한가? 라고 하면, STA로만 구동이 되는 COM를 사용하는 경우 -&amp;gt; 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;COM을 직접 사용하는 것이 아니여도 &lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;.NET Framework의 일부의 기능을 &lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;COM을 사용하고 있기 때문에, 그러한 기능을 사용하는 경우는 반드시 STA로 할 필요가 있다고 한다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이 내용을 찾아본 계기가 C#에서 스레드를 생성하여 사용하면 멀티 스레드가 되는것이 아닌가? 라는 생각을 했고, 그렇다면 [STAThread]가 이니라 [MTAThread]인 것 아닌가? 라고 생각했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 지금은 메인 스레드 입장에서 자신의 내부를 보았을 때 STA인지 MTA인지 구분인 것이고, 외부에서 생성된 다른 스레드와는 별개라고 이해하였다. 아직&amp;nbsp; 개념이 잘 안서있기 때문에 더 찾아봐야 겠다.&lt;/p&gt;</description>
      <category>C#</category>
      <category>.NET Framework</category>
      <category>c#</category>
      <category>COM 객체</category>
      <category>mta</category>
      <category>STA</category>
      <category>[STAThread]</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/130</guid>
      <comments>https://bacha.tistory.com/130#entry130comment</comments>
      <pubDate>Mon, 24 Jan 2022 09:52:08 +0900</pubDate>
    </item>
    <item>
      <title>DLL이란?</title>
      <link>https://bacha.tistory.com/129</link>
      <description>&lt;h1&gt;&lt;b&gt;DLL&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DLL은 다이나믹(Dynamic) 링크(Link) 라이브러리(Library)를 줄인 말로 개발하는 과정에서 자주 사용되는 표준적인 함수를 반복해서 작성하는 것을 방지하기 위해 자주 쓰인다. &lt;br /&gt;&lt;br /&gt;라이브러리를 한번 만들어 놓으면 다시 만들 필요가 없이, 불러와 사용하면 되기 때문에 개발 속도에 큰 이점이 있다. &lt;br /&gt;&lt;br /&gt;이러한&amp;nbsp;라이브러리를&amp;nbsp;언제&amp;nbsp;메인&amp;nbsp;프로그램에&amp;nbsp;연결하느냐에&amp;nbsp;따라서&amp;nbsp;2가지로&amp;nbsp;나뉜다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;-&amp;nbsp;Static&amp;nbsp;Link &lt;/b&gt;&lt;br /&gt;&lt;b&gt;-&amp;nbsp;Dynamic&amp;nbsp;link&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;DLL은&amp;nbsp;이름에서&amp;nbsp;보았듯이&amp;nbsp;후자를&amp;nbsp;의미한다. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Static&amp;nbsp;link&amp;nbsp;libray&lt;/b&gt; &lt;br /&gt;-&amp;nbsp;정적&amp;nbsp;링크라고&amp;nbsp;하며&amp;nbsp;컴파일&amp;nbsp;시점에서&amp;nbsp;라이브러리가&amp;nbsp;연결되어&amp;nbsp;실행&amp;nbsp;파일의&amp;nbsp;일부가&amp;nbsp;된다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;DLL&lt;/b&gt; &lt;br /&gt;-&amp;nbsp;동적&amp;nbsp;링크라고&amp;nbsp;하며&amp;nbsp;실행&amp;nbsp;파일에서&amp;nbsp;해당&amp;nbsp;라이브러리의&amp;nbsp;기능을&amp;nbsp;사용&amp;nbsp;시에만,&amp;nbsp;라이브럴&amp;nbsp;ㅣ파일을&amp;nbsp;참조&amp;nbsp;또는&amp;nbsp;다운로드&amp;nbsp;해서&amp;nbsp;메소드를&amp;nbsp;호출한다. &lt;br /&gt;- 정적 링크와는 달리 컴파일 시점엣 실행 파일에 메서드를 복사하지 않고, 메서드의 위치정보만 가지고 함수를 호출한다.&lt;br /&gt;-&amp;nbsp;DLL을&amp;nbsp;사용하면&amp;nbsp;리소스를&amp;nbsp;절약할&amp;nbsp;수&amp;nbsp;있고,&amp;nbsp;배포와&amp;nbsp;설치에&amp;nbsp;용이해&amp;nbsp;재사용성이&amp;nbsp;뛰어나다.&lt;/p&gt;</description>
      <category>기타</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/129</guid>
      <comments>https://bacha.tistory.com/129#entry129comment</comments>
      <pubDate>Mon, 24 Jan 2022 09:09:29 +0900</pubDate>
    </item>
    <item>
      <title>C# - WindowForm user32를 활용한 메모장 스크린샷 프로그램</title>
      <link>https://bacha.tistory.com/128</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;사용하고나 사용할 예정인 user32에 대한 조사를 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;GetWindowPlacement&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 윈도우의 위치, 크기, 최대/최소화 상태를 한꺼번에 조사&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 시스템은 내부적으로 윈도우의 좌표를 두쌍의 좌표와 한개의 사각형으로 기억&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;GetWindowRect&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 작업 영역의 크기 얻음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FindWindow&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 프로세스의 핸들을 찾아 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;PrintWindow&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 캡처를 원하는 창의 핸들과 DC(Device Context), 옵션 이렇게 3가지의 인수를 넘기면 해당창을 캡처한 비트맵 핸들을 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;GetWindowRgn&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 특성창의 크기 가져오기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CreateRectRgn&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 그래픽상의 크기 가져오기&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1642835890788&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MemoScreenShotDLLControlEx
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // 프로세스 핸들 찾기
        [DllImport(&quot;user32.dll&quot;)]
        public static extern int FindWindow(string lpClassName, string lpWindowName);

        //스크린샷
        [DllImport(&quot;user32.dll&quot;)]
        static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);


        // 프로세스가 존재하는지 여부, 핸들 구하기
        public IntPtr Client_Connection(string clientname)
        {
            IntPtr iResulthwnd = new IntPtr();
            int inthwnd = FindWindow(clientname, null);
            if (inthwnd != 0)
            {
                iResulthwnd = new IntPtr(inthwnd);
                MessageBox.Show(&quot;해당 프로세스가 열려 있습니다.&quot;);
                
            }
            else
            {
                iResulthwnd = new IntPtr(inthwnd);
                MessageBox.Show(&quot;해당 프로세스는 현재 존재하지 않습니다.&quot;);
                
            }
            return iResulthwnd;
        }


        private void button1_Click(object sender, EventArgs e)
        {

            IntPtr memoHandle = Client_Connection(&quot;notepad&quot;);

            if (memoHandle.Equals(IntPtr.Zero))
            {
                return;
            }

            //Graphics.FromHwnd(): 지정된 창 핸들에 대한 새 Graphics를 반환
            Graphics gfxWin = Graphics.FromHwnd(memoHandle); 

            //Rectangle: 사각형의 위치와 크기를 나타내는 네 정수의 집합을 저장하는 구조체
            //Rectangle.Round(): RectangleF 값을 가장 가까운 정수 값으로 반올림
            Rectangle rc = Rectangle.Round(gfxWin.VisibleClipBounds); 


            // 픽셀 포맷 정보 얻기 (Optional)
            PixelFormat pixelFormat = PixelFormat.Format32bppArgb;


            // 화면 크기만큼의 Bitmap 생성
            try
            {
                //Bitmap 클래스: 그래픽 이미지의 픽셀 데이터를 저장하는 클래스. 픽셀 단위로 데이터를 저장한다.
                using (Bitmap bmp = new Bitmap(rc.Width, rc.Height, pixelFormat))
                {
                    // Bitmap 이미지 변경을 위해 Graphics 객체 생성
                    //FromImage(): 지정된 Graphics에 대한 새 Image를 반환하는 메서드
                    using (Graphics gr = Graphics.FromImage(bmp))
                    {
                        //디바이스 컨텍스트에 대한 핸들을 가져온다.
                        IntPtr dc = gr.GetHdc();


                        bool success = PrintWindow(memoHandle, dc, 0);
                        gr.ReleaseHdc(dc);
                    }
                    bmp.Save(&quot;result.bmp&quot;);
                    MessageBox.Show(&quot;스냅샷 찰영 완료&quot;);
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(&quot;스냅샷 찰영 오류&quot;);

                // 윈도우 폼에서 콘솔을 보기 위해서는 Project -&amp;gt; (파일이름) Properties -&amp;gt; Output Type 변경
                Console.WriteLine(ex);
            }
            

        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[결과]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 현재 프로세스에 메모장이 없는 경우 FindWindow를 통해서 프로세스 존재여부를 판별한다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ngsT4/btrrr6e71pZ/klKoejVJk0m7cOzKy0C0xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ngsT4/btrrr6e71pZ/klKoejVJk0m7cOzKy0C0xk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ngsT4/btrrr6e71pZ/klKoejVJk0m7cOzKy0C0xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FngsT4%2Fbtrrr6e71pZ%2FklKoejVJk0m7cOzKy0C0xk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;664&quot; height=&quot;456&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 메모장이 현재 실행중인 프로세스에 존재할 경우 PrintWindow를 통해 스크린샷으로 저장되어&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;debug 파일 안에 result.bmp 파일로 저장된다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZO29f/btrrmgcX2oB/XcHCmorHivDZrBlT9jTh0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZO29f/btrrmgcX2oB/XcHCmorHivDZrBlT9jTh0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZO29f/btrrmgcX2oB/XcHCmorHivDZrBlT9jTh0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZO29f%2FbtrrmgcX2oB%2FXcHCmorHivDZrBlT9jTh0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;566&quot; height=&quot;412&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;817&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CQYYv/btrrr5AxajI/A7ttmtlihBVkatUuWiKQB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CQYYv/btrrr5AxajI/A7ttmtlihBVkatUuWiKQB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CQYYv/btrrr5AxajI/A7ttmtlihBVkatUuWiKQB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCQYYv%2Fbtrrr5AxajI%2FA7ttmtlihBVkatUuWiKQB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;714&quot; height=&quot;817&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;817&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* 단 아직 메모장이 최소화로 비활성창 상태일 경우 스크린샷을 찍지 못한다. 추후 코드 추가할 예정&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;419&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DgBLw/btrruAmIE5K/ZPHBJUKUYOtMBOwBzx3Hik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DgBLw/btrruAmIE5K/ZPHBJUKUYOtMBOwBzx3Hik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DgBLw/btrruAmIE5K/ZPHBJUKUYOtMBOwBzx3Hik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDgBLw%2FbtrruAmIE5K%2FZPHBJUKUYOtMBOwBzx3Hik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;571&quot; height=&quot;419&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;419&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>C#</category>
      <category>c#</category>
      <category>DLL</category>
      <category>FindWindow</category>
      <category>PrintWindow</category>
      <category>user32</category>
      <category>WindowForm</category>
      <category>메모장 스크린샷</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/128</guid>
      <comments>https://bacha.tistory.com/128#entry128comment</comments>
      <pubDate>Sat, 22 Jan 2022 16:27:30 +0900</pubDate>
    </item>
    <item>
      <title>C# - DLL 추가하기, DLL 사용하기, WindowForm과 Console창 같이 보기</title>
      <link>https://bacha.tistory.com/125</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;먼저 버튼을 클릭시 DLL 사용하기 위해 버튼 하나 생성했습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실행시 윈도우 폼과 콘솔창을 같이 띄워 결과를 보게 했습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;437&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXsDSS/btrrn2Z3SCV/FKScgGAyTM8cIwlKpwSEvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXsDSS/btrrn2Z3SCV/FKScgGAyTM8cIwlKpwSEvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXsDSS/btrrn2Z3SCV/FKScgGAyTM8cIwlKpwSEvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXsDSS%2Fbtrrn2Z3SCV%2FFKScgGAyTM8cIwlKpwSEvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;437&quot; height=&quot;342&quot; data-origin-width=&quot;437&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이후 DLL 파일을 생성하기 위한 Class Library 프로젝트를 추가합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;570&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SIpZI/btrrq0e82Ee/Nu98G2oBsbxnPMEUfRFUTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SIpZI/btrrq0e82Ee/Nu98G2oBsbxnPMEUfRFUTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SIpZI/btrrq0e82Ee/Nu98G2oBsbxnPMEUfRFUTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSIpZI%2Fbtrrq0e82Ee%2FNu98G2oBsbxnPMEUfRFUTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;728&quot; height=&quot;570&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;570&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Class Library로 생성&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1069&quot; data-origin-height=&quot;511&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAZzSb/btrrsmvu65N/l2O7haOlXGVPkcfxsK2Wk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAZzSb/btrrsmvu65N/l2O7haOlXGVPkcfxsK2Wk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAZzSb/btrrsmvu65N/l2O7haOlXGVPkcfxsK2Wk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAZzSb%2Fbtrrsmvu65N%2Fl2O7haOlXGVPkcfxsK2Wk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;715&quot; height=&quot;342&quot; data-origin-width=&quot;1069&quot; data-origin-height=&quot;511&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;간단한 class 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1642832035218&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace testDll
{
    public class TestDllClass
    {
        public void WriteConsole(String text)
        {
            Console.WriteLine(text + &quot;&amp;lt;&amp;lt;&amp;lt;DLL 가져옴&amp;gt;&amp;gt;&amp;gt;&quot;);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;작성한 class 파일을 빌드해줍니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;396&quot; data-origin-height=&quot;357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l0IQl/btrrpUsXMGq/7cNk5RL7AeMciVaiuCkhF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l0IQl/btrrpUsXMGq/7cNk5RL7AeMciVaiuCkhF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l0IQl/btrrpUsXMGq/7cNk5RL7AeMciVaiuCkhF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl0IQl%2FbtrrpUsXMGq%2F7cNk5RL7AeMciVaiuCkhF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;396&quot; height=&quot;357&quot; data-origin-width=&quot;396&quot; data-origin-height=&quot;357&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이제 아까 만들어둔 윈도우 폼 프로젝트에 방금 만든 DLL을 넣어줍니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;263&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k975j/btrrotC7RvV/7HUWkh58K1FAaIGAE0sgfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k975j/btrrotC7RvV/7HUWkh58K1FAaIGAE0sgfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k975j/btrrotC7RvV/7HUWkh58K1FAaIGAE0sgfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk975j%2FbtrrotC7RvV%2F7HUWkh58K1FAaIGAE0sgfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;575&quot; height=&quot;263&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;263&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Browse에서 아래 Browse.. 버튼을 클릭&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;681&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxGjGM/btrroF4niwf/BzywoKCrMX6D8kbwCy5SEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxGjGM/btrroF4niwf/BzywoKCrMX6D8kbwCy5SEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxGjGM/btrroF4niwf/BzywoKCrMX6D8kbwCy5SEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxGjGM%2FbtrroF4niwf%2FBzywoKCrMX6D8kbwCy5SEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;723&quot; height=&quot;681&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;681&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 방금 빌드했던 DLL 파일은 해당 프로젝트 -&amp;gt; testDll -&amp;gt; bin -&amp;gt; Debug 안에 있을 겁니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Form1.cs 에서 Using을 통해 testDLL 선언해주고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;객체 생성해서 DLL의 메서드를 사용해줍니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1642833144275&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using testDll;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            TestDllClass testDllClass = new TestDllClass();
            testDllClass.WriteConsole(&quot;버튼 눌렀을때 -----&amp;gt; &quot;);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결과를 콘솔로 보고 싶기 때문에&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;492&quot; data-origin-height=&quot;659&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eLgfEq/btrrmfLSvMK/fEHdwKKNXacbH3vK85MkEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eLgfEq/btrrmfLSvMK/fEHdwKKNXacbH3vK85MkEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eLgfEq/btrrmfLSvMK/fEHdwKKNXacbH3vK85MkEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeLgfEq%2FbtrrmfLSvMK%2FfEHdwKKNXacbH3vK85MkEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;370&quot; height=&quot;496&quot; data-origin-width=&quot;492&quot; data-origin-height=&quot;659&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Window Application에서 Colsole Application으로 바꿔줍니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; 이렇게 되면 윈도우폼 실행시 콘솔창도 같애 뜨게 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;577&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GS73q/btrrotpzIfD/vJ6opdK0Awvx4g7XdMIYQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GS73q/btrrotpzIfD/vJ6opdK0Awvx4g7XdMIYQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GS73q/btrrotpzIfD/vJ6opdK0Awvx4g7XdMIYQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGS73q%2FbtrrotpzIfD%2FvJ6opdK0Awvx4g7XdMIYQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;794&quot; height=&quot;446&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;577&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[결과]&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctGHSc/btrrumveVmG/Cgkf68cZ9fylgNeOk3Fkp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctGHSc/btrrumveVmG/Cgkf68cZ9fylgNeOk3Fkp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctGHSc/btrrumveVmG/Cgkf68cZ9fylgNeOk3Fkp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctGHSc%2FbtrrumveVmG%2FCgkf68cZ9fylgNeOk3Fkp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1233&quot; height=&quot;656&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1223&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pmcrw/btrroWrjSHC/aNZaVzbU7qveYSHwGyePs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pmcrw/btrroWrjSHC/aNZaVzbU7qveYSHwGyePs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pmcrw/btrroWrjSHC/aNZaVzbU7qveYSHwGyePs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpmcrw%2FbtrroWrjSHC%2FaNZaVzbU7qveYSHwGyePs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1223&quot; height=&quot;640&quot; data-origin-width=&quot;1223&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C#</category>
      <category>c#</category>
      <category>C# Console</category>
      <category>Class Libaray</category>
      <category>Colsole Application</category>
      <category>DLL</category>
      <category>DLL 사용하기</category>
      <category>DLL 추가하기</category>
      <category>Window Application</category>
      <category>WindowForm</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/125</guid>
      <comments>https://bacha.tistory.com/125#entry125comment</comments>
      <pubDate>Sat, 22 Jan 2022 15:36:40 +0900</pubDate>
    </item>
    <item>
      <title>C# - WindowForm 기초(ToolBox, Properties, Event, Button, TextBox)</title>
      <link>https://bacha.tistory.com/124</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;C#의 WindowForm기초와, 이를 활용해서 아주 간단한 Button/TextBox 프로그램 만들기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ToolBox&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 툴박스에서 원하는 컨트롤을 선택해 윈도우 폼에 배치가 가능합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;385&quot; data-origin-height=&quot;875&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9QqF2/btrrqZ8m0QW/UGuwNsLBIdTUwoPCArAVWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9QqF2/btrrqZ8m0QW/UGuwNsLBIdTUwoPCArAVWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9QqF2/btrrqZ8m0QW/UGuwNsLBIdTUwoPCArAVWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9QqF2%2FbtrrqZ8m0QW%2FUGuwNsLBIdTUwoPCArAVWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;295&quot; height=&quot;670&quot; data-origin-width=&quot;385&quot; data-origin-height=&quot;875&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Properties&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 프로퍼티는 선택한 폼 또는 컨트롤들의 속성을 변경할 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 버튼을 예로 들면 버튼의 크기나 모양등을 변경할 수 있는 곳이 이곳입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;369&quot; data-origin-height=&quot;866&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9hFRI/btrroWLAOb9/fEpBryXSqKTIcAdrmQj9z1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9hFRI/btrroWLAOb9/fEpBryXSqKTIcAdrmQj9z1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9hFRI/btrroWLAOb9/fEpBryXSqKTIcAdrmQj9z1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9hFRI%2FbtrroWLAOb9%2FfEpBryXSqKTIcAdrmQj9z1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;306&quot; height=&quot;718&quot; data-origin-width=&quot;369&quot; data-origin-height=&quot;866&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;버튼을 누르면 TextBox에 내용이 갱신되는 프로그램&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Button 추가&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- ToolBox에서 버튼 컨트롤 선택해 추가 후, Properties 에서 Text를 '내용 수정' 으로 변경&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- &lt;b&gt;Properties 에서&lt;span&gt; BackColor를 ActiveCation으로 변경&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;- &lt;b&gt;&lt;b&gt;Properties 에서&lt;span&gt;&lt;span&gt; Dock을 Top으로 변경&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;- &lt;b&gt;&lt;b&gt;Properties 에서&lt;span&gt;&lt;span&gt; AutoSize 를 True로 변경하고 원하는 크기만큼 조정&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r2U3W/btrrotJOZ76/vkSOQNTuJ5D8tL5dJn98TK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r2U3W/btrrotJOZ76/vkSOQNTuJ5D8tL5dJn98TK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r2U3W/btrrotJOZ76/vkSOQNTuJ5D8tL5dJn98TK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr2U3W%2FbtrrotJOZ76%2FvkSOQNTuJ5D8tL5dJn98TK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;418&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;TextBox 추가하기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- ToolBox에서 TextBox를 선택해 Form에 배치&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 생성한 TextBox1 선택 후 Properties 에서 MultiLine을 True로 변경&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- &lt;b&gt;Properties 에서&lt;span&gt; Dock을 Fill로 설정&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;556&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l03iG/btrroGPIJDm/YtsfhzZk7Qc8xd2EuVuH10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l03iG/btrroGPIJDm/YtsfhzZk7Qc8xd2EuVuH10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l03iG/btrroGPIJDm/YtsfhzZk7Qc8xd2EuVuH10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl03iG%2FbtrroGPIJDm%2FYtsfhzZk7Qc8xd2EuVuH10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;556&quot; height=&quot;410&quot; data-origin-width=&quot;556&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이제 버튼을 더블클릭하게 되면 버튼을 클릭했을 때 수행되는 이벤트를 작성하는 창으로 넘어가게 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;357&quot; data-origin-height=&quot;132&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAYZlz/btrrqZmY5nn/qKn7Iij4jmYzE93Tu5m7w1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAYZlz/btrrqZmY5nn/qKn7Iij4jmYzE93Tu5m7w1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAYZlz/btrrqZmY5nn/qKn7Iij4jmYzE93Tu5m7w1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAYZlz%2FbtrrqZmY5nn%2FqKn7Iij4jmYzE93Tu5m7w1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;357&quot; height=&quot;132&quot; data-origin-width=&quot;357&quot; data-origin-height=&quot;132&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; 이벤트는 이곳에서 확인이 가능합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Button1(내용 수정 버튼의 Name이 Button1 입니다.)을 클릭했을 때 textBox1(폼에 추가했던 textBox의 Name)의 Text를 &quot;Hello World!!&quot; 로 수정하겠다는 의미&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;589&quot; data-origin-height=&quot;105&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhCuA4/btrrod1iMoO/AvkzC3rtD80s0WN1DwkYJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhCuA4/btrrod1iMoO/AvkzC3rtD80s0WN1DwkYJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhCuA4/btrrod1iMoO/AvkzC3rtD80s0WN1DwkYJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhCuA4%2Fbtrrod1iMoO%2FAvkzC3rtD80s0WN1DwkYJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;589&quot; height=&quot;105&quot; data-origin-width=&quot;589&quot; data-origin-height=&quot;105&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[결과]&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;409&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ooZyh/btrrod774M9/Ho7KNwAlRM1T8qBHGopKm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ooZyh/btrrod774M9/Ho7KNwAlRM1T8qBHGopKm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ooZyh/btrrod774M9/Ho7KNwAlRM1T8qBHGopKm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FooZyh%2Fbtrrod774M9%2FHo7KNwAlRM1T8qBHGopKm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;592&quot; height=&quot;409&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;409&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HkPcw/btrrqbHXS1u/R5q7SPeDAmoKl8UDu3LPok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HkPcw/btrrqbHXS1u/R5q7SPeDAmoKl8UDu3LPok/img.png&quot; data-alt=&quot;&amp;amp;nbsp;&amp;amp;nbsp;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HkPcw/btrrqbHXS1u/R5q7SPeDAmoKl8UDu3LPok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHkPcw%2FbtrrqbHXS1u%2FR5q7SPeDAmoKl8UDu3LPok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;590&quot; height=&quot;410&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;nbsp;&amp;nbsp;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C#</category>
      <category>Button</category>
      <category>c#</category>
      <category>Event</category>
      <category>Properties</category>
      <category>textbox</category>
      <category>Toolbox</category>
      <category>WindowForm</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/124</guid>
      <comments>https://bacha.tistory.com/124#entry124comment</comments>
      <pubDate>Sat, 22 Jan 2022 14:40:56 +0900</pubDate>
    </item>
    <item>
      <title>C# - WindowForm 메모장 파일 생성, 내용 추가, 수정하기(WindowForm, MessageBox, MessageBoxButtons, File.WriteAllText, File.ReadAllText)</title>
      <link>https://bacha.tistory.com/123</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서 C#을 사용하게 되어 처음해보지만 공부하게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공부하면서 예제 및 개념을 정리하고 복습하고자 포스팅합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우 폼을 사용해 메모장을 생성하고 내용 추가 수정이 가능한 프로그램을 구현하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모장에서 수정된 내용이 윈도우 폼에서도 출력되며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러가지 조건에 따라 다른 MessageBox가 출력되도록 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내용 입력시 결과 창과 메모장에 내용 입력된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;679&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2pinI/btrrpnPHpIR/71ra4TM6z6GzaLDNJzg1c1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2pinI/btrrpnPHpIR/71ra4TM6z6GzaLDNJzg1c1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2pinI/btrrpnPHpIR/71ra4TM6z6GzaLDNJzg1c1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2pinI%2FbtrrpnPHpIR%2F71ra4TM6z6GzaLDNJzg1c1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;508&quot; height=&quot;313&quot; data-origin-width=&quot;679&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;415&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JblAp/btrrqbVrBxD/wugJbaS5YfNhsqT4s5BvJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JblAp/btrrqbVrBxD/wugJbaS5YfNhsqT4s5BvJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JblAp/btrrqbVrBxD/wugJbaS5YfNhsqT4s5BvJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJblAp%2FbtrrqbVrBxD%2FwugJbaS5YfNhsqT4s5BvJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;507&quot; height=&quot;312&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;415&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 창에서 수정 가능&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;415&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czIxKp/btrroyjOU0n/Sn6KOZPbl49qMoiGKGCzJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czIxKp/btrroyjOU0n/Sn6KOZPbl49qMoiGKGCzJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czIxKp/btrroyjOU0n/Sn6KOZPbl49qMoiGKGCzJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczIxKp%2FbtrroyjOU0n%2FSn6KOZPbl49qMoiGKGCzJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;518&quot; height=&quot;415&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;415&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 메모장에 가보면 내용이 수정되어 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;473&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kwJSq/btrrq0e6Wxc/PxNmH29yyrvBVTO5OnFVoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kwJSq/btrrq0e6Wxc/PxNmH29yyrvBVTO5OnFVoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kwJSq/btrrq0e6Wxc/PxNmH29yyrvBVTO5OnFVoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkwJSq%2Fbtrrq0e6Wxc%2FPxNmH29yyrvBVTO5OnFVoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;648&quot; height=&quot;473&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;473&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[Form1.cs]&lt;/p&gt;
&lt;pre id=&quot;code_1642828380327&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace WinFormExam01
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        String path = @&quot;C:\winFormFile.txt&quot;;

        private void button1_Click(object sender, EventArgs e)
        {
            

            if (!File.Exists(path)){
                // 파일 없으면 파일 생성
                string[] createText = {};
                result.Text = textBox1.Text;

                File.WriteAllText(path, textBox1.Text);
                textBox1.Text = &quot;&quot;;
                MessageBox.Show(&quot;파일생성/입력완료&quot;);
            }
            else if (textBox1.Text == &quot;&quot;)
            {
                MessageBox.Show(&quot;추가할 내용을 입력하세요.&quot;);
            }
            else
            {
                String readTxt = File.ReadAllText(path);
                if(readTxt == &quot;&quot;)
                    result.Text = readTxt + textBox1.Text;
                else
                    result.Text = readTxt + Environment.NewLine + textBox1.Text;

                File.WriteAllText(path, result.Text); //WriteAllText는 기존에 파일이 있으면 덮어씀
                textBox1.Text = &quot;&quot;;
                MessageBox.Show(&quot;입력완료&quot;);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (!File.Exists(path))
            {
                MessageBox.Show(&quot;수정할 파일이 없습니다.&quot;);
            }
            else if (result.Text == &quot;&quot;)
            {
                string message = &quot;입력한 내용이 없어 모두 삭제하게 됩니다.&quot; + Environment.NewLine + &quot;수정하시겠습니까?&quot;;
                string title = &quot;경고&quot;;
                MessageBoxButtons buttons = MessageBoxButtons.OKCancel;
                DialogResult dialogResult = MessageBox.Show(message, title, buttons);
                if (dialogResult == DialogResult.OK)
                {
                    File.WriteAllText(path, result.Text);
                    MessageBox.Show(&quot;수정완료&quot;);
                }
                else
                {
                }
            }
            else
            {
                File.WriteAllText(path, result.Text);
                MessageBox.Show(&quot;수정완료&quot;);
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>C#</category>
      <category>c#</category>
      <category>File.ReadAllText</category>
      <category>File.WriteAllText</category>
      <category>MessageBox</category>
      <category>MessageBoxButtons</category>
      <category>WindowForm</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/123</guid>
      <comments>https://bacha.tistory.com/123#entry123comment</comments>
      <pubDate>Sat, 22 Jan 2022 14:14:17 +0900</pubDate>
    </item>
    <item>
      <title>세션, 토큰, 쿠키</title>
      <link>https://bacha.tistory.com/122</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;세션&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서버에 로그인 되어있음이 지속되는 상태를 '세션' 이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;span style=&quot;background-color: #ffffff; color: #444444;&quot;&gt;일정 시간동안 같은 사용자(브라우저)로부터 들어오는&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #444444;&quot;&gt;일련의 요구를 하나의 상태로 보고, 그 상태를 일정하게 유지시키는 기술&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;세션의 동작 순서&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클라이언트가 페이지를 요청&lt;/li&gt;
&lt;li&gt;서버는 접근한 클라이언트의 Request-Header 필드인 Cookie를 확인하여,&lt;br /&gt;클라이언트가 해당 session-id를 보냈는지 확인한다.&lt;/li&gt;
&lt;li&gt;session-id가 존재하지 않는다면,&lt;br /&gt;서버는 session-id를 생성해 클라이언트에게 돌려준다.&lt;/li&gt;
&lt;li&gt;서버에서 클라이언트로 돌려준 session-id를 쿠키를 사용해 서버에 저장한다.&lt;br /&gt;쿠키 이름 : SESSIONID&lt;/li&gt;
&lt;li&gt;클라이언트는 재접속 시,&lt;br /&gt;이 쿠키(SESSIONID)를 이용하여 session-id 값을 서버에 전달&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세션과 토큰은 왜 필요한가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- HTTP(웹사이트를 이용할때 쓰는 프로토콜)은 stateless이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- stateless는 서버로 가는 모든 요청이 이전 요청과 독립적으로 다루어 진다는 뜻. 요청이 끝나면 서버는 내가 누군지 잊어버린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요청이 끝나면 서버는 우리가 누군지 잊어버린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이를 해결하는 방법이 세션&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 세션은 서버 확장시 세션의 정보의 동기화 문제가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 세션은 메모리에 저장되기 때문에 에러가 발생할 경우 휘발될 가능성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이러한 문제를 해결하는 방법이 토큰&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토큰(JWT - Json Web Token)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용자가 로그인을 하면 서버에서 상태를 저장하지 않고, 토큰 바디에 정보를 저장해 클라이언트가 가진 뒤, 이를 증명서 처럼 사용하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 세션의 한계와 문제점&lt;/b&gt;&lt;span style=&quot;background-color: #f8f9fa; color: #212529;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;때문에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;토큰이 등장&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- &lt;b&gt;토큰은 서버의 상태를 저장하지 않음 (Stateless)&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 토큰 자체로 정보를 가지고 있어서 별도의 인증 서버가 필요없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 토큰은 헤더, 페이로드, 시그니처로 3부분으로 구성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠키&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서버는 쿠키를 활용하여 나에 관한 정보(웹사이트의 언어 설정)를 브라우저에 데이터를 넣을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이후 해당 웹사이트에 방문할 때마다 브라우저는 해당 쿠키도 서버에게 보내준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 쿠키는 유효기간이 존재한다. 서버가 정한 기간에 따라 유효하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 서버에서 나의 브라우저로 쿠키를 전송&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 브라우저는 정보를 쿠키에 담아 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 추후 다음에 해당 웹사이트 방문 시 쿠키는 요청과 함께 서버로 보내지고, 서버는 쿠키가 기억해둔 언어 설정의 페이지를 제공&lt;/p&gt;</description>
      <category>기타</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/122</guid>
      <comments>https://bacha.tistory.com/122#entry122comment</comments>
      <pubDate>Thu, 16 Dec 2021 23:50:05 +0900</pubDate>
    </item>
    <item>
      <title>동기와 비동기</title>
      <link>https://bacha.tistory.com/121</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;동기식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt;함수를 호출할 때 그 함수가 끝날 때 까지 결과를 기다린다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; 동기식은 값이 꼭 필요하고 그 결과 값을 다른 곳으로 사용해야 할 때는 반드시 동기식으로 해야한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;비동기식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; 함수를 호출 하고나서 함수의 결과를 기다리지 않고 다른 업무를 동시에 수행한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; 함수 호출 후 함수의 수행 여부와 상관 없이 다른 업무로 넘어가도 상관 없는 경우 적용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; 비동기 프로그램의 경우 수행한 함수를 끝을 알리는 콜백 함수를 활용하여 마무리 한다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; 안드로이드에서의 통신, 노드JS의 기본 함수들의 호출은 대부분 비동기식이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기타</category>
      <category>동기</category>
      <category>비동기</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/121</guid>
      <comments>https://bacha.tistory.com/121#entry121comment</comments>
      <pubDate>Thu, 16 Dec 2021 21:32:48 +0900</pubDate>
    </item>
    <item>
      <title>Spring Boot - JSON 은  왜 사용하는가?</title>
      <link>https://bacha.tistory.com/120</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;전 세계 사람들이 영어를 공용어로 지정하여 통일된 언어 하나로 대화를 하는 것 처럼,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러가지 다양한 플랫폼에서 데이터를 주고 받기 위해서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 주고받기 위해서 JSON 형식으로 변환하여 주고 받는다.&amp;nbsp;&lt;/p&gt;</description>
      <category>KIC/Spring</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/120</guid>
      <comments>https://bacha.tistory.com/120#entry120comment</comments>
      <pubDate>Thu, 16 Dec 2021 16:32:23 +0900</pubDate>
    </item>
    <item>
      <title>Flutter - VsCode 간단한 코드 정리 단축키 및 방법</title>
      <link>https://bacha.tistory.com/119</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;969&quot; data-origin-height=&quot;215&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lOYlf/btrhUW1a2nX/NDfysKc2kkdMDKkjoKMmO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lOYlf/btrhUW1a2nX/NDfysKc2kkdMDKkjoKMmO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lOYlf/btrhUW1a2nX/NDfysKc2kkdMDKkjoKMmO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlOYlf%2FbtrhUW1a2nX%2FNDfysKc2kkdMDKkjoKMmO0%2Fimg.png&quot; data-origin-width=&quot;969&quot; data-origin-height=&quot;215&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이런식으로 연속된 괄호로 보기 어려운 코드가 있을 때&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;216&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xRFqA/btrhUYLsLfu/G9dJ49gHKTdMHCrPJHRbzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xRFqA/btrhUYLsLfu/G9dJ49gHKTdMHCrPJHRbzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xRFqA/btrhUYLsLfu/G9dJ49gHKTdMHCrPJHRbzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxRFqA%2FbtrhUYLsLfu%2FG9dJ49gHKTdMHCrPJHRbzk%2Fimg.png&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;216&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;끝 괄호 사이사이에 콤마를 넣어주고 format documnet 단축키 실행&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;827&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blCflP/btrhTSdUmez/1CSn7YZWKAUNcB1dhrbkoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blCflP/btrhTSdUmez/1CSn7YZWKAUNcB1dhrbkoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blCflP/btrhTSdUmez/1CSn7YZWKAUNcB1dhrbkoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblCflP%2FbtrhTSdUmez%2F1CSn7YZWKAUNcB1dhrbkoK%2Fimg.png&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;827&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;292&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G9jXu/btrhTRMSD52/Tuoo3NUjjRRfkif274fXYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G9jXu/btrhTRMSD52/Tuoo3NUjjRRfkif274fXYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G9jXu/btrhTRMSD52/Tuoo3NUjjRRfkif274fXYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG9jXu%2FbtrhTRMSD52%2FTuoo3NUjjRRfkif274fXYK%2Fimg.png&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;292&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;원하는 키로 바꿔서도 사용 가능하다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;콤마를 모두 찍은 상태에서 shift +alt + F 를 누르면 정렬 완료&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;433&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WALHR/btrhTtrUYsb/a2JMxzR1yyL7kHEDYPaoRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WALHR/btrhTtrUYsb/a2JMxzR1yyL7kHEDYPaoRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WALHR/btrhTtrUYsb/a2JMxzR1yyL7kHEDYPaoRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWALHR%2FbtrhTtrUYsb%2Fa2JMxzR1yyL7kHEDYPaoRK%2Fimg.png&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;433&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Flutter</category>
      <category>Flutter</category>
      <category>단축키</category>
      <category>코드 정렬</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/119</guid>
      <comments>https://bacha.tistory.com/119#entry119comment</comments>
      <pubDate>Sat, 16 Oct 2021 03:54:04 +0900</pubDate>
    </item>
    <item>
      <title>flutter - Error: The argument type 'String' can't be assigned to the parameter type 'Uri'.dart(argument_type_not_assignable)</title>
      <link>https://bacha.tistory.com/118</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;199&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPgtvL/btrhcOc5p9C/LjI2azqYQ7NSfadhwaGHB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPgtvL/btrhcOc5p9C/LjI2azqYQ7NSfadhwaGHB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPgtvL/btrhcOc5p9C/LjI2azqYQ7NSfadhwaGHB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPgtvL%2FbtrhcOc5p9C%2FLjI2azqYQ7NSfadhwaGHB0%2Fimg.png&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;199&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;http:0.13.3 버전으로 올라가면서 Uri를 parse 하도록 사용 방식이 변경되었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;get('uri'); 대신에 get(Uri.parse('uri'); 를 사용하면 해결된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;149&quot; width=&quot;926&quot; height=&quot;126&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5Qy5w/btrhfy7LX16/cbfy2HHD8Fotadkmlvkqnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5Qy5w/btrhfy7LX16/cbfy2HHD8Fotadkmlvkqnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5Qy5w/btrhfy7LX16/cbfy2HHD8Fotadkmlvkqnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5Qy5w%2Fbtrhfy7LX16%2Fcbfy2HHD8Fotadkmlvkqnk%2Fimg.png&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;149&quot; width=&quot;926&quot; height=&quot;126&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Flutter</category>
      <category>error</category>
      <category>Flutter</category>
      <category>Get</category>
      <category>HTTP</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/118</guid>
      <comments>https://bacha.tistory.com/118#entry118comment</comments>
      <pubDate>Sun, 10 Oct 2021 01:41:47 +0900</pubDate>
    </item>
    <item>
      <title>Flutter - Thread, Future, async 심화</title>
      <link>https://bacha.tistory.com/117</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[Thread]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 프로세스 내에서 실행되는 흐름의 단위&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Dart는 싱글 스레드로 운영되는 언어이다. 싱글 스레드로 동작 한다는 뜻은 오직 한번에 하나의 작업만 실행되고, 이 작업이 실행되는 동안 코드상에 존재하는 다른 작업들이 개입할 수 없다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Dart는 이런 싱글스레드의 단점을 Event loop로 해결한다. Dart는 스레드가 생성된 순간 3가지 작업을 하게 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; -&amp;gt; 선입 선출 방식으로 Micro Task(이벤트 큐로 넘어가기 전에, 아주 짧은 시간동안 비동기적으로 먼저 실행되고 끝&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 나는 작은 작업)와 &lt;b&gt;Evnet&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;준비&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; -&amp;gt; main 함수 실행&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; -&amp;gt; Evnet loop 실행&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[&lt;b&gt;Evnet loop&lt;/b&gt;]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 외부에서 전달되는 이벤트가 발생했을 때 이벤트과 관련된 코드들이 이벤트 큐에 등록이 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Future와 Stream도 이 이때 이벤트 큐에 등록이 되고 &lt;b&gt;Evnet loop를 통해서 처리된다.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;b&gt;[Future]&lt;/b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;- 비동기 방식으로 미래에 어느 시점에 완성이 되어서 실제적인 데이터가 되거나 에러를 반환하는 객체이다.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;- 코드상에서 새로운 Future를 객체화 시키면 다음 과정을 거친다.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1. 다트에 의해서 future 객체가 내부적인 배열에 등록&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;2.&amp;nbsp;Future관련해서&amp;nbsp;실행되어야&amp;nbsp;하는&amp;nbsp;코드들이&amp;nbsp;이벤트&amp;nbsp;큐에&amp;nbsp;등록&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;3.&amp;nbsp;불완전한&amp;nbsp;future객체가&amp;nbsp;반환&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/b&gt;4. Synchronous(동기적) 방식으로 실행되어야 할 다른 코드들이 있다면, 먼저 실행&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;5.&amp;nbsp;최종적으로&amp;nbsp;실제적인&amp;nbsp;data값이&amp;nbsp;future&amp;nbsp;객체로&amp;nbsp;전달&lt;br /&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;b&gt;[async method]&lt;/b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;- async 키워드를 사용하는 순간 Dart는 다음 과정을 거친다.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;1. 이 메서드를 통해서 나오는 결과물은 future임을 알게 된다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;2. &lt;b&gt;&lt;b&gt;await&amp;nbsp;&lt;/b&gt;&lt;/b&gt;키워드를 만날때까지 synchronous 방식으로 코드를 처리&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;3.&amp;nbsp;await&amp;nbsp;키워드를&amp;nbsp;만나면&amp;nbsp;future가&amp;nbsp;완료될때까지&amp;nbsp;대기&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;4.&amp;nbsp;future가&amp;nbsp;완료&amp;nbsp;되자마자&amp;nbsp;그&amp;nbsp;다음&amp;nbsp;코드들을&amp;nbsp;실행&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;- Dart는 await 키워드가 붙은 메서드를 만나면, 해당 메서드의 실행이 끝날 때까지 잠시 다른 코드 실행을 멈추게 되는 것&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[Future와 async 비교]&lt;/b&gt;&lt;b&gt;&lt;b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;- &lt;b&gt;&lt;b&gt;async 키워드는 비동기 방식으로 실행되는 함수라는 것을 Dart에게 알려주는 기능을 담당하고, await 키워드와 함께 미래의 어느 시점에 전달될 값을 기다리는 것이다.&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;- 이와는 다르게 Future는 하나의 객체로써 객체가 생성된 순간에는 미완성으로 존재하다가, 미래에 어느 시점에 데이터를 전달받은 온전한 객체가 되거나 문제가 생성될 시 에러를 반환하는 객체가 된다.&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Ex]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1633712285223&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void main() async {
  methodA();
  await methodB();
  await methodC('main');
  methodD();
}

methodA(){
  print('A');
}

methodB() async {
  print('B start');
  await methodC('B');
  print('B end');
}

methodC(String from) async {
  print('C start from $from');

  Future((){
    print('C running Future from $from');
  }).then((_){
    print('C end of Future from $from');
  });

  print('C end from $from');
}

methodD(){
  print('D');
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;306&quot; data-origin-height=&quot;300&quot; width=&quot;437&quot; height=&quot;428&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sGGTA/btrhgk8G5sK/5Raz3CxKTY6oRg7HwICjAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sGGTA/btrhgk8G5sK/5Raz3CxKTY6oRg7HwICjAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sGGTA/btrhgk8G5sK/5Raz3CxKTY6oRg7HwICjAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsGGTA%2Fbtrhgk8G5sK%2F5Raz3CxKTY6oRg7HwICjAk%2Fimg.png&quot; data-origin-width=&quot;306&quot; data-origin-height=&quot;300&quot; width=&quot;437&quot; height=&quot;428&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[결과 설명]&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[A]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- main 에서 시작되는 methodA 에 의해 출력&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[B start]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;main 함수에서 두번째로 실행되는 &lt;b&gt;methodB 함수가 실행되어 출력&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[C start from B]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;methodB 함수 내에서 &lt;/b&gt;&lt;/b&gt;await methodC('B'); 에서 &lt;b&gt;await&lt;span&gt; 키워드를 만나 &lt;b&gt;methodC 함수의 실행이 끝날때까지 &lt;b&gt;&lt;b&gt;&lt;b&gt;methodB&lt;span&gt; 함수 내에서 그 이하의 코드 실행을 멈추게 된다. 따라서 &lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;methodC&lt;span&gt; 함수 실행되어 출력&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[C end from B]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;다음 줄에 Future 키워드를 만나게 되어 Future 관련 코드들이 즉시 Event 큐에 등록된다. Future 다음 줄이 실행되어 출력&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[B end]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;await&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;키워드가 붙은 &lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;methodC&lt;span&gt;&lt;span&gt; 함수의 실행이 완료되어 다음 줄이 실행되어 출력&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[C start from main]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;main 에서 &lt;b&gt;&lt;b&gt;await&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;키워드가 붙은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;methodC&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수가 실행되어 &lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;methodC 함수의 실행이 끝날때까지 그 이하의 코드들은 대기하게 된다. &lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;methodC 함수 첫줄 출력&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[C end from main]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;다음 줄에 Future 키워드를 만나게 되어 Future 관련 코드들이 즉시 Event 큐에 등록된다. Future 다음 줄이 실행되어 출력&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[D]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;await&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;키워드가 붙은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;b&gt;methodC&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수의 실행이 완료되어 다음 줄이 실행되어 출력&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[C running Future from B]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- main의 코드들이 끝까지 실행되어 Synchronous(동기적) 방식으로 실행되어야 할 다른 코드들이 없으므로 Event 큐에 저장되어 있던 Future 관련 코드들이 실행된다. 선입선출 방식이므로 해당 코드 실행&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[C end of Future from B]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- then 코드에 의해서 해당 내용 출력&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[C running Future from main]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 선입 선출 방식에 따라 다음 내용 출력&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[C end of Future from main]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- then 코드에 의해서 해당 내용 출력&lt;/b&gt;&lt;/p&gt;</description>
      <category>Flutter</category>
      <category>async</category>
      <category>Await</category>
      <category>Flutter</category>
      <category>Future</category>
      <category>Thread</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/117</guid>
      <comments>https://bacha.tistory.com/117#entry117comment</comments>
      <pubDate>Sat, 9 Oct 2021 02:11:33 +0900</pubDate>
    </item>
    <item>
      <title>Flutter - Future, async, await</title>
      <link>https://bacha.tistory.com/116</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[Future]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 미래에 구체적인 결과물로 실제적인 객체로 반환된다는 의미&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 일종의 약속이자, 해당 결과를 추후에 확인 가능하다는 의미&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Future 클래스는 일정 소요시간이 지난 후에 실제 데이터 값이나, 에러가 있는 경우 에러를 반환한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Future 클래스는 &lt;b&gt;Future&amp;lt;String&amp;gt;같이, 제네릭처럼 어떤 결과물을 받아야 할지 미리 지정해둘 수 있다.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;- Future&amp;lt;void&amp;gt;와 일반 void 함수의 차이점은 언제 함수의 실행이 끝날지 지정해 줄수 있다는 것.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[async]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- async 클래스는 await 메서드를 가지고 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- await 으로 선언된 메서드는 응답이 처리될 때 까지 대기하는 비동기 식으로 동작한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- &lt;b&gt;async&lt;/b&gt;제어자는 항상 중괄호 앞에 선언해야 한다. 선헌하게 되면 await 키워드를 사용할 수 있게 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;293&quot; data-origin-height=&quot;83&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/drPtED/btrg2Ly8bfR/xUTmlYCIdPLcyMlEykpRQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/drPtED/btrg2Ly8bfR/xUTmlYCIdPLcyMlEykpRQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/drPtED/btrg2Ly8bfR/xUTmlYCIdPLcyMlEykpRQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdrPtED%2Fbtrg2Ly8bfR%2FxUTmlYCIdPLcyMlEykpRQ1%2Fimg.png&quot; data-origin-width=&quot;293&quot; data-origin-height=&quot;83&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[예제 코드]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1633533263649&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import 'dart:io';

void main() {
  showData();
}

void showData() async{
  startTask();
  String account = await accessData();
  fetchData(account);
}

void startTask() {
  String info1 = '요청 수행 시작';
  print(info1);
}

Future&amp;lt;String&amp;gt; accessData() async{
  String account;
  Duration time = Duration(seconds: 3);

  if (time.inSeconds &amp;gt; 2) {
    //sleep(time);

    // await 키워드는 Future.delayed의 실행이 다 될때까지 기다리라는 의미
    await Future.delayed(time, () {
      account = '8,500만원';
      print(account);
    });
  } else {
    String info2 = '데이터를 가져왔습니다.';
    print(info2);
  }
  return account;
}

void fetchData(String account) {
  String info3 = '잔액은 $account 입니다.';
  print(info3);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;201&quot; data-origin-height=&quot;85&quot; width=&quot;310&quot; height=&quot;131&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FqqJe/btrg2Mx1JIi/mMnfiBmOvXdFi9sidKdQ90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FqqJe/btrg2Mx1JIi/mMnfiBmOvXdFi9sidKdQ90/img.png&quot; data-alt=&quot;await 키워드가 없을 때 실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FqqJe/btrg2Mx1JIi/mMnfiBmOvXdFi9sidKdQ90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFqqJe%2Fbtrg2Mx1JIi%2FmMnfiBmOvXdFi9sidKdQ90%2Fimg.png&quot; data-origin-width=&quot;201&quot; data-origin-height=&quot;85&quot; width=&quot;310&quot; height=&quot;131&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;await 키워드가 없을 때 실행 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;75&quot; width=&quot;396&quot; height=&quot;116&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dzE0Sj/btrg4KfqnUN/5IkN0b7WXuVf7bjg8dDGH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzE0Sj/btrg4KfqnUN/5IkN0b7WXuVf7bjg8dDGH1/img.png&quot; data-alt=&quot;await 키워드가 있을 때 실행 화면 &quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzE0Sj/btrg4KfqnUN/5IkN0b7WXuVf7bjg8dDGH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdzE0Sj%2Fbtrg4KfqnUN%2F5IkN0b7WXuVf7bjg8dDGH1%2Fimg.png&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;75&quot; width=&quot;396&quot; height=&quot;116&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;await 키워드가 있을 때 실행 화면 &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/116</guid>
      <comments>https://bacha.tistory.com/116#entry116comment</comments>
      <pubDate>Thu, 7 Oct 2021 00:15:58 +0900</pubDate>
    </item>
    <item>
      <title>flutter - 2.0 button ElevatedButton으로 구글, 페이스북, 메일 로그인 버튼 만들기</title>
      <link>https://bacha.tistory.com/115</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 구글, 페이스북 이미지 파일&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bzAN9K/btrgWEGWVEY/HcuI4xhM6HDi8B3zLnU1c0/flogo.png?attach=1&amp;amp;knm=img.png&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;flogo.png&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/xPkPN/btrgQBSvM4Z/4oZ7velqLsSnZ3k8mYIcjk/glogo.png?attach=1&amp;amp;knm=img.png&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;glogo.png&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;imges 폴더를 만든 후 해당 파일을 저장한 뒤,&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;122&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/X18K0/btrgMAstAMd/MHtmYaciGkGzrFQonua3DK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/X18K0/btrgMAstAMd/MHtmYaciGkGzrFQonua3DK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/X18K0/btrgMAstAMd/MHtmYaciGkGzrFQonua3DK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FX18K0%2FbtrgMAstAMd%2FMHtmYaciGkGzrFQonua3DK%2Fimg.png&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;122&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;pubspec.yaml 파일에서 경로 설정해주기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 코드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1633455794243&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Login app',
      theme: ThemeData(primarySwatch: Colors.grey),
      home: LogIn(),
    );
  }
}

class LogIn extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.blue,
        title: Text(
          'Sign In',
          style: TextStyle(color: Colors.white),
        ),
        centerTitle: true,
        elevation: 0.2,
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [


            ElevatedButton(
              onPressed: () {
                print('TextButton Button');
              },

              child: Row(
                //spaceEvenly: 요소들을 균등하게 배치하는 속성
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Image.asset('images/glogo.png'),
                  Text('Login with Google',
                    style: TextStyle(color: Colors.black87, fontSize: 15.0),
                  ),
                  Opacity(
                    opacity: 0.0,
                    child: Image.asset('images/glogo.png'),
                  ),
                ],
              ), 
              style: ElevatedButton.styleFrom(
                primary: Colors.white,
                //shadowColor: Colors.black, 그림자 추가하는 속성

                minimumSize: Size.fromHeight(50), // 높이만 50으로 설정
                elevation: 1.0,
                shape: RoundedRectangleBorder(
                    // shape : 버튼의 모양을 디자인 하는 기능
                    borderRadius: BorderRadius.circular(4.0)),
                ),
            ),
            SizedBox(
              height: 10.0,
            ),
            ElevatedButton(
              onPressed: () {
                print('TextButton Button');
              },
              child: Row(
                //spaceEvenly: 요소들을 균등하게 배치하는 속성
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Image.asset('images/flogo.png'),
                  Text(
                    'Login with Facebook',
                    style: TextStyle(color: Colors.white, fontSize: 15.0),
                  ),
                  Opacity(
                    opacity: 0.0,
                    child: Image.asset('images/glogo.png'),
                  ),
                ],
              ),
              style: ElevatedButton.styleFrom(
                primary: Color(0xFF334D92),


                minimumSize: Size.fromHeight(50),
                elevation: 1.0,
                shape: RoundedRectangleBorder(

                    borderRadius: BorderRadius.circular(4.0)),
              ),
            ),
            SizedBox(
              height: 10.0,
            ),
            ElevatedButton(
              onPressed: () {
                print('TextButton Button');
              },
              child: Row(
                //spaceEvenly: 요소들을 균등하게 배치하는 속성
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Icon(
                      Icons.mail,
                      color: Colors.white,
                    ),
                  Text(
                    'Login with Email',
                    style: TextStyle(color: Colors.white, fontSize: 15.0),
                  ),
                  Opacity(
                    opacity: 0.0,
                    child: Icon(
                      Icons.mail,
                      //color: Colors.white,
                    ),
                  ),
                ],
              ),
              style: ElevatedButton.styleFrom(
                primary: Colors.green,


                minimumSize: Size.fromHeight(50),
                elevation: 1.0,
                shape: RoundedRectangleBorder(

                    borderRadius: BorderRadius.circular(4.0)),
              ),
            ),
            
          ],
        ),
      ),
    );
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. 결과 화면&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;786&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dC8cgB/btrgYlNFoAh/zOFyWy7yTXfikvhayKI3GK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dC8cgB/btrgYlNFoAh/zOFyWy7yTXfikvhayKI3GK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dC8cgB/btrgYlNFoAh/zOFyWy7yTXfikvhayKI3GK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdC8cgB%2FbtrgYlNFoAh%2FzOFyWy7yTXfikvhayKI3GK%2Fimg.png&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;786&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Flutter</category>
      <category>2.0 button</category>
      <category>ElevatedButton</category>
      <category>Flutter</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/115</guid>
      <comments>https://bacha.tistory.com/115#entry115comment</comments>
      <pubDate>Wed, 6 Oct 2021 02:47:28 +0900</pubDate>
    </item>
    <item>
      <title>Flutter - final 과 const</title>
      <link>https://bacha.tistory.com/114</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;final 과 const는 '제어자' 라고 하며 제어자란 클래스, 변수, 메서드를 정의할 때 함께 쓰여서 이것들을 사용하기 위한 옵션을 정해주는 역할을 수행한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;b&gt;- final 과 const 키워드의 가장 중요한 역할은 변수값이 한번 초기화 되면 바꿀 수 없게 하는 것이다.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;b&gt;- 문제는 이 같은 역할을 하는 &lt;b&gt;&lt;b&gt;final 과 const의 차이점이다.&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[final]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- final 변수는 런타임 시에 상수화 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- final은 const와는 달리 초기화 되는 시점이 앱이 실행이 될 때이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- &lt;b&gt;final은 한번 초기화되면 immutable하기 때문에 &lt;/b&gt;&lt;b&gt;값을 변경하고 싶다면 아예 새롭게 빌드 메서드 내에서 rebuild 해야 한다.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[const]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- &lt;b&gt;const 변수는 컴파일 시에 상수화 한다.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- const는 선언과 동시에 반드시 초기화 해야한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- &lt;b&gt;const에 final 변수처럼 컴파일 이후에 value 값을 재할당하면 에러가 난다.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>Flutter</category>
      <category>const</category>
      <category>final</category>
      <category>Flutter</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/114</guid>
      <comments>https://bacha.tistory.com/114#entry114comment</comments>
      <pubDate>Wed, 6 Oct 2021 00:07:07 +0900</pubDate>
    </item>
    <item>
      <title>day70 - Spring Framework(spring boot의 설정 application.properties)</title>
      <link>https://bacha.tistory.com/113</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;스프링 부트에서는 기존 스프링에서 web.xml 같은 설정 파일들을 application.properties에 가독성 좋게 모아놓았다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;324&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m9pib/btrghQIr2pU/DEZCRMKhkLnF5EqzMK2zx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m9pib/btrghQIr2pU/DEZCRMKhkLnF5EqzMK2zx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m9pib/btrghQIr2pU/DEZCRMKhkLnF5EqzMK2zx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm9pib%2FbtrghQIr2pU%2FDEZCRMKhkLnF5EqzMK2zx1%2Fimg.png&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;324&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;215&quot; data-origin-height=&quot;23&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rBNgE/btrgh912ky6/tMXyLy3njucMuffWx60Uk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rBNgE/btrgh912ky6/tMXyLy3njucMuffWx60Uk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rBNgE/btrgh912ky6/tMXyLy3njucMuffWx60Uk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrBNgE%2Fbtrgh912ky6%2FtMXyLy3njucMuffWx60Uk0%2Fimg.png&quot; data-origin-width=&quot;215&quot; data-origin-height=&quot;23&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[서버]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실습해보니 스프링 부트는 톰켓 서버를 로딩하지 않는다. 자기가 알아서 서버를 핸들링 한다고 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;38&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rwRVk/btrgh9nr14y/1aZduNoKr3zzJl89bB9n9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rwRVk/btrgh9nr14y/1aZduNoKr3zzJl89bB9n9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rwRVk/btrgh9nr14y/1aZduNoKr3zzJl89bB9n9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrwRVk%2Fbtrgh9nr14y%2F1aZduNoKr3zzJl89bB9n9K%2Fimg.png&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;38&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[기존 스프링의 viewResolvor]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기존 스프링의 &lt;b&gt;viewResolvor 부분이다. &lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;기존이라면 sevlet.xml에서&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;106&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Mqrwy/btrgh2u6EsC/ElElNMeOZS4evvKL47qY61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Mqrwy/btrgh2u6EsC/ElElNMeOZS4evvKL47qY61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Mqrwy/btrgh2u6EsC/ElElNMeOZS4evvKL47qY61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMqrwy%2Fbtrgh2u6EsC%2FElElNMeOZS4evvKL47qY61%2Fimg.png&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;106&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이렇게 썼을 내용을 단 두줄로 해결한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;79&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/R06Hx/btrgh9udnrP/73tPcm2xm8qqjOI9qhpyW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/R06Hx/btrgh9udnrP/73tPcm2xm8qqjOI9qhpyW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/R06Hx/btrgh9udnrP/73tPcm2xm8qqjOI9qhpyW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FR06Hx%2Fbtrgh9udnrP%2F73tPcm2xm8qqjOI9qhpyW0%2Fimg.png&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;79&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[DB 연결]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;db 연결 부분&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;103&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czWhsv/btrgjGkyjvm/W5MKOBN6wSmk9uavFyRcbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czWhsv/btrgjGkyjvm/W5MKOBN6wSmk9uavFyRcbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czWhsv/btrgjGkyjvm/W5MKOBN6wSmk9uavFyRcbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczWhsv%2FbtrgjGkyjvm%2FW5MKOBN6wSmk9uavFyRcbk%2Fimg.png&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;103&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Multipart]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기존 sevlet.xml의 multipartResolver 부분이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;83&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cy5XcZ/btrgbmWaW8l/UjTNdPuGb3lUJkgAat74A1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cy5XcZ/btrgbmWaW8l/UjTNdPuGb3lUJkgAat74A1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cy5XcZ/btrgbmWaW8l/UjTNdPuGb3lUJkgAat74A1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcy5XcZ%2FbtrgbmWaW8l%2FUjTNdPuGb3lUJkgAat74A1%2Fimg.png&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;83&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[UTF-8&amp;nbsp;ENCODING]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기존의 web.xml encodingFilter 부분이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>KIC/Spring</category>
      <category>Spring Boot</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/113</guid>
      <comments>https://bacha.tistory.com/113#entry113comment</comments>
      <pubDate>Tue, 28 Sep 2021 19:23:53 +0900</pubDate>
    </item>
    <item>
      <title>day69 - Spring Framework(spring boot 시작하기 STS4)</title>
      <link>https://bacha.tistory.com/112</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[sts4 개발 환경]&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[sts4 설치하기]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://spring.io/tools&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://spring.io/tools&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1632754093448&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Spring Tools 4 is the next generation of Spring tooling&quot; data-og-description=&quot;Largely rebuilt from scratch, Spring Tools 4 provides world-class support for developing Spring-based enterprise applications, whether you prefer Eclipse, Visual Studio Code, or Theia IDE.&quot; data-og-host=&quot;spring.io&quot; data-og-source-url=&quot;https://spring.io/tools&quot; data-og-url=&quot;https://spring.io/tools&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://spring.io/tools&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://spring.io/tools&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Spring Tools 4 is the next generation of Spring tooling&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Largely rebuilt from scratch, Spring Tools 4 provides world-class support for developing Spring-based enterprise applications, whether you prefer Eclipse, Visual Studio Code, or Theia IDE.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;spring.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;597&quot; data-origin-height=&quot;598&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYeNTt/btrgcBjDG39/oj9XlPk1beTbkuPRmFhf40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYeNTt/btrgcBjDG39/oj9XlPk1beTbkuPRmFhf40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYeNTt/btrgcBjDG39/oj9XlPk1beTbkuPRmFhf40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYeNTt%2FbtrgcBjDG39%2Foj9XlPk1beTbkuPRmFhf40%2Fimg.png&quot; data-origin-width=&quot;597&quot; data-origin-height=&quot;598&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[File - New - Project]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;482&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pkr4Z/btrf7AM4ilf/vfcOn6REwZQydgCvx3ItLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pkr4Z/btrf7AM4ilf/vfcOn6REwZQydgCvx3ItLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pkr4Z/btrf7AM4ilf/vfcOn6REwZQydgCvx3ItLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpkr4Z%2Fbtrf7AM4ilf%2FvfcOn6REwZQydgCvx3ItLK%2Fimg.png&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;482&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Spring Starter Project&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;838&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bttAR6/btrgbyHqUfI/Cb9PdQo4YR4GwN5Xw7qSU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bttAR6/btrgbyHqUfI/Cb9PdQo4YR4GwN5Xw7qSU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bttAR6/btrgbyHqUfI/Cb9PdQo4YR4GwN5Xw7qSU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbttAR6%2FbtrgbyHqUfI%2FCb9PdQo4YR4GwN5Xw7qSU1%2Fimg.png&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;838&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이름, 패키지 등 원하는 부분 변경하여 설정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;585&quot; data-origin-height=&quot;709&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kQj60/btrgbzGkyX2/zlwNcos7GgXG3FsQIKCCEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kQj60/btrgbzGkyX2/zlwNcos7GgXG3FsQIKCCEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kQj60/btrgbzGkyX2/zlwNcos7GgXG3FsQIKCCEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkQj60%2FbtrgbzGkyX2%2FzlwNcos7GgXG3FsQIKCCEk%2Fimg.png&quot; data-origin-width=&quot;585&quot; data-origin-height=&quot;709&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;검색해서 원하는 설정을 기입하고 완료&lt;/b&gt;&lt;/p&gt;</description>
      <category>KIC/Spring</category>
      <category>Spring Boot</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/112</guid>
      <comments>https://bacha.tistory.com/112#entry112comment</comments>
      <pubDate>Mon, 27 Sep 2021 23:50:12 +0900</pubDate>
    </item>
    <item>
      <title>day68 - 스프링 팀 프로젝트 관리자 페이지 구현</title>
      <link>https://bacha.tistory.com/111</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1404&quot; data-origin-height=&quot;831&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9yofY/btrgdGyeKoq/90CKyjjKqTWDkhHm9JZnCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9yofY/btrgdGyeKoq/90CKyjjKqTWDkhHm9JZnCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9yofY/btrgdGyeKoq/90CKyjjKqTWDkhHm9JZnCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9yofY%2FbtrgdGyeKoq%2F90CKyjjKqTWDkhHm9JZnCk%2Fimg.png&quot; data-origin-width=&quot;1404&quot; data-origin-height=&quot;831&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[userController.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1632753361208&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.kic.shopPro.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.kic.shopPro.domain.TopItemVO;
import com.kic.shopPro.domain.VisitorGraphVO;
import com.kic.shopPro.domain.VisitorVO;
import com.kic.shopPro.service.VisitorService;

@Controller
public class UserController {
	
	@Autowired
	private VisitorService visitorService;

	@RequestMapping(value=&quot;/admin/adminPage&quot;, method=RequestMethod.GET)
	public String adminPageGetMethod(Model model) {
		
		visitorService.addVisitor();
		
		List&amp;lt;VisitorVO&amp;gt; visitors = visitorService.readVisitorList(); // 오늘 방문자, 어제 방문자, 누적 방문자 수 출력 기능
		List&amp;lt;VisitorGraphVO&amp;gt; visitorGraph = visitorService.readVisitorGraphList(); // 방문자 그래프 출력 기능
		
		//String text = &quot;결제 완료&quot;;
		double reachedCost = ((double)visitorService.reachedTotalCost()/500000) * 100; // 50만원을 목표 금액으로한 퍼센트값 저장
		
		List&amp;lt;TopItemVO&amp;gt; topItemList = visitorService.readTopItemList();
		
		//오늘,어제 누적 방문자수 출력
		model.addAttribute(&quot;visitors&quot;, visitors);
		
		System.out.println(&quot;===========================&quot; + visitorGraph.size());
		System.out.println(&quot;===========================&quot; +visitorGraph.toString());
		System.out.println(&quot;===========================&quot; + visitorService.reachedTotalCost());
		System.out.println(&quot;===========================&quot; +reachedCost);
		
		// 방문자 그래프 출력
		model.addAttribute(&quot;visitorGraph&quot;, visitorGraph);
		
		// 목표 도달 수익률 추이 출력
		model.addAttribute(&quot;reachedCost&quot;, reachedCost);
		
		// 인기 품목 리스트
		model.addAttribute(&quot;topItemList&quot;, topItemList);
		
		
		return &quot;admin/adminPage&quot;;
	}

	
	
	
	@RequestMapping(value=&quot;/MyPage&quot;, method=RequestMethod.GET)
	public String myPageGetMethod() {
		return &quot;MyPage&quot;;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[userMapper.xml]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1632753403864&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;

&amp;lt;!DOCTYPE mapper PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot; &quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&amp;gt;

&amp;lt;mapper namespace=&quot;com.kic.mapper.userMapper&quot;&amp;gt;

	
	
	&amp;lt;select id=&quot;readVisit&quot; resultType=&quot;com.kic.shopPro.domain.VisitorVO&quot;&amp;gt;
		&amp;lt;![CDATA[ (select count(*) visitor from visitor group by visitdate order by visitdate desc limit 0, 2)
					UNION
					(select count(*) visitor from visitor) ]]&amp;gt;
	&amp;lt;/select&amp;gt;
	
	&amp;lt;select id=&quot;readVisitGraph&quot; resultType=&quot;com.kic.shopPro.domain.VisitorGraphVO&quot;&amp;gt;
		&amp;lt;![CDATA[ select visitdate, count(*) visitor from visitor group by visitdate order by visitdate limit 0, 5]]&amp;gt;
	&amp;lt;/select&amp;gt;
	
	&amp;lt;insert id=&quot;addVisit&quot;&amp;gt;
	 	&amp;lt;![CDATA[ insert into visitor(visitdate) values(NOW())  ]]&amp;gt;
    &amp;lt;/insert&amp;gt;
    
    &amp;lt;select id=&quot;reachedCost&quot; resultType=&quot;int&quot;&amp;gt;
		&amp;lt;![CDATA[   select sum(price) reachCost from orderlist where pay= &quot;결제 완료&quot;]]&amp;gt;
	&amp;lt;/select&amp;gt;
	
	&amp;lt;select id=&quot;readTopItem&quot; resultType=&quot;com.kic.shopPro.domain.TopItemVO&quot;&amp;gt;
		&amp;lt;![CDATA[ 	select i.itemname
					from orderlist o, item i
					where o.orderid = i.itemid
					and pay= &quot;결제 완료&quot; order by count desc  ]]&amp;gt;
	&amp;lt;/select&amp;gt;

&amp;lt;/mapper&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[adminPage.jsp]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1632753443858&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot; pageEncoding=&quot;UTF-8&quot;%&amp;gt;
&amp;lt;%@ taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot; %&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;title&amp;gt;W3.CSS Template&amp;lt;/title&amp;gt;
&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&amp;gt;

&amp;lt;!-- 수정  --&amp;gt;
&amp;lt;!-- 차트 부분--&amp;gt;
&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt; 
&amp;lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&amp;gt;



&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;https://www.w3schools.com/w3css/4/w3.css&quot;&amp;gt;
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;https://fonts.googleapis.com/css?family=Raleway&quot;&amp;gt;
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css&quot;&amp;gt;



&amp;lt;!-- 차트 링크 --&amp;gt; 
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css&quot; integrity=&quot;sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T&quot; crossorigin=&quot;anonymous&quot;&amp;gt; 
&amp;lt;script src=&quot;https://cdn.jsdelivr.net/npm/chart.js@2.8.0&quot;&amp;gt;&amp;lt;/script&amp;gt;



&amp;lt;style&amp;gt;
body,h1,h2,h3,h4,h5,h6 {font-family: &quot;Raleway&quot;, sans-serif}
hr {
  height: 0.5px;
  background-color: gray;
}
&amp;lt;/style&amp;gt;
&amp;lt;body class=&quot;w3-light-grey w3-content&quot; style=&quot;max-width:1600px&quot;&amp;gt;

&amp;lt;!-- Sidebar/menu --&amp;gt;
&amp;lt;nav class=&quot;w3-sidebar w3-collapse w3-white w3-animate-left&quot; style=&quot;z-index:3;width:300px;&quot; id=&quot;mySidebar&quot;&amp;gt;&amp;lt;br&amp;gt;
  &amp;lt;div class=&quot;w3-container&quot;&amp;gt;
    &amp;lt;a href=&quot;#&quot; onclick=&quot;w3_close()&quot; class=&quot;w3-hide-large w3-right w3-jumbo w3-padding w3-hover-grey&quot; title=&quot;close menu&quot;&amp;gt;
      &amp;lt;i class=&quot;fa fa-remove&quot;&amp;gt;&amp;lt;/i&amp;gt;
    &amp;lt;/a&amp;gt;
    &amp;lt;h2 onclick=&quot;location.href ='/shopPro/main'&quot;&amp;gt;&amp;lt;b&amp;gt;쇼핑몰 사이트&amp;lt;/b&amp;gt;&amp;lt;/h2&amp;gt;
    &amp;lt;p class=&quot;w3-text-grey&quot;&amp;gt;Market Info&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&quot;w3-bar-block&quot;&amp;gt;
    &amp;lt;a href=&quot;#portfolio&quot; onclick=&quot;w3_close()&quot; class=&quot;w3-bar-item w3-button w3-padding w3-text-teal&quot;&amp;gt;&amp;lt;i class=&quot;fa fa-th-large fa-fw w3-margin-right&quot;&amp;gt;&amp;lt;/i&amp;gt;admin Info&amp;lt;/a&amp;gt; 
    &amp;lt;a href=&quot;#about&quot; onclick=&quot;w3_close()&quot; class=&quot;w3-bar-item w3-button w3-padding&quot;&amp;gt;&amp;lt;i class=&quot;fa fa-user fa-fw w3-margin-right&quot;&amp;gt;&amp;lt;/i&amp;gt;ABOUT&amp;lt;/a&amp;gt; 
    &amp;lt;a href=&quot;#contact&quot; onclick=&quot;w3_close()&quot; class=&quot;w3-bar-item w3-button w3-padding&quot;&amp;gt;&amp;lt;i class=&quot;fa fa-envelope fa-fw w3-margin-right&quot;&amp;gt;&amp;lt;/i&amp;gt;CONTACT&amp;lt;/a&amp;gt;
  &amp;lt;/div&amp;gt;

&amp;lt;/nav&amp;gt;



&amp;lt;!-- Overlay effect when opening sidebar on small screens --&amp;gt;
&amp;lt;div class=&quot;w3-overlay w3-hide-large w3-animate-opacity&quot; onclick=&quot;w3_close()&quot; style=&quot;cursor:pointer&quot; title=&quot;close side menu&quot; id=&quot;myOverlay&quot;&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;!-- !PAGE CONTENT! --&amp;gt;
&amp;lt;div class=&quot;w3-main&quot; style=&quot;margin-left:300px&quot;&amp;gt;

  &amp;lt;!-- Header --&amp;gt;
  &amp;lt;!-- 
  &amp;lt;header id=&quot;portfolio&quot;&amp;gt;
    &amp;lt;a href=&quot;#&quot;&amp;gt;&amp;lt;img src=&quot;/w3images/avatar_g2.jpg&quot; style=&quot;width:65px;&quot; class=&quot;w3-circle w3-right w3-margin w3-hide-large w3-hover-opacity&quot;&amp;gt;&amp;lt;/a&amp;gt;
    &amp;lt;span class=&quot;w3-button w3-hide-large w3-xxlarge w3-hover-text-grey&quot; onclick=&quot;w3_open()&quot;&amp;gt;&amp;lt;i class=&quot;fa fa-bars&quot;&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;div class=&quot;w3-container&quot;&amp;gt;
    
    &amp;lt;h1&amp;gt;&amp;lt;b&amp;gt;관리자 페이지&amp;lt;/b&amp;gt;&amp;lt;/h1&amp;gt;
	&amp;lt;br&amp;gt;
    &amp;lt;/div&amp;gt;
    
  &amp;lt;/header&amp;gt;
   --&amp;gt;
   
   &amp;lt;!-- 관리자 페이지 헤더 --&amp;gt;
  &amp;lt;jsp:include page=&quot;/WEB-INF/views/sideView/adminHeader.jsp&quot;&amp;gt;&amp;lt;/jsp:include&amp;gt;

  &amp;lt;div class=&quot;w3-container w3-padding-large&quot; style=&quot;margin-bottom:32px;&quot;&amp;gt;

    
    &amp;lt;h4&amp;gt;&amp;lt;b&amp;gt;방문자 수&amp;lt;/b&amp;gt;&amp;lt;/h4&amp;gt;
    &amp;lt;br&amp;gt;
    &amp;lt;!-- Progress bars / Skills --&amp;gt;
    &amp;lt;table style=&quot;width:500px&quot;&amp;gt;
    &amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;오늘 방문수&amp;lt;/b&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;어제 방문수&amp;lt;/b&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;누적 방문수&amp;lt;/b&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
    
    &amp;lt;tr&amp;gt;
    &amp;lt;c:forEach var=&quot;member&quot; items=&quot;${visitors}&quot;&amp;gt;
       &amp;lt;td&amp;gt; ${member.visitor}&amp;lt;/td&amp;gt;
       
    &amp;lt;/c:forEach&amp;gt;
    &amp;lt;/tr&amp;gt;

    &amp;lt;/table&amp;gt;



    &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;
    
    
    
	&amp;lt;h4&amp;gt;&amp;lt;b&amp;gt;방문자 수 그래프&amp;lt;/b&amp;gt;&amp;lt;/h4&amp;gt;
    &amp;lt;div class=&quot;container&quot; style=&quot;width:70%; float:left;&quot;&amp;gt; 
    	&amp;lt;canvas id=&quot;myChart&quot;&amp;gt;&amp;lt;/canvas&amp;gt; 
    &amp;lt;/div&amp;gt;
    
    
    
    &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;
    
    &amp;lt;!-- 부트스트랩 --&amp;gt; 
    &amp;lt;script src=&quot;https://code.jquery.com/jquery-3.3.1.slim.min.js&quot; 				
    		integrity=&quot;sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo&quot; 
    		crossorigin=&quot;anonymous&quot;&amp;gt;
    &amp;lt;/script&amp;gt; 
    &amp;lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js&quot; 
    		integrity=&quot;sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1&quot; 
    		crossorigin=&quot;anonymous&quot;&amp;gt;
    &amp;lt;/script&amp;gt; 
    &amp;lt;script src=&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js&quot; 
    		integrity=&quot;sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM&quot; 
    		crossorigin=&quot;anonymous&quot;&amp;gt;
    &amp;lt;/script&amp;gt;
    
    
    &amp;lt;!-- 차트 --&amp;gt; 
    &amp;lt;script&amp;gt; 
    	var ctx = document.getElementById('myChart').getContext('2d');
    	
    	var date = new Array();
    	var visitdata = new Array();
    	&amp;lt;c:forEach var=&quot;member&quot; items=&quot;${visitorGraph}&quot;&amp;gt;date.push(&quot;${member.visitdate}&quot;);visitdata.push(&quot;${member.visitor}&quot;); &amp;lt;/c:forEach&amp;gt;
        var chart = new Chart(ctx, 
        	{ // 챠트 종류를 선택 
            	type: 'line', // 챠트를 그릴 데이타 
            	data: { 
                	labels: date, 						
                	
                	
                	datasets: [{ 
                    	label: '방문자 수 차트', 
                        backgroundColor: 'transparent', 
                        borderColor: 'red', 
                        data: visitdata
                     }] 
                    }, 
                    // 옵션 
                    options: {} 
                  }); 
    &amp;lt;/script&amp;gt;


    &amp;lt;h4&amp;gt;&amp;lt;b&amp;gt;수익 목표 달성률&amp;lt;/b&amp;gt;&amp;lt;/h4&amp;gt;
    &amp;lt;br&amp;gt;
    &amp;lt;div class=&quot;w3-grey&quot; style=&quot;width:70%;&quot;&amp;gt;
      &amp;lt;div class=&quot;w3-container w3-dark-grey w3-padding w3-center&quot; style=&quot;width:${reachedCost}%&quot;&amp;gt;${reachedCost}%&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;
    &amp;lt;hr&amp;gt;
    &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;
    
    
      &amp;lt;div&amp;gt;
          &amp;lt;h4&amp;gt;How much I charge&amp;lt;/h4&amp;gt;
    &amp;lt;!-- Pricing Tables --&amp;gt;

      
      &amp;lt;div class=&quot;w3-third w3-margin-bottom&quot;&amp;gt;
        &amp;lt;ul class=&quot;w3-ul w3-border w3-white &quot;&amp;gt;
          &amp;lt;li class=&quot;w3-black w3-center w3-xlarge w3-padding-32&quot;&amp;gt;인기 상품 품목&amp;lt;/li&amp;gt;

	   	 &amp;lt;table&amp;gt;
	   	    
   			 &amp;lt;c:forEach end=&quot;4&quot; varStatus=&quot;i&quot; var=&quot;member&quot; items=&quot;${topItemList}&quot;&amp;gt;
   			  &amp;lt;tr&amp;gt;
     		  &amp;lt;td&amp;gt; &amp;lt;li class=&quot;w3-padding-16&quot;&amp;gt;&amp;lt;b&amp;gt; ${i.index + 1}. &amp;amp;nbsp;&amp;lt;/b&amp;gt;&amp;lt;td&amp;gt;${member.itemName}&amp;lt;/li&amp;gt;&amp;lt;/td&amp;gt;
       		  &amp;lt;/tr&amp;gt;
    		&amp;lt;/c:forEach&amp;gt;
    		

    	&amp;lt;/table&amp;gt;
        &amp;lt;/ul&amp;gt;
      &amp;lt;/div&amp;gt;
      
      

    &amp;lt;/div&amp;gt;

      

   &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;
  &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;
    &amp;lt;hr&amp;gt;
    &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;
  


  &amp;lt;!-- Footer --&amp;gt;
  &amp;lt;footer class=&quot;w3-container w3-padding-32 w3-dark-grey&quot;&amp;gt;
  &amp;lt;div class=&quot;w3-row-padding&quot;&amp;gt;
    &amp;lt;div class=&quot;w3-third&quot;&amp;gt;
      &amp;lt;h3&amp;gt;FOOTER&amp;lt;/h3&amp;gt;
      &amp;lt;p&amp;gt;Praesent tincidunt sed tellus ut rutrum. Sed vitae justo condimentum, porta lectus vitae, ultricies congue gravida diam non fringilla.&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;Powered by &amp;lt;a href=&quot;https://www.w3schools.com/w3css/default.asp&quot; target=&quot;_blank&quot;&amp;gt;w3.css&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  
    &amp;lt;div class=&quot;w3-third&quot;&amp;gt;
      &amp;lt;h3&amp;gt;BLOG POSTS&amp;lt;/h3&amp;gt;
      &amp;lt;ul class=&quot;w3-ul w3-hoverable&quot;&amp;gt;
        &amp;lt;li class=&quot;w3-padding-16&quot;&amp;gt;
          &amp;lt;img src=&quot;/w3images/workshop.jpg&quot; class=&quot;w3-left w3-margin-right&quot; style=&quot;width:50px&quot;&amp;gt;
          &amp;lt;span class=&quot;w3-large&quot;&amp;gt;Lorem&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;
          &amp;lt;span&amp;gt;Sed mattis nunc&amp;lt;/span&amp;gt;
        &amp;lt;/li&amp;gt;
        &amp;lt;li class=&quot;w3-padding-16&quot;&amp;gt;
          &amp;lt;img src=&quot;/w3images/gondol.jpg&quot; class=&quot;w3-left w3-margin-right&quot; style=&quot;width:50px&quot;&amp;gt;
          &amp;lt;span class=&quot;w3-large&quot;&amp;gt;Ipsum&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;
          &amp;lt;span&amp;gt;Praes tinci sed&amp;lt;/span&amp;gt;
        &amp;lt;/li&amp;gt; 
      &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class=&quot;w3-third&quot;&amp;gt;
      &amp;lt;h3&amp;gt;POPULAR TAGS&amp;lt;/h3&amp;gt;
      &amp;lt;p&amp;gt;
        &amp;lt;span class=&quot;w3-tag w3-black w3-margin-bottom&quot;&amp;gt;Travel&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;w3-tag w3-grey w3-small w3-margin-bottom&quot;&amp;gt;New York&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;w3-tag w3-grey w3-small w3-margin-bottom&quot;&amp;gt;London&amp;lt;/span&amp;gt;
        &amp;lt;span class=&quot;w3-tag w3-grey w3-small w3-margin-bottom&quot;&amp;gt;IKEA&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;w3-tag w3-grey w3-small w3-margin-bottom&quot;&amp;gt;NORWAY&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;w3-tag w3-grey w3-small w3-margin-bottom&quot;&amp;gt;DIY&amp;lt;/span&amp;gt;
        &amp;lt;span class=&quot;w3-tag w3-grey w3-small w3-margin-bottom&quot;&amp;gt;Ideas&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;w3-tag w3-grey w3-small w3-margin-bottom&quot;&amp;gt;Baby&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;w3-tag w3-grey w3-small w3-margin-bottom&quot;&amp;gt;Family&amp;lt;/span&amp;gt;
        &amp;lt;span class=&quot;w3-tag w3-grey w3-small w3-margin-bottom&quot;&amp;gt;News&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;w3-tag w3-grey w3-small w3-margin-bottom&quot;&amp;gt;Clothing&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;w3-tag w3-grey w3-small w3-margin-bottom&quot;&amp;gt;Shopping&amp;lt;/span&amp;gt;
        &amp;lt;span class=&quot;w3-tag w3-grey w3-small w3-margin-bottom&quot;&amp;gt;Sports&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;w3-tag w3-grey w3-small w3-margin-bottom&quot;&amp;gt;Games&amp;lt;/span&amp;gt;
      &amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;

  &amp;lt;/div&amp;gt;
  &amp;lt;/footer&amp;gt;
  
  &amp;lt;div class=&quot;w3-black w3-center w3-padding-24&quot;&amp;gt;Powered by &amp;lt;a href=&quot;https://www.w3schools.com/w3css/default.asp&quot; title=&quot;W3.CSS&quot; target=&quot;_blank&quot; class=&quot;w3-hover-opacity&quot;&amp;gt;w3.css&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;!-- End page content --&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;script&amp;gt;
// Script to open and close sidebar
function w3_open() {
    document.getElementById(&quot;mySidebar&quot;).style.display = &quot;block&quot;;
    document.getElementById(&quot;myOverlay&quot;).style.display = &quot;block&quot;;
}
 
function w3_close() {
    document.getElementById(&quot;mySidebar&quot;).style.display = &quot;none&quot;;
    document.getElementById(&quot;myOverlay&quot;).style.display = &quot;none&quot;;
}
&amp;lt;/script&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>KIC/Spring</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/111</guid>
      <comments>https://bacha.tistory.com/111#entry111comment</comments>
      <pubDate>Mon, 27 Sep 2021 23:39:06 +0900</pubDate>
    </item>
    <item>
      <title>day67 - Spring Framework(mvc)</title>
      <link>https://bacha.tistory.com/110</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;[EventController.java]&lt;/p&gt;
&lt;pre id=&quot;code_1632380181944&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package controller;

import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import event.Event;
import event.SearchOption;
import service.EventService;
import event.EventType;

@Controller
@RequestMapping(&quot;/event&quot;) 
public class EventController {
private static final String REDIRECT_EVENT_LIST = &quot;redirect:/event/list&quot;;
	private EventService eventService;
	public EventController() {
		eventService = new EventService(); 
	}
		
	@RequestMapping(&quot;/list&quot;)
	public String list (SearchOption option, Model model) {
		List&amp;lt;Event&amp;gt; eventList = eventService.getOpenedEventList (option); 
		model.addAttribute(&quot;eventList&quot;, eventList); 
		model.addAttribute(&quot;eventTypes&quot;, EventType.values()); 
		return &quot;event/list&quot;;
	}

	@RequestMapping(&quot;/list2&quot;)
	public ModelAndView list2(SearchOption option) {
		List&amp;lt;Event&amp;gt; eventList = eventService.getOpenedEventList (option); 
		ModelAndView modelView = new ModelAndView();	
		modelView.setViewName(&quot;event/list&quot;);
		modelView.addObject(&quot;eventList&quot;, eventList);
		modelView.addObject(&quot;eventTypes&quot;, EventType.values());
		return modelView;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[Event.java]&lt;/p&gt;
&lt;pre id=&quot;code_1632380202363&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package event;

public class Event {

	private Long id;
	private String name;
	private EventType type;

	public Long getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	public EventType getType() {
		return type;
	}

	public static Event create(Long id, String name, EventType type) {
		Event result = new Event();
		result.id = id;
		result.name = name;
		result.type = type;
		return result;
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[EventType.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1632380233751&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package event;

public enum EventType {

	FLASHMOB, CIRCUS, CONFERENCE
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[SearchOption.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1632380270389&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package event;

import java.util.Collection;
import java.util.Date;

public class SearchOption {
	private Collection&amp;lt;EventType&amp;gt; types;
	private boolean allType;
	private Date from;
	private Date to;

	public Collection&amp;lt;EventType&amp;gt; getTypes() {
		return types;
	}

	public void setTypes(Collection&amp;lt;EventType&amp;gt; types) {
		this.types = types;
	}

	public boolean isAllType() {
		return allType || types == null;
	}

	public void setAllType(boolean allType) {
		this.allType = allType;
	}

	public Date getFrom() {
		return from;
	}

	public void setFrom(Date from) {
		this.from = from;
	}

	public Date getTo() {
		return to;
	}

	public void setTo(Date to) {
		this.to = to;
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>KIC/Spring</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/110</guid>
      <comments>https://bacha.tistory.com/110#entry110comment</comments>
      <pubDate>Thu, 23 Sep 2021 15:58:16 +0900</pubDate>
    </item>
    <item>
      <title>day66 - Spring Framework(mvc)</title>
      <link>https://bacha.tistory.com/109</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[MvcQuickStartConfig]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631856312744&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package controller;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration 
@EnableWebMvc
public class MvcQuickStartConfig {

	@Bean
	public InternalResourceViewResolver viewResolver() { 
		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); 
		viewResolver.setPrefix(&quot;/WEB-INF/view/&quot;); 
		viewResolver.setSuffix(&quot;.jsp&quot;);
		return viewResolver;
	}

	@Bean
	public HelloController2 helloController() {
		return new HelloController2();
	}

}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>KIC/Spring</category>
      <category>mvc</category>
      <category>spring</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/109</guid>
      <comments>https://bacha.tistory.com/109#entry109comment</comments>
      <pubDate>Fri, 17 Sep 2021 14:26:35 +0900</pubDate>
    </item>
    <item>
      <title>day65 - Spring Framework(스프링, Annotation)</title>
      <link>https://bacha.tistory.com/108</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;[boardController.java]&lt;/p&gt;
&lt;pre id=&quot;code_1631697840920&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package controller;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import com.oreilly.servlet.MultipartRequest;

import service.BoardMybatisDao;
import model.Board;


@Controller
@RequestMapping(&quot;/board/&quot;)
public class BoardController{
	
	HttpServletRequest request;
	Model m;
	HttpSession session;
	
	@Autowired
	BoardMybatisDao dao;
	
	@ModelAttribute
	void init(HttpServletRequest request, Model m) {
		this.request = request;
		this.m = m;
		this.session = request.getSession();
	}
	
	@RequestMapping(&quot;list&quot;) // 실질적으로는 /board/list 인 샘
	public String list(){
		/*
		 * 게시물 목록 보기 
		 * 1. pageNum 파라미터 존재. pageNum 파라미터 없으면 1로 설정. 
		 * 2. 10건의 게시물 출력. =&amp;gt; db에서
		 *    해당 페이지에 출력되는 게시물만 조회. 순서 : 최근 게시물 순으로 
		 * 3. 화면에 출력.
		 * 4. boardid 파라메터가 없으면 session을 수정하지 않음 default는 1임
		 */

		// pageNum이 넘어와야 pageNum이 바뀜
		if (request.getParameter(&quot;pageNum&quot;) != null) {
			session.setAttribute(&quot;pageNum&quot;, request.getParameter(&quot;pageNum&quot;));
		}
		// boardid가 넘어와야 세션이 변경됨 : 현재 게시판분류에 따른 입력,수정을 적용
		if (request.getParameter(&quot;boardid&quot;) != null) {
			session.setAttribute(&quot;boardid&quot;, request.getParameter(&quot;boardid&quot;));
			session.setAttribute(&quot;pageNum&quot;, &quot;1&quot;);
		}

		
		String pageNum = (String) session.getAttribute(&quot;pageNum&quot;);
		if (pageNum == null) 	pageNum = &quot;1&quot;;
		int pageInt = Integer.parseInt(pageNum);
		
		String boardid = (String) session.getAttribute(&quot;boardid&quot;);
		if (boardid == null)  	boardid = &quot;1&quot;;
		

		
		
		int limit = 10; // 한페이지에 출력할 게시물 건수
		
		int boardcount = dao.boardCount(boardid);// 등록된 전체 게시물의 건수
		/*
		 * pageInt-현재 페이지 넘버, 
		 * limit-한페이지에 출력할 게시물 건수
		 * boardcount--등록된 전체 게시물의 건수
		 * boardid-공지사항(1),자유게시판(2), QnA(3)
		 */
		List&amp;lt;Board&amp;gt; list = dao.list(pageInt, limit, boardcount, boardid); // 화면에 출력된 게시물 데이터
		// 13 ---&amp;gt; boardcount/limit : 4 + 1
		//-----------paging 작업
		int maxpage = (int) (boardcount / limit) + (boardcount % limit == 0 ? 0 : 1);
		int bottomLine = 3;
		// page 1,2,3 : 1, 4,5,6: 2
		int startpage = 1 + (pageInt - 1) / bottomLine * bottomLine;
		int endpage = startpage + bottomLine - 1;
		if (endpage &amp;gt; maxpage) 	endpage = maxpage;
		int boardnum = boardcount - (pageInt - 1) * limit;  //100개 1:100, 2:90, 3:80
		//-----------paging 작업
		
		
		

		
		//print list
		m.addAttribute(&quot;boardcount&quot;, boardcount);  // 등록된 전체 게시물의 건수
		m.addAttribute(&quot;list&quot;, list);  //프린트한 게시물
		m.addAttribute(&quot;boardnum&quot;, boardnum); //게시물 시작번호
		m.addAttribute(&quot;pageNum&quot;, pageNum);  //현재 페이지 번호
		
		//하단 paging
		m.addAttribute(&quot;startpage&quot;, startpage); // 하단 시작 페이지
		m.addAttribute(&quot;endpage&quot;, endpage);  //하단 end 페이지
		m.addAttribute(&quot;bottomLine&quot;, bottomLine);  //하단 화면당 페이지 보기
		m.addAttribute(&quot;maxpage&quot;, maxpage);  //총 페이지수
	
		//게시판 제목
		m.addAttribute(&quot;boardName&quot;, getBoardName(boardid));  //게시판 제목 (공지시항, 자유게시판, QnA)
		
		return &quot;board/list&quot;;
	}
	
	
	public String getBoardName(String boardid) {
		
		String boardName = &quot;&quot;;
		switch (boardid) {
		case &quot;1&quot;: {   boardName=&quot;공지사항&quot;; break;	}
		case &quot;2&quot;: {   boardName=&quot;자유게시판&quot;; break;	}
		case &quot;3&quot;: {   boardName=&quot;QnA&quot;; break;	}
		default:
			 boardName=&quot;공지사항&quot;;
		}
		
		return boardName;
	}
	
	
	
	
	
	
	@RequestMapping(&quot;writeForm&quot;)
	public String writeForm() {
		String boardid = (String) request.getSession().getAttribute(&quot;boardid&quot;);
		if (boardid == null)  	boardid = &quot;1&quot;;
		m.addAttribute(&quot;boardName&quot;, getBoardName(boardid));
		return &quot;board/writeForm&quot;;
	}
	
	@RequestMapping(&quot;writePro&quot;)
	public String writePro(Board board) {
		String uploadpath = request.getServletContext().getRealPath(&quot;/&quot;) + &quot;upfile&quot;;
		
		MultipartFile multipartFile = board.getF();
		
		if(!multipartFile.isEmpty()) {
			File file = new File(uploadpath, multipartFile.getOriginalFilename());
			try {
				multipartFile.transferTo(file);
				board.setFile1(multipartFile.getOriginalFilename());
			}catch(IllegalStateException e) {
				e.printStackTrace();
			}catch(IOException e) {
				e.printStackTrace();
			}
			
		}else {
			board.setFile1(&quot;&quot;);
		}
		String boardid = (String) session.getAttribute(&quot;boardid&quot;);
		if (boardid == null)  	
			boardid = &quot;1&quot;;
		board.setBoardid(boardid);
		String msg = &quot;게시물 등록 실패&quot;;
		String url = &quot;board/writeForm&quot;;
		if(dao.insert(board)) {
			msg=&quot;게시물 등록 성공&quot;;
			url=&quot;board/list&quot;;
		}
		m.addAttribute(&quot;msg&quot;, msg);
		m.addAttribute(&quot;url&quot;, url);
		return &quot;alert&quot;;
	}


	
	@RequestMapping(&quot;info&quot;)
	public String info(int num){

		Board board = dao.selectOne(num); // 게시물 조회
		dao.readcntadd(num); // 조회건수증가
		m.addAttribute(&quot;board&quot;, board);
		String boardid = (String) request.getSession().getAttribute(&quot;boardid&quot;);
		if (boardid == null)  	boardid = &quot;1&quot;;
		m.addAttribute(&quot;boardName&quot;, getBoardName(boardid));
		
		return &quot;board/info&quot;;
	}

	@RequestMapping(&quot;updateForm&quot;)
	public String updateForm(int num){
		/*
		 * 1. num 값의 게시물을 조회화여 화면 출력하기
		 */
		Board board = dao.selectOne(num);
		m.addAttribute(&quot;board&quot;, board);
		return &quot;board/updateForm&quot;;
	}
	
	@RequestMapping(&quot;update  &quot;)
	public String update(Board board) {
		String uploadpath = request.getServletContext().getRealPath(&quot;/&quot;) + &quot;upfile&quot;;
		
		MultipartFile multipartFile = board.getF();
		
		if(!multipartFile.isEmpty()) {
			File file = new File(uploadpath, multipartFile.getOriginalFilename());
			try {
				multipartFile.transferTo(file);
				board.setFile1(multipartFile.getOriginalFilename());
			}catch(IllegalStateException e) {
				e.printStackTrace();
			}catch(IOException e) {
				e.printStackTrace();
			}
			
		}else {
			board.setFile1(&quot;&quot;);
		}
		Board dbBoard = dao.selectOne(board.getNum());
		String msg = &quot;비밀번호가 틀렸습니다.&quot;;
		String url = &quot;board/updateForm?num=&quot; + board.getNum();
		
		if(board.getPass().equals(dbBoard.getPass())){
			if(dao.update(board)) {
				msg=&quot;게시물 수정 성공&quot;;
				url=&quot;board/list&quot;;
			}else {
				msg = &quot;게시물 수정 실패&quot;;
			}
		}
		m.addAttribute(&quot;msg&quot;, msg);
		m.addAttribute(&quot;url&quot;, url);
		return &quot;alert&quot;;
		
	}

	@RequestMapping(&quot;deleteForm&quot;)
	public String deleteForm(int num){

		m.addAttribute(&quot;num&quot;, num);
		return &quot;board/deleteForm&quot;;
	}

	@RequestMapping(&quot;delete&quot;)
	public String delete(int num, String pass){

		System.out.println(pass);
		String msg = &quot;비밀번호가 틀렸습니다!&quot;;
		String url = &quot;board/deleteForm?num=&quot; + num;
		
		Board board = dao.selectOne(num);
		// board.getPass() : db에 저장된 비밀번호
		if (pass.equals(board.getPass())) {
			if (dao.delete(num)) {
				msg = &quot;게시글을 성공적으로 삭제하였습니다.&quot;;
				url = &quot;board/list&quot;;
			} else {
				msg = &quot;게시글을 삭제하는데 실패하였습니다!&quot;;
				url = &quot;board/info?num=&quot; + num;
			}
		}

		m.addAttribute(&quot;url&quot;, url);
		m.addAttribute(&quot;msg&quot;, msg);

		return &quot;alert&quot;;
	}

	@RequestMapping(&quot;replyForm&quot;)
	public String replyForm(int num){
		/*
		 * 답변글 쓰기 화면 
		 * 1. 원글의 num을 파라미터로 받는다. 
		 * 2. 원글의 num,ref,reflevel,refstep 정보를 저장 
		 * 3. 입력 화면 표시
		 */

		
		Board board = dao.selectOne(num); // 게시물 조회

		m.addAttribute(&quot;board&quot;, board);
		String boardid = (String) request.getSession().getAttribute(&quot;boardid&quot;);
		if (boardid == null)  	boardid = &quot;1&quot;;
		m.addAttribute(&quot;boardName&quot;, getBoardName(boardid));
		return &quot;board/replyForm&quot;;
	}

	
	
	
	
	@RequestMapping(&quot;replyPro&quot;)
	public String replyPro(Board board){

		String boardid = (String) request.getSession().getAttribute(&quot;boardid&quot;);
		if (boardid == null) 	boardid = &quot;1&quot;;

		board.setFile1(&quot;&quot;);
		board.setBoardid(boardid);
		
		dao.refstepadd(board.getRef(), board.getRefstep());
		// 3. Board 객체를 db에 insert 하기.
		String msg = &quot;답변등록시 오류발생&quot;;
		String url = &quot;board/replyForm?num=&quot; + board.getNum();
		if (dao.insert(board)) {
			msg = &quot;답변등록 완료&quot;;	url = &quot;board/list&quot;;
		}
		m.addAttribute(&quot;url&quot;, url);
		m.addAttribute(&quot;msg&quot;, msg);
		return &quot;alert&quot;;
	}
	
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>KIC/Spring</category>
      <category>spring</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/108</guid>
      <comments>https://bacha.tistory.com/108#entry108comment</comments>
      <pubDate>Wed, 15 Sep 2021 18:24:22 +0900</pubDate>
    </item>
    <item>
      <title>Flutter - APK 파일 생성하기</title>
      <link>https://bacha.tistory.com/107</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;일단 저는 VSCode 환경입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 생성하고 싶은 프로젝트로 가서 &amp;nbsp;터미널 창에서 해당 프로젝트 위치로 이동합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(해당 프로젝트에서 터미널을 열었다면 이미 자동으로 이동되어 있습니다.)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 터미널에 flutter build apk --release --target-platform=android-arm64 를 입력합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1218&quot; data-origin-height=&quot;177&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvaFw4/btre5PpZfWo/Byttx64Z7qCzPbKMPR52H1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvaFw4/btre5PpZfWo/Byttx64Z7qCzPbKMPR52H1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvaFw4/btre5PpZfWo/Byttx64Z7qCzPbKMPR52H1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvaFw4%2Fbtre5PpZfWo%2FByttx64Z7qCzPbKMPR52H1%2Fimg.png&quot; data-origin-width=&quot;1218&quot; data-origin-height=&quot;177&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;114&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwANH6/btre5clniE4/cR7omwcIGaMZsuBT1VObC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwANH6/btre5clniE4/cR7omwcIGaMZsuBT1VObC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwANH6/btre5clniE4/cR7omwcIGaMZsuBT1VObC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwANH6%2Fbtre5clniE4%2FcR7omwcIGaMZsuBT1VObC1%2Fimg.png&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;114&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 생성된 apk 파일 경로는 build/app/outputs/apk/release/app-release.apk 입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;329&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WpzcT/btreZ0M6Mqx/pxWet81pt4VGk1fhfpzink/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WpzcT/btreZ0M6Mqx/pxWet81pt4VGk1fhfpzink/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WpzcT/btreZ0M6Mqx/pxWet81pt4VGk1fhfpzink/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWpzcT%2FbtreZ0M6Mqx%2FpxWet81pt4VGk1fhfpzink%2Fimg.png&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;329&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이 파일을 안드로이드 폰에 가져가서 실행시키면 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;flutter build apk --release --target-platform=android-arm64를 실행 시키면&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;733&quot; data-origin-height=&quot;56&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXATda/btre342uJ9y/7HsSLkws6SnSQkj7IFmLnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXATda/btre342uJ9y/7HsSLkws6SnSQkj7IFmLnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXATda/btre342uJ9y/7HsSLkws6SnSQkj7IFmLnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXATda%2Fbtre342uJ9y%2F7HsSLkws6SnSQkj7IFmLnK%2Fimg.png&quot; data-origin-width=&quot;733&quot; data-origin-height=&quot;56&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이렇게 오류가 나면서 릴리스가 안될 때가 있는데 오류를 찬찬히 없앤 후 릴리스 하거나&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;가장 쉬운 방법으로는&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;225&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RwHhw/btre4Gtu9xO/KHq052bYr0NUmqigLIUGY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RwHhw/btre4Gtu9xO/KHq052bYr0NUmqigLIUGY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RwHhw/btre4Gtu9xO/KHq052bYr0NUmqigLIUGY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRwHhw%2Fbtre4Gtu9xO%2FKHq052bYr0NUmqigLIUGY0%2Fimg.png&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;225&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;본인의 스마트폰으로 에뮬레이터를 돌려본 적이 있을 경우에는&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;옆 파일 중에 app.apk파일을 그대로 가져다가 핸드폰에 실행하면 되는 것 같습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Flutter</category>
      <category>apk</category>
      <category>apk 파일 오류</category>
      <category>Flutter</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/107</guid>
      <comments>https://bacha.tistory.com/107#entry107comment</comments>
      <pubDate>Wed, 15 Sep 2021 01:06:35 +0900</pubDate>
    </item>
    <item>
      <title>day64 - Spring Framework(스프링, AOP)</title>
      <link>https://bacha.tistory.com/106</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Main3.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631630713478&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package ch03_AOPXmlAnno;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import di06.Article;
import di06.ArticleNotFoundException;
import di06.Member;
import di06.MemberService;
import di06.ReadArticleService;
import di06.UpdateInfo;

public class Main3 {
	public static void main(String[] args) {
		
		String[] config = {&quot;ch03_AOPXmlAnno/annotation.xml&quot;}; 
		ApplicationContext ctx = new ClassPathXmlApplicationContext(config); 
		ReadArticleService service = ctx.getBean(&quot;readArticleService&quot;, ReadArticleService.class);
	
		try {
			Article a1 =  service.getArticleAndReadCnt(1); //A 
			Article a2 = service.getArticleAndReadCnt(1); //B 
			System.out.println(&quot;[main] a1 == a2 : &quot; + (a1==a2));
			service.getArticleAndReadCnt(0); //C
		} catch (ArticleNotFoundException e) {
	
		System.out.println(&quot;[main]&quot; + e.getMessage());
		}
		System.out.println();
		System.out.println(&quot;=== updateMemberInfoTraceAspect 연습&quot;);
		MemberService memberService = ctx.getBean(&quot;memberService&quot;, MemberService.class);
		memberService.regist(new Member());
		memberService.update(&quot;hong&quot;, new UpdateInfo());//traceAspect AOP 대상이 되는 메서드
		memberService.delete(&quot;hong2&quot;, &quot;test&quot;);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[LoggingAspect.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631630729350&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package di07;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Aspect
@Order(1)
public class LoggingAspect {
	final String publicMethod = &quot;execution(public * di06.*Service.*(..))&quot;;
	
	@Before(publicMethod)
	public void before() {
		System.out.println(&quot;[LA]메서드 실행 전(before) 전처리 수행함.&quot;);
	}
	
	@AfterReturning(pointcut = publicMethod, returning = &quot;ret&quot;)
	public void afterReturning(Object ret) {
		System.out.println(&quot;[LA]메서드 정상 처리(afterReturning) 후 수행함 리턴값: &quot; + ret);
	}
	
	@AfterThrowing(pointcut = publicMethod, throwing = &quot;ex&quot;)
	public void afterThrowing(Throwable ex) {
		System.out.println(&quot;[LA]메서드 예외 발생 후(afterThrowing) 수행함 예외:&quot; +ex.getMessage());
	}
	
	@After(publicMethod)
	public void afterFinally() {
		System.out.println(&quot;[LA]메서드 실행 후(afterFinally) 후처리 수행함&quot;);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ArticleCacheAdvice.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631630761950&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package di07;

import java.util.HashMap;
import java.util.Map;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import di06.Article;

@Component
@Aspect
@Order(2)
public class ArticleCacheAdvice {
	private Map&amp;lt;Integer, Article&amp;gt; cache = new HashMap&amp;lt;Integer, Article&amp;gt;();
	
	@Around(&quot;execution(public * *..ReadArticleServiceImpl.*(..))&quot;)
	public Article cache(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println(&quot;[ACA] cache before 실행&quot;);
		
		Integer id = (Integer)joinPoint.getArgs()[0];
		Article article = cache.get(id);
		if(article != null) {
			System.out.println(&quot;[ACA] cache에서 Article[&quot; + id +&quot;] 가져옴&quot;);
			return article;
		}
		Article ret = (Article)joinPoint.proceed();
		System.out.println(&quot;[ACA] cache after 실행&quot;);
		if(ret != null) {
			cache.put(id,  ret);
			System.out.println(&quot;[ACA] cache에 Article[&quot; +id +&quot;] 객체를 추가함&quot;);
		}
		return ret;
	}
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>KIC/Spring</category>
      <category>annotation</category>
      <category>AOP</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/106</guid>
      <comments>https://bacha.tistory.com/106#entry106comment</comments>
      <pubDate>Tue, 14 Sep 2021 23:46:16 +0900</pubDate>
    </item>
    <item>
      <title>day63 - Spring Framework(스프링, AOP)</title>
      <link>https://bacha.tistory.com/105</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[AOP]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Aspect Oriented Programming. 관점 지향 프로그래밍으로 어플리케이션에서 전반적으로 사용되는 공통 기능들을 공통 관심 사항으로 구분한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 중복 코드를 제거하고 그로 인한 간경성과 생산성을 얻을 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 재사용성과 유지보수성 또한 증가한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Advice&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;언제 공통 관심 기능을 핵심 로직에 적용할 것인 지를 정의한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Jointpoint&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Advice 가 적용 가능한 지점을 의미한다. 메소드 호출, 필드값 변경 등이 이에 해당한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Pointcut&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Joinpoint의 부분 집합으로써 실제로 Advice가 적용 되는 Jointpoint를 말한다. 정규 표현식이나 Aspectj의 문법을 사용하여 Pointcout을 정의할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Aspect&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 여러 객체에 공통으로 적용되는 공통 관심 사항을 Aspect라고 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[Advice의 종류]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Before Advice&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;대상 객체의 메서드 호출 전에 공통 기능을 실행한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- After Returning &lt;b&gt;Advice&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;대상 객체의 메서드가 예외 없이 실행한 이후에 공통 기능을 실행한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- After Throwing &lt;b&gt;Advice&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;대상 객체의 메서드 실행 도중 예외가 발생시에 공통 기능을 실행한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- After &lt;b&gt;Advice&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;대상 객체의 메서드 실행 도중 예외가 발생 했는지 여부와 상관없이 메서드 실행 후 공통 기능을 실행한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(try catch finally 에서 finally 블록과 비슷한 역할이다.)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Around &lt;b&gt;Advice&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;대상 객체의 메서드 실행 전, 후 또는 예외 발생 시점에 공통 기능을 실행 시에 사용한다. 범용으로 사용 가능하다.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;[Main2.java]&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631539337836&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package ch03_AOPXmlAnno;
import org.springframework.context. ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import di06.Article;
import di06.ArticleNotFoundException;
import di06.ReadArticleService;

public class Main2 {

	public static void main(String[] args) {

	String[] config = {&quot;ch03_AOPXmlAnno/di.xml&quot;, &quot;ch03_AOPXmlAnno/aop2.xml&quot;}; 
	ApplicationContext ctx = new ClassPathXmlApplicationContext(config); 
	ReadArticleService service = ctx.getBean(&quot;readArticleService&quot;, ReadArticleService.class);

	try {
		Article a1 =  service.getArticleAndReadCnt(1); //A 
		Article a2 = service.getArticleAndReadCnt(1); //B 
		System.out.println(&quot;[main] a1 == a2 : &quot; + (a1==a2));
		service.getArticleAndReadCnt(0); //C
	} catch (ArticleNotFoundException e) {

	System.out.println(&quot;[main]&quot; + e.getMessage());
	}
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[aop.xml]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631539354907&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&amp;gt;
&amp;lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot; 
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; 
	xmlns:context=&quot;http://www.springframework.org/schema/context&quot; 
	xmlns:p=&quot;http://www.springframework.org/schema/p&quot; 
	xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot; 
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
			http://www.springframework.org/schema/beans/spring-beans.xsd
			http://www.springframework.org/schema/aop 
			http://www.springframework.org/schema/aop/spring-aop.xsd
			http://www.springframework.org/schema/context
			http://www.springframework.org/schema/context/spring-context.xsd&quot;&amp;gt;

	&amp;lt;bean id=&quot;LoggingAdvice&quot; class=&quot;di06.LoggingAdvice&quot; /&amp;gt;
	&amp;lt;bean id=&quot;cacheAdvice&quot; class=&quot;di06.ArticleCacheAdvice&quot;/&amp;gt;

	&amp;lt;aop:config&amp;gt;
		&amp;lt;aop:aspect id=&quot;LoggingAspect&quot; ref=&quot;LoggingAdvice&quot;&amp;gt;
			&amp;lt;aop:pointcut id=&quot;publicMethod&quot;
				expression=&quot;execution (public * di06.*Service.*(..))&quot; /&amp;gt;
			&amp;lt;aop:before method=&quot;before&quot;
				pointcut=&quot;execution (public * di06.*Service.*(..))&quot; /&amp;gt;
			&amp;lt;aop:after-returning method=&quot;afterReturning&quot;
				pointcut-ref=&quot;publicMethod&quot; returning=&quot;ret&quot; /&amp;gt;
			&amp;lt;aop:after-throwing method=&quot;afterThrowing&quot;
				throwing=&quot;ex&quot; pointcut-ref=&quot;publicMethod&quot; /&amp;gt;	
			&amp;lt;aop:after method=&quot;afterFinally&quot; 
				pointcut-ref=&quot;publicMethod&quot; /&amp;gt;
		&amp;lt;/aop:aspect&amp;gt;
		
		&amp;lt;aop:aspect id=&quot;cacheAspect&quot; ref=&quot;cacheAdvice&quot;&amp;gt;
			&amp;lt;aop:around method=&quot;cache&quot; pointcut=&quot;execution(public * *..ReadArticleServiceImpl.*(..))&quot;/&amp;gt;
		&amp;lt;/aop:aspect&amp;gt;
	&amp;lt;/aop:config&amp;gt;
&amp;lt;/beans&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[LoggingAdvice.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631539398816&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package di06;

public class LoggingAdvice {
	public void before() {
		System.out.println(&quot;[LA]메서드 실행 전(before) 전처리 수행함.&quot;);
	}
	public void afterReturning(Object ret) {
		System.out.println(&quot;[LA]메서드 정상 처리(afterReturning) 후 수행함 리턴값: &quot; + ret);
	}
	public void afterThrowing(Throwable ex) {
		System.out.println(&quot;[LA]메서드 예외 발생 후(afterThrowing) 수행함 예외:&quot; +ex.getMessage());
	}
	public void afterFinally() {
		System.out.println(&quot;[LA]메서드 실행 후(afterFinally) 후처리 수행함&quot;);
	}
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>KIC/Spring</category>
      <category>AOP</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/105</guid>
      <comments>https://bacha.tistory.com/105#entry105comment</comments>
      <pubDate>Mon, 13 Sep 2021 22:23:32 +0900</pubDate>
    </item>
    <item>
      <title>day62 - Spring Framework(스프링, Annotation)</title>
      <link>https://bacha.tistory.com/104</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Main3_xml.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631283540037&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package ch02_mainDI;

import org.springframework.context.support.GenericXmlApplicationContext;

import di03.AuthException;
import di03.AuthenticationService;
import di03.PasswordChangeService;
import di03.UserNotFoundException;

public class Main3_xml {
	public static void main(String[] args) {
		GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(&quot;classpath:ch02_DIXML/Container3.xml&quot;);
		PasswordChangeService pcw = (PasswordChangeService) ctx.getBean(&quot;pwChangeSvc&quot;);
		System.out.println(pcw);
		
		AuthenticationService authSvc = 
				ctx.getBean(&quot;authenticationService&quot;, AuthenticationService.class);
		runAuthAndCatchAuthEx(authSvc, &quot;bkchoi&quot;, &quot;1111&quot;);
		runAuthAndCatchAuthEx(authSvc, &quot;bkchoi&quot;, &quot;11111&quot;);
		runAuthAndCatchAuthEx(authSvc, &quot;bkchoi&quot;, &quot;111111&quot;);
		try {
			authSvc.authenticate(&quot;bkchoi2&quot;, &quot;1111&quot;);
		} catch (UserNotFoundException ex) {
		}
		authSvc.authenticate(&quot;bkchoi&quot;, &quot;1234&quot;);
		System.out.println(&quot;=======================&quot;);
		PasswordChangeService pwChgSvc = ctx.getBean(PasswordChangeService.class);
		pwChgSvc.changePassword(&quot;bkchoi&quot;, &quot;1234&quot;, &quot;5678&quot;);
		runAuthAndCatchAuthEx(authSvc, &quot;bkchoi&quot;, &quot;1234&quot;);
		authSvc.authenticate(&quot;bkchoi&quot;, &quot;5678&quot;);
		ctx.close();

	}
	
	private static void runAuthAndCatchAuthEx(
			AuthenticationService authSvc, String userId, String password) {
		try {
			authSvc.authenticate(userId, password);
		} catch (AuthException ex) {
		}
	}

	
	
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Main4_xmlAnno.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631283522148&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package ch02_mainDI;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

import ch02_DIXML.ContainerAnno;
import di03.AuthException;
import di03.AuthenticationService;
import di03.PasswordChangeService;
import di03.UserNotFoundException;

public class Main4_xmlAnno {
	public static void main(String[] args) {
		useBean(new GenericXmlApplicationContext(&quot;classpath:ch02_DIXML/Container3.xml&quot;));
		System.out.println(&quot;====================&quot;);
		useBean(new AnnotationConfigApplicationContext(ContainerAnno.class));
	}
	static void useBean(AbstractApplicationContext ctx) {
		PasswordChangeService pcw = (PasswordChangeService) ctx.getBean(&quot;pwChangeSvc&quot;);
		System.out.println(pcw);
		
		AuthenticationService authSvc = 
				ctx.getBean(&quot;authenticationService&quot;, AuthenticationService.class);
		runAuthAndCatchAuthEx(authSvc, &quot;bkchoi&quot;, &quot;1111&quot;);
		runAuthAndCatchAuthEx(authSvc, &quot;bkchoi&quot;, &quot;11111&quot;);
		runAuthAndCatchAuthEx(authSvc, &quot;bkchoi&quot;, &quot;111111&quot;);
		try {
			authSvc.authenticate(&quot;bkchoi2&quot;, &quot;1111&quot;);
		} catch (UserNotFoundException ex) {
		}
		authSvc.authenticate(&quot;bkchoi&quot;, &quot;1234&quot;);
		System.out.println(&quot;=======================&quot;);
		PasswordChangeService pwChgSvc = ctx.getBean(PasswordChangeService.class);
		pwChgSvc.changePassword(&quot;bkchoi&quot;, &quot;1234&quot;, &quot;5678&quot;);
		runAuthAndCatchAuthEx(authSvc, &quot;bkchoi&quot;, &quot;1234&quot;);
		authSvc.authenticate(&quot;bkchoi&quot;, &quot;5678&quot;);
		ctx.close();
	}
	private static void runAuthAndCatchAuthEx(
			AuthenticationService authSvc, String userId, String password) {
		try {
			authSvc.authenticate(userId, password);
		} catch (AuthException ex) {
		}
	}
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>KIC/Spring</category>
      <category>annotation</category>
      <category>스프링</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/104</guid>
      <comments>https://bacha.tistory.com/104#entry104comment</comments>
      <pubDate>Fri, 10 Sep 2021 23:19:31 +0900</pubDate>
    </item>
    <item>
      <title>day61 - Spring Framework(스프링, DI)</title>
      <link>https://bacha.tistory.com/103</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Container3.xml]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631200161286&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;

&amp;lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot; 
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&amp;gt;

	&amp;lt;bean id=&quot;user1&quot; class=&quot;di03.User&quot;&amp;gt; 
		&amp;lt;constructor-arg value=&quot;bkchoi&quot; /&amp;gt; 
		&amp;lt;constructor-arg value=&quot;1234&quot; /&amp;gt; 
	&amp;lt;/bean&amp;gt;

	&amp;lt;bean id=&quot;user2&quot; class=&quot;di03.User&quot;&amp;gt; 
		&amp;lt;constructor-arg value=&quot;madvirus&quot; /&amp;gt; 
		&amp;lt;constructor-arg value=&quot;qwer&quot; /&amp;gt; 
	&amp;lt;/bean&amp;gt;

	&amp;lt;bean id=&quot;userRepository&quot; class=&quot;di03.UserRepository&quot;&amp;gt;
		&amp;lt;property name=&quot;users&quot;&amp;gt;
			&amp;lt;list&amp;gt;
				&amp;lt;ref bean=&quot;user1&quot; /&amp;gt;		
				&amp;lt;ref bean=&quot;user2&quot; /&amp;gt;		
			&amp;lt;/list&amp;gt;
		&amp;lt;/property&amp;gt; &amp;lt;/bean&amp;gt;

	&amp;lt;bean id=&quot;pwChangeSvc&quot;
			class=&quot;di03.PasswordChangeService&quot;&amp;gt;
		&amp;lt;constructor-arg&amp;gt;&amp;lt;ref bean=&quot;userRepository&quot;/&amp;gt;&amp;lt;/constructor-arg&amp;gt;
	&amp;lt;/bean&amp;gt;
	
	&amp;lt;bean id=&quot;authFailLogger&quot; class=&quot;di03.AuthFailLogger&quot;&amp;gt;
		&amp;lt;property name=&quot;threshold&quot; value=&quot;2&quot;/&amp;gt;
	&amp;lt;/bean&amp;gt;
	
	&amp;lt;bean id=&quot;authenticationService&quot; class=&quot;di03.AuthenticationService&quot;&amp;gt;
		&amp;lt;property name=&quot;failLogger&quot; ref=&quot;authFailLogger&quot;/&amp;gt;
		&amp;lt;property name=&quot;userRepository&quot; ref=&quot;userRepsitory&quot; /&amp;gt;
	&amp;lt;/bean&amp;gt;
&amp;lt;/beans&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[user.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631200258456&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package di03;

public class User {
	private String id;
	private String password;
	
	public User(String id, String password) {
		super();
		this.id = id;
		this.password = password;
	}
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

	
	
}
package di03;

public class User {
	private String id;
	private String password;
	
	public User(String id, String password) {
		super();
		this.id = id;
		this.password = password;
	}
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

	
	
}
package di03;

public class User {
	private String id;
	private String password;
	
	public User(String id, String password) {
		super();
		this.id = id;
		this.password = password;
	}
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

	
	
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[UserRepository.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631200267502&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package di03;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserRepository {
	
	private Map&amp;lt;String, User&amp;gt; userMap = new HashMap&amp;lt;String, User&amp;gt;();
	public void setUsers(List&amp;lt;User&amp;gt; users) {
		for(User u : users) {
			userMap.put(u.getId(), u);
		}
		
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[AuthFailLogger.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631200275378&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package di03;

public class AuthFailLogger {
	private int threshold;
	
	public void setThreshold(int threshold) {
		this.threshold = threshold;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[AuthenticationService.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631200282249&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package di03;

public class AuthenticationService {
	AuthFailLogger authFailLogger;
	UserRepository userRepository;
	
	public void setFailLogger(AuthFailLogger authFailLogger) {
		this.authFailLogger = authFailLogger;
	}
	public void setUserRepository(UserRepository userRepository) {
		this.userRepository = userRepository;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>KIC/Spring</category>
      <category>DI</category>
      <category>spring 예제</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/103</guid>
      <comments>https://bacha.tistory.com/103#entry103comment</comments>
      <pubDate>Fri, 10 Sep 2021 00:11:40 +0900</pubDate>
    </item>
    <item>
      <title>day60 - Spring Framework(스프링, DI 시작)</title>
      <link>https://bacha.tistory.com/102</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[Spring]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 자바 플랫폼을 위한 오픈 소스 애플리케이션이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 스프링 프레임워크는 IOC 기반의 프레임워크로 IOC는 &lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Inversion of Control의 약자이다. 말그대로 역전 제어로 제어의 역전 통해서 모듈간의 결합도를 낮춰 효율적으로 개발할 수 있도록 돕는 프레임워크이다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 의존성 주입(Dependency Injection) 을 통한 유연한 프레임 워크를 구현할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 관점 지향 프로그래밍(AOP: Aspect Orineted Programming) 을 지원한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 반복적인 코드를 제거하는데 효과적어서 효율성이 증대된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[.jar]&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- jar 파일은 클래스 파일을 모아둔 것이다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 자신의 소스코드 대신 jar 파일만 줘서 다른 사람들에게 내 코드를 제공하지 않으면서 기능을 제공할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 개인이 jar 파일을 만들어서 사용하거나 배포할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 크게 보면 이것이 스프링에서 pom.xml의 역할과 비슷하다고 한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[DI]&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Dependency Injection의 약어. 의존관계 주입.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 객체 사이의 의존 관계가 자기 자신이 아닌 외부에 의해 설정된다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>KIC/Spring</category>
      <category>DI</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/102</guid>
      <comments>https://bacha.tistory.com/102#entry102comment</comments>
      <pubDate>Wed, 8 Sep 2021 21:46:05 +0900</pubDate>
    </item>
    <item>
      <title>day59 - MyBatis(게시판 mybatis 적용)</title>
      <link>https://bacha.tistory.com/101</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[board.xml]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631021399119&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;

&amp;lt;!DOCTYPE mapper PUBLIC &quot;-//mybatis.org/DTD Mapper 3.0//EN&quot;
&quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&amp;gt;
&amp;lt;mapper namespace=&quot;board&quot; &amp;gt;

&amp;lt;select id=&quot;seqNextval&quot; resultType=&quot;int&quot;&amp;gt;
select multiboardseq.nextval from dual
&amp;lt;/select&amp;gt;
&amp;lt;insert id=&quot;insertBoard&quot; parameterType=&quot;board&quot;&amp;gt;

insert into multiboard
(num, name, pass, subject, content, file1, regdate, readcnt, ref,reflevel, refstep, boardid) values 
(#{num}, #{name}, #{pass},#{subject},#{content}, #{file1}, 
sysdate, 0,#{ref}, #{reflevel},#{refstep},#{boardid})

&amp;lt;/insert&amp;gt;
&amp;lt;!-- 파라미터가 boardid 하나만 있으므로   parameterType은 String, 결과 값은 count 값이므로 int--&amp;gt;
&amp;lt;select id=&quot;boardCount&quot; parameterType=&quot;String&quot; resultType=&quot;int&quot;&amp;gt;

select count(*) count from multiboard where boardid=#{boardid} &amp;lt;/select&amp;gt;

&amp;lt;!-- 파라미터가 여러개이니 map으로, 결과 값은 * 로 여러개를 묶어 출력하니 board 로 --&amp;gt;
&amp;lt;select id=&quot;list&quot; parameterType=&quot;map&quot; resultType=&quot;board&quot;&amp;gt;

select * from (select rownum rnum,a.*

from (select * from multiboard where boardid = #{boardid} order by ref desc, refstep) a )

where rnum between #{start} and #{end}
&amp;lt;/select&amp;gt;

&amp;lt;!-- select는 결과값이 select문을 통해 출력되기 때문에 parameterType 뿐만 아니라 resultType도 있어야 한다.  --&amp;gt;
&amp;lt;select id=&quot;selectOne&quot; parameterType=&quot;int&quot; resultType=&quot;board&quot;&amp;gt;
select * from multiboard where num=#{num}
&amp;lt;/select&amp;gt;

&amp;lt;select id=&quot;readcntadd&quot; parameterType=&quot;int&quot;&amp;gt;
update  multiboard set readcnt = readcnt + 1  where num =#{num}
&amp;lt;/select&amp;gt;

&amp;lt;update id=&quot;refstepadd&quot; parameterType=&quot;map&quot;&amp;gt;
update  multiboard set refstep = refstep + 1&quot; + &quot; where ref = #{ref} and refstep &amp;gt; #{refstep}
&amp;lt;/update&amp;gt;


&amp;lt;update id=&quot;update&quot; parameterType=&quot;board&quot;&amp;gt;
update  multiboard set name=#{name},subject=#{subject},content=#{content},file1=#{file1}    where num=#{num}
&amp;lt;/update&amp;gt;

&amp;lt;!-- insert, update, delete는 결과 값이 없기 때문에 resultType은 없고 parameterType은 있다.  --&amp;gt;
&amp;lt;delete id=&quot;delete&quot; parameterType=&quot;int&quot;&amp;gt;
delete from multiboard where num=#{num}
&amp;lt;/delete&amp;gt;
&amp;lt;/mapper&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[BoardController.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631021426100&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.oreilly.servlet.MultipartRequest;

import dao.BoardMybatisDao;
import model.Board;

public class BoardController extends Action {
	
	public String list(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		/*
		 * 게시물 목록 보기 
		 * 1. pageNum 파라미터 존재. pageNum 파라미터 없으면 1로 설정. 
		 * 2. 10건의 게시물 출력. =&amp;gt; db에서
		 *    해당 페이지에 출력되는 게시물만 조회. 순서 : 최근 게시물 순으로 
		 * 3. 화면에 출력.
		 * 4. boardid 파라메터가 없으면 session을 수정하지 않음 default는 1임
		 */
		HttpSession session = request.getSession();
		// pageNum이 넘어와야 pageNum이 바뀜
		if (request.getParameter(&quot;pageNum&quot;) != null) {
			session.setAttribute(&quot;pageNum&quot;, request.getParameter(&quot;pageNum&quot;));
		}
		// boardid가 넘어와야 세션이 변경됨 : 현재 게시판분류에 따른 입력,수정을 적용
		if (request.getParameter(&quot;boardid&quot;) != null) {
			session.setAttribute(&quot;boardid&quot;, request.getParameter(&quot;boardid&quot;));
			session.setAttribute(&quot;pageNum&quot;, &quot;1&quot;);
		}

		
		String pageNum = (String) session.getAttribute(&quot;pageNum&quot;);
		if (pageNum == null) 	pageNum = &quot;1&quot;;
		int pageInt = Integer.parseInt(pageNum);
		
		String boardid = (String) session.getAttribute(&quot;boardid&quot;);
		if (boardid == null)  	boardid = &quot;1&quot;;
		

		
		
		int limit = 10; // 한페이지에 출력할 게시물 건수
		BoardMybatisDao dao = new BoardMybatisDao();
		int boardcount = dao.boardCount(boardid);// 등록된 전체 게시물의 건수
		/*
		 * pageInt-현재 페이지 넘버, 
		 * limit-한페이지에 출력할 게시물 건수
		 * boardcount--등록된 전체 게시물의 건수
		 * boardid-공지사항(1),자유게시판(2), QnA(3)
		 */
		List&amp;lt;Board&amp;gt; list = dao.list(pageInt, limit, boardcount, boardid); // 화면에 출력된 게시물 데이터
		// 13 ---&amp;gt; boardcount/limit : 4 + 1
		//-----------paging 작업
		int maxpage = (int) (boardcount / limit) + (boardcount % limit == 0 ? 0 : 1);
		int bottomLine = 3;
		// page 1,2,3 : 1, 4,5,6: 2
		int startpage = 1 + (pageInt - 1) / bottomLine * bottomLine;
		int endpage = startpage + bottomLine - 1;
		if (endpage &amp;gt; maxpage) 	endpage = maxpage;
		int boardnum = boardcount - (pageInt - 1) * limit;  //100개 1:100, 2:90, 3:80
		//-----------paging 작업
		
		
		

		
		//print list
		request.setAttribute(&quot;boardcount&quot;, boardcount);  // 등록된 전체 게시물의 건수
		request.setAttribute(&quot;list&quot;, list);  //프린트한 게시물
		request.setAttribute(&quot;boardnum&quot;, boardnum); //게시물 시작번호
		request.setAttribute(&quot;pageNum&quot;, pageNum);  //현재 페이지 번호
		
		//하단 paging
		request.setAttribute(&quot;startpage&quot;, startpage); // 하단 시작 페이지
		request.setAttribute(&quot;endpage&quot;, endpage);  //하단 end 페이지
		request.setAttribute(&quot;bottomLine&quot;, bottomLine);  //하단 화면당 페이지 보기
		request.setAttribute(&quot;maxpage&quot;, maxpage);  //총 페이지수
	
		//게시판 제목
		request.setAttribute(&quot;boardName&quot;, getBoardName(boardid));  //게시판 제목 (공지시항, 자유게시판, QnA)
		
		return &quot;/view/board/list.jsp&quot;;
	}
	
	
	public String getBoardName(String boardid) {
		
		String boardName = &quot;&quot;;
		switch (boardid) {
		case &quot;1&quot;: {   boardName=&quot;공지사항&quot;; break;	}
		case &quot;2&quot;: {   boardName=&quot;자유게시판&quot;; break;	}
		case &quot;3&quot;: {   boardName=&quot;QnA&quot;; break;	}
		default:
			 boardName=&quot;공지사항&quot;;
		}
		
		return boardName;
	}
	
	
	
	
	
	

	public String writeForm(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		String boardid = (String) request.getSession().getAttribute(&quot;boardid&quot;);
		if (boardid == null)  	boardid = &quot;1&quot;;
		request.setAttribute(&quot;boardName&quot;, getBoardName(boardid));
		return &quot;/view/board/writeForm.jsp&quot;;
	}

	public String writePro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		/* 준비사항 :  WebContent/upfile folder작성하세요
		 * 1. 파라미터 값을 model.Board 객체 저장. 
		 * 2. sequence.nextval 처리 */
		String uploadpath = request.getServletContext().getRealPath(&quot;/&quot;) + &quot;upfile&quot;;
		int size = 10 * 1024 * 1024;
		MultipartRequest multi;
		//boardid session 저장 내용 : default  1
		String boardid = (String) request.getSession().getAttribute(&quot;boardid&quot;);
		if (boardid == null) 	boardid = &quot;1&quot;;  //1 공지사항
		try {	multi = new MultipartRequest(request, uploadpath, size, &quot;utf-8&quot;);
			Board board = new Board();
			board.setName(multi.getParameter(&quot;name&quot;));	board.setPass(multi.getParameter(&quot;pass&quot;));
			board.setSubject(multi.getParameter(&quot;subject&quot;));
			board.setContent(multi.getParameter(&quot;content&quot;));
			board.setFile1(multi.getFilesystemName(&quot;file1&quot;));		board.setBoardid(boardid);
			if (board.getFile1() == null) 	board.setFile1(&quot;&quot;);
			// 2. sequence nextval 입력
			BoardMybatisDao dao = new BoardMybatisDao();
			// 3. board 객체의 내용을 db에 insert 하기
			String msg = &quot;게시물 등록 실패&quot;;		String url = &quot;board/writeForm&quot;;
			if (dao.insert(board)) {		msg = &quot;게시물 등록 성공&quot;;		url = &quot;board/list&quot;;	}
			request.setAttribute(&quot;msg&quot;, msg);
			request.setAttribute(&quot;url&quot;, url);
		} catch (IOException e) {
			e.printStackTrace();		}
		return &quot;/view/alert.jsp&quot;;
	}	

	public String info(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		/*
		 * : 게시물 상세 보기 :board/info?num=41 
		 * 
		 * 1. num 파라미터를 이용하여 db에 해당 게시물 조회 
		 *      Board board = new BoardMybatisDao().selectOne(num); 
		 * 2. 조회수 증가시키기. 
		 * readcnt+1 new BoardDao().readcntadd(num); 
		 * 
		 * 3. 1번에서 조회한 게시물데이터를 화면에 출력하기
		 */

		int num = Integer.parseInt(request.getParameter(&quot;num&quot;));
		// 파라미터값읽기
		BoardMybatisDao dao = new BoardMybatisDao();
		Board board = dao.selectOne(num); // 게시물 조회
		dao.readcntadd(num); // 조회건수증가
		request.setAttribute(&quot;board&quot;, board);
		String boardid = (String) request.getSession().getAttribute(&quot;boardid&quot;);
		if (boardid == null)  	boardid = &quot;1&quot;;
		request.setAttribute(&quot;boardName&quot;, getBoardName(boardid));
		
		return &quot;/view/board/info.jsp&quot;;
	}

	
	public String updateForm(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		/*
		 * 1. num 값의 게시물을 조회화여 화면 출력하기
		 */
		int num = Integer.parseInt(request.getParameter(&quot;num&quot;));
		Board board = new BoardMybatisDao().selectOne(num);
		request.setAttribute(&quot;board&quot;, board);
		return &quot;/view/board/updateForm.jsp&quot;;
	}

	public String update(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		/*
		 * 1. 파라미터정보들을 Board 객체 저장. 
		 * 2. 비밀번호 검증 비밀번호
		 * 일치 : 수정으로. 
		 * 비밀번호 불일치 : 비밀번호 오류 메세지 출력하고, updateForm.jsp로 페이지 이동 3. 수정성공 : 수정성공
		 * 메시지 출력 후 list.jsp 페이지 이동 수정실패 : 수정실패 메시지 출력 후 updateForm.jsp 페이지 이동
		 */

		// 파라미터 정보 Board 객체에 저장
		Board board = new Board();
		String uploadpath = request.getServletContext().getRealPath(&quot;/&quot;) + &quot;upfile/&quot;;
		MultipartRequest multi;
		try {
			multi = new MultipartRequest(request, uploadpath, 10 * 1024 * 1024, &quot;euc-kr&quot;);

			board.setNum(Integer.parseInt(multi.getParameter(&quot;num&quot;)));
			board.setName(multi.getParameter(&quot;name&quot;));
			board.setPass(multi.getParameter(&quot;pass&quot;));
			board.setSubject(multi.getParameter(&quot;subject&quot;));
			board.setContent(multi.getParameter(&quot;content&quot;));
			board.setFile1(multi.getFilesystemName(&quot;file1&quot;));
			// 수정시 첨부파일의 수정이 발생하지 않은 경우
			if (board.getFile1() == null || board.getFile1().equals(&quot;&quot;)) {
				board.setFile1(multi.getParameter(&quot;file2&quot;));
			}
			// 비밀번호 검증
			BoardMybatisDao dao = new BoardMybatisDao();
			Board dbBoard = dao.selectOne(board.getNum());
			String msg = &quot;비밀번호가 틀렸습니다.&quot;;
			String url = &quot;board/updateForm?num=&quot; + board.getNum();

			if (board.getPass().equals(dbBoard.getPass())) {
				// 수정하기
				if (dao.update(board)) {
					msg = &quot;게시물 수정 완료&quot;;
					url = &quot;board/list&quot;;
				} else {
					msg = &quot;게시물 수정 실패&quot;;
				}
			}
			request.setAttribute(&quot;url&quot;, url);
			request.setAttribute(&quot;msg&quot;, msg);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return &quot;/view/alert.jsp&quot;;
	}

	public String deleteForm(HttpServletRequest request, HttpServletResponse response) throws Throwable {

		int num = Integer.parseInt(request.getParameter(&quot;num&quot;));
		request.setAttribute(&quot;num&quot;, num);
		return &quot;/view/board/deleteForm.jsp&quot;;
	}

	public String delete(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		/*
		 * /WebContent/model1/board/delete.jsp 1. num,pass 파라미터를 변수에 저장. 2. 입력된 비밀번호와 db
		 * 비밀번호 검증 틀린경우 : 비밀번호 오류 메시지 출력, deleteForm.jsp 페이지 이동 3. 게시물 삭제. 삭제 성공 : 삭제 성공
		 * 메시지 출력, list.jsp 페이지 이동 삭제 실패 : 삭제 실패 메시지 출력, info.jsp 페이지 이동
		 */

		int num = Integer.parseInt(request.getParameter(&quot;num&quot;));
		String pass = request.getParameter(&quot;pass&quot;); // 입력된 비밀번호
		System.out.println(pass);
		String msg = &quot;비밀번호가 틀렸습니다!&quot;;
		String url = &quot;board/deleteForm?num=&quot; + num;
		BoardMybatisDao dao = new BoardMybatisDao();
		Board board = dao.selectOne(num);
		// board.getPass() : db에 저장된 비밀번호
		if (pass.equals(board.getPass())) {
			if (dao.delete(num)) {
				msg = &quot;게시글을 성공적으로 삭제하였습니다.&quot;;
				url = &quot;board/list&quot;;
			} else {
				msg = &quot;게시글을 삭제하는데 실패하였습니다!&quot;;
				url = &quot;board/info?num=&quot; + num;
			}
		}

		request.setAttribute(&quot;url&quot;, url);
		request.setAttribute(&quot;msg&quot;, msg);

		return &quot;/view/alert.jsp&quot;;
	}

	public String replyForm(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		/*
		 * 답변글 쓰기 화면 
		 * 1. 원글의 num을 파라미터로 받는다. 
		 * 2. 원글의 num,ref,reflevel,refstep 정보를 저장 
		 * 3. 입력 화면 표시
		 */

		int num = Integer.parseInt(request.getParameter(&quot;num&quot;));// 파라미터값읽기
		BoardMybatisDao dao = new BoardMybatisDao();
		Board board = dao.selectOne(num); // 게시물 조회

		request.setAttribute(&quot;board&quot;, board);
		String boardid = (String) request.getSession().getAttribute(&quot;boardid&quot;);
		if (boardid == null)  	boardid = &quot;1&quot;;
		request.setAttribute(&quot;boardName&quot;, getBoardName(boardid));
		return &quot;/view/board/replyForm.jsp&quot;;
	}

	
	
	
	
	
	public String replyPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		request.setCharacterEncoding(&quot;utf-8&quot;);
		String boardid = (String) request.getSession().getAttribute(&quot;boardid&quot;);
		if (boardid == null) 	boardid = &quot;1&quot;;
		Board board = new Board();
		board.setNum(Integer.parseInt(request.getParameter(&quot;num&quot;)));
		board.setRef(Integer.parseInt(request.getParameter(&quot;ref&quot;)));
		board.setReflevel(Integer.parseInt(request.getParameter(&quot;reflevel&quot;)));
		board.setRefstep(Integer.parseInt(request.getParameter(&quot;refstep&quot;)));
		board.setName(request.getParameter(&quot;name&quot;));
		board.setPass(request.getParameter(&quot;pass&quot;));
		board.setSubject(request.getParameter(&quot;subject&quot;));
		board.setContent(request.getParameter(&quot;content&quot;));
		board.setFile1(&quot;&quot;);
		board.setBoardid(boardid);
		BoardMybatisDao dao = new BoardMybatisDao();
		dao.refstepadd(board.getRef(), board.getRefstep());
		// 3. Board 객체를 db에 insert 하기.
		String msg = &quot;답변등록시 오류발생&quot;;
		String url = &quot;board/replyForm?num=&quot; + board.getNum();
		if (dao.insert(board)) {
			msg = &quot;답변등록 완료&quot;;	url = &quot;board/list&quot;;
		}
		request.setAttribute(&quot;url&quot;, url);
		request.setAttribute(&quot;msg&quot;, msg);
		return &quot;/view/alert.jsp&quot;;
	}
	
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>KIC/MyBatis</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/101</guid>
      <comments>https://bacha.tistory.com/101#entry101comment</comments>
      <pubDate>Tue, 7 Sep 2021 22:30:35 +0900</pubDate>
    </item>
    <item>
      <title>day58 - MyBatis(parameterType, resultType, 게시판에 mybatis 적용)</title>
      <link>https://bacha.tistory.com/100</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;[board.xml]&lt;/p&gt;
&lt;pre id=&quot;code_1630939549637&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;

&amp;lt;!DOCTYPE mapper PUBLIC &quot;-//mybatis.org/DTD Mapper 3.0//EN&quot;
&quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&amp;gt;
&amp;lt;mapper namespace=&quot;board&quot; &amp;gt;

&amp;lt;select id=&quot;seqNextval&quot; resultType=&quot;int&quot;&amp;gt;
select multiboardseq.nextval from dual
&amp;lt;/select&amp;gt;
&amp;lt;insert id=&quot;insertBoard&quot; parameterType=&quot;board&quot;&amp;gt;

insert into multiboard
(num, name, pass, subject, content, file1, regdate, readcnt, ref,reflevel, refstep, boardid) values 
(# {num}, #{name}, #{pass},#{subject},#{content}, #{file1}, 
sysdate, 0,#{ref}, #{reflevel},#{refstep},#{boardid})

&amp;lt;/insert&amp;gt;
&amp;lt;!-- 파라미터가 boardid 하나만 있으므로   parameterType은 String, 결과 값은 count 값이므로 int--&amp;gt;
&amp;lt;select id=&quot;boardCount&quot; parameterType=&quot;String&quot; resultType=&quot;int&quot;&amp;gt;

select count(*) count from multiboard where boardid=#{boardid} &amp;lt;/select&amp;gt;

&amp;lt;!-- 파라미터가 여러개이니 map으로, 결과 값은 * 로 여러개를 묶어 출력하니 board 로 --&amp;gt;
&amp;lt;select id=&quot;list&quot; parameterType=&quot;map&quot; resultType=&quot;board&quot;&amp;gt;

select * from (select rownum rnum,a.*

from (select * from multiboard where boardid = #{boardid} order by ref desc, refstep) a )

where rnum between #{start} and #{end}
&amp;lt;/select&amp;gt;

&amp;lt;!-- select는 결과값이 select문을 통해 출력되기 때문에 parameterType 뿐만 아니라 resultType도 있어야 한다.  --&amp;gt;
&amp;lt;select id=&quot;selectOne&quot; parameterType=&quot;int&quot; resultType=&quot;board&quot;&amp;gt;
select * from multiboard where num=#{num}
&amp;lt;/select&amp;gt;

&amp;lt;select id=&quot;readcntadd&quot; parameterType=&quot;int&quot;&amp;gt;
update  multiboard set readcnt = readcnt + 1  where num =#{num}
&amp;lt;/select&amp;gt;

&amp;lt;update id=&quot;refstepadd&quot; parameterType=&quot;map&quot;&amp;gt;
update  multiboard set refstep = refstep + 1&quot; + &quot; where ref = #{ref} and refstep &amp;gt; #{refstep}
&amp;lt;/update&amp;gt;


&amp;lt;update id=&quot;update&quot; parameterType=&quot;board&quot;&amp;gt;
update  multiboard set name=#{name},subject=#{subject},content=#{content},file1=#{file1}&quot; + &quot; where num=#{num}
&amp;lt;/update&amp;gt;

&amp;lt;!-- insert, update, delete는 결과 값이 없기 때문에 resultType은 없고 parameterType은 있다.  --&amp;gt;
&amp;lt;delete id=&quot;delete&quot; parameterType=&quot;int&quot;&amp;gt;
delete from multiboard where num=#{num}
&amp;lt;/delete&amp;gt;
&amp;lt;/mapper&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>KIC/MyBatis</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/100</guid>
      <comments>https://bacha.tistory.com/100#entry100comment</comments>
      <pubDate>Mon, 6 Sep 2021 23:46:11 +0900</pubDate>
    </item>
    <item>
      <title>AutoHotkey로 방향키 대신 wasd 또는 ijkl를 방향키로 쓰기 - AutoHotkey 다운 부터 키맵 설정, 시작 프로그램 등록하기</title>
      <link>https://bacha.tistory.com/99</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(최종 코드는 가장 아래에 있습니다.)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코딩을 하다보면 방향키를 사용할 때가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 방향키는 상대적으로 오른쪽에 위치해서 손목을 계속 꺾어야 하는 불편함이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평소에는 괜찮았는데 요즘 손목이 아프기 시작해서 방법을 강구하다가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오토핫키를 써서 리눅스의 단축키처럼 키보드에서 손을 덜 움직이고 편하게 코딩할 수 있도록 설정하는 방법을 찾게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yongj.in/utility/AutoHotKey-CapsLock+ijkl%EB%A5%BC-%EB%B0%A9%ED%96%A5%ED%82%A4%EB%A1%9C-%EB%B0%94%EA%BE%B8%EA%B8%B0/&quot;&gt;https://yongj.in/utility/AutoHotKey-CapsLock+ijkl%EB%A5%BC-%EB%B0%A9%ED%96%A5%ED%82%A4%EB%A1%9C-%EB%B0%94%EA%BE%B8%EA%B8%B0/&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1630830311604&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[AutoHotKey] CapsLock+ijkl를 방향키로 바꾸기&quot; data-og-description=&quot;오토핫키 하나로 일반 키보드를 코딩용 키보드로 만든다.&quot; data-og-host=&quot;yongj.in&quot; data-og-source-url=&quot;https://yongj.in/utility/AutoHotKey-CapsLock+ijkl%EB%A5%BC-%EB%B0%A9%ED%96%A5%ED%82%A4%EB%A1%9C-%EB%B0%94%EA%BE%B8%EA%B8%B0/&quot; data-og-url=&quot;https://16yongjin.github.io//utility/AutoHotKey-CapsLock+ijkl%EB%A5%BC-%EB%B0%A9%ED%96%A5%ED%82%A4%EB%A1%9C-%EB%B0%94%EA%BE%B8%EA%B8%B0/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://yongj.in/utility/AutoHotKey-CapsLock+ijkl%EB%A5%BC-%EB%B0%A9%ED%96%A5%ED%82%A4%EB%A1%9C-%EB%B0%94%EA%BE%B8%EA%B8%B0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yongj.in/utility/AutoHotKey-CapsLock+ijkl%EB%A5%BC-%EB%B0%A9%ED%96%A5%ED%82%A4%EB%A1%9C-%EB%B0%94%EA%BE%B8%EA%B8%B0/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[AutoHotKey] CapsLock+ijkl를 방향키로 바꾸기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;오토핫키 하나로 일반 키보드를 코딩용 키보드로 만든다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yongj.in&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://www.kbdmania.net/xe/tipandtech/7063618&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://www.kbdmania.net/xe/tipandtech/7063618&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1630830320307&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Tip &amp;amp; Tech : KBDMania - 오토핫키를 이용하여 CapsLock을 펑션키로 사용하기&quot; data-og-description=&quot;안녕하세요, 660m 유저입니다. 다들 아시다시피 일반적으로 fn키는 키매핑이 존재하지 않아서 키매핑 프로그램들로 키를 바꾸는 것이 불가능합니다. 그래서 fn키 위치를 바꾸는 것은 포기하고 Caps&quot; data-og-host=&quot;www.kbdmania.net&quot; data-og-source-url=&quot;http://www.kbdmania.net/xe/tipandtech/7063618&quot; data-og-url=&quot;http://www.kbdmania.net/xe/tipandtech/7063618&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;http://www.kbdmania.net/xe/tipandtech/7063618&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.kbdmania.net/xe/tipandtech/7063618&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Tip &amp;amp; Tech : KBDMania - 오토핫키를 이용하여 CapsLock을 펑션키로 사용하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요, 660m 유저입니다. 다들 아시다시피 일반적으로 fn키는 키매핑이 존재하지 않아서 키매핑 프로그램들로 키를 바꾸는 것이 불가능합니다. 그래서 fn키 위치를 바꾸는 것은 포기하고 Caps&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.kbdmania.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 많이 참고한 블로그이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러가지 블로그에서 좋은점을 가져오고 오토핫키 다운 부터 사용하기에 최적화 한 후 주의사항도 알아보도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 오토핫키 다운&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://www.autohotkey.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.autohotkey.com/&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1630830784388&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;AutoHotkey&quot; data-og-description=&quot;AutoHotkey provides a simple, flexible syntax allowing you to focus more on the task at hand rather than every single little technicality. It supports not only the popular imperative-procedural paradigm, but also object-oriented and command-based programmi&quot; data-og-host=&quot;www.autohotkey.com&quot; data-og-source-url=&quot;https://www.autohotkey.com/&quot; data-og-url=&quot;https://www.autohotkey.com/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.autohotkey.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.autohotkey.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;AutoHotkey&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;AutoHotkey provides a simple, flexible syntax allowing you to focus more on the task at hand rather than every single little technicality. It supports not only the popular imperative-procedural paradigm, but also object-oriented and command-based programmi&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.autohotkey.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;먼저 해당 사이트에 들어가서 오토핫키를 다운 받는다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;860&quot; data-origin-height=&quot;562&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMu830/btrd5kxYxAS/Q8N18VTjkkVl6dbQXCjUN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMu830/btrd5kxYxAS/Q8N18VTjkkVl6dbQXCjUN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMu830/btrd5kxYxAS/Q8N18VTjkkVl6dbQXCjUN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMu830%2Fbtrd5kxYxAS%2FQ8N18VTjkkVl6dbQXCjUN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;592&quot; height=&quot;406&quot; data-origin-width=&quot;860&quot; data-origin-height=&quot;562&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Download -&amp;gt; &lt;b&gt;Download&lt;span&gt; Current Version 을 눌러 다운 받아 실행하면&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;146&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FEuTn/btrd65USb5t/FAK2qllkK3irqKdGjtJiN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FEuTn/btrd65USb5t/FAK2qllkK3irqKdGjtJiN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FEuTn/btrd65USb5t/FAK2qllkK3irqKdGjtJiN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFEuTn%2Fbtrd65USb5t%2FFAK2qllkK3irqKdGjtJiN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;146&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;146&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;가 생기고 실행하보면 도움말이랑 가이드라인만 있고 실제 코딩 영역은 없다.&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1140&quot; data-origin-height=&quot;723&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vT5tl/btrd9l4cXaw/3liv7U4amsoHaOQ7ojbC81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vT5tl/btrd9l4cXaw/3liv7U4amsoHaOQ7ojbC81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vT5tl/btrd9l4cXaw/3liv7U4amsoHaOQ7ojbC81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvT5tl%2Fbtrd9l4cXaw%2F3liv7U4amsoHaOQ7ojbC81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;423&quot; height=&quot;268&quot; data-origin-width=&quot;1140&quot; data-origin-height=&quot;723&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로그램을 만드는 방법은 해당 프로그램을 실행시키는 것이 아니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실제 방법은 먼저 메모장 파일을 하나 만들어서&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1630831330712&quot; class=&quot;java&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SetCapsLockState, AlwaysOff




#If GetKeyState(&quot;Capslock&quot;,&quot;P&quot;)
	i::Up
	j::Left
	k::Down
	l::Right
	u::BackSpace
	o::Del

	]::Send, {&amp;gt;}
	1::Send, {(}
	2::Send, {)}
	3::Send, {{}
	4::Send, {}}
	5::Send, {[}
	6::Send, {]}
	7::PgUp
	8::PgDn


	w::PgUp
	a::^+Left
	s::PgDn
	d::^+Right
	e:: Send, {=}
	q::BackSpace
	t::_
	r::=
	z::Home
	x::End
	c::^c
	v::^v
	h::^Left
	`;::^Right


	=::Send, {=}{&amp;gt;}
	n::Home
	m::End
	f::CapsLock
	,::Send, {&amp;lt;}{-}
	.::Send, {-}{&amp;gt;}
#If


^F10::Send CtrlUp&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;해당 코드를 복사 붙혀넣기를 하고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;116&quot; data-origin-height=&quot;104&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bECiBi/btreaRoclc0/AAh3FJHI4CHAYYObYJBBpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bECiBi/btreaRoclc0/AAh3FJHI4CHAYYObYJBBpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bECiBi/btreaRoclc0/AAh3FJHI4CHAYYObYJBBpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbECiBi%2FbtreaRoclc0%2FAAh3FJHI4CHAYYObYJBBpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;116&quot; height=&quot;104&quot; data-origin-width=&quot;116&quot; data-origin-height=&quot;104&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;확장자를 .txt 에서 .ahk로 바꿔주면 오토핫키 스크립트 파일을 만들어 줄 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. CapsLock으로 사용법 및 원하는 대로 설정 변경하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[사용법]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 모든 커맨드는 &lt;/b&gt;&lt;b&gt;caps lock 버튼을 누른 상태에서 다른 버튼을 누르면 실행된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- ijkl를 누르면 방향키 없이 방향키 조작이 가능하다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- j 와 l 옆에 h와 ; 는 각각 ctrl + left, ctrl + right로 설정하여 문장 사이를 빠르게 넘어갈 수 있게 하였다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; 그냥 ctrl + caps lock + j or l 또한 가능하지만 누르기 불편해서 따로 지정해 주었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- n과 m은&amp;nbsp; &amp;nbsp;home 키와 end키로 지정하였다. 문장의 처음 과 끝으로 이동할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- u와 o는 backspace 와 delete 로 지정하였다. 방향키 만큼 쓰지는 않게 되는 것 같다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[설정 변경하기]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;먼저 오토 핫키는 특수키를 특정 문자와 매칭되어 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;175&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qs3mI/btrd1zbShkC/dnO1wPKqTKRj6P5B5uQeek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qs3mI/btrd1zbShkC/dnO1wPKqTKRj6P5B5uQeek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qs3mI/btrd1zbShkC/dnO1wPKqTKRj6P5B5uQeek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqs3mI%2Fbtrd1zbShkC%2FdnO1wPKqTKRj6P5B5uQeek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;175&quot; height=&quot;165&quot; data-origin-width=&quot;175&quot; data-origin-height=&quot;165&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 위의 해당 코드를 보면 알겠지만 &lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;기존 단축키 명령어는&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;x::^c 이런식으로 사이에 :: 를 사용한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 커맨드를 통해 실제 문자를 출력하고 싶다면&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;x::send,{&amp;gt;} 형식으로 작성하면 출력할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 기존 오토핫키에서 문법으로 사용하고 있는 ; 같은 문자를 단축키로 사용하고 싶다면&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;`; 로 ; 옆에 `를 붙여서 사용한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 한영키는 오토핫키로 커맨드 조작이 불가능하다고 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 오토핫키 스크립트를 컴퓨터 시작 시에 실행시키기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;오토핫키 스크립트를 작성하고 실행하면 정상적으로 작동하지만&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;컴퓨터를 키고나서 자동으로 프로그램이 실행하였으면 했다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법은 win + r 을 눌러서&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;271&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HIblM/btrd1eSOsai/f2V8QKy9t9mPORS8lIPGeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HIblM/btrd1eSOsai/f2V8QKy9t9mPORS8lIPGeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HIblM/btrd1eSOsai/f2V8QKy9t9mPORS8lIPGeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHIblM%2Fbtrd1eSOsai%2Ff2V8QKy9t9mPORS8lIPGeK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;505&quot; height=&quot;271&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;271&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;shell:startup을 작성하고 확인을 누른다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bX6QeY/btrd2x5IF02/f3ZQLKZGWtZc58cirw4WWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bX6QeY/btrd2x5IF02/f3ZQLKZGWtZc58cirw4WWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bX6QeY/btrd2x5IF02/f3ZQLKZGWtZc58cirw4WWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbX6QeY%2Fbtrd2x5IF02%2Ff3ZQLKZGWtZc58cirw4WWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1104&quot; height=&quot;433&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 이렇게 시작 프로그램 파일이 있는데 여기에 해당 스크립트 파일 바로가기를 생성해 넣어주면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 컴퓨터가 시작되었을 대 스크립트 파일이 자동으로 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 주의점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;만약에 게임을 하게 되면 오토핫키가 문제가 될 수 있다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;롤 같은 경우 오토핫키를 사용시에 자동으로 제제를 가하는 듯 하다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;오토핫키 스크립트가 실행되는 중에 롤을 플레이하게 되면 갑자기 게임이 다운되는 경우가 있는데&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이때 컴퓨터를 다시 껐다 켜도 해당 판은 재접속이 불가능하다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;게임 플레이 전에는 해당 파일을 잠시 종료시키길 추천한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(*롤 클라이언트를 감지해 롤 실행시 오토핫키 종료하는 코드 추가)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[스크립트 수정]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 롤 프로세스를 탐지해서 롤 클아이언트 실행시 스크립트 자동 종료하는 코드 추가&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Sleep, 1000 추가로 리소스 덜 쓰게 변경&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[크롬 탭 이동]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;nbsp; a, d로 스크린 탭 이동 기능&amp;nbsp; 추가&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- w, s로 스크롤 하기 - 마우스 스크롤 두번 정도( pg up down이 화면을 너무 많이 넘겨 설정 했다.)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[윈도우 가상 데스크톱]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;- r로 가상 데스크톱 생성, t 로 가상 데스크톱 삭제 &lt;b&gt;추가&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- q e로 가상 데스크톱 좌우 이동 추가&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1642132819814&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SetCapsLockState, AlwaysOff


Loop{
        IfWinExist, ahk_exe LeagueClientUx.exe
        {
		ExitApp
        }
        Sleep, 1000
}


#If GetKeyState(&quot;Capslock&quot;,&quot;P&quot;)
	i::Up
	j::Left
	k::Down
	l::Right
	u::BackSpace
	o::Del

	]::Send, {&amp;gt;}
	1::Send, {(}
	2::Send, {)}
	3::Send, {{}
	4::Send, {}}
	5::Send, {[}
	6::Send, {]}
	7::PgUp
	8::PgDn


	w::Send, {Up}{Up}{Up}{Up}{Up}{Up}
	a::Send, ^+{tab}
	s::Send, {Down}{Down}{Down}{Down}{Down}{Down}
	d::Send, ^{tab}
	f::Send, ^w
	r::Send, #^d
	e::Send, #^{Right}
	q::Send, #^{Left}
	t::Send, ^#{F4}
	z::Send, {F11}
	x::Send, {F10}
	c::Send, +{F11}
	v::^v
	h::^Left
	`;::^Right


	=::Send, {=}{&amp;gt;}
	n::Send, !{tab}
	m::Home
	g::CapsLock
	,::End
	.::Send, {-}{&amp;gt;}
#If



^F10::Send CtrlUp&lt;/code&gt;&lt;/pre&gt;</description>
      <category>기타</category>
      <category>autohotkey</category>
      <category>가상 데스크톱</category>
      <category>방향키 ijkl</category>
      <category>방향키 wasd</category>
      <category>방향키 단축키</category>
      <category>방향키 메크로</category>
      <category>방향키 바꾸기</category>
      <category>방향키 설정</category>
      <category>오토핫키</category>
      <category>코딩</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/99</guid>
      <comments>https://bacha.tistory.com/99#entry99comment</comments>
      <pubDate>Sun, 5 Sep 2021 18:55:05 +0900</pubDate>
    </item>
    <item>
      <title>day57 - MyBatis(parameterType, resultType)</title>
      <link>https://bacha.tistory.com/98</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;84&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNobfd/btrd3a9kEIC/g6IFjmybWTllfUnWj8kmr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNobfd/btrd3a9kEIC/g6IFjmybWTllfUnWj8kmr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNobfd/btrd3a9kEIC/g6IFjmybWTllfUnWj8kmr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNobfd%2Fbtrd3a9kEIC%2Fg6IFjmybWTllfUnWj8kmr0%2Fimg.png&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;84&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[parameterType]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 마이바티스에서 parameterType 속성을 사용해서 해당 파라미터의 자료형을 명시해준다. 위에서는 student 객체에 결과가 담긴다. student는&amp;nbsp; 미리 생성해둔 &lt;b&gt;Model 객체이다.&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[resultType]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;nbsp; select 된 데이터를 반환할 그릇을 의미한다고 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; 즉&amp;nbsp; parameterType으로 col 과 value가 Map 자료형임을 명시하고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; resultType으로 결과 값이 student 객체에 담길 것이라는 의미&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[#{}]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- #{} 사용시 PreparedStatement 생성되고 PreparedStatement 매개 변수 값 안전하게 설정한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;- PreparedStatement 가 제공하는 set 계열의 메소드를 사용하여 (?)를 대체할 값을 지정한다. &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;- 데이터 문자열을 자동으로 인식하기 때문에 자동 따옴표 붙인다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 쿼리 주입을 예방할 수 있어서 보안 측면에서 유리하다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[&lt;b&gt;${}&lt;/b&gt;]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- ${} 사용시 Statement 생성하고 Statement 매개변수 값 그대로 전달한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 전달한 &lt;span style=&quot;color: #000000;&quot;&gt;문자열에&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;따옴표가&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;붙지&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;않는다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 테이블이나 컬럼명을 파라미터로 전달하고 싶을 때 사용한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- ORDER BY 함수를 사용할 때 자동 따옴표가 붙으면 함수가 안먹기 때문에 ${}를 써야한다고 한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 쿼리 주입을 예방할 수 없어서 보안 측면에서는 불리하다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[StudentMapper2.xml]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1630686727108&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&amp;gt;
&amp;lt;!-- /src/mapperXML/StudentMapper2.xml --&amp;gt; 
&amp;lt;!DOCTYPE mapper PUBLIC &quot;-//mybatis.org/DTD Mapper 3.0//EN&quot; 
&quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&amp;gt;

&amp;lt;mapper namespace=&quot;student2&quot;&amp;gt;

&amp;lt;select id=&quot;select&quot; resultType=&quot;student&quot;&amp;gt;
	select * from student

&amp;lt;/select&amp;gt;

&amp;lt;select id=&quot;select2&quot; resultType=&quot;student&quot; parameterType=&quot;map&quot;&amp;gt;
	select * from student
	&amp;lt;where&amp;gt;
		&amp;lt;if test=&quot;grade !=null&quot;&amp;gt; grade=#{grade}&amp;lt;/if&amp;gt;
		&amp;lt;if test=&quot;height !=null&quot;&amp;gt;height &amp;gt;= #{height}&amp;lt;/if&amp;gt;
		&amp;lt;if test=&quot;studno !=null&quot;&amp;gt;studno = #{studno}&amp;lt;/if&amp;gt;
	&amp;lt;/where&amp;gt;
&amp;lt;/select&amp;gt;


&amp;lt;!-- map 에서 내가 원하는 컬럼을 골라 사용 가능 하도록 where ${col} = #{value}로 지정 --&amp;gt;
&amp;lt;select id=&quot;select3&quot; resultType=&quot;student&quot; parameterType=&quot;map&quot;&amp;gt;
	select * from student
		where ${col} = #{value}
&amp;lt;/select&amp;gt;

&amp;lt;select id=&quot;select4&quot; resultType=&quot;student&quot; parameterType=&quot;map&quot;&amp;gt;
	select ${col} from student
&amp;lt;/select&amp;gt;

&amp;lt;select id=&quot;select5&quot; resultType=&quot;student&quot; parameterType=&quot;map&quot;&amp;gt;
	select * from student
	&amp;lt;choose&amp;gt;
	&amp;lt;when test=&quot;grade !=null and height !=null&quot;&amp;gt;
	where grade = #{grade} and height = #{height}
	&amp;lt;/when&amp;gt;
	&amp;lt;when test=&quot;grade!=null&quot;&amp;gt;where grade = #{grade}&amp;lt;/when&amp;gt;
	&amp;lt;when test=&quot;height!=null&quot;&amp;gt;where height &amp;gt;= #{height}&amp;lt;/when&amp;gt;
	&amp;lt;/choose&amp;gt;
&amp;lt;/select&amp;gt;

&amp;lt;select id=&quot;select6&quot; resultType=&quot;student&quot; parameterType=&quot;map&quot;&amp;gt;
	select * from student
	&amp;lt;trim prefix=&quot;where&quot; prefixOverrides=&quot;AND || OR&quot;&amp;gt;
		&amp;lt;if test=&quot;grade != null&quot;&amp;gt; and grade = #{grade}&amp;lt;/if&amp;gt;
		&amp;lt;if test=&quot;height != null&quot;&amp;gt; and height &amp;gt;= #{height}&amp;lt;/if&amp;gt;
		&amp;lt;if test=&quot;weight != null&quot;&amp;gt; and weight &amp;gt;= #{weight}&amp;lt;/if&amp;gt;
	&amp;lt;/trim&amp;gt;
&amp;lt;/select&amp;gt;

&amp;lt;select id=&quot;select7&quot; resultType=&quot;student&quot; parameterType=&quot;map&quot;&amp;gt;
	select * from student
	&amp;lt;if test=&quot;datas !=null&quot;&amp;gt;
	where ${col} in
	&amp;lt;foreach collection=&quot;datas&quot; item=&quot;d&quot; separator=&quot;,&quot;
		open=&quot;(&quot;  close=&quot;)&quot;&amp;gt;#{d}
	&amp;lt;/foreach&amp;gt;
	&amp;lt;/if&amp;gt;
		
&amp;lt;/select&amp;gt;

&amp;lt;/mapper&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Main3StudentXML.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1630686755228&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import model.Student;

public class Main3StudentXML {
	private final static String NS = &quot;student.&quot;; 
	private static Map map = new HashMap(); 
	public static void main(String[] args) {

		SqlSessionFactory sqlMap = Main1.initMybatis(); 
		SqlSession session = sqlMap.openSession();
		
		System.out.println(&quot;student table 추가&quot;);
		Student s= new Student();
		s.setStudno(1111);
		s.setName(&quot;케이아&quot;);
		s.setGrade(1);
		s.setId(&quot;kic001&quot;);
		s.setJumin(&quot;1111111111&quot;);
		s.setDeptno1(101);
		
//		int cnt = session.insert(NS+&quot;insert&quot; , s);
//		System.out.println(&quot;student record 추가: &quot; + cnt);
//		session.commit();
		
		s.setGrade(2);
		s.setWeight(60);
		s.setHeight(180);
		s.setProfno(2222);
		s.setStudno(1111);
		
//		int cnt = session.update(NS + &quot;update&quot;, s);
//		System.out.println(&quot;student record 수정: &quot; + cnt);
//		session.commit();
		
//		int cnt = session.delete(NS + &quot;delete&quot;, 1111);
//		System.out.println(&quot;student record 삭제: &quot; + cnt);
//		session.commit();
		

		
		//전체 뽑기
		//List&amp;lt;Student&amp;gt; li = session.selectList (NS+&quot;select&quot; , s);
		
		// 1111만 선택해 뽑기
		List&amp;lt;Student&amp;gt; li = session.selectList (NS+&quot;select&quot; , 1111); 
		System.out.println(&quot;student row count: &quot;+li.size());

		for (Student st : li) {
			System.out.println(st);
		}
		
		li = session.selectList(NS + &quot;selectRMap&quot;);
		System.out.println(&quot;student row count: &quot;+li.size());
		for (Student st : li) {
			System.out.println(st);
		}
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Main4StudentXML.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1630686769592&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import model.Student;

public class Main4StudentXML {
	// 수정 사항
	//1, config.xml에 &amp;lt;mapper resource=&quot;mapperXML/StudentMapper2.xml&quot;/&amp;gt;를 추가해줘야 한다.
	//2. StudentMapper2 의 namespace와 NS =&quot;student2.&quot;가 같아야 한다.
	//3. parameterType가 아니라 resultType=&quot;student&quot; 로 수정해야 한다.
	private final static String NS =&quot;student2.&quot;;
	private static Map map = new HashMap();
	
	public static void main(String[] args) {
		SqlSessionFactory sqlMap = Main1.initMybatis(); 
		SqlSession session = sqlMap.openSession();
		List&amp;lt;Student&amp;gt; li = session.selectList (NS+&quot;select&quot;); 
//		
//		Student s= new Student();
//		System.out.println(&quot;student row count: &quot;+li.size());
//
//		for (Student st : li) {
//			System.out.println(st);
//		}
		
		
		
		//map.put(&quot;grade&quot;, 1);
		//map.put(&quot;height&quot;, 180);
		map.put(&quot;studno&quot;, 9711);
		li = session.selectList(NS+&quot;select2&quot;, map);
		System.out.println(&quot;student row count: &quot;+li.size());
		for (Student st : li) {
			System.out.println(st);
		}
		
		System.out.println(&quot;=====================================================&quot;);
		
		// 이렇게 내가 원하는 컬럼을 골라 사용 가능
		map.clear();
		map.put(&quot;col&quot;, &quot;height&quot;);
		map.put(&quot;value&quot;, 180);
		
//		map.put(&quot;col&quot;, &quot;weight&quot;);
//		map.put(&quot;value&quot;, 70);
		li = session.selectList(NS+&quot;select3&quot;, map);
		System.out.println(&quot;student row count: &quot;+li.size());
		for (Student st : li) {
			System.out.println(st);
		}
		
		map.clear();
		map.put(&quot;col&quot;, &quot;name&quot;);
		li = session.selectList(NS+&quot;select4&quot;, map);
		System.out.println(&quot;student row count: &quot;+li.size());
		for (Student st : li) {
			System.out.println(st);
		}
		
		System.out.println(&quot;=====================================================&quot;);
		
		
		map.clear();
		//map.put(&quot;grade&quot;, &quot;1&quot;);
		map.put(&quot;height&quot;, 170);
		li = session.selectList(NS+&quot;select5&quot;, map);
		System.out.println(&quot;student row count: &quot;+li.size());
		for (Student st : li) {
			System.out.println(st);
		}
		
		
		System.out.println(&quot;=====================================================&quot;);
		
		
		map.clear();
		map.put(&quot;grade&quot;, &quot;1&quot;);
		map.put(&quot;height&quot;, 170);
		map.put(&quot;height&quot;, 60);
		li = session.selectList(NS+&quot;select6&quot;, map);
		System.out.println(&quot;student row count: &quot;+li.size());
		for (Student st : li) {
			System.out.println(st);
		}
		
		
		
		System.out.println(&quot;=====================================================&quot;);
		List&amp;lt;Integer&amp;gt; ali = Arrays.asList(101, 201);
		map.clear();
		map.put(&quot;col&quot;, &quot;deptno1&quot;);
		map.put(&quot;datas&quot;, ali);
		li = session.selectList(NS+&quot;select7&quot;, map);
		System.out.println(&quot;student row count: &quot;+li.size());
		for (Student st : li) {
			System.out.println(st);
		}

	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;237&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3o3Hp/btrdVk6IOUB/bS1nxaxA4oJKkzrXOsbNL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3o3Hp/btrdVk6IOUB/bS1nxaxA4oJKkzrXOsbNL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3o3Hp/btrdVk6IOUB/bS1nxaxA4oJKkzrXOsbNL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3o3Hp%2FbtrdVk6IOUB%2FbS1nxaxA4oJKkzrXOsbNL0%2Fimg.png&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;237&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>KIC/MyBatis</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/98</guid>
      <comments>https://bacha.tistory.com/98#entry98comment</comments>
      <pubDate>Fri, 3 Sep 2021 12:19:13 +0900</pubDate>
    </item>
    <item>
      <title>day56 - MyBatis(Mybatis, Mybatis 실행 절차)</title>
      <link>https://bacha.tistory.com/97</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[MyBatis]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- &lt;span style=&quot;color: #000000;&quot;&gt;자바에서 데이터베이스 프로그래밍을 좀 더 쉽게 할 수 있게 도와 주는 개발 프레임 워크이다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- java beans 객체를 preparedStatement parameters와 ResultMaps로 쉽게 매핑을 할수 있도록 도와준다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 이를 통해 database에 접근하기 위한 자바 코드의 양을 줄일 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[MyBatis 실행 절차]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 객체를 파라미터로 전달&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;-&amp;gt; javaBeans, Map or primitive Wrapper&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 매핑되는 sql 문장을 수행&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;-&amp;gt; sql Maps 프레임워크는 PreparedStatement 인스턴스 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;-&amp;gt; 객체로부터 제공되는 값들을 파라미터로 세팅&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. SQL 문장을 수행하고 ResultSet으로부터 결과 객체를 생성.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;-&amp;gt; Update의 경우에는 영향을 받은 rows 수가 반환된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;-&amp;gt; 쿼리의 경우 하나 혹은 여러 객체들이 반환된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[mybatis 태그들]&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;572&quot; data-origin-height=&quot;179&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lrkDf/btrdQBU5ITr/1iRMjWiBHSw13PDwjpT1D1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lrkDf/btrdQBU5ITr/1iRMjWiBHSw13PDwjpT1D1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lrkDf/btrdQBU5ITr/1iRMjWiBHSw13PDwjpT1D1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlrkDf%2FbtrdQBU5ITr%2F1iRMjWiBHSw13PDwjpT1D1%2Fimg.png&quot; data-origin-width=&quot;572&quot; data-origin-height=&quot;179&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 여기서 comment는 클래스를 의미한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 기존 jsp 에서는 VALUE(?, ?, ? ... ) 이런식으로 ? 를 써줬지만&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- mybatis에서는 comment라는 클래스를 parameterType으로 지정해 주고 comment 클래스 안에 부합하는 변수들이 존재한다면 getUserId와 같은 것들을 끌어와 VALUE() 안에 있는 변수들과 자동적으로 대응시켜준다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[변수 설정]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 만약 DB에서 설정한 컬럼 명과 setter getter에서 설정한 프로퍼티 이름이 다를 경우에는 resultMap으로 설정할 수는 있지만 웬만하면 컬럼명과 setter/getter 프로퍼티 명은 같게 해주는 것이 무조건 좋다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[MemberMapper1.xml]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1630603086987&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&amp;gt;
&amp;lt;!DOCTYPE mapper PUBLIC &quot;//mybatis.org/DTD Mapper 3.0//EN&quot; 
&quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&amp;gt;
&amp;lt;mapper namespace=&quot;member&quot;&amp;gt;
	&amp;lt;select id=&quot;count&quot; resultType=&quot;int&quot;&amp;gt;
		select count(*) from member2
	&amp;lt;/select&amp;gt;
	
	&amp;lt;select id=&quot;list&quot; resultType=&quot;member&quot;&amp;gt;
		select * from member2
	&amp;lt;/select&amp;gt;
	
	&amp;lt;select id=&quot;selectId&quot; parameterType=&quot;string&quot; resultType=&quot;member&quot;&amp;gt;
		select * from member2 where id = #{value}
	&amp;lt;/select&amp;gt;
	
	&amp;lt;select id=&quot;selectName&quot; parameterType=&quot;string&quot; resultType=&quot;member&quot;&amp;gt;
		select * from member2 where name like '%${value}%'
	&amp;lt;/select&amp;gt;
	
	&amp;lt;select id=&quot;selectNameGender&quot; parameterType=&quot;map&quot; resultType=&quot;member&quot;&amp;gt;
		select * from member2 where name like '%${name}%' and gender = #{gender}
	&amp;lt;/select&amp;gt;



&amp;lt;/mapper&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[main1.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1630603110484&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main;

import java.io.IOException;
import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class Main1 {

	public static void main(String[] args) { 
		initMybatis();
	}

	public static SqlSessionFactory initMybatis() { 
		SqlSessionFactory sqlMap = null;
	
		Reader reader = null;
		
		try {
		
		reader =  Resources.getResourceAsReader(&quot;mapperXML/mybatis-config.xml&quot;); 
		sqlMap = new SqlSessionFactoryBuilder ().build(reader);
		System.out.println(&quot;ok config&quot;); 
		} catch (IOException e) {
		
			// TODO Auto-generated catch block. 
			e.printStackTrace();
		}
		return sqlMap;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[main2MemberXML.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1630603132277&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main;

import java.lang.reflect.Member;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

public class Main2MemberXML {
	private final static String NS =&quot;member.&quot;;
	
	public static void main(String[] args) {
		SqlSessionFactory sqlmap = Main1.initMybatis();
		SqlSession session = sqlmap.openSession();
		
		// 하나 받아오기
		int x = session.selectOne(NS + &quot;count&quot;);
		System.out.println(&quot;count: &quot;+ x);
		
		// 리스트 받아오기
		List&amp;lt;Member&amp;gt; li = session.selectList(NS + &quot;count&quot;);
		for(Member m : li) {
			System.out.println(m);
		}
		
		Member member = session.selectOne(NS + &quot;selectId&quot;);
		System.out.println(member);
		
		li = session.selectList(NS + &quot;selectName&quot; , &quot;2&quot;);
		for(Member m : li) {
			System.out.println(m);
		}
		
		Map map = new HashMap();
		map.put(&quot;name&quot;, &quot;4&quot;); // 이름에 4가 들어간 사람을 추출하기 위함
		map.put(&quot;gender&quot;, &quot;1&quot;);
		li = session.selectList(NS + &quot;selectNameGender&quot; , map);
		
		for(Member m : li) {
			System.out.println(m);
		}
	}
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>KIC/MyBatis</category>
      <category>Mapper</category>
      <category>mybatis</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/97</guid>
      <comments>https://bacha.tistory.com/97#entry97comment</comments>
      <pubDate>Fri, 3 Sep 2021 02:19:30 +0900</pubDate>
    </item>
    <item>
      <title>java.sql.SQLException: ORA-01017: invalid username/password; logon denied</title>
      <link>https://bacha.tistory.com/96</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;284&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nRr27/btrdXyWAflV/rPoJDRdUXwDiNpkXOcAX21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nRr27/btrdXyWAflV/rPoJDRdUXwDiNpkXOcAX21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nRr27/btrdXyWAflV/rPoJDRdUXwDiNpkXOcAX21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnRr27%2FbtrdXyWAflV%2FrPoJDRdUXwDiNpkXOcAX21%2Fimg.png&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;284&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mybatis 실습 도중에 이러한 오류가 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 지정해두었던 DB 연결 비밀번호에 오타가 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB 연결하는 아이디와 비밀번호를 한번더 확인해보자.&lt;/p&gt;</description>
      <category>KIC/MyBatis</category>
      <category>DB error</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/96</guid>
      <comments>https://bacha.tistory.com/96#entry96comment</comments>
      <pubDate>Fri, 3 Sep 2021 01:56:01 +0900</pubDate>
    </item>
    <item>
      <title>day55 - JSP(공지사항 페이지 )</title>
      <link>https://bacha.tistory.com/95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[BoardDao.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1630516836044&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import model.Board;
import util.DBConnection;

public class BoardDao {
	public boolean insert(Board board) {
		Connection conn = DBConnection.getConnection();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		System.out.println(&quot;insert:&quot;+board);
		int num = 0;
		String sql1 = &quot;select multiboardseq.nextval from dual&quot;;
		String sql2 = &quot;insert into multiboard &quot; + &quot;(num, name, pass, subject, content, file1, regdate,&quot;
				+ &quot;readcnt, ref, reflevel, refstep, boardid)&quot; + &quot;  values  (?,?,?,?,?,?,sysdate,0,?,?,?,?)&quot;;
		//---------------------------
		int ref = 0, reflevel = 0, refstep = 0;
		//---------------------------
		try {
			pstmt = conn.prepareStatement(sql1);
			rs = pstmt.executeQuery();
			if(rs.next()) num = rs.getInt(1);
			// ---------------- 답글인 경우
			if(board.getNum() &amp;gt; 0) {
				ref = board.getRef();
				reflevel = board.getReflevel() + 1;
				refstep = board.getRefstep() + 1;
			}else {
				
				ref = num;
			}
			// ---------------- 답글인 경우
			pstmt = conn.prepareStatement(sql2);
			pstmt.setInt(1, num);
			pstmt.setString(2, board.getName());
			pstmt.setString(3, board.getPass());
			pstmt.setString(4, board.getSubject());
			pstmt.setString(5, board.getContent());
			pstmt.setString(6, board.getFile1());
			pstmt.setInt(7, ref);
			pstmt.setInt(8, reflevel);
			pstmt.setInt(9, refstep);
			pstmt.setString(10, board.getBoardid());
			pstmt.executeUpdate();
			return true;
				
			}catch(SQLException e) {
				e.printStackTrace();
		}
		finally {
			DBConnection.close(conn, pstmt, null);
		}
		return false;
	}
	
	public int boardCount(String boardid) {
		Connection conn = DBConnection.getConnection();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			pstmt = conn.prepareStatement(&quot;select count(*) count from multiboard where boardid  = ?&quot;);
			pstmt.setString(1, boardid);
			rs = pstmt.executeQuery();
			rs.next();
			return rs.getInt(1);
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			DBConnection.close(conn, pstmt, rs);
		}
		return 0;
	}
	
	public List&amp;lt;Board&amp;gt; list(int pageInt, int limit, int boardcount, String boardid){
		Connection conn = DBConnection.getConnection();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		List&amp;lt;Board&amp;gt; list = new ArrayList&amp;lt;Board&amp;gt;();
		//----------------------
		int start = (pageInt - 1) * limit + 1;
		int end = start + limit -1;
		String sql = &quot;select * from (select rownum rnum, a.* &quot;
				+ &quot; from (select * from multiboard where boardid = ? order by ref desc, refstep) a) &quot;
				+ &quot;where rnum between ? and ?&quot;;
		System.out.println(sql);
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, boardid);
			pstmt.setInt(2, start);
			pstmt.setInt(3, end);
			System.out.println(start + &quot;:&quot; + end);
			rs = pstmt.executeQuery();
			while(rs.next()) {
				Board b = new Board();
				b.setNum(rs.getInt(&quot;num&quot;));
				b.setName(rs.getString(&quot;name&quot;));
				b.setPass(rs.getString(&quot;pass&quot;));
				b.setSubject(rs.getString(&quot;subject&quot;));
				b.setContent(rs.getString(&quot;content&quot;));
				b.setFile1(rs.getString(&quot;file1&quot;));
				b.setRef(rs.getInt(&quot;ref&quot;));
				b.setReflevel(rs.getInt(&quot;reflevel&quot;));
				b.setRefstep(rs.getInt(&quot;refstep&quot;));
				b.setReadcnt(rs.getInt(&quot;readcnt&quot;));
				b.setRegdate(rs.getTimestamp(&quot;regdate&quot;));
				list.add(b);
				
				
			}
			return list;
			
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			DBConnection.close(conn, pstmt, rs);
		}
		return null;
	}
	
	public Board selectOne(int num){
		Connection conn = DBConnection.getConnection();
		PreparedStatement pstmt = null;
		ResultSet rs = null;

		String sql = &quot;select *  from multiboard where num =?&quot;;
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, num);
			rs = pstmt.executeQuery();
			while(rs.next()) {
				Board b = new Board();
				b.setNum(rs.getInt(&quot;num&quot;));
				b.setName(rs.getString(&quot;name&quot;));
				b.setPass(rs.getString(&quot;pass&quot;));
				b.setSubject(rs.getString(&quot;subject&quot;));
				b.setContent(rs.getString(&quot;content&quot;));
				b.setFile1(rs.getString(&quot;file1&quot;));
				b.setRef(rs.getInt(&quot;ref&quot;));
				b.setReflevel(rs.getInt(&quot;reflevel&quot;));
				b.setRefstep(rs.getInt(&quot;refstep&quot;));
				b.setReadcnt(rs.getInt(&quot;readcnt&quot;));
				b.setRegdate(rs.getTimestamp(&quot;regdate&quot;));
				return b;
				
				
			}

		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			DBConnection.close(conn, pstmt, rs);
		}
		return null;
	}
	
	public void readcntadd(int num) {
		Connection conn = DBConnection.getConnection();
		PreparedStatement pstmt = null;
		String sql = &quot;update multiboard set readcnt = readcnt + 1 where num=?&quot;;
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, num);
			pstmt.executeUpdate();
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			DBConnection.close(conn, pstmt, null);
		}
	}
	
	public void refstepadd(int ref, int refstep) {
		Connection conn = DBConnection.getConnection();
		PreparedStatement pstmt = null;
		String sql = &quot;update multiboard set readcnt = readcnt + 1 where num=? and refstep &amp;gt; ?&quot;;
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, ref);
			pstmt.setInt(2, refstep);
			pstmt.executeUpdate();
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			DBConnection.close(conn, pstmt, null);
		}
	}
	
	
	

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[replyForm.jsp]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1630516857096&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot;
    pageEncoding=&quot;UTF-8&quot;%&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
&amp;lt;title&amp;gt;게시판 글쓰기&amp;lt;/title&amp;gt;
&amp;lt;script&amp;gt;
function board_submit(){
	var f = document.f;
	if(f.name.value==&quot;&quot;){
		alert(&quot;이름을 입력하세요&quot;)
		f.name.focus();
		return;
	}
	if(f.pass.value==&quot;&quot;){
		alert(&quot;비밀번호을 입력하세요&quot;)
		f.pass.focus();
		return;
	}
	if(f.subject.value==&quot;&quot;){
		alert(&quot;제목을 입력하세요&quot;)
		f.subject.focus();
		return;
	}
	if(f.content.value==&quot;&quot;){
		alert(&quot;내용을 입력하세요&quot;)
		f.content.focus();
		return;
	}
	f.submit();
}
&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;form action=&quot;replyPro&quot; method=&quot;post&quot; name=&quot;f&quot;&amp;gt;
&amp;lt;imput type=&quot;hidden&quot; name=&quot;num&quot; value=&quot;${board.num}&quot;&amp;gt;
&amp;lt;imput type=&quot;hidden&quot; name=&quot;ref&quot; value=&quot;${board.ref}&quot;&amp;gt;
&amp;lt;imput type=&quot;hidden&quot; name=&quot;refstep&quot; value=&quot;${board.refstep}&quot;&amp;gt;
&amp;lt;imput type=&quot;hidden&quot; name=&quot;reflevel&quot; value=&quot;${board.reflevel}&quot;&amp;gt;
&amp;lt;div class = &quot;w3-content&quot;&amp;gt;
&amp;lt;table&amp;gt;
	&amp;lt;caption&amp;gt;답글쓰기&amp;lt;/caption&amp;gt;
	&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;글쓴이&amp;lt;/th&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&quot;text&quot; name=&quot;name&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
	&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;비밀번호&amp;lt;/th&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&quot;password&quot; name=&quot;pass&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
	&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;제목&amp;lt;/th&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&quot;text&quot; name=&quot;subject&quot; value=&quot;re:${board.subject}&quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
	&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;내용&amp;lt;/th&amp;gt;&amp;lt;td&amp;gt;&amp;lt;textarea rows=&quot;15&quot; name=&quot;content&quot;&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
	&amp;lt;tr&amp;gt;
		&amp;lt;td colspan=&quot;2&quot;&amp;gt;&amp;lt;a href=&quot;javascript:board_submit()&quot;&amp;gt;[답글등록]&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
	&amp;lt;/tr&amp;gt;
&amp;lt;/table&amp;gt;
&amp;lt;/div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;
http://localhost:8090/kicPro/board/writeForm
&amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>KIC/JSP</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/95</guid>
      <comments>https://bacha.tistory.com/95#entry95comment</comments>
      <pubDate>Thu, 2 Sep 2021 02:21:11 +0900</pubDate>
    </item>
    <item>
      <title>day54 - JSP(공지사항 페이지)</title>
      <link>https://bacha.tistory.com/94</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[BoardController,java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1630426531510&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package controller;

import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.oreilly.servlet.MultipartRequest;

import dao.BoardDao;
import dao.MemberDao;
import model.Board;
import model.Member;

public class BoardController extends Action{
	public String hello(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// TODO Auto-generated method stub
		request.setAttribute(&quot;hello&quot;, &quot;hello 테스트 입니다.&quot;);
		
		return &quot;/view/hello.jsp&quot;;
	}
	
	public String list(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		/*
		 * 게시물 목록 보기 
		 * 1. pageNum 파라미터 존재. pageNum 파라미터 없으면 1로 설정. 
		 * 2. 10건의 게시물 출력. =&amp;gt; db에서
		 *    해당 페이지에 출력되는 게시물만 조회. 순서 : 최근 게시물 순으로 
		 * 3. 화면에 출력.
		 * 4. boardid 파라메터가 없으면 session을 수정하지 않음 default는 1임
		 */

		// TODO Auto-generated method stub
		HttpSession session = request.getSession();
		
		//pageNum 이 넘어와야 pageNum이 바뀜
		if(request.getParameter(&quot;pageNum&quot;) != null) {
			session.setAttribute(&quot;page&quot;, request.getParameter(&quot;pageNum&quot;));
		}
		
		//boardid가 넘어와야 세션이 변경됨 : 현재 게시판 분류에 따른 입력, 수정을 적용
		if(request.getParameter(&quot;boardid&quot;) != null) {
			session.setAttribute(&quot;boardid&quot;, request.getParameter(&quot;boardid&quot;));
			session.setAttribute(&quot;pageNum&quot;, &quot;1&quot;);
		}
		
		String pageNum = (String) session.getAttribute(&quot;pageNum&quot;);
		if(pageNum == null) pageNum = &quot;1&quot;;
		int pageInt = Integer.parseInt(pageNum);
		
		String boardid = (String)session.getAttribute(&quot;boardid&quot;);
		if(boardid == null) boardid = &quot;1&quot;;
		
		int limit = 3; // 한 페이지에 출력할 게시물 건수
		BoardDao dao = new BoardDao();
		int boardcount = dao.boardCount(boardid); //등록된 전체 게시물의 건수
		/*
		 * pageInt-현재 페이지 넘버, 
		 * limit-한페이지에 출력할 게시물 건수
		 * boardcount--등록된 전체 게시물의 건수
		 * boardid-공지사항(1),자유게시판(2), QnA(3)
		 */

		List&amp;lt;Board&amp;gt; list = dao.list(pageInt, limit, boardcount, boardid); // 화면에 출력된 게시물 데이터
		// 13 ---&amp;gt; boardcount/limit : 4 + 1
		int maxpage = (int)(boardcount/limit) + (boardcount % limit == 0 ? 0 : 1);
		int bottomLine = 3;
		//page 1,2,3 : 1, 4,5,6 : 2
		int startpage = 1 + (pageInt -1) * limit;
		int endpage = 3 + (pageInt -1) * limit;
		
		int boardnum = boardcount - (pageInt -1 )*limit ;
		String boardName = &quot;&quot;;
		
		switch(boardid) {
			case &quot;1&quot;: {
				boardName = &quot;공지사항&quot;; 
				break;
			}
			case &quot;2&quot;: {
				boardName = &quot;자유게시판&quot;; 
				break;
			}
			case &quot;3&quot;: {
				boardName = &quot;QnA&quot;; 
				break;
			}
			default:
				boardName=&quot;공지사항&quot;;
		}
		
		request.setAttribute(&quot;boardcount&quot;, boardcount);
		request.setAttribute(&quot;list&quot;, list);
		request.setAttribute(&quot;boardnum&quot;, boardnum);
		request.setAttribute(&quot;startpage&quot;, startpage);
		request.setAttribute(&quot;endpage&quot;, endpage);
		request.setAttribute(&quot;bottomLine&quot;, bottomLine);
		request.setAttribute(&quot;maxpage&quot;, maxpage);
		request.setAttribute(&quot;pageNum&quot;, pageNum);
		request.setAttribute(&quot;boardName&quot;, boardName);
		
		
		
		return &quot;/view/board/list.jsp&quot;;
	}
	
	public String memberInput(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// TODO Auto-generated method stub
		request.setAttribute(&quot;input&quot;, &quot;member Input 테스트 입니다.&quot;);
		
		return &quot;/view/memberInput.jsp&quot;;
	}
	
	public String writenForm(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// TODO Auto-generated method stub

		return &quot;/view/board/writenForm.jsp&quot;;
	}
	
	public String writePro(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		String uploadpath = request.getServletContext().getRealPath(&quot;/&quot;) + &quot;upfile&quot;;
		int size = 10 * 1024 * 1024;
		MultipartRequest multi;
		
		//board session 저장 내용: defualt 1
		String boardid = (String)request.getSession().getAttribute(&quot;boardid&quot;);
		if(boardid == null) boardid=&quot;1&quot;;
		
		try {
			multi = new MultipartRequest(request, uploadpath, size, &quot;utf-8&quot;);
			Board board = new Board();
			board.setName(multi.getParameter(&quot;name&quot;));
			board.setSubject(multi.getParameter(&quot;subject&quot;));
			board.setPass(multi.getParameter(&quot;pass&quot;));
			board.setContent(multi.getParameter(&quot;content&quot;));
			board.setFile1(multi.getParameter(&quot;file1&quot;));
			board.setBoardid(boardid);
			if(board.getFile1() == null) board.setFile1(&quot;&quot;);
			
			BoardDao dao = new BoardDao();
			
			String msg = &quot;게시물 등록 실패&quot;;
			String url = &quot;board/writenForm&quot;;
			if(dao.insert(board)) {
				msg = &quot;게시물 등록 성공&quot;;
				url = &quot;board/list&quot;;
			}
			request.setAttribute(&quot;msg&quot;, msg);
			request.setAttribute(&quot;url&quot;, url);
			
		}catch(IOException e) {
			e.printStackTrace();
		}
		return &quot;/view/alert.jsp&quot;;
		
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[BoardDao.java]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1630426559497&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import model.Board;
import util.DBConnection;

public class BoardDao {
	public boolean insert(Board board) {
		Connection conn = DBConnection.getConnection();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		System.out.println(&quot;insert:&quot;+board);
		int num = 0;
		String sql1 = &quot;select multiboardseq.nextval from dual&quot;;
		String sql2 = &quot;insert into multiboard &quot; + &quot;(num, name, pass, subject, content, file1, regdate,&quot;
				+ &quot;readcnt, ref, reflevel, refstep, boardid)&quot; + &quot;  values  (?,?,?,?,?,?,sysdate,0,?,?,?,?)&quot;;
		//---------------------------
		int ref = 0, reflevel = 0, refstep = 0;
		//---------------------------
		try {
			pstmt = conn.prepareStatement(sql1);
			rs = pstmt.executeQuery();
			if(rs.next()) num = rs.getInt(1);
			// ---------------- 답글인 경우
			if(board.getNum() &amp;gt; 0) {
				ref = board.getRef();
				reflevel = board.getReflevel() + 1;
				refstep = board.getRefstep() + 1;
			}else {
				
				ref = num;
			}
			// ---------------- 답글인 경우
			pstmt = conn.prepareStatement(sql2);
			pstmt.setInt(1, num);
			pstmt.setString(2, board.getName());
			pstmt.setString(3, board.getPass());
			pstmt.setString(4, board.getSubject());
			pstmt.setString(5, board.getContent());
			pstmt.setString(6, board.getFile1());
			pstmt.setInt(7, ref);
			pstmt.setInt(8, reflevel);
			pstmt.setInt(9, refstep);
			pstmt.setString(10, board.getBoardid());
			pstmt.executeUpdate();
			return true;
				
			}catch(SQLException e) {
				e.printStackTrace();
		}
		finally {
			DBConnection.close(conn, pstmt, null);
		}
		return false;
	}
	
	public int boardCount(String boardid) {
		Connection conn = DBConnection.getConnection();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			pstmt = conn.prepareStatement(&quot;select count(*) count from multiboard where boardid  = ?&quot;);
			pstmt.setString(1, boardid);
			rs = pstmt.executeQuery();
			rs.next();
			return rs.getInt(1);
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			DBConnection.close(conn, pstmt, rs);
		}
		return 0;
	}
	
	public List&amp;lt;Board&amp;gt; list(int pageInt, int limit, int boardcount, String boardid){
		Connection conn = DBConnection.getConnection();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		List&amp;lt;Board&amp;gt; list = new ArrayList&amp;lt;Board&amp;gt;();
		//----------------------
		int start = (pageInt - 1) * limit + 1;
		int end = start + limit -1;
		String sql = &quot;select * from (select rownum rnum, a.* &quot;
				+ &quot; from (select * from multiboard where boardid = ? order by ref desc, refstep) a) &quot;
				+ &quot;where rnum between ? and ?&quot;;
		System.out.println(sql);
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, boardid);
			pstmt.setInt(2, start);
			pstmt.setInt(3, end);
			System.out.println(start + &quot;:&quot; + end);
			rs = pstmt.executeQuery();
			while(rs.next()) {
				Board b = new Board();
				b.setNum(rs.getInt(&quot;num&quot;));
				b.setName(rs.getString(&quot;name&quot;));
				b.setPass(rs.getString(&quot;pass&quot;));
				b.setSubject(rs.getString(&quot;subject&quot;));
				b.setContent(rs.getString(&quot;content&quot;));
				b.setFile1(rs.getString(&quot;file1&quot;));
				b.setRef(rs.getInt(&quot;ref&quot;));
				b.setReflevel(rs.getInt(&quot;reflevel&quot;));
				b.setRefstep(rs.getInt(&quot;refstep&quot;));
				b.setReadcnt(rs.getInt(&quot;readcnt&quot;));
				b.setRegdate(rs.getTimestamp(&quot;regdate&quot;));
				list.add(b);
				
				
			}
			return list;
			
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			DBConnection.close(conn, pstmt, rs);
		}
		return null;
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>KIC/JSP</category>
      <category>jsp</category>
      <category>공지사항 페이지</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/94</guid>
      <comments>https://bacha.tistory.com/94#entry94comment</comments>
      <pubDate>Wed, 1 Sep 2021 01:16:21 +0900</pubDate>
    </item>
    <item>
      <title>day53 - JSP(사진 추가 페이지)</title>
      <link>https://bacha.tistory.com/93</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[photoFrom.jsp]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1630336207020&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot;
    pageEncoding=&quot;UTF-8&quot;%&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
&amp;lt;title&amp;gt;회원 사진 등록&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt; 사진 photo 폴더 생성 (f5)
&amp;lt;h3&amp;gt;업로드&amp;lt;/h3&amp;gt;
&amp;lt;form action=&quot;&amp;lt;%=request.getContextPath()%&amp;gt;/member/photoPro&quot; method=&quot;post&quot;
enctype=&quot;multipart/form-data&quot;&amp;gt;
	&amp;lt;input type=&quot;file&quot; name=&quot;picture&quot;&amp;gt;
	&amp;lt;input type=&quot;submit&quot; value=&quot;사진등록&quot;&amp;gt;

&amp;lt;/form&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[photoPro.jsp]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1630336239331&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot;
    pageEncoding=&quot;UTF-8&quot;%&amp;gt;
    
&amp;lt;!--
1. 파일 업로드 하기 -&amp;gt; 업로드 위치는 /photo로 설정
2. 파일 내용을 opener에 출력하기. 현재 윈도우는 close 함
  --&amp;gt;
&amp;lt;script&amp;gt;
img = opener.document.getElementById(&quot;pic&quot;);
img.src=&quot;&amp;lt;%=request.getContextPath()%&amp;gt;/photo/${filename}&quot;; // 업로드된 이미지 회원가입 화면에 출력
opener.document.f.picture.value=&quot;${filename}&quot;;
self.close();
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>KIC/JSP</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/93</guid>
      <comments>https://bacha.tistory.com/93#entry93comment</comments>
      <pubDate>Tue, 31 Aug 2021 00:10:53 +0900</pubDate>
    </item>
    <item>
      <title>day52 - JSP(login, memberList)</title>
      <link>https://bacha.tistory.com/92</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[memberInfo]&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1630074357750&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot;
    pageEncoding=&quot;UTF-8&quot;%&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
&amp;lt;title&amp;gt;Insert title here&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div class=&quot;w3-content &quot; style=&quot;width:80%; align-self: center;&quot;&amp;gt;
	&amp;lt;form action=&quot;&amp;lt;%=request.getContextPath()%&amp;gt;/member/memberInputPro&quot; 
	name=&quot;f&quot; method=&quot;post&quot;&amp;gt;
		&amp;lt;input type=&quot;hidden&quot; name=&quot;picture&quot; value=&quot;&quot;&amp;gt;
		&amp;lt;table   &amp;gt;
			&amp;lt;caption&amp;gt;회원가입&amp;lt;/caption&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td rowspan=&quot;4&quot; valign=&quot;bottom&quot;&amp;gt;&amp;lt;img src=&quot;&quot; width=&quot;100&quot;
					height=&quot;120&quot; id=&quot;pic&quot;&amp;gt;&amp;lt;br&amp;gt; &amp;lt;font size=&quot;1&quot;&amp;gt;&amp;lt;a
						href=&quot;javascript:win_upload()&quot;&amp;gt;사진등록&amp;lt;/a&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;
				&amp;lt;td&amp;gt;아이디&amp;lt;/td&amp;gt;
				&amp;lt;td&amp;gt;&amp;lt;input type=&quot;text&quot; name=&quot;id&quot;&amp;gt;&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td&amp;gt;비밀번호&amp;lt;/td&amp;gt;
				&amp;lt;td&amp;gt;&amp;lt;input type=&quot;password&quot; name=&quot;pass&quot;&amp;gt;&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td&amp;gt;이름&amp;lt;/td&amp;gt;
				&amp;lt;td&amp;gt;&amp;lt;input type=&quot;text&quot; name=&quot;name&quot;&amp;gt;&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td&amp;gt;성별&amp;lt;/td&amp;gt;
				&amp;lt;td&amp;gt;&amp;lt;input type=&quot;radio&quot;  value=&quot;1&quot; name=&quot;gender&quot; checked&amp;gt;남
					&amp;lt;input type=&quot;radio&quot;  value=&quot;2&quot; name=&quot;gender&quot; &amp;gt;여&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td&amp;gt;전화번호&amp;lt;/td&amp;gt;
				&amp;lt;td colspan=&quot;2&quot;&amp;gt;&amp;lt;input type=&quot;text&quot; name=&quot;tel&quot;&amp;gt;&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td&amp;gt;이메일&amp;lt;/td&amp;gt;
				&amp;lt;td colspan=&quot;2&quot;&amp;gt;&amp;lt;input type=&quot;text&quot; name=&quot;email&quot;&amp;gt;&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td colspan=&quot;3&quot;  align=&quot;right&quot;&amp;gt;&amp;lt;input type=&quot;submit&quot;   value=&quot;회원가입&quot;&amp;gt;&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
		&amp;lt;/table&amp;gt;
		
	&amp;lt;/form&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[memberUpdate]&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1630074378153&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot;
    pageEncoding=&quot;UTF-8&quot;%&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
&amp;lt;title&amp;gt;Insert title here&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div class=&quot;w3-content &quot; style=&quot;width:80%; align-self: center;&quot;&amp;gt;
	&amp;lt;form action=&quot;&amp;lt;%=request.getContextPath()%&amp;gt;/member/memberUpdatePro&quot; 
	name=&quot;f&quot; method=&quot;post&quot;&amp;gt;
		&amp;lt;input type=&quot;hidden&quot; name=&quot;picture&quot; value=&quot;&quot;&amp;gt;
		&amp;lt;table   &amp;gt;
			&amp;lt;caption&amp;gt;회원가입&amp;lt;/caption&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td rowspan=&quot;4&quot; valign=&quot;bottom&quot;&amp;gt;&amp;lt;img src=&quot;&quot; width=&quot;100&quot;
					height=&quot;120&quot; id=&quot;pic&quot;&amp;gt;&amp;lt;br&amp;gt; &amp;lt;font size=&quot;1&quot;&amp;gt;&amp;lt;a
						href=&quot;javascript:win_upload()&quot;&amp;gt;사진등록&amp;lt;/a&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;
				&amp;lt;td&amp;gt;아이디&amp;lt;/td&amp;gt;
				&amp;lt;td&amp;gt;${member.id}&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td&amp;gt;비밀번호&amp;lt;/td&amp;gt;
				&amp;lt;td&amp;gt;&amp;lt;input type=&quot;password&quot; name=&quot;pass&quot;&amp;gt;&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td&amp;gt;이름&amp;lt;/td&amp;gt;
				&amp;lt;td&amp;gt;&amp;lt;input type=&quot;text&quot; name=&quot;name&quot; value=&quot;${member.name}&quot;&amp;gt;&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td&amp;gt;성별&amp;lt;/td&amp;gt;
				&amp;lt;td&amp;gt;&amp;lt;input type=&quot;radio&quot;  value=&quot;1&quot; name=&quot;gender&quot; ${memeber.gender=1? 'checked' : ''}&amp;gt;
					&amp;lt;input type=&quot;radio&quot;  value=&quot;2&quot; name=&quot;gender&quot; ${memeber.gender=2? 'checked' : ''}&amp;gt;&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td&amp;gt;전화번호&amp;lt;/td&amp;gt;
				&amp;lt;td colspan=&quot;2&quot;&amp;gt;&amp;lt;input type=&quot;text&quot; name=&quot;tel&quot; value=&quot;${member.tel}&quot;&amp;gt;&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td&amp;gt;이메일&amp;lt;/td&amp;gt;
				&amp;lt;td colspan=&quot;2&quot;&amp;gt;&amp;lt;input type=&quot;text&quot; name=&quot;email&quot; value=&quot;${member.email}&quot;&amp;gt;&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
			&amp;lt;tr&amp;gt;
				&amp;lt;td colspan=&quot;3&quot;  align=&quot;right&quot;&amp;gt;&amp;lt;input type=&quot;submit&quot;   value=&quot;정보수정&quot;&amp;gt;&amp;lt;/td&amp;gt;
			&amp;lt;/tr&amp;gt;
		&amp;lt;/table&amp;gt;
		
	&amp;lt;/form&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>KIC/JSP</category>
      <category>login</category>
      <category>memberList</category>
      <author>바차</author>
      <guid isPermaLink="true">https://bacha.tistory.com/92</guid>
      <comments>https://bacha.tistory.com/92#entry92comment</comments>
      <pubDate>Fri, 27 Aug 2021 23:26:37 +0900</pubDate>
    </item>
  </channel>
</rss>