<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>고은별의 기술 공유 연구소</title>
    <link>https://luvris2.tistory.com/</link>
    <description>프로그래밍을 주로 다루는 블로그입니다.
배우면서 정보를 공유하기 때문에 부족함이 많습니다.
틀린 부분이 있다면 언제든 지적 부탁드립니다 :)</description>
    <language>ko</language>
    <pubDate>Sat, 9 May 2026 08:28:53 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>luvris2</managingEditor>
    <image>
      <title>고은별의 기술 공유 연구소</title>
      <url>https://tistory1.daumcdn.net/tistory/5347021/attach/d670c107d16e477faff8f3077dd1f877</url>
      <link>https://luvris2.tistory.com</link>
    </image>
    <item>
      <title>마비노기 모바일 숙제 도우미 - 모비노기 도우미 v1.3.1</title>
      <link>https://luvris2.tistory.com/939</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이전 버전 사용 시, 현재 실행 중인 프로그램을 반드시 종료해 주세요.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로그램의 이상이 보인다면, '환경설정 -&amp;gt; 초기화' 기능을 이용해 주세요.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1.3.0 버전에서 발견된 버그가 수정된 버전입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;다운로드 링크&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;암호 : mobinogihelper&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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;a href=&quot;https://drive.google.com/file/d/1lGsVofpwzgvji4Aqb9uzB6K3eEX1Km8C/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://drive.google.com/file/d/1lGsVofpwzgvji4Aqb9uzB6K3eEX1Km8C/view?usp=sharing&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1752715244903&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;모비노기도우미 v1.3.1_pwd.zip&quot; data-og-description=&quot;&quot; data-og-host=&quot;drive.google.com&quot; data-og-source-url=&quot;https://drive.google.com/file/d/1lGsVofpwzgvji4Aqb9uzB6K3eEX1Km8C/view?usp=sharing&quot; data-og-url=&quot;https://drive.google.com/file/d/1lGsVofpwzgvji4Aqb9uzB6K3eEX1Km8C/view?usp=sharing&amp;amp;usp=embed_facebook&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://drive.google.com/file/d/1lGsVofpwzgvji4Aqb9uzB6K3eEX1Km8C/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://drive.google.com/file/d/1lGsVofpwzgvji4Aqb9uzB6K3eEX1Km8C/view?usp=sharing&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;모비노기도우미 v1.3.1_pwd.zip&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;drive.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;❓&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;바이러스라고 다운로드가&amp;nbsp;&lt;/span&gt;안 돼요!&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;/&amp;nbsp;바이러스라면서&amp;nbsp;&lt;/span&gt;다운로드하면&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;파일이&amp;nbsp;&lt;/span&gt;삭제돼요!&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 파일은 사용자의 편의성을 위하여 프로그램 실행에 필요한&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;모든 구성요소를 자체적으로 포함한 버전입니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 단일 exe 확장자 파일로 구성되며 용량이 다소 많아&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;특정 환경에서는 바이러스로 의심되는 것 같습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;바이러스 관련으로 모비노기 도우미 사용이 어려우신 분들은&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아래의&lt;i&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;'런타임 패키지 미포함 버전'&lt;/i&gt;을 다운로드하여주세요.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;프로그램 실행 시 팝업 되는 설치 링크로 이동하여 &lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;반드시 런타임 패키지를 설치&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;하여야만&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;모비노기 도우미를 이용할 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;런타임 패키지 미포함 모비노기 도우미 v.1.3.1&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://drive.google.com/file/d/175dTENq3HGlSuSZ8uxzXyrSLq8bwebSN/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://drive.google.com/file/d/175dTENq3HGlSuSZ8uxzXyrSLq8bwebSN/view?usp=sharing&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1752715261569&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;MobinogiHelper v1.3.1.zip&quot; data-og-description=&quot;&quot; data-og-host=&quot;drive.google.com&quot; data-og-source-url=&quot;https://drive.google.com/file/d/175dTENq3HGlSuSZ8uxzXyrSLq8bwebSN/view?usp=sharing&quot; data-og-url=&quot;https://drive.google.com/file/d/175dTENq3HGlSuSZ8uxzXyrSLq8bwebSN/view?usp=sharing&amp;amp;usp=embed_facebook&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://drive.google.com/file/d/175dTENq3HGlSuSZ8uxzXyrSLq8bwebSN/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://drive.google.com/file/d/175dTENq3HGlSuSZ8uxzXyrSLq8bwebSN/view?usp=sharing&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;MobinogiHelper v1.3.1.zip&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;drive.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;+ 추가 제보)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;윈도우10에서는 바이러스로 여전히 다운로드되지 않는다는 제보가 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;마이크로소프트에서 지원 종료를 하기 때문에 가능하면 윈도우11을 사용해 주세요.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;오류 수정사항&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2025-07-17&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;보기 옵션의 '80% 작게 보기' 설정된 상태에서 캐릭터 추가 시 오류가 뜨는 현상 수정&lt;/li&gt;
&lt;li&gt;스크롤 바가 이상하게 보이는 현상 수정
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;추가된 캐릭터가 5개 미만의 경우 스크롤 바 레이아웃 이상 현상 수정&lt;/li&gt;
&lt;li&gt;보기 설정 변경 시, 숙제 리스트 탭의 스크롤 바 레이아웃 이상 현상 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;초기화&amp;nbsp;기능&amp;nbsp;오작동&amp;nbsp;오류&amp;nbsp;수정&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>포트폴리오/모비노기 도우미</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/939</guid>
      <comments>https://luvris2.tistory.com/939#entry939comment</comments>
      <pubDate>Thu, 17 Jul 2025 10:21:56 +0900</pubDate>
    </item>
    <item>
      <title>마비노기 모바일 숙제 도우미 - 모비노기 도우미 v1.3.0</title>
      <link>https://luvris2.tistory.com/938</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이전 버전 사용 시, 현재 실행중인 프로그램을 반드시 종료해주세요.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로그램의 이상이 보인다면, '환경설정 -&amp;gt; 초기화' 기능을 이용해주세요.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;'80% 작게 보기' 옵션 상태에서 캐릭터를 추가할 경우 오류가 발생하고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;추 후 수정하여 업데이트 할 예정이니 불편하시더라도&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;'80% 작게 보기' 옵션은 &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;모든 캐릭터와 콘텐츠가 추가 된 이후 보기 용도로 사용&lt;/b&gt;하시거나,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;기존 보기 방법을 사용&lt;/b&gt;해주세요.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; 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;암호 : mobinogihelper&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;a href=&quot;https://drive.google.com/file/d/1xVrTavZ1J2wl-03xq_hkKQHz--wXsYYM/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://drive.google.com/file/d/1xVrTavZ1J2wl-03xq_hkKQHz--wXsYYM/view?usp=sharing&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1752418073113&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;모비노기도우미 v1.3.0_pwd.zip&quot; data-og-description=&quot;&quot; data-og-host=&quot;drive.google.com&quot; data-og-source-url=&quot;https://drive.google.com/file/d/1xVrTavZ1J2wl-03xq_hkKQHz--wXsYYM/view?usp=sharing&quot; data-og-url=&quot;https://drive.google.com/file/d/1xVrTavZ1J2wl-03xq_hkKQHz--wXsYYM/view?usp=sharing&amp;amp;usp=embed_facebook&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://drive.google.com/file/d/1xVrTavZ1J2wl-03xq_hkKQHz--wXsYYM/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://drive.google.com/file/d/1xVrTavZ1J2wl-03xq_hkKQHz--wXsYYM/view?usp=sharing&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;모비노기도우미 v1.3.0_pwd.zip&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;drive.google.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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;❓ &lt;span style=&quot;text-align: start;&quot;&gt;바이러스라고 다운로드가&amp;nbsp;&lt;/span&gt;안돼요!&lt;span style=&quot;text-align: start;&quot;&gt; /&amp;nbsp;바이러스라면서&amp;nbsp;&lt;/span&gt;다운로드하면&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;파일이&amp;nbsp;&lt;/span&gt;삭제돼요! &lt;/b&gt;&lt;/h3&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;때문에 단일 exe 확장자 파일로 구성되며 용량이 다소 많습니다.&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;i&gt; '런타임 패키지 미포함 버전'&lt;/i&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;span style=&quot;color: #ee2323;&quot;&gt;프로그램 실행 시 팝업되는 설치 링크로 이동하여 반드시 런타임 패키지를 설치&lt;/span&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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;런타임 패키지 미포함 모비노기 도우미 v.1.3.0&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://drive.google.com/file/d/15Im3v9skxCLwCxprQDf-szD_bNwrQu-U/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://drive.google.com/file/d/15Im3v9skxCLwCxprQDf-szD_bNwrQu-U/view?usp=sharing&lt;/a&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-07-06&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주간 숙제 아이콘 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;주말 어비스&lt;/b&gt; : 주말 어비스 3회 클리어 퀘스트&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주말 레이드&lt;/b&gt; : 주말 레이드 1회 클리어 퀘스트&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;환경 설정 옵션 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;보기 설정&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;80% 작게 보기&lt;/b&gt; : 기존 크기보다 80% 작은 크기로 UI 구성, 숙제 컨텐츠를 5칸씩 보이도록 함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;원래대로 보기&lt;/b&gt; : 기존 크기 그대로 UI 구성, 숙제 컨텐츠를 4칸씩 보이도록 함&lt;/li&gt;
&lt;li&gt;옵션 추가로 인해 제작자 배너는 불필요해보여서 제거하였습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-07-11&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주간 숙제 아이콘 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;어비스 교환&lt;/b&gt; : 몰리NPC를 통해 심연의 화석을 붉은 심연의 화석으로 교환하는 것을 확인하기 위함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;2027-07-13&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생활 아이콘 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;일일 물물교환&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;NPC : 셰이머스, 고양이상인&lt;/li&gt;
&lt;li&gt;물품 : &lt;b&gt;뛰어난붕대, 하트토큰&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주간 구매 물품&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;NPC : 엔델리온, 크리스텔&lt;/li&gt;
&lt;li&gt;물품 : &lt;b&gt;성수&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;주간 컨텐츠 아이콘 추가&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주말 어비스&lt;/li&gt;
&lt;li&gt;주말 레이드&lt;/li&gt;
&lt;li&gt;어비스 교환&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;292&quot; data-origin-height=&quot;80&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dp1bWl/btsPg9l9mDI/7eOvavzRqbvctYRjgj2VSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dp1bWl/btsPg9l9mDI/7eOvavzRqbvctYRjgj2VSk/img.png&quot; data-alt=&quot;추가된 주간 컨텐츠 아이콘 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dp1bWl/btsPg9l9mDI/7eOvavzRqbvctYRjgj2VSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdp1bWl%2FbtsPg9l9mDI%2F7eOvavzRqbvctYRjgj2VSk%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;292&quot; height=&quot;80&quot; data-origin-width=&quot;292&quot; data-origin-height=&quot;80&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;추가된 주간 컨텐츠 아이콘 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&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;생활 컨텐츠 아이콘 추가&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;추가된 물품 아이콘&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;388&quot; data-origin-height=&quot;87&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWTB0F/btsPg6CVejD/N88vy8BauIXUno647yNOqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWTB0F/btsPg6CVejD/N88vy8BauIXUno647yNOqK/img.png&quot; data-alt=&quot;추가된 'NPC별 물품별 상세히 보기' 아이콘 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWTB0F/btsPg6CVejD/N88vy8BauIXUno647yNOqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWTB0F%2FbtsPg6CVejD%2FN88vy8BauIXUno647yNOqK%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;388&quot; height=&quot;87&quot; data-origin-width=&quot;388&quot; data-origin-height=&quot;87&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;추가된 'NPC별 물품별 상세히 보기' 아이콘 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;추가된 NPC 아이콘&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;83&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d8yIMv/btsPgVuTPyc/kRPWwZmUtkV6wuSJvD8emK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d8yIMv/btsPgVuTPyc/kRPWwZmUtkV6wuSJvD8emK/img.png&quot; data-alt=&quot;추가된 'NPC 아이콘만 보기' 아이콘 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d8yIMv/btsPgVuTPyc/kRPWwZmUtkV6wuSJvD8emK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd8yIMv%2FbtsPgVuTPyc%2FkRPWwZmUtkV6wuSJvD8emK%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;380&quot; height=&quot;83&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;83&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;추가된 'NPC 아이콘만 보기' 아이콘 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&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;환경 설정 옵션 추가&lt;/b&gt;&lt;/h3&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;561&quot; data-origin-height=&quot;748&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dli1Rx/btsPhkugoKH/5Unwk3u5XUYocZQOo7VhA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dli1Rx/btsPhkugoKH/5Unwk3u5XUYocZQOo7VhA0/img.png&quot; data-alt=&quot;환경설정에서 확인 가능한 보기 설정 옵션 미리보기 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dli1Rx/btsPhkugoKH/5Unwk3u5XUYocZQOo7VhA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdli1Rx%2FbtsPhkugoKH%2F5Unwk3u5XUYocZQOo7VhA0%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;561&quot; height=&quot;748&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;748&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;환경설정에서 확인 가능한 보기 설정 옵션 미리보기 화면&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;646&quot; data-origin-height=&quot;401&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5DNKM/btsPhjPDEc8/rdM9aDfYJfoQVKsr5MR9EK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5DNKM/btsPhjPDEc8/rdM9aDfYJfoQVKsr5MR9EK/img.png&quot; data-alt=&quot;좌: 원래대로 보기 / 우 : 80% 작게 보기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5DNKM/btsPhjPDEc8/rdM9aDfYJfoQVKsr5MR9EK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5DNKM%2FbtsPhjPDEc8%2FrdM9aDfYJfoQVKsr5MR9EK%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;646&quot; height=&quot;401&quot; data-origin-width=&quot;646&quot; data-origin-height=&quot;401&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;좌: 원래대로 보기 / 우 : 80% 작게 보기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>포트폴리오/모비노기 도우미</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/938</guid>
      <comments>https://luvris2.tistory.com/938#entry938comment</comments>
      <pubDate>Sun, 13 Jul 2025 23:51:40 +0900</pubDate>
    </item>
    <item>
      <title>마비노기 모바일 숙제 도우미 - 모비노기 도우미 v1.2.1</title>
      <link>https://luvris2.tistory.com/937</link>
      <description>&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;암호 : mobinogihelper&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://drive.google.com/file/d/1HG9u1WUpgnGRKVS2EFVqxyuQNkmnAw_7/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://drive.google.com/file/d/1HG9u1WUpgnGRKVS2EFVqxyuQNkmnAw_7/view?usp=sharing&lt;/a&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;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2025-06-20&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;유저 편의성 개선 작업
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;커스텀 콘텐츠 아이콘 추가 시, 컨트롤을 눌러서 추가했었어야 하는 번거로움 제거&lt;/li&gt;
&lt;li&gt;마우스 클릭으로 선택 / 선택 해제가 가능하도록 변경&lt;/li&gt;
&lt;li&gt;콘텐츠 아이콘 선택 시 유저가 직관적으로 순서를 확인할 수 있도록 순서 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;사용자가 선택한 숙제 리스트가 간헐적으로 순서 상관없이 뒤죽박죽으로 나타나는 현상 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-22&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;물물 교환 업데이트(물품 변경)로 인한 아이콘 추가 및 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-23&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;레이드 아이콘을 삭제하고 글라스기브넨, 화이트 서큐버스 아이콘 새로 추가&lt;/li&gt;
&lt;li&gt;&lt;b&gt;v1.2.1 버전 배포&lt;/b&gt;&lt;/li&gt;
&lt;/ul&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;체크할 숙제 콘텐츠를 추가하는 방식 변경&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;기존&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;컨트롤 키를 누르고 선택&lt;/li&gt;
&lt;li&gt;확인을 누르면 선택한 순서대로 추가&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc4Zrq/btsOJNYl5ZQ/lJsn3T6F3nkT8VKTiPcJtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc4Zrq/btsOJNYl5ZQ/lJsn3T6F3nkT8VKTiPcJtk/img.png&quot; data-alt=&quot;기존 콘텐츠 추가 방식 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc4Zrq/btsOJNYl5ZQ/lJsn3T6F3nkT8VKTiPcJtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc4Zrq%2FbtsOJNYl5ZQ%2FlJsn3T6F3nkT8VKTiPcJtk%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;555&quot; height=&quot;270&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;기존 콘텐츠 추가 방식 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;변경&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;마우스 클릭으로 해당 콘텐츠를 선택/선택 해제 할 수 있도록 변경
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;선택한 순서를 사용자가 직관적으로 확인할 수 있도록 선택 순서 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;순서를 확인한 뒤, 확인을 눌러 콘텐츠 추가&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&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;555&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qT6dn/btsOKoDZeRH/JhqUGrtDnWJkGzIkl9iSd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qT6dn/btsOKoDZeRH/JhqUGrtDnWJkGzIkl9iSd1/img.png&quot; data-alt=&quot;변경된 콘텐츠 추가 방식 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qT6dn/btsOKoDZeRH/JhqUGrtDnWJkGzIkl9iSd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqT6dn%2FbtsOKoDZeRH%2FJhqUGrtDnWJkGzIkl9iSd1%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;555&quot; height=&quot;270&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;변경된 콘텐츠 추가 방식 예시 화면&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;콘텐츠 아이콘 추가 및 변경&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;레이드 아이콘&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 레이드가 글라스기브넨 하나뿐이였으나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6월 23일 화이트 서큐버스 레이드가 추가 되었음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 따라 레이드 아이콘을 '글라스기브넨'과 '화이트 서큐버스'로 분리&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;변경 전&lt;/b&gt; : 레이드&lt;/li&gt;
&lt;li&gt;&lt;b&gt;변경 후&lt;/b&gt; : '글라스기브넨', '흰큐버스' 두 개의 아이콘으로 분리&lt;/li&gt;
&lt;/ul&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;콘텐츠 아이콘 변경&lt;/b&gt;&lt;/h3&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;아르미스 일일 교환 추가&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;물물교환 물품 변경으로 인한 아이콘 변경&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt; NPC별 물품 상세히 보기 &lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;발터&lt;/b&gt; : 상급 목재 &amp;gt; 가죽&lt;/li&gt;
&lt;li&gt;&lt;b&gt;칼릭스&lt;/b&gt; : 최상급 목재 &amp;gt; 가죽+&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>포트폴리오/모비노기 도우미</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/937</guid>
      <comments>https://luvris2.tistory.com/937#entry937comment</comments>
      <pubDate>Mon, 23 Jun 2025 14:28:46 +0900</pubDate>
    </item>
    <item>
      <title>마비노기 모바일 숙제 도우미 - 모비노기 도우미 v1.2.0</title>
      <link>https://luvris2.tistory.com/936</link>
      <description>&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;암호 : mobinogihelper&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://drive.google.com/file/d/1nobmkq-uJKmo-z6GtIyh8YZji_pX48yY/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://drive.google.com/file/d/1nobmkq-uJKmo-z6GtIyh8YZji_pX48yY/view?usp=sharing&lt;/a&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-18&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;프로그램 실행 시, 최신 버전 확인 및 업데이트 알림 기능&lt;/b&gt; 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최신 버전 존재할 경우, 해당 알림을 누르면 다운로드 페이지로 이동&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;숙제 및 생활 관련 리스트 스크롤 시, 좌측의 메인 타이틀은 움직이지 않도록 수정&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;콘텐츠 아이콘 관련
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일일 및 주간 숙제 콘텐츠 일부 디자인 수정&lt;/li&gt;
&lt;li&gt;숙제 콘텐츠 아이콘 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일일 숙제 콘텐츠 아이콘 추가 : 일일 미션&lt;/li&gt;
&lt;li&gt;주간 숙제 아이콘 변경 : 별의 인장 -&amp;gt; 마물 퇴치 증표&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;환경 설정 : 결계 알리미 관련
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;'결계 숙제 끝나면 알리미 끄기' 옵션 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 캐릭터가 결계 횟수를 소진하면, 해당 옵션 선택 시 알리미 비활성화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-19&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;숙제 초기화 로직 변경
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다문화권 시간 체계(윈도우 시간 표시가 다른 환경)를 수용하도록 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;반호르 관련 생활 콘텐츠 아이콘 추가&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;v1.2.0 버전 배포&lt;/b&gt;&lt;/li&gt;
&lt;/ul&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하지 않을 경우 우측의 'X'를 눌러 해당 알림을 끌 수 있습니다.&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;617&quot; data-origin-height=&quot;153&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fh24R/btsOHe2pZc4/1sE3LSa4BJALjNvGkoTfZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fh24R/btsOHe2pZc4/1sE3LSa4BJALjNvGkoTfZ0/img.png&quot; data-alt=&quot;업데이트 알림 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fh24R/btsOHe2pZc4/1sE3LSa4BJALjNvGkoTfZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFh24R%2FbtsOHe2pZc4%2F1sE3LSa4BJALjNvGkoTfZ0%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;617&quot; height=&quot;153&quot; data-origin-width=&quot;617&quot; data-origin-height=&quot;153&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;업데이트 알림 예시 화면&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;숙제 및 생활 관련 편의성 개선&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숙제 혹은 생활 리스트 스크롤 시,&lt;br /&gt;좌측의 메인 타이틀은 움직이지 않도록 수정&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;616&quot; data-origin-height=&quot;803&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mFRag/btsOHXm3Jf4/MvlMW7OB9LDpnfFrgZPMkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mFRag/btsOHXm3Jf4/MvlMW7OB9LDpnfFrgZPMkK/img.png&quot; data-alt=&quot;리스트를 스크롤 한 예시 화면, 오늘의 숙제와 이번주 숙제는 고정되도록 변경되었음&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mFRag/btsOHXm3Jf4/MvlMW7OB9LDpnfFrgZPMkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmFRag%2FbtsOHXm3Jf4%2FMvlMW7OB9LDpnfFrgZPMkK%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;400&quot; height=&quot;521&quot; data-origin-width=&quot;616&quot; data-origin-height=&quot;803&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;리스트를 스크롤 한 예시 화면, 오늘의 숙제와 이번주 숙제는 고정되도록 변경되었음&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;결계 알리미 관련&lt;/b&gt;&lt;/h2&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;알리미가 비활성화되도록 옵션 추가&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;139&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KcWTq/btsOJw2T5g8/kCWVDeiodyszkHESbsSDok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KcWTq/btsOJw2T5g8/kCWVDeiodyszkHESbsSDok/img.png&quot; data-alt=&quot;결계 알리미 옵션 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KcWTq/btsOJw2T5g8/kCWVDeiodyszkHESbsSDok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKcWTq%2FbtsOJw2T5g8%2FkCWVDeiodyszkHESbsSDok%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;541&quot; height=&quot;139&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;139&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결계 알리미 옵션 예시 화면&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;콘텐츠 아이콘 관련&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;추가&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;일일 숙제 콘텐츠
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;일일 미션&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;구매 및 교환 콘텐츠
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;반호르 관련&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;변경&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;주간 숙제 콘텐츠
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;별의 인장 &amp;gt; 마물 퇴치 증표&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;수정&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;일부 일일 및 주간 숙제 콘텐츠 아이콘 디자인 수정&lt;/li&gt;
&lt;/ul&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;숙제 초기화 관련&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UTC(협정 세계시)를 사용하여,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간 표기 체계가 다를 시스템(예1: &lt;i&gt;2025-06-19&lt;/i&gt;, 예2: &lt;i&gt;2025-06-19 목&lt;/i&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;b&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;219&quot; data-origin-height=&quot;80&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXHNYU/btsOHnNbyuU/YWT77Uo1VKEBbM6zTabRKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXHNYU/btsOHnNbyuU/YWT77Uo1VKEBbM6zTabRKK/img.png&quot; data-alt=&quot;한국 시간 표시 체계 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXHNYU/btsOHnNbyuU/YWT77Uo1VKEBbM6zTabRKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXHNYU%2FbtsOHnNbyuU%2FYWT77Uo1VKEBbM6zTabRKK%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;219&quot; height=&quot;80&quot; data-origin-width=&quot;219&quot; data-origin-height=&quot;80&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;한국 시간 표시 체계 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;219&quot; data-origin-height=&quot;92&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wNfgo/btsOJKfLDaT/PUsBRTnylpFlJPW20mszk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wNfgo/btsOJKfLDaT/PUsBRTnylpFlJPW20mszk1/img.png&quot; data-alt=&quot;영어권 시간 표시 체계 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wNfgo/btsOJKfLDaT/PUsBRTnylpFlJPW20mszk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwNfgo%2FbtsOJKfLDaT%2FPUsBRTnylpFlJPW20mszk1%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;219&quot; height=&quot;92&quot; data-origin-width=&quot;219&quot; data-origin-height=&quot;92&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;영어권 시간 표시 체계 예시&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>포트폴리오/모비노기 도우미</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/936</guid>
      <comments>https://luvris2.tistory.com/936#entry936comment</comments>
      <pubDate>Thu, 19 Jun 2025 17:16:32 +0900</pubDate>
    </item>
    <item>
      <title>마비노기 모바일 숙제 도우미 - 모비노기 도우미 v1.1.1_fix</title>
      <link>https://luvris2.tistory.com/935</link>
      <description>&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;a href=&quot;https://gall.dcinside.com/mgallery/board/view?id=mabinogimobile&amp;amp;no=988305&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gall.dcinside.com/mgallery/board/view?id=mabinogimobile&amp;amp;no=988305&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;hellip; 이제는 더 간편하게 관리해보자! '0'&lt;br /&gt;버전1.0에 이은 컨텐츠 추가 및 유저 커스텀이 가능하도록 업데이트된 버전입니다.&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;비밀번호 : mobinogihelper&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://drive.google.com/file/d/1v7u-uyM7DXuMMNdtsw7rcIPNeCxze95y/view?usp=sharing&quot;&gt;https://drive.google.com/file/d/1v7u-uyM7DXuMMNdtsw7rcIPNeCxze95y/view?usp=sharing&lt;/a&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;추가 및 수정 사항 (2025-06-18)&lt;/b&gt;&lt;/h2&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2025-05-25
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐릭터를 자유롭게 추가할 수 있도록 변경
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;플러스 모양 아이콘을 눌러 캐릭터를 여러 개 추가&lt;/b&gt;할 수 있도록 기능 확장&lt;/li&gt;
&lt;li&gt;캐릭터 추가 시,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;아이디를 기입할 수 있도록 변경&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(아이디는 최대 4자까지 입력 가능함)&lt;/li&gt;
&lt;li&gt;기존 추가된 캐릭터의 아이디 또한 변경 가능하도록 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2025-05-27
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;트레이 기능&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2025-05-29
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;숙제 리스트의 새로운 컨텐츠 아이콘 추가&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;컨텐츠 확인을 사용자가 유동적으로 할 수 있도록 커스텀 기능 추가&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;유저가 직접 컨트롤 키를 눌러 순서를 정하여 컨텐츠를 추가하여 관리할 수 있도록 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2025-06-05
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;메모장 기능&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2025-06-10 : 메모장 자동 저장 기능 추가 (매 30분 마다)&lt;/li&gt;
&lt;li&gt;2025-06-10 : 프로그램 종료 시 메모 내용 자동 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2025-06-06
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실행 폴더에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;설정 파일(settings.ini)을 생성하지 않도록 변경&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2025-06-11
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;생활 관련 컨텐츠 아이콘 추가&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2025-06-12
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;환경 설정 기능 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;옵션 : 결계 알리미 관련
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;결계 알리미를 '숙제 리스트' 탭이 아닌 '환경설정' 탭으로 이동&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;결계 알리미 디자인 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;옵션 : 프로그램 닫기 관련
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;프로그램 종료를 누를 경우, 선택된 옵션에 따라 작동하도록 변경&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 종료하기 : 닫기 버튼을 누를 경우, 프로그램이 종료 됨&lt;/li&gt;
&lt;li&gt;트레이로 보내기 : 닫기 버튼을 누를 경우, 트레이로 이동되며 창은 사라짐&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;도네이션 배너 제작 및 프로그램 환경설정 탭 내 배치&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2025-06-14
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐릭터 추가 기능 관련
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐릭터 추가 UI 변경&lt;/li&gt;
&lt;li&gt;&lt;b&gt;캐릭터 추가 시 이미지를 선택하여 유저가 직접 캐릭터 이미지를 추가할 수 있도록 함&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;이미지 프리셋 18종 추가&lt;/li&gt;
&lt;li&gt;이미지는 제공되는 프리셋 또는 직접 이미지를 불러와 추가할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;환경 설정 기능 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 초기화 : 모든 설정 및 추가한 캐릭터까지 모두 초기화되도록 함&lt;/li&gt;
&lt;li&gt;횟수 초기화 알림 창 UI 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2025-06-15
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 중복 실행 시, 기존 실행중인 프로그램을 활성화하도록 변경&lt;/li&gt;
&lt;li&gt;프로그램의 마지막 실행 위치를 기억하여 다음 실행 시 해당 위치로 실행되도록 변경&lt;/li&gt;
&lt;li&gt;프로그램의 사이즈를 조절할 수 있도록 변경&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모비노기 도우미 1.1 버전 배포&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2025-06-17 &lt;b&gt;(버그 픽스 버전 v1.1.1)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;오류 수정&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램이 꺼진 상태로 초기화 타임이 지날 경우, 콘텐츠가 초기화되지 않는 현상 수정&lt;/li&gt;
&lt;li id=&quot;block-7ab5eef1-37e6-4bf8-aefa-0b4453114cfc&quot; data-title=&quot;아이템 목록&quot; data-type=&quot;core/list-item&quot; data-block=&quot;7ab5eef1-37e6-4bf8-aefa-0b4453114cfc&quot;&gt;
&lt;div contenteditable=&quot;true&quot; data-wp-block-attribute-key=&quot;content&quot;&gt;결계 3분 타이머에 글꼴이 적용되지 않은 현상 수정&lt;/div&gt;
&lt;/li&gt;
&lt;li id=&quot;block-8996cebb-826d-4040-bec6-51e5ab42314e&quot; data-title=&quot;아이템 목록&quot; data-type=&quot;core/list-item&quot; data-block=&quot;8996cebb-826d-4040-bec6-51e5ab42314e&quot;&gt;
&lt;div contenteditable=&quot;true&quot; data-wp-block-attribute-key=&quot;content&quot;&gt;간헐적으로 시스템 시간 오류로 인해 프로그램이 정상적으로 실행되지 않던 현상 수정&lt;/div&gt;
&lt;ul id=&quot;block-10d80b20-80e3-4ba9-b1ca-274d36b03348&quot; style=&quot;list-style-type: disc;&quot; data-is-drop-zone=&quot;true&quot; data-title=&quot;목록&quot; data-type=&quot;core/list&quot; data-block=&quot;10d80b20-80e3-4ba9-b1ca-274d36b03348&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li id=&quot;block-89882355-769f-4d1e-a2d9-dddedc7e49c5&quot; data-title=&quot;아이템 목록&quot; data-type=&quot;core/list-item&quot; data-block=&quot;89882355-769f-4d1e-a2d9-dddedc7e49c5&quot;&gt;
&lt;div contenteditable=&quot;true&quot; data-wp-block-attribute-key=&quot;content&quot;&gt;이전 버전(1.0)에서 사용자분들께서 말씀하셨던 settings.ini 파일 관련 오류입니다.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li id=&quot;block-b44f5c7e-4b16-4dc0-becd-e22661cf39c9&quot; data-title=&quot;아이템 목록&quot; data-type=&quot;core/list-item&quot; data-block=&quot;b44f5c7e-4b16-4dc0-becd-e22661cf39c9&quot;&gt;
&lt;div contenteditable=&quot;true&quot; data-wp-block-attribute-key=&quot;content&quot;&gt;해상도가 다른 컴퓨터에서 프로그램이 이상하게 보이는 현상 수정&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li id=&quot;block-fa7acb03-cb3b-4fe9-9711-ee1bdcdc4b86&quot; data-title=&quot;아이템 목록&quot; data-type=&quot;core/list-item&quot; data-block=&quot;fa7acb03-cb3b-4fe9-9711-ee1bdcdc4b86&quot;&gt;
&lt;div contenteditable=&quot;true&quot; data-wp-block-attribute-key=&quot;content&quot;&gt;&lt;b&gt;추가&lt;/b&gt;&lt;/div&gt;
&lt;ul id=&quot;block-a49294e5-c833-40b0-b9b6-8afef8fb57c4&quot; style=&quot;list-style-type: disc;&quot; data-is-drop-zone=&quot;true&quot; data-title=&quot;목록&quot; data-type=&quot;core/list&quot; data-block=&quot;a49294e5-c833-40b0-b9b6-8afef8fb57c4&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li id=&quot;block-d7417cb1-ac62-4267-b0a7-24ef65398b4a&quot; data-title=&quot;아이템 목록&quot; data-type=&quot;core/list-item&quot; data-block=&quot;d7417cb1-ac62-4267-b0a7-24ef65398b4a&quot;&gt;
&lt;div contenteditable=&quot;true&quot; data-wp-block-attribute-key=&quot;content&quot;&gt;환경 설정에 디스코드 서버로 이동하는 배너 버튼 추가&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-title=&quot;아이템 목록&quot; data-type=&quot;core/list-item&quot; data-block=&quot;d7417cb1-ac62-4267-b0a7-24ef65398b4a&quot;&gt;2025-06-18 &lt;b&gt;(초기화 오류 재수정 버전 v1.1.1_fix)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-title=&quot;아이템 목록&quot; data-type=&quot;core/list-item&quot; data-block=&quot;d7417cb1-ac62-4267-b0a7-24ef65398b4a&quot;&gt;숙제 초기화 로직에 잘못된 변수가 사용되어 정상 작동하지 않은 것을 확인, 수정 버전 재배포&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&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;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결계 기능 관련
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;알림 소리 조절&lt;/li&gt;
&lt;li&gt;알림 소리를 사용자가 원하는 소리로 변경&lt;/li&gt;
&lt;li&gt;알림 소리 음소거&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;사용자가 컨텐츠 추가 시, 편의성 개선 작업 (컨트롤 키로만 추가하는 번거로움을 없앨 예정)&lt;/li&gt;
&lt;li&gt;6월 19일 새로 추가될 컨텐츠 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;발견된 이슈&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이슈 제보 바람&lt;/li&gt;
&lt;/ul&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;br /&gt;&lt;/b&gt;&lt;b&gt;게임 컨텐츠 관리에 보다 직관적이고 효율적으로&lt;br /&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;616&quot; data-origin-height=&quot;803&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkkK2u/btsOBjDI3cq/EuqaQKTv5UguaKW9fWBHck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkkK2u/btsOBjDI3cq/EuqaQKTv5UguaKW9fWBHck/img.png&quot; data-alt=&quot;모비노기 숙제 도우미 1.1 버전 사용 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkkK2u/btsOBjDI3cq/EuqaQKTv5UguaKW9fWBHck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdkkK2u%2FbtsOBjDI3cq%2FEuqaQKTv5UguaKW9fWBHck%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;400&quot; height=&quot;521&quot; data-origin-width=&quot;616&quot; data-origin-height=&quot;803&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;모비노기 숙제 도우미 1.1 버전 사용 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&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;br /&gt;효율적이고 직관적인&amp;nbsp;&lt;b&gt;일일/주간 숙제를 손쉽게 체크하기 위한 프로그램&lt;/b&gt;입니다.&lt;br /&gt;매일 또는 주간 단위로&amp;nbsp;&lt;b&gt;반복되는 콘텐츠들의 진행 여부를 체크&lt;/b&gt;할 수 있으며,&lt;br /&gt;&lt;b&gt;매일 오전 6시, 주간 숙제 초기화 시 자동으로 리셋&lt;/b&gt;되어&lt;br /&gt;귀찮은 수동 초기화 없이 깔끔하게 숙제를 관리할 수 있도록 설계되어 있습니다.&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;OS : Windows 한정, 오직 윈도우에서만 실행 가능!&lt;/b&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주요 기능들을 소개해볼게요!&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  주요 기능&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅&amp;nbsp;일일/주간 콘텐츠 체크 기능&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;숙제를 완료했는지 헷갈릴 틈 없이 한 눈에 확인!&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;매일, 매주하는&amp;nbsp;&lt;b&gt;숙제 자동 초기화&lt;/b&gt;!&lt;/li&gt;
&lt;li&gt;번거로운 수동 관리 없이, 숙제 체크는 이 도우미 하나면 OK!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;312&quot; data-origin-height=&quot;551&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qCa6M/btsOCg0yau6/BRN3TEQjRtp4iZacX6Amdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qCa6M/btsOCg0yau6/BRN3TEQjRtp4iZacX6Amdk/img.png&quot; data-alt=&quot;일일/주간 숙제 관리 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qCa6M/btsOCg0yau6/BRN3TEQjRtp4iZacX6Amdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqCa6M%2FbtsOCg0yau6%2FBRN3TEQjRtp4iZacX6Amdk%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;250&quot; height=&quot;442&quot; data-origin-width=&quot;312&quot; data-origin-height=&quot;551&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;일일/주간 숙제 관리 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  나만의 캐릭터로, 더 몰입감 있게!&lt;/b&gt;&lt;/h3&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;나만의 아바타와 함께 숙제를 관리&lt;/b&gt;할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐릭터 이미지를 넣기 귀찮으신 분들은 기본적으로 제공되는 프리셋을 이용해도 좋아요!&lt;br /&gt;제 캐릭터와 지인들의 모습을 프리셋으로 넣었어요! :)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  어떻게 활용되나요?&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐릭터 프로필 이미지로 등록되어, &lt;b&gt;숙제 리스트에 함께 표시&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;부캐릭터를 여러 개 등록했다면, &lt;b&gt;각 캐릭터별 이미지로 쉽게 구분&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;단순한 숙제 도우미를 넘어, &lt;b&gt;내 캐릭터 중심의 UI로 감정 몰입도 UP!&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; ️ 사용 방법도 간단해요!&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;초록색 플러스 버튼&lt;/b&gt;을 누르거나 이미 생성되어 있는 캐릭터 클릭&lt;/li&gt;
&lt;li&gt;캐릭터 이름을 입력 후, &lt;b&gt;&amp;ldquo;이미지 불러오기&amp;rdquo;&lt;/b&gt; 버튼 클릭&lt;/li&gt;
&lt;li&gt;내 PC에서 원하는 캐릭터 스크린샷 선택&lt;/li&gt;
&lt;li&gt;&lt;b&gt;'확인 버튼'&lt;/b&gt; 클릭! 등록 완료! 숙제 화면에서도 이미지가 바로 반영됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;805&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqcHOX/btsOBjqgHsV/jfxlwRFyQf2liFLGM4K3Kk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqcHOX/btsOBjqgHsV/jfxlwRFyQf2liFLGM4K3Kk/img.gif&quot; data-alt=&quot;캐릭터를 추가하는 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqcHOX/btsOBjqgHsV/jfxlwRFyQf2liFLGM4K3Kk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cqcHOX/btsOBjqgHsV/jfxlwRFyQf2liFLGM4K3Kk/img.gif&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;600&quot; height=&quot;512&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;805&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;캐릭터를 추가하는 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✏️ 내가 원하는 숙제, 직접 추가하세요! &amp;ndash; 커스텀 콘텐츠 등록 기능&lt;/b&gt;&lt;/h3&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  이런 상황, 다들 한 번쯤 있지 않으셨나요?&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&quot;내가 따로 챙기는 숙제가 있는데, 기본 목록에 없어서 불편해!&quot;&lt;/li&gt;
&lt;li&gt;&quot;따로 체크하고 싶은 숙제가 있는데 정리가 안 돼&amp;hellip;&quot;&lt;/li&gt;
&lt;/ul&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;체크 및 초기화 관리도 기본 콘텐츠와 동일하게 가능!&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 alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;801&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WDmzM/btsOBDIJw7W/5lf5gOKf0LwFCb9n2Gfjuk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WDmzM/btsOBDIJw7W/5lf5gOKf0LwFCb9n2Gfjuk/img.gif&quot; data-alt=&quot;콘텐츠를 직접 골라 추가하는 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WDmzM/btsOBDIJw7W/5lf5gOKf0LwFCb9n2Gfjuk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/WDmzM/btsOBDIJw7W/5lf5gOKf0LwFCb9n2Gfjuk/img.gif&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;400&quot; height=&quot;527&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;801&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;콘텐츠를 직접 골라 추가하는 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콘텐츠를 추가할 때에는 &lt;b&gt;컨트롤(Ctrl) 키를 눌러 순서를 정하고, 확인&lt;/b&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;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;&lt;b&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;555&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZRatB/btsOGWuyyX3/dgkoXhQpERPHnao9k6SM60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZRatB/btsOGWuyyX3/dgkoXhQpERPHnao9k6SM60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZRatB/btsOGWuyyX3/dgkoXhQpERPHnao9k6SM60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZRatB%2FbtsOGWuyyX3%2FdgkoXhQpERPHnao9k6SM60%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;555&quot; height=&quot;270&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;270&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;558&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DsHaJ/btsOH79Gjjs/z0msTWK17itfpNgVZ2GAX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DsHaJ/btsOH79Gjjs/z0msTWK17itfpNgVZ2GAX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DsHaJ/btsOH79Gjjs/z0msTWK17itfpNgVZ2GAX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDsHaJ%2FbtsOH79Gjjs%2Fz0msTWK17itfpNgVZ2GAX0%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;558&quot; height=&quot;270&quot; data-origin-width=&quot;558&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  생활 콘텐츠도 이제 꼼꼼하게! &amp;ndash; 세분화된 생활 숙제 관리 기능 추가&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다양한 생활 관련 콘텐츠도 세부적으로 관리&lt;/b&gt;할 수 있도록 기능을 강화했습니다.&lt;br /&gt;물품별로 관리하고 싶은 사람, 간단하게 NPC로만 관리하고 싶은사람...&lt;br /&gt;&lt;b&gt;&quot;당신이 뭘 좋아할지 몰라서 다 준비했어!  &quot;&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  어떤 점이 좋아졌나요?&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;일일 교환, 주간 구매 숙제 항목을 구분&lt;/b&gt;해 보기 쉽게 정리&lt;/li&gt;
&lt;li&gt;생활 관련 숙제를 자주 챙기는 유저들에게는, &lt;b&gt;놓치기 쉬운 세세한 부분까지 챙길 수 있도록 커스텀 맞춤형 기능!&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;⚙️ 더 나에게 맞게! &amp;ndash; 환경 설정 옵션으로 보기 방식을 자유롭게 조절하세요&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숙제 도우미는 사용자 편의성을 최우선으로 생각했어요.&lt;br /&gt;그래서 &lt;b&gt;생활 숙제를 얼마나 간단하게 또는 자세하게 볼지&lt;/b&gt;, &lt;b&gt;환경 설정에서 직접 선택&lt;/b&gt;할 수 있도록 했습니다!&lt;br /&gt;기본적으로는 'NPC별 물품 상세히 보기'로 보이도록 되어 있어요.&lt;br /&gt;이 옵션은 &lt;b&gt;선택 한 후, 콘텐츠를 추가할 때부터 적용&lt;/b&gt;됩니다.&lt;br /&gt;이를 이용해 일일 교환은 물품별로, 주간 교환은 NPC별로 하는 등, 여러 가지 형태로 설정 가능해요.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;⚙️ 환경 설정 &amp;gt; 구매 및 교환&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;90&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxqUR1/btsOB1Jlrks/btSFKERkYbtomDlXoxK6z1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxqUR1/btsOB1Jlrks/btSFKERkYbtomDlXoxK6z1/img.png&quot; data-alt=&quot;환경설정 탭에서 '구매 및 교환'의 옵션 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxqUR1/btsOB1Jlrks/btSFKERkYbtomDlXoxK6z1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxqUR1%2FbtsOB1Jlrks%2FbtSFKERkYbtomDlXoxK6z1%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;554&quot; height=&quot;90&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;90&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;환경설정 탭에서 '구매 및 교환'의 옵션 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;NPC 아이콘만 보기&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 교환 및 구매를 담당하는 NPC 이름만으로 간단하게 표기&lt;/li&gt;
&lt;li&gt;복잡하고 헷갈리기 쉬운 사람은 어떤 NPC를 찾아가야 하는지만 알면 되니, 훨씬 간결하고 직관적!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;NPC별 물품 상세히 보기&lt;/b&gt; (기본값)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;꼼꼼히 숙제를 체크하고 싶은 유저에게 최적화!&lt;/li&gt;
&lt;li&gt;구매 및 교환에 필요한 세부 항목이 나열되어 디테일하게 콘텐츠 관리 가능!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;797&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ThC7c/btsOA5sgALM/nW3NWmxXDA7lQFXxObek81/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ThC7c/btsOA5sgALM/nW3NWmxXDA7lQFXxObek81/img.gif&quot; data-alt=&quot;상품별, NPC별 옵션을 설정해서 구매 및 교환의 콘텐츠를 추가하는 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ThC7c/btsOA5sgALM/nW3NWmxXDA7lQFXxObek81/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/ThC7c/btsOA5sgALM/nW3NWmxXDA7lQFXxObek81/img.gif&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;400&quot; height=&quot;524&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;797&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;상품별, NPC별 옵션을 설정해서 구매 및 교환의 콘텐츠를 추가하는 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콘텐츠를 추가할 때에는 &lt;b&gt;컨트롤(Ctrl) 키를 눌러 순서를 정하고, 확인&lt;/b&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;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;&lt;b&gt;✅ &lt;b&gt;NPC 아이콘만 보기&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오늘의 교환 물품&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;365&quot; data-origin-height=&quot;367&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czGged/btsOG64ERAW/vL4oFP6YcaqsSG5TBFFLe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czGged/btsOG64ERAW/vL4oFP6YcaqsSG5TBFFLe0/img.png&quot; data-alt=&quot;오늘의 교환 물품, NPC 아이콘만 보기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czGged/btsOG64ERAW/vL4oFP6YcaqsSG5TBFFLe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczGged%2FbtsOG64ERAW%2FvL4oFP6YcaqsSG5TBFFLe0%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;365&quot; height=&quot;367&quot; data-origin-width=&quot;365&quot; data-origin-height=&quot;367&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;오늘의 교환 물품, NPC 아이콘만 보기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이번주 구매 물품&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;368&quot; data-origin-height=&quot;163&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBPVrs/btsOGruZdMV/xA2D7szTMighFd8Ednlwy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBPVrs/btsOGruZdMV/xA2D7szTMighFd8Ednlwy0/img.png&quot; data-alt=&quot;이번주 구매 물품, NPC 아이콘만 보기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBPVrs/btsOGruZdMV/xA2D7szTMighFd8Ednlwy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBPVrs%2FbtsOGruZdMV%2FxA2D7szTMighFd8Ednlwy0%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;368&quot; height=&quot;163&quot; data-origin-width=&quot;368&quot; data-origin-height=&quot;163&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이번주 구매 물품, NPC 아이콘만 보기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ &lt;b&gt;NPC별 물품 상세히 보기&lt;/b&gt; &lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오늘의 교환 물품&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;365&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/noqGR/btsOHnd6eM3/hReqSc8dZ8o6fYrwSy8POK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/noqGR/btsOHnd6eM3/hReqSc8dZ8o6fYrwSy8POK/img.png&quot; data-alt=&quot;오늘의 교환 물품, NPC별 물품 상세히 보기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/noqGR/btsOHnd6eM3/hReqSc8dZ8o6fYrwSy8POK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnoqGR%2FbtsOHnd6eM3%2FhReqSc8dZ8o6fYrwSy8POK%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;365&quot; height=&quot;468&quot; data-origin-width=&quot;365&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;오늘의 교환 물품, NPC별 물품 상세히 보기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이번주 구매 물품&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;667&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tWayU/btsOF5MtAz8/nDcqDatg8z9PajoKVX0Yk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tWayU/btsOF5MtAz8/nDcqDatg8z9PajoKVX0Yk1/img.png&quot; data-alt=&quot;이번주 구매 물품, NPC별 물품 상세히 보기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tWayU/btsOF5MtAz8/nDcqDatg8z9PajoKVX0Yk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtWayU%2FbtsOF5MtAz8%2FnDcqDatg8z9PajoKVX0Yk1%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;375&quot; height=&quot;667&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;667&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이번주 구매 물품, NPC별 물품 상세히 보기&lt;/figcaption&gt;
&lt;/figure&gt;
&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;가끔 숙제를 체크하면서 실수로 완료 체크를 눌렀다든지,&lt;br /&gt;구멍과 결계 숙제의 횟수를 잘못 체크하는 일이 생기곤 하죠.&lt;br /&gt;이럴 때를 대비해,&amp;nbsp;&lt;b&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;560&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccMwR9/btsOCBwHIKM/hIs7nw7Cg4lCURTZpC1usk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccMwR9/btsOCBwHIKM/hIs7nw7Cg4lCURTZpC1usk/img.gif&quot; data-alt=&quot;사용자가 숙제를 체크/체크해제하고 횟수를 수동으로 초기화하는 예시화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccMwR9/btsOCBwHIKM/hIs7nw7Cg4lCURTZpC1usk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/ccMwR9/btsOCBwHIKM/hIs7nw7Cg4lCURTZpC1usk/img.gif&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;400&quot; height=&quot;400&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사용자가 숙제를 체크/체크해제하고 횟수를 수동으로 초기화하는 예시화면&lt;/figcaption&gt;
&lt;/figure&gt;
&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;현재 콘텐츠 커스텀 추가 기능은 컨트롤을 통해서 여러 개를 선택 한 후 확인을 누르면&lt;br /&gt;선택된 콘텐츠들이 새롭게 재배치되는 구조로 설계되어 있습니다.&lt;br /&gt;기존에서 &lt;b&gt;추가되는 개념이 아닌, 새롭게 선택한 콘텐츠들로 재구성&lt;/b&gt;되는 거죠.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  내 숙제, 내 방식대로 정리한다 &amp;ndash; 메모장 기능 추가!&lt;/b&gt;&lt;/h3&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;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;✨ 어떤 걸 쓸 수 있나요?&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;  &lt;b&gt;내가 따로 관리하는 추가 숙제나 체크할 정보&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;  &lt;b&gt;이벤트 아이템 교환 일정, 교환 우선순위 정리&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;  &lt;b&gt;부캐릭터별 해야 할 작업 간단히 정리&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;  &lt;b&gt;타인과의 약속, 협동 퀘스트 예약 메모까지!&lt;/b&gt;&lt;/li&gt;
&lt;/ul&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;&lt;b&gt;간단하고 빠르게 입력 가능&lt;/b&gt;한 자유 메모 공간 제공&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모는 &lt;b&gt;30분마다 자동 저장&lt;/b&gt;되어, 예기치 못한 상황 방지&lt;/li&gt;
&lt;li&gt;프로그램 종료 시 메모를 저장하기 때문에 &lt;b&gt;따로 저장할 필요 없음!&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;당신만의 마비노기 일지를 함께 써 내려가는 공간&lt;/b&gt;,&lt;br /&gt;숙제도, 일정도, 아이디어도 자유롭게 기록하세요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oT0TC/btsOA6kpLhk/qHAAkW15hA2rBBU7GQ1uSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oT0TC/btsOA6kpLhk/qHAAkW15hA2rBBU7GQ1uSk/img.png&quot; data-alt=&quot;메모장 사용 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oT0TC/btsOA6kpLhk/qHAAkW15hA2rBBU7GQ1uSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoT0TC%2FbtsOA6kpLhk%2FqHAAkW15hA2rBBU7GQ1uSk%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;515&quot; height=&quot;210&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;210&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;메모장 사용 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  결계 알림 기능&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;매 시간마다 생성되는 &amp;lsquo;결계&amp;rsquo;, 깜빡하지 않도록 알림으로 챙기자!&lt;br /&gt;&lt;/b&gt;한 번 놓치면 다음 기회를 기다려야 해서, 상당히 귀찮죠 ㅠ3ㅠ&lt;br /&gt;그래서&amp;nbsp;숙제&amp;nbsp;도우미는&amp;nbsp;결계&amp;nbsp;시간에&amp;nbsp;맞춰&amp;nbsp;&lt;b&gt;총&amp;nbsp;4단계&amp;nbsp;알림&lt;/b&gt;을 제공해요!&lt;br /&gt;모든 알림은&amp;nbsp;&lt;b&gt;윈도우 화면 우측 하단 (시계 위)에 알림 팝업&lt;/b&gt;이 출력됩니다.&lt;br /&gt;결계 설정은 &lt;b&gt;프로그램 상단 탭 '환경설정'에서 설정 가능&lt;/b&gt;해요.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;⚙️ 환경 설정 &amp;gt; 결계 알리미&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;145&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C5oFm/btsOBoLPxlo/Hvn3cnIW1i5w7av6fzKtSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C5oFm/btsOBoLPxlo/Hvn3cnIW1i5w7av6fzKtSK/img.png&quot; data-alt=&quot;결계 알리미 설정 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C5oFm/btsOBoLPxlo/Hvn3cnIW1i5w7av6fzKtSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC5oFm%2FbtsOBoLPxlo%2FHvn3cnIW1i5w7av6fzKtSK%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;594&quot; height=&quot;145&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;145&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결계 알리미 설정 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;PS. 예시 화면으로 제공된 화면은 테스트 화면이므로 윈도우의 실제 시간은 무시해주세요.&lt;/u&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;⏰ 10분 전 / 5분 전 미리 알림&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;미리미리 준비할 수 있도록 여유 있게 확인하자!&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시간에 쫓기지 않고 여유롭게 결계를 준비할 수 있도록 해주는 기능&lt;/b&gt;입니다.&lt;/li&gt;
&lt;li&gt;이 알림은&amp;nbsp;&lt;b&gt;사전 준비용&lt;/b&gt;입니다. 아직 던전을 돌고 있다면 빠르게 마무리해서 결계를 준비해보세요!&lt;/li&gt;
&lt;li&gt;&lt;b&gt;결계가 실제로 생성되는 시간(정각) 10분 혹은 5분 전에 미리 알림&lt;/b&gt;이 울립니다.&lt;/li&gt;
&lt;li&gt;사용자가 현재 게임에 집중하지 않고 있더라도 &quot;결계 알리미&quot;를 통해 결계를 인지할 수 있어요.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfNosw/btsOA3H1Nkf/Yaqc2pCmjXvWK9V4H7yrx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfNosw/btsOA3H1Nkf/Yaqc2pCmjXvWK9V4H7yrx1/img.png&quot; data-alt=&quot;결계 생성 10분 전과 결계 생성 5분 전 알림 팝업 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfNosw/btsOA3H1Nkf/Yaqc2pCmjXvWK9V4H7yrx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfNosw%2FbtsOA3H1Nkf%2FYaqc2pCmjXvWK9V4H7yrx1%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;1040&quot; height=&quot;496&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;496&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결계 생성 10분 전과 결계 생성 5분 전 알림 팝업 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;⏰ 정각 알림 &amp;ndash; 결계가 생성되면 즉시 알림!&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;결계가 실제로 생성되는 시간(정각)에 알림이 울리도록 해주는 기능&lt;/b&gt;입니다.&lt;/li&gt;
&lt;li&gt;이 알림을 통해 결계가 시작되기 전 사용자는 미리 준비를 할 수 있도록 해주는 역할을 해요.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단, '결계 시작 3분 타이머 기능'을 사용할 경우 해당 알림은 노출되지 않고 타이머가 노출되요!&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvS44M/btsOA5MxZZu/iOJAtNkAlK3W9LiM2Cvb61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvS44M/btsOA5MxZZu/iOJAtNkAlK3W9LiM2Cvb61/img.png&quot; data-alt=&quot;정각마다 생성되는 결계 생성 알림 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvS44M/btsOA5MxZZu/iOJAtNkAlK3W9LiM2Cvb61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvS44M%2FbtsOA5MxZZu%2FiOJAtNkAlK3W9LiM2Cvb61%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;472&quot; height=&quot;528&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정각마다 생성되는 결계 생성 알림 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;⏳ 결계 시작 3분 전 타이머 알림 &amp;ndash; 결계 시작 전 집중 준비 시간 확보!&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;결계 앞에 세워두고 언제 시작하나 확인하기 너무 귀찮으시죠?&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;결계 생성 후 실질적으로 결계를 시작하는 시간을 타이머&lt;/b&gt;로 알려줍니다.&lt;/li&gt;
&lt;li&gt;결계 생성부터 시작까지(총 3분)의 남은 시간이 보여주며,&amp;nbsp;&lt;b&gt;실질적인 시작 타이밍에 맞춰 사용자가 놓치지 않게 도와주는 기능&lt;/b&gt;을 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;501&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5HM8K/btsOB9Htftg/hABoOGNFm1kg9AyT6l6wAK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5HM8K/btsOB9Htftg/hABoOGNFm1kg9AyT6l6wAK/img.gif&quot; data-alt=&quot;결계 시작 3분 타이머 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5HM8K/btsOB9Htftg/hABoOGNFm1kg9AyT6l6wAK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/5HM8K/btsOB9Htftg/hABoOGNFm1kg9AyT6l6wAK/img.gif&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;536&quot; height=&quot;501&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;501&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결계 시작 3분 타이머 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; ️ 결계 알림 팝업은 윈도우 좌측 하단에서 확인!&amp;nbsp;&amp;ndash;&amp;nbsp;'아.. 맞다.. 결계!'&amp;nbsp;게임 중에도 알림을 놓치지 말자!&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;모든 결계 알림은 윈도우 화면 우측 하단에 팝업으로 표시&lt;/b&gt;됩니다.&lt;/li&gt;
&lt;li&gt;마비노기 모바일을 하거나, 다른 작업을 하다가도&amp;nbsp;&lt;b&gt;알림이 시각적으로 띄워져 즉시 확인 가능&lt;/b&gt;해요.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;'띵!' 소리&lt;/b&gt;와 함께 팝업이 노출되도록 되어 있어요.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; ️ 깔끔하게 종료하거나, 조용히 숨겨두거나 &amp;ndash; 트레이 기능 추가&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;lsquo;닫기 설정&amp;rsquo;으로 나에게 맞는 방식 선택!&lt;/b&gt;&lt;br /&gt;&lt;b&gt;사용자 환경에 맞게 프로그램 종료 방식을 선택&lt;/b&gt;할 수 있도록&lt;b&gt; &amp;lsquo;닫기 설정&amp;rsquo; 기능&lt;/b&gt;을 제공합니다.&lt;br /&gt;창을 닫을 때 어떻게 동작할지 직접 설정해보세요!&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;⚙️ 환경 설정 &amp;gt; 닫기 설정&lt;/b&gt;&lt;/h4&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;567&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0Ug88/btsOA9VKhdL/9QK6KJA4d28i16Q3LHfp30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0Ug88/btsOA9VKhdL/9QK6KJA4d28i16Q3LHfp30/img.png&quot; data-alt=&quot;닫기 설정 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0Ug88/btsOA9VKhdL/9QK6KJA4d28i16Q3LHfp30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0Ug88%2FbtsOA9VKhdL%2F9QK6KJA4d28i16Q3LHfp30%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;567&quot; height=&quot;91&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;닫기 설정 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;프로그램 종료하기&lt;/b&gt; (기본값)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;창 닫기(X 클릭) 시, &lt;b&gt;모비노기 도우미가 완전히 종료&lt;/b&gt;됩니다.&lt;/li&gt;
&lt;li&gt;리소스를 아끼고 싶거나, 필요할 때만 실행하고 싶은 분께 적합!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;트레이로 보내기&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;창 닫기 시, 프로그램이 &lt;b&gt;완전히 종료되지 않고 작업 표시줄 트레이로 최소화&lt;/b&gt;됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;백그라운드에서 조용히 실행&lt;/b&gt;되며, 알림 기능(예: 결계 알림 등)은 그대로 유지됩니다.&lt;/li&gt;
&lt;li&gt;게임 중 방해되지 않고, &lt;b&gt;불필요한 창이 계속 떠 있는 것을 방지&lt;/b&gt;할 수 있어요.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  특히 &amp;lsquo;트레이로 보내기&amp;rsquo;는&lt;br /&gt;&lt;b&gt;결계 알림만 받고 싶을 때&lt;/b&gt;,&lt;b&gt; 수시로 도우미를 꺼내 쓰고 싶을 때&lt;/b&gt; 아주 유용합니다!&lt;br /&gt;당신의 사용 스타일에 맞춰, 모비노기 도우미의 종료 방식도 유연하게!&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  문제가 생겼을 땐, 처음으로!&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;lsquo;환경 설정 &amp;gt; 초기화&amp;rsquo; 기능으로 프로그램을 원래 상태로 복원&lt;/b&gt;!&lt;br /&gt;간혹 프로그램 사용 중 오류가 발생하거나, 설정이 꼬여버렸을 때&lt;br /&gt;&amp;ldquo;그냥 싹 다 초기화하고 처음부터 다시 설정하고 싶다!&amp;rdquo; 싶은 순간이 있죠?&lt;br /&gt;이 기능은 다음과 같은 상황에서 유용해요&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램에 이상한 버그가 생겼을 때&lt;/li&gt;
&lt;li&gt;설정을 너무 많이 바꿔서 되돌리기 복잡할 때&lt;/li&gt;
&lt;li&gt;다른 캐릭터로 완전히 새로 시작하고 싶을 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럴 때를 위해 &lt;b&gt;&amp;lsquo;초기화&amp;rsquo; 기능&lt;/b&gt;을 제공합니다.&lt;br /&gt;&lt;b&gt;환경 설정 메뉴에서 '초기화' 버튼을 클릭하면&lt;/b&gt;,&lt;br /&gt;모든 데이터를 지우고 &lt;b&gt;처음 설치했을 때의 상태로 되돌릴 수 있어요.&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;⚠️ 초기화 시 주의사항!&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;  &lt;b&gt;설정한 모든 옵션이 사라집니다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;  &lt;b&gt;메모장에 작성한 모든 내용도 삭제&lt;/b&gt;됩니다.&lt;/li&gt;
&lt;li&gt;  &lt;b&gt;커스텀 숙제, 캐릭터 이미지, 환경설정, 알림 옵션 등도 모두 초기화&lt;/b&gt;됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  정말 초기화를 진행할 경우,&lt;br /&gt;&lt;b&gt;&amp;ldquo;모든 정보를 초기화하시겠습니까?&amp;rdquo;라는 확인창이 한 번 더 뜨니 실수 걱정은 줄였습니다.&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;이미지 관련&lt;/b&gt; - DALL-E&lt;/li&gt;
&lt;li&gt;&lt;b&gt;동영상 관련&lt;/b&gt; - Runway&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사용된 글꼴&lt;/b&gt; - 배달의민족 주아체&lt;/li&gt;
&lt;/ul&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;C# (.NET 8.0) Winfoms&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Firebase RealtimeDatabase&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;2025-05-01&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결계 타이머 기능
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;3시간 간격, 결계 시작 10분 전 타이머 기능 개발&lt;/li&gt;
&lt;li&gt;윈도우 화면 우측 하단(시계 바로 위)에 결계 알림 팝업창을 출력하도록 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-05-15&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자가 직관적으로 사용할 수 있도록 UI 변경
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러가지 일일/주간 컨텐츠를 확인할 수 있도록 프로그램 디자인 변경&lt;/li&gt;
&lt;li&gt;컨텐츠 클리어 유무를 체크할 수 있도록 기능 추가 (체킹, 횟수 카운트다운)&lt;/li&gt;
&lt;li&gt;각 컨텐츠의 남은 시간을 확인할 수 있도록 남은 시간 표기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-05-16&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마우스 커서 추가&lt;/li&gt;
&lt;li&gt;숙제 여부를 프로그램 종료 후 재시작 시 유지되도록 변경 (설정파일 추가)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-05-22&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매일 오전 6시, 월요일 오전 6시마다 일일/주간 숙제 자동 초기화&lt;/li&gt;
&lt;li&gt;결계 타이머 기능 수정 및 UI 보완
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1시간 간격으로 기능 수정&lt;/li&gt;
&lt;li&gt;결계 타이머 기능 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;5분 전 알림&lt;/li&gt;
&lt;li&gt;결계 시작 전 3분 타이머
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시작 전 3분 타이머 기능 활성화 시, 결계가 생성되고부터 시작될때까지 팝업으로 시작되기까지의 잔여시간을 팝업창으로 보여줌&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;각 알림별 팝업 디자인 추가&lt;/li&gt;
&lt;li&gt;팝업 닫기 기능 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-05-23&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결계 알림 팝업 시, 게임 플레이 중 동작을 방해하지 않도록 수정&lt;/li&gt;
&lt;li&gt;v1.0 &lt;b&gt;배포&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-05-25&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 프로그램 코드 재정의
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;커스텀 추가를 위해 기존의 로직 전체를 수정하는 방향으로 진행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;캐릭터 커스텀 기능 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐릭터를 여러 개 추가할 수 있도록 기능 확장
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;플러스 모양의 아이콘을 눌러 진행함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;캐릭터명 설정 기능 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐릭터 확장 버튼 클릭 시, 캐릭터명을 설정할 수 있도록 변경&lt;/li&gt;
&lt;li&gt;이름을 잘못 입력하였을 경우, 캐릭터 아이콘을 클릭하여 캐릭명 수정 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-05-27&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;관리자 권한으로 실행할지 사용자에게 물어보고 실행하도록 변경
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;관리자 권한으로 실행하지 않을 경우, 프로그램을 실행할 수 없도록 함
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2025-06-15 : 해당 기능 비활성화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;프로그램 중복 실행 방지 기능 추가&lt;/li&gt;
&lt;li&gt;트레이 기능 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-05-29&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;새로운 컨텐츠 아이콘 추가&lt;/li&gt;
&lt;li&gt;컨텐츠 확인을 유동적으로 할 수 있도록 커스텀 기능 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-04&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상단의 탭 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생활 관련 탭 (일일&amp;amp;주간 교환 및 구매를 위한 체크 리스트)&lt;/li&gt;
&lt;li&gt;메모장 탭&lt;/li&gt;
&lt;li&gt;환경 설정 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-05&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모장 탭 기능 개발
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모장 탭에서 글 편집 기능 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-06&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생활 관련 탭 기능 개발
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생활 관련 탭 레이아웃 구성&lt;/li&gt;
&lt;li&gt;설정 파일(settings.ini)을 모비노기 도우미 실행 폴더에 생성하지 않도록 변경
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;설정 파일 저장 경로(사용자 로밍 폴더) : %appdata%\MobinogiHelper&lt;/li&gt;
&lt;li&gt;설정 파일명 : mobi_setting.ini&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-08&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;설정 정보를 불러오는 내부 로직 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-10&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모장 탭 기능 개발 (가독성을 위해 윈도우 기본 글꼴 적용)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 종료 시 메모장 내용 저장 기능 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모 파일 저장 경로(사용자 로밍 폴더) : %appdata%\MobinogiHelper&lt;/li&gt;
&lt;li&gt;메모 파일명 : mobi_memo.txt&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;메모장 자동 저장 기능 추가 (매 30분마다 자동 저장)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-11&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생활 관련 탭 기능 개발
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨텐츠 아이콘 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;'배달의민족 주아체' 글꼴 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-12&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;환경 설정 탭 기능 개발
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;환경 설정 탭 레이아웃 구성&lt;/li&gt;
&lt;li&gt;옵션: &quot;결계 알리미&quot; 관련
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결계 알리미를 숙제 탭이 아닌 환경 설정 탭으로 이동&lt;/li&gt;
&lt;li&gt;결계 알리미 디자인 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;옵션: &quot;프로그램 닫기&quot; 관련
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 종료를 누를 경우, '종료'와 '트레이로 보내기' 택 1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;도네이션 배너 제작 및 프로그램 내 탑재&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-14&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐릭터 추가 기능 변경
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐릭터 추가 UI 변경&lt;/li&gt;
&lt;li&gt;캐릭터 추가 시 이미지를 선택하여 캐릭터를 추가할 수 있도록 함
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이미지는 제공되는 프리셋 또는 직접 이미지를 불러와 추가할 수 있음&lt;/li&gt;
&lt;li&gt;프리셋 18종 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;환경 설정 탭 기능 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 초기화 : 모든 설정 및 추가한 캐릭터 이미지 모두 초기화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;횟수 초기화 알림 창 UI 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-15&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 중복 실행 방지 기능 변경
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중복 실행 시, 기존 실행중인 프로그램 활성화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;프로그램 사용 위치 기억 기능 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 마지막 위치를 확인하여 다음 실행 시 해당 위치로 실행되도록 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;프로그램의 사이즈를 조절할 수 있도록 변경&lt;/li&gt;
&lt;li&gt;글꼴 폰트를 더욱 매끄럽고 부드럽게 보이기 하기 위해 GDI+ 방식 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-17&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;환경 설정 탭 기능 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;디스코드 : 해당 배너 버튼을 누르면 도우미 디스코드 서버로 연결&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025-06-18&lt;/p&gt;</description>
      <category>포트폴리오/모비노기 도우미</category>
      <category>v1.1</category>
      <category>마비노기 모바일</category>
      <category>모비노기</category>
      <category>버전1.1</category>
      <category>숙제 도우미</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/935</guid>
      <comments>https://luvris2.tistory.com/935#entry935comment</comments>
      <pubDate>Sun, 15 Jun 2025 16:47:34 +0900</pubDate>
    </item>
    <item>
      <title>마비노기 모바일 숙제 도우미 - 모비노기 도우미 v1.0</title>
      <link>https://luvris2.tistory.com/934</link>
      <description>&lt;div&gt;&lt;span style=&quot;color: #333333;&quot;&gt;매일, 매주 반복되는 숙제&amp;hellip; 이제는 더 간편하게 관리해보자! '0'&lt;/span&gt;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;수정사항&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2025-05-23 (v1.0.1)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;4K 모니터, 화면 배율이 100%가 아닌 125%, 150% 등의 배율에서 프로그램의 글자 위치가 어긋나는 현상 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;프로그램 소개&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;이 프로그램은...&lt;br /&gt;&lt;/b&gt;&lt;b&gt;게임 컨텐츠 관리에 보다 직관적이고 효율적으로&lt;br /&gt;숙제를 확인하고 관리할 수 있도록하기 위해 제작되었습니다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;524&quot; data-origin-height=&quot;699&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Jbr6P/btsN7PDTv8S/jRPzbQAnlp5YRRF4VZAnSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Jbr6P/btsN7PDTv8S/jRPzbQAnlp5YRRF4VZAnSk/img.png&quot; data-alt=&quot;모비노기 숙제 도우미 v1.0 사용 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Jbr6P/btsN7PDTv8S/jRPzbQAnlp5YRRF4VZAnSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJbr6P%2FbtsN7PDTv8S%2FjRPzbQAnlp5YRRF4VZAnSk%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;524&quot; height=&quot;699&quot; data-origin-width=&quot;524&quot; data-origin-height=&quot;699&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;모비노기 숙제 도우미 v1.0 사용 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&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;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;✨ 모비노기 숙제 도우미란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;&lt;span style=&quot;color: #333333;&quot;&gt;마비노기 모바일 유저들을 위해 제작된,&lt;br /&gt;효율적이고 직관적인 &lt;b&gt;일일/주간 숙제를 손쉽게 체크하기 위한 프로그램&lt;/b&gt;입니다.&lt;br /&gt;매일 또는 주간 단위로 &lt;b&gt;반복되는 콘텐츠들의 진행 여부를 체크&lt;/b&gt;할 수 있으며,&lt;br /&gt;&lt;b&gt;매일 오전 6시, 주간 숙제 초기화 시 자동으로 리셋&lt;/b&gt;되어&lt;br /&gt;귀찮은 수동 초기화 없이 깔끔하게 숙제를 관리할 수 있도록 설계되어 있습니다.&lt;/span&gt;&lt;/div&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;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;✅ 다운로드 링크&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://drive.google.com/file/d/1Il2BbWb3mPFhLlRUAZPaMt7EBHZ5UZIe/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://drive.google.com/file/d/1Il2BbWb3mPFhLlRUAZPaMt7EBHZ5UZIe/view?usp=sharing&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;h3 data-ke-size=&quot;size23&quot;&gt;사용 가능한 환경&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OS : Windows 한정, 오직 윈도우에서만 실행 가능!&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;주요 기능들을 소개해볼게요!&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;  주요 기능&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;✅ &lt;b&gt;일일/주간 콘텐츠 체크 기능&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;숙제를 완료했는지 헷갈릴 틈 없이 한 눈에 확인!&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;매일, 매주하는 &lt;b&gt;숙제 자동 초기화&lt;/b&gt;!&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;번거로운 수동 관리 없이, 숙제 체크는 이 도우미 하나면 OK!&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;276&quot; data-origin-height=&quot;484&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biWiyg/btsN9GkTnmw/OY8L8P73Cd973bK90v8go1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biWiyg/btsN9GkTnmw/OY8L8P73Cd973bK90v8go1/img.png&quot; data-alt=&quot;일일/주간 숙제 관리 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biWiyg/btsN9GkTnmw/OY8L8P73Cd973bK90v8go1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiWiyg%2FbtsN9GkTnmw%2FOY8L8P73Cd973bK90v8go1%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;276&quot; height=&quot;484&quot; data-origin-width=&quot;276&quot; data-origin-height=&quot;484&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;일일/주간 숙제 관리 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&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;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;❓ 숙제 체크를 잘못했을 때에는? 실수해도 괜찮아요!&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;가끔 숙제를 체크하면서 실수로 완료 체크를 눌렀다든지,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;구멍과 결계 숙제의 횟수를 잘못 체크하는 일이 생기곤 하죠.&lt;br /&gt;&lt;/span&gt;이럴 때를 대비해, &lt;b&gt;사용자가 직접 숙제 체크 기록을 초기화&lt;/b&gt;할 수 있어요!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;272&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bG5Xo9/btsN93G4QfV/yDUDXDfjpCZY3DkDQtKCYk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bG5Xo9/btsN93G4QfV/yDUDXDfjpCZY3DkDQtKCYk/img.gif&quot; data-alt=&quot;사용자가 숙제를 체크/체크해제하고 횟수를 수동으로 초기화하는 예시화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bG5Xo9/btsN93G4QfV/yDUDXDfjpCZY3DkDQtKCYk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bG5Xo9/btsN93G4QfV/yDUDXDfjpCZY3DkDQtKCYk/img.gif&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;272&quot; height=&quot;293&quot; data-origin-width=&quot;272&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사용자가 숙제를 체크/체크해제하고 횟수를 수동으로 초기화하는 예시화면&lt;/figcaption&gt;
&lt;/figure&gt;
&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;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;  결계 알림 기능&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;매 시간마다 생성되는 &amp;lsquo;결계&amp;rsquo;, 깜빡하지 않도록 알림으로 챙기자!&lt;br /&gt;&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;한 번 놓치면 다음 기회를 기다려야 해서, 상당히 귀찮죠 ㅠ3ㅠ&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;그래서&amp;nbsp;숙제&amp;nbsp;도우미는&amp;nbsp;결계&amp;nbsp;시간에&amp;nbsp;맞춰&amp;nbsp;&lt;b&gt;총&amp;nbsp;4단계&amp;nbsp;알림&lt;/b&gt;을 제공해요!&lt;br /&gt;모든 알림은 &lt;b&gt;윈도우 화면 우측 하단 (시계 위)에 알림 팝업&lt;/b&gt;이 출력됩니다.&lt;br /&gt;결계 설정은 프로그램 오른쪽 아래에서 설정 가능해요.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;letter-spacing: 0px; color: #333333;&quot;&gt;&lt;/span&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;205&quot; data-origin-height=&quot;172&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HSrow/btsN741UrH4/34QRNwgJqeCJ0vpCnsV9BK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HSrow/btsN741UrH4/34QRNwgJqeCJ0vpCnsV9BK/img.png&quot; data-alt=&quot;결계 알리미 설정 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HSrow/btsN741UrH4/34QRNwgJqeCJ0vpCnsV9BK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHSrow%2FbtsN741UrH4%2F34QRNwgJqeCJ0vpCnsV9BK%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;205&quot; height=&quot;172&quot; data-origin-width=&quot;205&quot; data-origin-height=&quot;172&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결계 알리미 설정 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;i&gt;&lt;u&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;PS. 예시 화면으로 제공된 화면은 테스트 화면이므로 윈도우의 실제 시간은 무시해주세요.&lt;/span&gt;&lt;/u&gt;&lt;/i&gt;&lt;i&gt;&lt;u&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/u&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&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: #333333;&quot;&gt;&lt;b&gt;⏰ 10분 전 / 5분 전 미리 알림&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;미리미리 준비할 수 있도록 여유 있게 확인하자!&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;시간에 쫓기지 않고 여유롭게 결계를 준비할 수 있도록 해주는 기능&lt;/b&gt;입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이 알림은 &lt;b&gt;사전 준비용&lt;/b&gt;입니다. 아직 던전을 돌고 있다면 빠르게 마무리해서 결계를 준비해보세요!&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;결계가 실제로 생성되는 시간(정각) 10분 혹은 5분 전에 미리 알림&lt;/b&gt;이 울립니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;사용자가 현재 게임에 집중하지 않고 있더라도 &quot;결계 알리미&quot;를 통해 결계를 인지할 수 있어요.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bs6vjZ/btsN9IpvGST/mgogay2RWmV3M5v4AAwrZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bs6vjZ/btsN9IpvGST/mgogay2RWmV3M5v4AAwrZK/img.png&quot; data-alt=&quot;결계 생성 10분 전과 결계 생성 5분 전 알림 팝업 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bs6vjZ/btsN9IpvGST/mgogay2RWmV3M5v4AAwrZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbs6vjZ%2FbtsN9IpvGST%2Fmgogay2RWmV3M5v4AAwrZK%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;1040&quot; height=&quot;496&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;496&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결계 생성 10분 전과 결계 생성 5분 전 알림 팝업 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;⏰ 정각 알림 &amp;ndash; 결계가 생성되면 즉시 알림!&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;결계가 실제로 생성되는 시간(정각)에 알림이 울리도록 해주는 기능&lt;/b&gt;입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이 알림을 통해 결계가 시작되기 전 사용자는 미리 준비를 할 수 있도록 해주는 역할을 해요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;단, '결계 시작 3분 타이머 기능'을 사용할 경우 해당 알림은 노출되지 않고 타이머가 노출되요!&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qdMEq/btsN75mg4eS/r7gL7AkcHIZl6Hjctyw6ek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qdMEq/btsN75mg4eS/r7gL7AkcHIZl6Hjctyw6ek/img.png&quot; data-alt=&quot;정각마다 생성되는 결계 생성 알림 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qdMEq/btsN75mg4eS/r7gL7AkcHIZl6Hjctyw6ek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqdMEq%2FbtsN75mg4eS%2Fr7gL7AkcHIZl6Hjctyw6ek%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;472&quot; height=&quot;528&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정각마다 생성되는 결계 생성 알림 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;⏳ 결계 시작 3분 전 타이머 알림 &amp;ndash; 결계 시작 전 집중 준비 시간 확보!&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;결계 앞에 세워두고 언제 시작하나 확인하기 너무 귀찮으시죠?&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;결계 생성 후 실질적으로 결계를 시작하는 시간을 타이머&lt;/b&gt;로 알려줍니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;결계 생성부터 시작까지(총 3분)의 남은 시간이 보여주며, &lt;b&gt;실질적인 시작 타이밍에 맞춰 사용자가 놓치지 않게 도와주는 기능&lt;/b&gt;을 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;501&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1AIXx/btsN9I4ep0C/Cv6wVKaIuuvCDAcnooLBXK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1AIXx/btsN9I4ep0C/Cv6wVKaIuuvCDAcnooLBXK/img.gif&quot; data-alt=&quot;결계 시작 3분 타이머 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1AIXx/btsN9I4ep0C/Cv6wVKaIuuvCDAcnooLBXK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/b1AIXx/btsN9I4ep0C/Cv6wVKaIuuvCDAcnooLBXK/img.gif&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;536&quot; height=&quot;501&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;501&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결계 시작 3분 타이머 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt; ️ 결계 알림 팝업은 윈도우 좌측 하단에서 확인! &lt;b&gt;&amp;ndash; &lt;/b&gt;&lt;b&gt;'아.. 맞다.. 결계!'&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; 게임 중에도 알림을 놓치지 말자!&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;모든 결계 알림은 윈도우 화면 우측 하단에 팝업으로 표시&lt;/b&gt;됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;마비노기 모바일을 하거나, 다른 작업을 하다가도 &lt;b&gt;알림이 시각적으로 띄워져 즉시 확인 가능&lt;/b&gt;해요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;'띵!' 소리&lt;/b&gt;와 함께 팝업이 노출되도록 되어 있어요.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&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;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;이미지 관련&lt;/b&gt; - DALL-E&lt;/li&gt;
&lt;li&gt;&lt;b&gt;동영상 관련&lt;/b&gt; - Runway&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사용된 글꼴&lt;/b&gt; - 배달의민족 주아체&lt;/li&gt;
&lt;/ul&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C# (.NET 8.0) Winfoms&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;span style=&quot;color: #333333;&quot;&gt;프로그램 개발 히스토리&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2025-05-01&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;결계 타이머 기능&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;3시간 간격, 결계 시작 10분 전 타이머 기능 개발&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;윈도우 화면 우측 하단(시계 바로 위)에 결계 알림 팝업창을 출력하도록 추가&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2025-05-15&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;사용자가 직관적으로 사용할 수 있도록 UI 변경&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;여러가지 일일/주간 컨텐츠를 확인할 수 있도록 프로그램 디자인 변경&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;컨텐츠 클리어 유무를 체크할 수 있도록 기능 추가 (체킹, 횟수 카운트다운)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;각 컨텐츠의 남은 시간을 확인할 수 있도록 남은 시간 표기 &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2025-05-16&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;마우스 커서 추가&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;숙제 여부를 프로그램 종료 후 재시작 시 유지되도록 변경 (설정파일 추가) &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2025-05-22 &lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;매일 오전 6시, 월요일 오전 6시마다 일일/주간 숙제 자동 초기화 &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;결계 타이머 기능 수정 및 UI 보완&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;1시간 간격으로 기능 수정 &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;결계 타이머 기능 추가&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;5분 전 알림&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;결계 시작 전 3분 타이머&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;시작 전 3분 타이머 기능 활성화 시, 결계가 생성되고부터 시작될때까지 팝업으로 시작되기까지의 잔여시간을 팝업창으로 보여줌&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;각 알림별 팝업 디자인 추가&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;팝업 닫기 기능 추가&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2025-05-23&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;결계 알림 팝업 시, 게임 플레이 중 동작을 방해하지 않도록 수정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;배포&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>포트폴리오/모비노기 도우미</category>
      <category>마비노기 모바일</category>
      <category>모비노기 도우미</category>
      <category>숙제 도우미</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/934</guid>
      <comments>https://luvris2.tistory.com/934#entry934comment</comments>
      <pubDate>Fri, 23 May 2025 01:46:38 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL - 테이블 저장 시 발생하는 오류 해결 방법 (Saving changes is not permitted.)</title>
      <link>https://luvris2.tistory.com/933</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요구하는 서비스에 따라 가끔은 데이터베이스의 테이블을 수정해야하는 경우가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 MS-SQL(SSMS)를 사용하면서 컬럼명을 추가/변경/삭제를 하게 되면 자주 볼 수 있는 오류인데,&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;h2 data-ke-size=&quot;size26&quot;&gt;Error&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rXfBD/btsJ88L6MKn/WUStyFvKE4eW37lbL7ce3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rXfBD/btsJ88L6MKn/WUStyFvKE4eW37lbL7ce3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rXfBD/btsJ88L6MKn/WUStyFvKE4eW37lbL7ce3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrXfBD%2FbtsJ88L6MKn%2FWUStyFvKE4eW37lbL7ce3k%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; alt=&quot;SSMS에서 테이블 구조 변경 후 저장 시 오류가 발생되는 에러 메시지&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;424&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;424&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;/p&gt;
&lt;pre id=&quot;code_1729064016866&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Saving changes is not permitted.
The changes that you have made require the following tables to be dropped and re-created.
You have either made changes to a table that can't be re-created
or enabled the option Prevent saving changes that require the table to be re-created.&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;원인&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 오류 메시지는 SQL Server Management Studio (SSMS)에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블의 스키마(열 정의, 데이터 형식 등)에 변경했을 때 발생하는 에러이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSMS에서는 특정 변경 사항(예: 열의 추가, 데이터 형식 변경 등)이 발생하면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블을 삭제하고 새로 생성하여 변경 사항을 적용하게 되는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSMS의 기본 설정으로는 이러한 동작이 차단되도록 옵션이 설정되어 있기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블을 삭제 및 재생성해야 하는 변경을 허용하지 않아 발생하는 오류이다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;해결 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제를 해결하려면, SSMS 설정에서 해당 옵션을 비활성화해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSMS에서 아래의 메뉴를 누른다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Tools - Options&lt;/li&gt;
&lt;li&gt;(한글판의 경우) 도구 - 옵션&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBhtzj/btsJ7qns42L/qbwkkcqiCYJZA6dUI6xfA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBhtzj/btsJ7qns42L/qbwkkcqiCYJZA6dUI6xfA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBhtzj/btsJ7qns42L/qbwkkcqiCYJZA6dUI6xfA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBhtzj%2FbtsJ7qns42L%2FqbwkkcqiCYJZA6dUI6xfA1%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; alt=&quot;MS-SQL에서 옵션을 들어가기 위한 경로 설명 이미지&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;288&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;288&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;옵션에서 아래의 해당 옵션을 체크 해제하고, 적용을 위해 OK를 눌러 옵션 적용을 마친다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Designers - Table and Database Designers
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;'&lt;b&gt;Prevent saving changes that require table re-creation&lt;/b&gt;' 체크 해제&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(한글판의 경우) 디자이너 - 테이블 및 데이터베이스 디자이너
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;'&lt;b&gt;테이블을 다시 만들어야 하는 변경 내용 저장 사용 안함&lt;/b&gt;' 체크 해제&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;434&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUir2z/btsJ74c89yf/O19m0Qn951bghpzdKNzD1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUir2z/btsJ74c89yf/O19m0Qn951bghpzdKNzD1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUir2z/btsJ74c89yf/O19m0Qn951bghpzdKNzD1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUir2z%2FbtsJ74c89yf%2FO19m0Qn951bghpzdKNzD1K%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; alt=&quot;테이블을 재저장 하기 위한 옵션 해제 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;744&quot; height=&quot;434&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;434&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;size26&quot;&gt;테스트&lt;/h2&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 style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;테이블이 데이터베이스에 저장됩니다. 계속하시겠습니까?&quot;&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;525&quot; data-origin-height=&quot;424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rkur6/btsJ7NbDZNZ/jk3eyYeVN8aHwEJdQvYetK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rkur6/btsJ7NbDZNZ/jk3eyYeVN8aHwEJdQvYetK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rkur6/btsJ7NbDZNZ/jk3eyYeVN8aHwEJdQvYetK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frkur6%2FbtsJ7NbDZNZ%2Fjk3eyYeVN8aHwEJdQvYetK%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; alt=&quot;테이블 구조 변경 후 저장하면 출력되는 창&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;424&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;424&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;이제 'Yes'를 누르면 구조가 변경된 테이블을 저장할 수 있게 된다.&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MS-SQL에서 테이블 구조를 변경할 때 테이블이 삭제되고 새로 생성되는 이유는&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;SQL Server는 테이블을 삭제하고 재생성하는 방식으로 변경 사항을 적용한다.&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;테이블의 스키마가 변경되면 SQL Server는 모든 데이터 페이지를 다시 작성해야 할 수도 있기 때문이다.&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;</description>
      <category>Database/MS-SQL</category>
      <category>MS-SQL</category>
      <category>SQL Server</category>
      <category>SSMS</category>
      <category>오류</category>
      <category>테이블 구조 변경</category>
      <category>트러블슈팅</category>
      <category>해결 방법</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/933</guid>
      <comments>https://luvris2.tistory.com/933#entry933comment</comments>
      <pubDate>Wed, 16 Oct 2024 17:02:18 +0900</pubDate>
    </item>
    <item>
      <title>Docker Desktop Error - Virtual Machine Platform is not enabled. Enable it using the following PowerShell script ~</title>
      <link>https://luvris2.tistory.com/932</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Error&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1728360802857&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Docker Desktop - Virtual Machine Platform is not enabled.
Enable it using the following PowerShell script (in an administrative PowerShell)
and then restart your computer before using Docker Desktop:

Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform&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;이 오류는 Docker Desktop을 실행할 때 Windows에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Virtual Machine Platform 기능이 활성화되지 않아서 발생하는 오류이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker Desktop이 WSL2를 사용하려면 이 기능이 필수적으로 활성화되있어야 한다.&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크립트를 그대로 파워쉘에 입력하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Virtual Machine Platform을 활성화해보자.&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;PowerShell을 관리자 권한으로 실행하기&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Windows 검색창에서 &quot;&lt;b&gt;PowerShell&lt;/b&gt;&quot;을 검색한다. &lt;/li&gt;
&lt;li&gt;Windows PowerShell을 마우스 오른쪽 클릭 후 &quot;&lt;b&gt;관리자 권한으로 실행&lt;/b&gt;&quot;을 선택한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Virtual Machine Platform 활성화하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PowerShell에서 다음 명령어를 입력한다.&lt;/p&gt;
&lt;pre id=&quot;code_1728361684598&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이 명령어는 Windows의 Virtual Machine Platform 기능을 활성화하는 명령어이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어를 입력하면 컴퓨터를 재시작할 것이냐고 묻는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;YES를 입력해서 시스템을 재부팅하자.&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;/h3&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dyCKlo/btsJXV8h5J9/PmTmYyMTjc92Qp58IrPWUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dyCKlo/btsJXV8h5J9/PmTmYyMTjc92Qp58IrPWUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dyCKlo/btsJXV8h5J9/PmTmYyMTjc92Qp58IrPWUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdyCKlo%2FbtsJXV8h5J9%2FPmTmYyMTjc92Qp58IrPWUk%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; alt=&quot;도커 데스크탑 구동 화면&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>DevOps/Docker</category>
      <category>Desktop</category>
      <category>docker</category>
      <category>error</category>
      <category>virtual machine platform is not enabled</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/932</guid>
      <comments>https://luvris2.tistory.com/932#entry932comment</comments>
      <pubDate>Tue, 8 Oct 2024 13:34:46 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL - 빠르게 알아보는 데이터베이스 용량 경량화하기 (데이터 및 로그 축소)</title>
      <link>https://luvris2.tistory.com/931</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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;DBCC SHRINKDATABASE 구문&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1727841159606&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DBCC SHRINKDATABASE(데이터베이스명, 여유공간사이즈)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;데이터베이스의 파일(데이터, 로그)을 축소하여 디스크 공간을 회수하는 데 사용하는 명령어&lt;/li&gt;
&lt;li&gt;&lt;b&gt;첫 번째 파라미터&lt;/b&gt; : 축소하려는 데이터베이스의 이름을 입력&lt;/li&gt;
&lt;li&gt;&lt;b&gt;두 번째 파라미터&lt;/b&gt; : 선택사항, 데이터베이스 파일 내에서 남겨둘 여유 공간의 비율 입력&lt;br /&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;예시1) 만약 '10'의 값을 입력할 경우에는 10% 여유 공간을 남김&lt;/li&gt;
&lt;li&gt;예시2) 파라미터의 값을 입력하지 않으면 여유 공간 없이 축소 진행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;DBCC SHRINKFILE 구문&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1727841295463&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DBCC SHRINKFILE (파일이름, 축소할용량);&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;특정 파일의 크기를 축소하여 사용하지 않는 디스크 공간을 회수하는 데 사용하는 명령어&lt;/li&gt;
&lt;li&gt;&lt;b&gt;첫 번째 파라미터&lt;/b&gt; : 축소하려는 파일의 이름 입력&lt;/li&gt;
&lt;li&gt;&lt;b&gt;두 번째 파라미터&lt;/b&gt; : 축소하려는 목표 파일의 크기(MB 단위) 입력
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;예시1) 5의 값을 입력할 경우, 최대 5메가까지 축소 작업을 시도함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;pre id=&quot;code_1727841555330&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 현재 데이터베이스의 파일명을 모를 경우의 용량 확인
use xxx
exec sp_helpfile -- xxx 데이터베이스 데이터 파일 용량 415기가 / 로그 용량 91기가

-- DB 작업 축소 전 용량 확인
use xxx
SELECT name AS [파일명], size * 8 / 1024 AS [크기(MB)]
FROM sys.master_files
WHERE type_desc = 'ROWS' and name = 'xxx' -- 데이터 파일 축소 전 : 415816 MB

-- 필요 없는 데이터 삭제
delete from ~
truncate table ~

-- 데이터베이스 용량 축소
DBCC SHRINKDATABASE(xxx)

-- DB 작업 축소 후 용량 확인
use xxx
SELECT name AS [파일명], size * 8 / 1024 AS [크기(MB)]
FROM sys.master_files
WHERE type_desc = 'ROWS' and name = 'xxx' -- 데이터 파일 축소 전 : 92547MB&lt;/code&gt;&lt;/pre&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;/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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 개발 환경에서는 상관없으나 실제 서비스 중인 데이터베이스에서는 위험할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1727841605262&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- DB 작업 축소 전 용량 확인
use xxx
SELECT name AS [파일명], size * 8 / 1024 AS [크기(MB)]
FROM sys.master_files
WHERE type_desc = 'LOG' and name = 'xxx_log' -- 로그 파일 축소 전 : 91528 MB

-- 로그를 아예 날려버리기 위해 간단 복구 모델로 변경
ALTER DATABASE xxx SET RECOVERY SIMPLE

-- 로그 파일 축소
DBCC SHRINKFILE (xxx_log, 5);  -- 5MB로 축소

-- 복구 모델을 다시 전체 복구로 변경
ALTER DATABASE xxx SET RECOVERY FULL

-- DB 작업 축소 후 용량 확인
use xxx
SELECT name AS [파일명], size * 8 / 1024 AS [크기(MB)]
FROM sys.master_files
WHERE type_desc = 'LOG' and name = 'xxx_log' -- 축소 후 : 5 MB&lt;/code&gt;&lt;/pre&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;span style=&quot;color: #333333; text-align: start;&quot;&gt;요약하여&lt;/span&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/database/sqlserver-how-to-shrink-database-file-size/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MSSQL&amp;nbsp;&amp;ndash;&amp;nbsp;데이터베이스&amp;nbsp;용량&amp;nbsp;및&amp;nbsp;로그&amp;nbsp;사이즈&amp;nbsp;축소하기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1727842012007&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;MSSQL - 데이터베이스 용량 및 로그 사이즈 축소하기 - 은별 월드&quot; data-og-description=&quot;혹시 데이터베이스 용량 때문에 고민해본 적이 있을까? 서비스를 운영하다 보면 자연스레 데이터가 계속 쌓이면서 데이터베이스 용량이 증가하고어느샌가 알게 모르게 디스크 공간이 부족해지&quot; data-og-host=&quot;eunbyeol.co.kr&quot; data-og-source-url=&quot;https://eunbyeol.co.kr/blog/database/sqlserver-how-to-shrink-database-file-size/&quot; data-og-url=&quot;https://eunbyeol.co.kr/blog/database/sqlserver-how-to-shrink-database-file-size/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/rgLH3/hyXaEZS415/QyHHllceCcne21cNQ0WE70/img.png?width=285&amp;amp;height=218&amp;amp;face=0_0_285_218,https://scrap.kakaocdn.net/dn/dpUuv7/hyXay6rrWV/NpiU3CRfedc4t0udyOPbK1/img.png?width=285&amp;amp;height=218&amp;amp;face=0_0_285_218&quot;&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/database/sqlserver-how-to-shrink-database-file-size/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://eunbyeol.co.kr/blog/database/sqlserver-how-to-shrink-database-file-size/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/rgLH3/hyXaEZS415/QyHHllceCcne21cNQ0WE70/img.png?width=285&amp;amp;height=218&amp;amp;face=0_0_285_218,https://scrap.kakaocdn.net/dn/dpUuv7/hyXay6rrWV/NpiU3CRfedc4t0udyOPbK1/img.png?width=285&amp;amp;height=218&amp;amp;face=0_0_285_218');&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;MSSQL - 데이터베이스 용량 및 로그 사이즈 축소하기 - 은별 월드&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;eunbyeol.co.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;</description>
      <category>Database/MS-SQL</category>
      <category>db 경량화</category>
      <category>MSSQL</category>
      <category>데이터베이스 용량 사이즈 줄이기</category>
      <category>디비 축소</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/931</guid>
      <comments>https://luvris2.tistory.com/931#entry931comment</comments>
      <pubDate>Wed, 2 Oct 2024 13:07:59 +0900</pubDate>
    </item>
    <item>
      <title>Android Studio - We recommend using a newer Android Gradle plugin to use compileSdk xx</title>
      <link>https://luvris2.tistory.com/930</link>
      <description>&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;구글 플레이에 출시되어 있는 앱을 API 34 수준의 요구사항을 타겟팅을 해야 하는 작업에 앞서,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 스튜디오에서 다음과 같은 경고 메시지가 출력되었다.&lt;/p&gt;
&lt;pre id=&quot;code_1726712391840&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;We recommend using a newer Android Gradle plugin to use compileSdk = 34

This Android Gradle plugin (8.0.2) was tested up to compileSdk = 33.

You are strongly encouraged to update your project to use a newer
Android Gradle plugin that has been tested with compileSdk = 34.

If you are already using the latest version of the Android Gradle plugin,
you may need to wait until a newer version with support for compileSdk = 34 is available.&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;이 말은 즉, 특정 SDK의 API를 사용하려면 안드로이드 그레이들의 플러그인을 최신화하란 말이다.&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;color: #ef5369; background-color: #dddddd;&quot;&gt;&lt;b&gt;8.1.1&lt;/b&gt;&lt;/span&gt; 버전 이상으로 올리라고 하는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무리 업데이트를 확인해보아도 안드로이드 스튜디오에서는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;&lt;b&gt;8.0.2&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;/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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/783&quot;&gt;Android Studio Build Error) We recommend using a newer Android Gradle plugin to use compileSdk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;/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;span style=&quot;color: #666666;&quot;&gt;&lt;i&gt;&lt;b&gt;* 여기서 AGP란, Android Gradle Plugin의 약자로, 흔히 알고 있는 그레이들을 의미한다.&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #ffffff; color: #202124; text-align: start; border-collapse: collapse; width: 100%; height: 168px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: left; height: 20px;&quot;&gt;Android 스튜디오 버전&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 20px;&quot;&gt;필요한 AGP 버전&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: left; height: 20px;&quot;&gt;무당벌레 | 2024년 2월 1일&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 20px;&quot;&gt;3.2~8.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: left; height: 20px;&quot;&gt;코알라 기능 출시 | 2024년 1월 2일&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 20px;&quot;&gt;3.2~8.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: left; height: 20px;&quot;&gt;코알라 | 2024년 1월 1일&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 20px;&quot;&gt;3.2~8.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: left; height: 20px;&quot;&gt;해파리 | 2023년 3월 1일&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 20px;&quot;&gt;3.2~8.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;text-align: left; height: 17px;&quot;&gt;Iguana | 2023.2.1&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 17px;&quot;&gt;3.2~8.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;text-align: left; height: 17px;&quot;&gt;Hedgehog | 2023.1.1&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 17px;&quot;&gt;3.2-8.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;text-align: left; height: 17px;&quot;&gt;Giraffe | 2022.3.1&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 17px;&quot;&gt;3.2~8.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;text-align: left; height: 17px;&quot;&gt;Flamingo | 2022.2.1&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 17px;&quot;&gt;3.2~8.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;(출처 : &lt;a href=&quot;https://developer.android.com/studio/releases?hl=ko#android_gradle_plugin_and_android_studio_compatibility&quot;&gt;안드로이드 스튜디오 공식 레퍼런스 - 새로운 기능&lt;/a&gt;)&lt;/i&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;b&gt;Help - About&lt;/b&gt;' 를 차례로 눌러보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나 같은 경우에는 &lt;b&gt;Android Studio Flaming&lt;/b&gt;였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지에서 안내한 내용 그대로 내 안드로이드 스튜디오는 최대 8.0까지만 지원하지 않으니&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8.0.2 이후 업데이트가 없다고 나온 것이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;487&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk6G16/btsJFcvdehZ/NkUokr6q8l9F5jAUWYUkuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk6G16/btsJFcvdehZ/NkUokr6q8l9F5jAUWYUkuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk6G16/btsJFcvdehZ/NkUokr6q8l9F5jAUWYUkuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbk6G16%2FbtsJFcvdehZ%2FNkUokr6q8l9F5jAUWYUkuK%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; alt=&quot;안드로이드 스튜디오 버전 확인 방법 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;732&quot; height=&quot;487&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;487&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;size26&quot;&gt;&lt;b&gt;해결 방법&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;안드로이드 스튜디오에 호환되는 버전으로 업그레이드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;compileSdk에 맞는 최소 AGP(Android Gradle Plugin) 버전을 사용하려면&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;Help - Check for Updates&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;232&quot; data-origin-height=&quot;482&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KApd6/btsJEkgsUHW/3vt1vZzCOPLkWutieQIiz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KApd6/btsJEkgsUHW/3vt1vZzCOPLkWutieQIiz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KApd6/btsJEkgsUHW/3vt1vZzCOPLkWutieQIiz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKApd6%2FbtsJEkgsUHW%2F3vt1vZzCOPLkWutieQIiz1%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; alt=&quot;안드로이드 스튜디오 업데이트 확인 및 업데이트 예시&quot; loading=&quot;lazy&quot; width=&quot;232&quot; height=&quot;482&quot; data-origin-width=&quot;232&quot; data-origin-height=&quot;482&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;/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;Update...&lt;/b&gt;'를 누르면 화면 정중앙에 업데이트 팝업이 다시 출력되는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'&lt;b&gt;Download&lt;/b&gt;' 버튼을 누르면 안드로이드 스튜디오 다운로드 페이지로 이동된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 버전의 Android Studio를 다운로드를 한 후 재설치를 진행하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfMdHH/btsJFK6gtYn/BOp3w8NrwpWT1uKqN40tBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfMdHH/btsJFK6gtYn/BOp3w8NrwpWT1uKqN40tBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfMdHH/btsJFK6gtYn/BOp3w8NrwpWT1uKqN40tBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfMdHH%2FbtsJFK6gtYn%2FBOp3w8NrwpWT1uKqN40tBK%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; alt=&quot;안드로이드 스튜디오 업데이트 확인 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;362&quot; height=&quot;127&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;127&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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;당연한 이야기이지만, 안드로이드 스튜디오를 재설치할 때에는&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;실행되어 있는 안드로이드 스튜디오는 종료한 뒤 재설치해주어야 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;그레이들 버전 업데이트&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트에서 프로젝트를 담당하는 &quot;&lt;b&gt;build.gradle(Project: xxx)&lt;/b&gt;&quot; 파일을 열자.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러면 의존성을 주입하는 곳에 그레이들 버전을 입력하는 곳(com.android.tools.build:gradle)이 보일 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;현재 요구하는 API 34의 최소 그레이들 버전은 8.1.1이므로, 나는 8.1.1을 해주었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;물론 그 이상의 버전을 선택해도 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1726817131793&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:8.1.1' // 8.0.2에서 8.1.1로 업데이트
        classpath 'com.google.gms:google-services:4.3.14'
    }
}&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;Sync Now&lt;/b&gt;'를 눌러 해당 프로젝트에 적용될 수 있도록 해준다.&lt;/p&gt;</description>
      <category>Mobile/Android</category>
      <category>AGP</category>
      <category>android studio</category>
      <category>Update</category>
      <category>그레이들 버전</category>
      <category>안드로이드 스튜디오</category>
      <category>업데이트</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/930</guid>
      <comments>https://luvris2.tistory.com/930#entry930comment</comments>
      <pubDate>Thu, 19 Sep 2024 12:04:42 +0900</pubDate>
    </item>
    <item>
      <title>Python Flask - Flask 서버에 무료 SSL 인증서 적용하는 방법 (Windows, win-acme, NginX)</title>
      <link>https://luvris2.tistory.com/929</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;무료 인증서를 발급 받기 위해 Let's Encrypt의 SSL 인증을 받아야 할 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 서버(Apache, NginX 등)를 이용하여 웹 루트를 정하고 인증을 받는 방식으로 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 윈도우에서 win-acme 도구를 이용하여 무료 SSL 인증서 발급 시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 파일 방식으로 인증을 받는 식인데, 문제는 여기서 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flask의 경우에는 서버 자체에서 특정 URL의 경로를 미리 정의해주지 않으면 안된다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 win-acme 도구는 사이트 인증 시 내가 지정한 웹 루트에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;랜덤으로 주어진 코드가 적혀있는 파일이 생성되는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 동적인 상황에 생성되는 랜덤 주소 URL 링크를 미리 알 방법이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 내가 지정한 웹 루트에 '.&lt;i&gt;well-known/acme-challenge/랜덤값&lt;/i&gt;' 이 주어지는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 랜덤값을 미리 알 수 없으니 SSL 인증을 위해 해당 주소를 사전에 정의할 수 없다는 것이다.&lt;/p&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;b&gt;윈도우&lt;/b&gt; 운영체제에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) &lt;b&gt;엔진엑스&lt;/b&gt;를 이용하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) &lt;b&gt;파이썬 플라스크&lt;/b&gt; 서버를&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4) &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;b&gt;win-acme&lt;/b&gt;&lt;span&gt; 도구를 통해 &lt;b&gt;네트워크 경로의 파일 방식&lt;/b&gt;으로&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;무료 SSL 인증서를 발급 받을 수 있도록 인증하는 방법에 대해 다룬다.&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;이 글은 Flask 서버에 한정되어 SSL 인증을 받을 수 있는 방법을 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;윈도우에서 무료 SSL 인증서를 발급받고자 한다면 아래의 글을 확인하자.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/916&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;nginx - 윈도우에서 무료 SSL 발급 및 적용하기 (Let's Encript ACME For Windows)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;Nginx 설정&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;우선 win-acme 도구를 통해 해당 경로의 파일을 생성할 수 있도록 엔진엑스를 설정해주자.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;location&lt;/span&gt; 부분에 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;/.well-known/acme-challenge/&lt;/span&gt; 경로 접근 시 생성될 디렉토리를 지정해준다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;플라스크 서버는 기본적으로 파일을 다루는 디렉토리의 기본 경로는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;static&lt;/span&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;때문에 가능하면 플라스크가 구동되고 있는 프로젝트 루트 디렉토리에서&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;하위 디렉토리인 'static'으로 SSL &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;인증을 받을 수 있도록 경로를 지정해주자.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;내 경우엔 FlaskBlogServer 라는 프로젝트 디렉토리의 static 디렉토리를 지정해두었다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;그러면 SSL 인증 시 생성될 디렉토리 구조는&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;'&lt;i&gt;C:\WorkSpace\FlaskBlogServer\static\.well-known\acme-challenge\파일이름&lt;/i&gt;'이 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1726067448157&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 설정 예시
server {
    listen          80; # Python Flask Auto Posting Server
    server_name     post.eunbyeol.co.kr;
    return 301      https://$server_name$request_uri;

    location /.well-known/acme-challenge/ {
        root        C:/WorkSpace/FlaskBlogServer/static;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Flask Routes 설정&lt;/h2&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;나는 여기서 경로의 마지막 부분의 값을 변수로 받아 생성된 파일을 다시 리턴할 수 있도록 하였다.&lt;/p&gt;
&lt;pre id=&quot;code_1726067791249&quot; class=&quot;reasonml&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;# 블루 프린트 등록
routesBp = Blueprint('routes', __name__, template_folder='../templates')

# SSL 인증을 받기 위한 경로 설정
@routesBp.route('/.well-known/acme-challenge/&amp;lt;path:filename&amp;gt;')
def serve_acme_challenge(filename):
    return send_from_directory('static/.well-known/acme-challenge', filename)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;send_from_directory&lt;/b&gt; : 서버에서 특정 디렉토리 내에 있는 파일을 클라이언트로 전송할 때 사용하는 함수이다. 파일 다운로드 기능이나 동적으로 파일을 제공할 때 유용하게 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이로써 SSL 인증을 받기 위한 Nginx와 Flask의 설정이 끝났다.&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;win-acme로 인증 받기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-1484169609317244&quot; data-ad-slot=&quot;2004881032&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;     (adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&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;win-acme를 실행하여 차례대로 아래의 과정을 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Please&amp;nbsp;choose&amp;nbsp;from&amp;nbsp;the&amp;nbsp;menu:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;M&lt;/b&gt;: Create certificate (full options)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;How shall we determine the domain(s) to include in the certificate?:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;2&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;:&amp;nbsp;Manual&amp;nbsp;input&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;Host:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;SSL 인증받을 본인 웹 사이트 주소 입력 (예시: &lt;b&gt;post.eunbyeol.co.kr&lt;/b&gt;)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;Friendly&amp;nbsp;name&amp;nbsp;'[Manual]&amp;nbsp;post.eunbyeol.co.kr'.&amp;nbsp;&amp;lt;Enter&amp;gt;&amp;nbsp;to&amp;nbsp;accept&amp;nbsp;or&amp;nbsp;type&amp;nbsp;desired&amp;nbsp;name:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;그냥 &lt;b&gt;Enter&lt;/b&gt;로 진행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Would you like to split this source into multiple certificates?:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;1&lt;/b&gt;: Separate&amp;nbsp;certificate&amp;nbsp;for&amp;nbsp;each&amp;nbsp;domain&amp;nbsp;(e.g.&amp;nbsp;*.example.com)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;How would you like prove ownership for the domain(s)?:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;1&lt;/b&gt;: [http]&amp;nbsp;Save&amp;nbsp;verification&amp;nbsp;files&amp;nbsp;on&amp;nbsp;(network)&amp;nbsp;path&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Path:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Flask 프로젝트의 static 경로 입력 (예시: &lt;b&gt;C:\WorkSpace\FlaskBlogServer\static&lt;/b&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Copy&amp;nbsp;default&amp;nbsp;web.config&amp;nbsp;before&amp;nbsp;validation?&amp;nbsp;(y/n*)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;N&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;What kind of private key should be used for the certificate?:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;2:&lt;/b&gt; RSA key&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;How would you like to store the certificate?:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;2:&lt;/b&gt; PEM&amp;nbsp;encoded&amp;nbsp;files&amp;nbsp;(Apache,&amp;nbsp;nginx,&amp;nbsp;etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;File path:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;SSL 인증서가 저장될 경로 입력 (예시: &lt;b&gt;C:\dev\nginx-1.26.1\ssl&lt;/b&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Choose from the menu:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;1:&lt;/b&gt; None&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Would you like to store it in another way too?:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;5:&amp;nbsp;&lt;/b&gt;No&amp;nbsp;(additional)&amp;nbsp;store&amp;nbsp;steps&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Which installation step should run first?:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;3:&lt;/b&gt;&amp;nbsp;No&amp;nbsp;(additional)&amp;nbsp;installation&amp;nbsp;steps&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력을 모두 마치면 인증이 진행되며, 지정한 경로에 .pem 파일이 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 파일로 SSL을 적용하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cq7whG/btsJxYedysS/CqkqqLrguRrgsVTASoEyV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cq7whG/btsJxYedysS/CqkqqLrguRrgsVTASoEyV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cq7whG/btsJxYedysS/CqkqqLrguRrgsVTASoEyV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcq7whG%2FbtsJxYedysS%2FCqkqqLrguRrgsVTASoEyV0%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; alt=&quot;win-acme 도구를 통해 flask 서버의 ssl 인증서를 발급 받은 결과 화면&quot; loading=&quot;lazy&quot; width=&quot;662&quot; height=&quot;214&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;214&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;size26&quot;&gt;NginX에 SSL 인증서 적용하기&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;http 주소를 https로 리다이렉트 하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 https로 접속할 수 있게 http로 접속 시 리다이렉트를 해줄 수 있도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확인해봐야할 부분은 '&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;return 301&lt;/span&gt;'이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청받은 주소를 https로 변경하여 접속할 수 있도록 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 예시 코드이다.&lt;/p&gt;
&lt;pre id=&quot;code_1726068891812&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server {
    listen          80; # Python Flask Auto Posting Server
    server_name     post.eunbyeol.co.kr;
    return 301      https://$server_name$request_uri; # https로 리다이렉트
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;https의 SSL 인증서 적용하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 과정을 통해 발급 받은 pem 인증 파일을 Nginx에 등록해주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;win-acme에서 지정한 SSL 파일 저장 경로에 존재하는 pem 파일을&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 예시를 보고 자신에게 맞게 변경하여 넣어주자.&lt;/p&gt;
&lt;pre id=&quot;code_1726068990944&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server {
    listen          443 ssl;
    server_name     post.eunbyeol.co.kr;

    ssl_certificate C:/dev/nginx-1.26.1/ssl/post.eunbyeol.co.kr-crt.pem;
    ssl_certificate_key C:/dev/nginx-1.26.1/ssl/post.eunbyeol.co.kr-key.pem;
    ssl_trusted_certificate C:/dev/nginx-1.26.1/ssl/post.eunbyeol.co.kr-chain.pem;

    location / {
        proxy_pass  http://192.168.0.78:4002/;
    }
}&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 플라스크 서버가 켜져있다면 서버 또한 재시작해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 웹 사이트에 접속하면 정상적으로 SSL이 적용되어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;https로 페이지를 보여주는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcV1gp/btsJx9tcIAE/X6gkV7ud9RTaJBOgKUN4Ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcV1gp/btsJx9tcIAE/X6gkV7ud9RTaJBOgKUN4Ik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcV1gp/btsJx9tcIAE/X6gkV7ud9RTaJBOgKUN4Ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcV1gp%2FbtsJx9tcIAE%2FX6gkV7ud9RTaJBOgKUN4Ik%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; alt=&quot;SSL 인증서를 적용하고 난 후 웹 사이트에 접속하여 https로 이상없이 접속되는 것을 확인하는 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;445&quot; height=&quot;333&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;333&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Back End/Flask</category>
      <category>flask</category>
      <category>https</category>
      <category>nginx</category>
      <category>Python</category>
      <category>SSL</category>
      <category>window</category>
      <category>서버</category>
      <category>윈도우</category>
      <category>파이썬</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/929</guid>
      <comments>https://luvris2.tistory.com/929#entry929comment</comments>
      <pubDate>Thu, 12 Sep 2024 00:45:45 +0900</pubDate>
    </item>
    <item>
      <title>C# - 파일 처리 메모리 누수 트러블슈팅</title>
      <link>https://luvris2.tistory.com/928</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;막연하게 간단한 기능을 하는 프로그램을 제작할 때까지는 몰랐다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러나 대량의 파일을, 대량의 데이터를 다루고 처리해야하는 상황에서&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하루가 지나도록, 아니 시간이 지나면 지날수록 작업 속도가 현저히 느려지는 현상이 발생하였다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;분명 테스트할 때는 이상 없었는데...&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;확인해보니 프로그램을 처음 실행했을 때의 메모리는 21메가를 차지하였지만,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하루가 지난 상태에서 메모리 사용률은 7기가에 임박했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&quot;무엇이 문제일까?&quot;&lt;/b&gt;&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;파일 디렉토리를 탐색하는 방법을 좀 더 효율적으로!&lt;/b&gt;&lt;/span&gt;&lt;/h2&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; text-align: start;&quot;&gt;C#에서는&amp;nbsp;&lt;/span&gt;Directory&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;&amp;nbsp;클래스를 통해 폴더를 다룰 수 있는데&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;&lt;b&gt; Directory.GetFiles&lt;/b&gt;&lt;/span&gt; 메서드를 이용하여 폴더 내 파일 목록을 가져오도록 구현했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하지만 이는 잘못된 선택이였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;span style=&quot;text-align: start;&quot;&gt;Directory.GetFiles&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;메서드는 분명 사용하기 쉽지만&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;폴더 내 파일 개수가 많아질수록 성능이 크게 저하될 수 있다는 단점&lt;/b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;이 있다는 것을 알아냈다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;모든 파일 정보를 메모리에 한 번에 로드하기 때문에 대용량의 파일을 탐색할수록 로딩 시간이 매우 길어진다.&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&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;&lt;span style=&quot;color: #000000;&quot;&gt;이를 해결하기 위해서&amp;nbsp; &lt;span style=&quot;text-align: start;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #dddddd; color: #ef5369;&quot;&gt;Directory.EnumerateFiles&lt;/span&gt;&lt;/b&gt; 메서드를 이용하면,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;조금 더 효율적으로 파일 탐색 작업을 수행할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;Directory.EnumerateFiles&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;메서드는 파일 목록 전체를 한 번에 메모리에 로드하는 대신,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;파일을 하나씩 순차적으로 처리&lt;/b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;할 수 있는&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;IEnumerable&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&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;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;즉, &lt;span style=&quot;text-align: start;&quot;&gt;Directory.EnumerateFiles&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;메서드는 파일을 하나씩 처리하기 때문에&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;Directory.GetFiles&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;보다 메모리 사용량이 적고, 대량의 파일을 처리할 때&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;성능상 유리&lt;/b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;하다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Directory.GetFiles&amp;nbsp;: 모든 파일을 한 번에 가져오기&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Directory.GetFiles&amp;nbsp;메서드는 지정된 폴더 내의 모든 파일 목록을&amp;nbsp;string&amp;nbsp;배열 형태로 반환한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;cmake&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;string[] allFiles = Directory.GetFiles(@&quot;C:\MyFolder&quot;);

foreach (string file in allFiles)
{
    Console.WriteLine(file);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Directory.EnumerateFiles&amp;nbsp;: 파일을 하나씩 순차적으로 처리&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;cmake&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;foreach (string file in Directory.EnumerateFiles(@&quot;C:\MyFolder&quot;))
{
    Console.WriteLine(file);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;결론적으로&amp;nbsp;폴더 내 파일 개수가 적고 모든 파일 정보가 필요한 경우,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Directory.GetFiles&amp;nbsp;메서드를 사용하는 것이 간편하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;테스트에는 문제가 없었던 이유 또한 위와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하지만&amp;nbsp;&lt;b&gt;대량의 파일을 다루거나 파일을 하나씩 처리하면서 &lt;/b&gt;&lt;b&gt;중간에 작업을 중단해야 하는 경우&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Directory.EnumerateFiles&amp;nbsp;메서드를 사용&lt;/b&gt;하는 것이 성능 면에서 유리하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;처리된 메모리 자원은 해제하도록! (GC)&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;작업 수행을 통해 즉시 처리되고 다시 사용되지 않을 자원은 메모리를 해제하여 공간을 확보한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;단 한 번의 루프문은 작업량이 많아질수록 (내가 처한 상황은 루프문이 100만번 돌아야했다.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저장되는 파일 구조의 정보가 계속해서 메모리를 할당하여 사용되는 메모리양이 증가한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이를 해결하기 위해서 &lt;b&gt;수동으로 GC (가비지 컬렉터)를 호출&lt;/b&gt;하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;대량의 파일 관련 정보를 저장하는 루프문의 로직에서&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;batch의 작업 수를 체크하도록하는 역할을 갖는 변수를 두었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;해당 변수를 통해 batch의 작업 할당량이 채워진 시점에 분기점을 나누고,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;가비지 컬렉터로 메모리를 제거하여 자원을 확보하는 식으로 변경하였다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1725121716516&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GC.Collect(); // 가비지 컬렉션 강제 호출
GC.WaitForPendingFinalizers(); // 모든 종료 작업을 완료할 때까지 대기&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;span style=&quot;color: #000000;&quot;&gt;가비지 컬렉션에 대한 내용은 아래의 링크에서 자세히 알아볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;gt; &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://eunbyeol.co.kr/blog/programming/csharp-what-is-garbage-collection/&quot;&gt;C# &amp;ndash; 초보 개발자를 위한 가비지 컬렉션 기초&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;사용을 마친 객체의 자원은 바로바로 반납되도록! (Using, Dispose)&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일을 읽고 쓰는 과정에서 StreamReader 객체와 StreamWriter 객체가 빈번하게 호출되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;StreamReader/&lt;span style=&quot;text-align: start;&quot;&gt;StreamWriter &lt;/span&gt;객체는 사용이 끝난 후 해제해 주어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt; StreamReader가 내부적으로 파일 스트림을 유지하고 있기 때문에&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;파일을 다 읽은 후에도 메모리를 점유할 수 있다.&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt; 당연하면서도 놓치기 쉬운 부분이였다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;확인해보니 코드 내에서는 따로 Dispose 메서드를 사용하지 않았었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 문제를 해결하기 위해 using 블록을 사용하여 StreamReader가 사용된 후 자동으로 해제되도록 변경하였다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1725121133322&quot; class=&quot;pgsql&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;csharp&quot;&gt;&lt;code&gt;void readFile(string path)
{
    using (StreamReader reader = new StreamReader(path))
    {
        string line, text = &quot;&quot;;
        while ((line = reader.ReadLine()) != null)
        {
            text += line;
        }

        findText(path, text);
    }
}&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;span style=&quot;color: #000000;&quot;&gt;using 블록을 왜 사용하는지, 어떤 점에 이득이 있는지에 대한 내용은 아래의 링크에서 자세히 알아볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;gt; &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://eunbyeol.co.kr/blog/programming/csharp-what-is-using-keyword/&quot;&gt;C# &amp;ndash; using 키워드, 왜 사용할까?&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;메모리 사용을 최소화하기 위한 문자열 최적화!&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대량의 파일을 StreamReader 객체를 통해 반복적으로 파일의 읽어드리는 작업에서&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;읽어드린 파일의 내용을 저장할 string 객체 또한 지속적으로 내용이 변경되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특히 string 객체의 쓰임새가 StreamReader에서 불러온 내용을&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;한 줄 한 줄 새로 내용을 추가하는 식의 코드인데,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;string 객체는 불변 객체로, 추가된 내용을 임시 string 객체를 만들어 새로 저장하는 방식이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그에 반해 StringBuilder 객체는 가변 객체이므로 말 그대로 내용이 추가(수정)가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;while 문을 통해 지속적으로 내용이 추가되는 코드에서&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 방식은 string 객체를 사용하면 결국 메모리를 많이 사용하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;기존&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1725122912709&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 스트림 리더 객체 생성
StreamReader reader = new StreamReader(filePath);

// 파일 읽기
string line, text = &quot;&quot;;
while ((line = reader.ReadLine()) != null)
{
	text += line;
}

// text 변수를 통해 처리 관련 로직 수행&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;수정&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1725123058338&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 스트림 리더 객체 생성
using (StreamReader reader = new StreamReader(path))
{
    StringBuilder stringBuilder = new StringBuilder();
    
    // 파일 읽기
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        stringBuilder.AppendLine(line);
    }
    
    // 처리 관련 로직 수행
}&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;span style=&quot;color: #000000;&quot;&gt;문자열을 효율적으로 다루기 위해 StringBuilder에 대해 더 자세히 알아보고 싶다면 아래의 링크를 참고하자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;gt; &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://eunbyeol.co.kr/blog/programming/csharp-what-use-string-vs-stringbuilder-compare/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C# &amp;ndash; 문자열 다루기 String vs StringBuilder, 무엇을 사용해야 할까?&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C#을 원하는 기능만을 구현하며 성능 퍼포먼스적으로 단 한 번도 제대로 생각해본 적이 없다.&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;이렇게 성장해 나가는 거겠지 뭐.&lt;/p&gt;</description>
      <category>Programming/C#</category>
      <category>c#</category>
      <category>메모리 누수</category>
      <category>트러블슈팅</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/928</guid>
      <comments>https://luvris2.tistory.com/928#entry928comment</comments>
      <pubDate>Sun, 1 Sep 2024 02:04:00 +0900</pubDate>
    </item>
    <item>
      <title>C# SqlConnection Reference Error - 네임스페이스 'System.Data.SqlClient'에 형식 이름 'SqlConnection'이(가) 없습니다. / 서버에 연결했지만 로그인하는 동안 오류가 발생했습니다. 신뢰되지 않은 기관에서 인증서 체인을 발급했습니다.</title>
      <link>https://luvris2.tistory.com/927</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터베이스 객체 사용 오류 발생&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;C# Winform 프로젝트에서 데이터베이스에 연결하려고 'SqlConnection' 객체를 사용하니 오류가 발생된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1724979593191&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CS1069 네임스페이스 'System.Data.SqlClient'에 형식 이름 'SqlConnection'이(가) 없습니다.&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;span style=&quot;color: #000000;&quot;&gt;using System.Data.SqlClient이 잘 명시되어 있음에도 오류가 출력된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;원인&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt; &lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;Microsoft는 최신 버전의 Visual Studio 및&lt;/span&gt;&amp;nbsp;.NET Core 5.0 이상에서 System.Data.SqlClient를 제거했다고 한다.&lt;/span&gt;&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; text-align: left;&quot;&gt;즉, &lt;b&gt;Microsoft는&lt;/b&gt;&lt;/span&gt;&lt;b&gt; .NET Core 또는 .NET 5 이상에서는 System.Data.SqlClient가 기본적으로 포함되지 않는다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여태 데이터베이스를 사용했던 프로젝트는 .NET Framework를 사용했던 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.NET Framework 프로젝트에서 System.Data.SqlClient는 기본적으로 포함되어 있다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;해결 방법&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;NuGet 패키지를 통해 참조를 추가하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하지만 .NET Core/5+부터는 System.Data.SqlClient 대신&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Microsoft.Data.SqlClient를 사용하는 것을 권장하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bz3Flt/btsJlKyCcll/glJjp7xDnzpD0aSj3PGKEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bz3Flt/btsJlKyCcll/glJjp7xDnzpD0aSj3PGKEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bz3Flt/btsJlKyCcll/glJjp7xDnzpD0aSj3PGKEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbz3Flt%2FbtsJlKyCcll%2FglJjp7xDnzpD0aSj3PGKEK%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; alt=&quot;Nuget 패키지 관리를 통해 SqlClient를 설치하는 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;936&quot; height=&quot;440&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;440&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: #000000;&quot;&gt;이제 코드에 문제 없이 SqlConnection 객체가 잘 참조되고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;84&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcSUsb/btsJjVhsqN7/izh3xgiolgkXJ8skBqQUa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcSUsb/btsJjVhsqN7/izh3xgiolgkXJ8skBqQUa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcSUsb/btsJjVhsqN7/izh3xgiolgkXJ8skBqQUa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcSUsb%2FbtsJjVhsqN7%2Fizh3xgiolgkXJ8skBqQUa1%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; alt=&quot;SqlConnection의 오류가 사라진 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;473&quot; height=&quot;84&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;84&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: #000000;&quot;&gt;만약 데이터베이스 연결 시도 시 아래와 같은 오류가 발생한다면,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;연결 옵션에서 &lt;b&gt;TrustServerCertificate&lt;/b&gt;를 &lt;b&gt;True&lt;/b&gt;로 설정해주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;오류 내용&lt;/b&gt; : 서버에 연결했지만 로그인하는 동안 오류가 발생했습니다. 신뢰되지 않은 기관에서 인증서 체인을 발급했습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1724983290459&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 연결 설정에서 TrustServerCertificate=True 설정
string connectionString = &quot;Server=_;Database=_;User Id=_;Password=_;TrustServerCertificate=True&quot;;

using (SqlConnection connection = new SqlConnection(connectionString))
{
	// 코드 작성
}&lt;/code&gt;&lt;/pre&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;span style=&quot;color: #000000;&quot;&gt;참고&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;http://Unable%20to locate System.Data.SqlClient reference&quot;&gt;stackoverflow -Unable to locate System.Data.SqlClient reference&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Programming/C#</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/927</guid>
      <comments>https://luvris2.tistory.com/927#entry927comment</comments>
      <pubDate>Fri, 30 Aug 2024 10:47:44 +0900</pubDate>
    </item>
    <item>
      <title>압축 알고리즘 - PNG 파일, 왜 압축하면 더 커질까? 압축 시 용량이 늘어나는 이유</title>
      <link>https://luvris2.tistory.com/926</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;일반적으로 파일을 압축하면 용량이 줄어드는 것이 당연하다고 생각한다.&lt;br&gt;하지만 PNG 파일은 압축을 하면 오히려 용량이 늘어나는 경우가 많다.&lt;br&gt;왜 이런 현상이 발생하는 걸까?&lt;br&gt;이는 PNG 파일의 압축 방식과 일반적인 압축 프로그램의 작동 방식의 차이에서 기인한다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; PNG 파일의 특별한 성질&lt;/b&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;PNG 파일은 이미 최적화된 상태로 압축되어 저장되는 무손실 이미지 파일이다.&lt;br&gt;마치 공기를 뺀 풍선처럼 더 이상 압축할 공간이 없는 셈이다.&lt;br&gt;때문에&amp;nbsp;일반적인 압축 프로그램은,&lt;br&gt;이미 최적화된 PNG 파일에서 이러한 과정을 통해 얻을 수 있는 효과가 미미하다.&lt;br&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;압축 프로그램은 PNG 파일의 특징을 완벽하게 이해하지 못하고&lt;br&gt;일반적인 파일 압축 방식을 적용하려고 한다.&lt;br&gt;이는 마치 이미 잘 정리된 서랍에 다시 한번 정리를 시도하는 것과 같다.&lt;br&gt;오히려 정리된 서랍을 더 어지럽힐 수 있다.&lt;br&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;PNG 파일은 이미 최적화된 구조를 가지고 있다.&lt;br&gt;그렇기 때문에 일반적인 압축 프로그램이 추가로 압축할 수 있는 부분이 적다.&lt;br&gt;이는 즉, 추가로 하는 압축으로 얻는 이득이 적다는 것을 의미한다.&lt;br&gt;또한, 압축 프로그램은 압축된 파일의 정보를 저장하기 위해 메타데이터를 추가한다.&lt;br&gt;이로 인해 메타데이터가 추가되어 파일 크기가 오히려 늘어날 수 있다. &lt;br&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;br&gt;조금 더 해당 내용에 대해 자세히 알고 싶다면&lt;br&gt;아래의 링크를 참고하자.&lt;/p&gt;&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/cs-trust-png-file-additional-compress/&quot; target=&quot;_self&quot;&gt;&lt;span&gt;CS – PNG 파일을 압축하면 용량이 오히려 늘어난다고?&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>이론/Algorithm</category>
      <category>CS</category>
      <category>PNG</category>
      <category>알고리즘</category>
      <category>압축</category>
      <category>용량 증가</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/926</guid>
      <comments>https://luvris2.tistory.com/926#entry926comment</comments>
      <pubDate>Thu, 22 Aug 2024 22:50:26 +0900</pubDate>
    </item>
    <item>
      <title>C# - 파일을 열고 쓰는 방법에 대해 알아보자. (파일 열기,읽기,쓰기,저장)</title>
      <link>https://luvris2.tistory.com/925</link>
      <description>&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;너무 귀찮아서 미루고 미루다가 이제서야 글을 쓴다.&lt;/p&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;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;StreamReader&lt;/b&gt;와 &lt;b&gt;StreamWriter&lt;/b&gt;가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;StreamReader는 말 그대로 스트림 데이터를 읽을 수 있도록 해주는 클래스이고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;StreamWriter는 스트림 데이터를 쓸 수 있도록 해주는 클래스이다.&lt;/p&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 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;스트림 리더로 텍스트 파일 읽기 (파일 열기)&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #444444; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;먼저,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;StreamReader&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;객체를 생성하고 읽을 파일의 경로를 지정해야 한다.&lt;br /&gt;그리고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;ReadLine()&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드를 사용하여 파일에서 한 줄씩 읽어온다.&lt;br /&gt;파일 읽기가 끝나면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Close()&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드를 사용하여 StreamReader 객체를 닫는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #444444; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;ReadLine() 메서드&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파일에서 한 줄을 읽어와 문자열로 반환하는 메서드&lt;/li&gt;
&lt;li&gt;파일의 끝에 도달하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;null&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;값 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1723771840926&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 읽어올 파일 경로 지정
string filePath = &quot;C:\\example.txt&quot;; 

// 스트림 리더 객체 생성
StreamReader reader = new StreamReader(filePath);

// 파일 읽기
string line;
while ((line = reader.ReadLine()) != null)
{
    Console.WriteLine(line); // 읽은 내용 콘솔에 출력
}

// 스트림 리더 객체 닫기
reader.Close();&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;스트림 라이터로 텍스트 파일 쓰기&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #444444; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;StreamReader는 파일 읽기 전용 도구이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #444444; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;텍스트 파일을 쓰려면 StreamWriter 클래스를 사용해야 한다.&lt;br /&gt;StreamWriter 사용법은 StreamReader와 매우 유사하다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #444444; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;먼저,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;StreamWriter&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;객체를 생성하고 쓸 파일의 경로를 지정한다.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;*&amp;nbsp;&lt;b&gt;두 번째 매개변수&lt;/b&gt;가&amp;nbsp;&lt;b&gt;true&lt;/b&gt;일 경우에는 파일에 내용을 추가하며,&amp;nbsp;&lt;b&gt;false&lt;/b&gt;일 경우에는 파일의 내용을 덮어쓴다.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #444444; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;그리고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;WriteLine()&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드를 사용하여 파일에 텍스트를 저장한다.&lt;br /&gt;파일 쓰기가 끝나면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Close()&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드를 사용하여 StreamWriter 객체를 닫는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #444444; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;WriteLine() 메서드&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파일에 텍스트를 쓰는 메서드&lt;/li&gt;
&lt;li&gt;두 번째 매개변수를 지정할 경우, 파일이 없으면 새 파일을 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1723771926272&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 읽어올 파일 경로 지정
string filePath = &quot;C:\\example.txt&quot;; 

// 스트림 라이터 객체 생성, true 옵션은 파일에 내용을 추가하겠다는 의미
StreamWriter writer = new StreamWriter(filePath, true);

// 파일 쓰기
writer.WriteLine(&quot;새로운 내용 추가&quot;);

// 스트림 라이터 객체 닫기
writer.Close();&lt;/code&gt;&lt;/pre&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;/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;/h3&gt;
&lt;pre id=&quot;code_1723772142365&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 파일 불러오기
private void btnRead_Click(object sender, EventArgs e)
{
    // 텍스트를 표시할 텍스트박스 초기화
    txtContent.Text = &quot;&quot;;
    
    // 기본 경로 : 프로젝트 실행 경로를 기준으로 함
	string basePath = Environment.CurrentDirectory;

    // 불러올 파일 경로 확인
    string filePath = basePath + &quot;\\&quot; + txtOriginPath.Text;

    // 파일 경로 유효성 확인
    if (File.Exists(filePath))
    {
        using (StreamReader reader = new StreamReader(filePath))
        {
            // 파일 읽기
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                txtContent.Text += line + Environment.NewLine; // 줄의 마지막이면 다음 줄로 이동
            }
        }
    }
}&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;pre id=&quot;code_1723772204031&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 파일 저장하기
private void btnSave_Click(object sender, EventArgs e)
{
    // 기본 경로 : 프로젝트 실행 경로를 기준으로 함
    string basePath = Environment.CurrentDirectory;

    // 저장할 파일 경로 확인
    string FilePath = basePath + &quot;\\&quot; + txtOriginPath.Text;

    // 저장할 파일 내용
    string content = txtContent.Text;

    // 파일 쓰기 : false (덮어쓰기)
    using (StreamWriter writer = new StreamWriter(FilePath, false))
    {
        writer.WriteLine(content);
    }
}&lt;/code&gt;&lt;/pre&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;h3 data-ke-size=&quot;size23&quot;&gt;테스트에 사용될 파일&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #444444; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;경로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;: 프로젝트 실행 경로/test1.txt (\bin\Debug\net8.0-windows)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;내용&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;: 테스트 파일입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxdZGD/btsI4jiFD0q/072IkTozL1aKkNcKsXZ1Ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxdZGD/btsI4jiFD0q/072IkTozL1aKkNcKsXZ1Ik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxdZGD/btsI4jiFD0q/072IkTozL1aKkNcKsXZ1Ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxdZGD%2FbtsI4jiFD0q%2F072IkTozL1aKkNcKsXZ1Ik%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; alt=&quot;C# 파일 읽기/쓰기에 사용될 테스트 텍스트 문서 파일 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;448&quot; height=&quot;217&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;217&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;size26&quot;&gt;파일 불러오기 테스트&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #444444; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;파일 경로 입력 : test1.txt&lt;/li&gt;
&lt;li&gt;파일 불러오기 버튼을 클릭하여 텍스트 문서 파일이 불러와지는지 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pLB9e/btsI3YFRiJK/aQiVmlvUeYd4Efntf8tnrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pLB9e/btsI3YFRiJK/aQiVmlvUeYd4Efntf8tnrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pLB9e/btsI3YFRiJK/aQiVmlvUeYd4Efntf8tnrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpLB9e%2FbtsI3YFRiJK%2FaQiVmlvUeYd4Efntf8tnrk%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; alt=&quot;씨샵으로 만들어진 윈도우 프로그램에서 파일 불러오기 버튼을 눌러 텍스트 문서 파일을 불러온 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;683&quot; height=&quot;360&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;360&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;h3 style=&quot;background-color: #ffffff; color: #444444; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;파일 저장 후 다시 불러오기&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #444444; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;파일 경로 입력 : test1.txt&lt;/li&gt;
&lt;li&gt;파일 불러오기 버튼 클릭&lt;/li&gt;
&lt;li&gt;파일의 내용이 불러와져 있는 텍스트 박스에 파일 내용 수정&lt;/li&gt;
&lt;li&gt;파일 저장하기 버튼 클릭&lt;/li&gt;
&lt;li&gt;파일 불러오기 버튼을 클릭하여 저장한 내용을 다시 불러오는지 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biCn5R/btsI4cD4cMb/OKy0K0VsKK6XgDXLvkIlbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biCn5R/btsI4cD4cMb/OKy0K0VsKK6XgDXLvkIlbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biCn5R/btsI4cD4cMb/OKy0K0VsKK6XgDXLvkIlbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiCn5R%2FbtsI4cD4cMb%2FOKy0K0VsKK6XgDXLvkIlbK%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; alt=&quot;씨샵으로 만들어진 윈도우 프로그램에서 파일 저장하기 버튼을 눌러 텍스트 문서 파일을 저장한 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;683&quot; height=&quot;360&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;360&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;size26&quot;&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;/p&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/programming/csharp-how-to-file-copy-move-delete/&quot;&gt;C# Winform &amp;ndash; 파일 다루고 처리하기 (파일 읽기/쓰기/이동/복사/삭제하기)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/luvris2/CSharp-Winforms-Example/tree/main/C%23_Winform_File_Management_Example&quot;&gt;Github - C#_Winform_File_Management_Example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Programming/C#</category>
      <category>c#</category>
      <category>StreamReader</category>
      <category>streawriter</category>
      <category>파일 쓰기</category>
      <category>파일 열기</category>
      <category>파일 읽기</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/925</guid>
      <comments>https://luvris2.tistory.com/925#entry925comment</comments>
      <pubDate>Fri, 16 Aug 2024 10:46:35 +0900</pubDate>
    </item>
    <item>
      <title>MySQL, Linux - 리눅스에서 MySQL 데이터베이스 포트 확인하기, 포트 번호 바꾸기</title>
      <link>https://luvris2.tistory.com/923</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;리눅스 우분투에서 RDBMS MySQL 데이터베이스의 포트를 변경하는 방법은 두가지가 있다.&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;리눅스 Ubuntu에서 MySQL 포트 확인하는 방법&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. MySQL의 설정파일 (mysql.conf)를 이용한 포트 확인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 명령어를 입력하여 mysql 설정 파일에 접근한다.&lt;/p&gt;
&lt;pre id=&quot;code_1721284026256&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;port = xxxx&lt;/span&gt;로 되어 있는 부분을 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거기에 적혀있는 숫자가 MySQL의 포트 번호이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 주석이 되어 있으면 기본 포트 번호인 3306를 사용하고 있는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;555&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RnU6K/btsIDV9Okjf/QxNJ8eGvPpemKw32t0e1P1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RnU6K/btsIDV9Okjf/QxNJ8eGvPpemKw32t0e1P1/img.png&quot; data-alt=&quot;리눅스에서 MySQL의 설정 파일을 이용하여 포트번호를 확인하는 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RnU6K/btsIDV9Okjf/QxNJ8eGvPpemKw32t0e1P1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRnU6K%2FbtsIDV9Okjf%2FQxNJ8eGvPpemKw32t0e1P1%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; alt=&quot;리눅스에서 MySQL의 설정 파일을 이용하여 포트번호를 확인하는 예시&quot; loading=&quot;lazy&quot; width=&quot;664&quot; height=&quot;555&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;555&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;리눅스에서 MySQL의 설정 파일을 이용하여 포트번호를 확인하는 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&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. SQL 쿼리를 이용한 포트 확인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL의 쿼리 내에서 글로벌 변수를 확인하여 포트의 번호를 알아내는 방법이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-1484169609317244&quot; data-ad-slot=&quot;2004881032&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL에 접속한다.&lt;/p&gt;
&lt;pre id=&quot;code_1721286638232&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo mysql -u root -p&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;/p&gt;
&lt;pre id=&quot;code_1721283968445&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SHOW GLOBAL VARIABLES LIKE 'port';&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;Value 컬럼에 현재 사용중인 포트 번호를 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;334&quot; data-origin-height=&quot;116&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WfEPL/btsIDmAen4U/AEOacK3iajQcbLfpkG8Xe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WfEPL/btsIDmAen4U/AEOacK3iajQcbLfpkG8Xe0/img.png&quot; data-alt=&quot;MySQL 글로벌 변수를 이용하여 포트 번호를 확인하는 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WfEPL/btsIDmAen4U/AEOacK3iajQcbLfpkG8Xe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWfEPL%2FbtsIDmAen4U%2FAEOacK3iajQcbLfpkG8Xe0%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; alt=&quot;MySQL 글로벌 변수를 이용하여 포트 번호를 확인하는 예시&quot; loading=&quot;lazy&quot; width=&quot;334&quot; height=&quot;116&quot; data-origin-width=&quot;334&quot; data-origin-height=&quot;116&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MySQL 글로벌 변수를 이용하여 포트 번호를 확인하는 예시&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;리눅스에서 포트 번호를 바꾸는 방법은?&lt;/b&gt;&lt;/h2&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;pre id=&quot;code_1721284474644&quot; class=&quot;awk&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf&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;✅ 포트 번경하기&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;내용 중 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;port&lt;/span&gt; 부분을 찾아 커서를 이동한다.&lt;/li&gt;
&lt;li&gt;앞에 주석(#)을 삭제한다.&lt;/li&gt;
&lt;li&gt;port 값에 원하는 포트 번호를 입력한다.&lt;/li&gt;
&lt;li&gt;저장한다. (Ctrl+X, y, Enter 차례로 입력)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;555&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SZdb9/btsIFlsNRR5/4ufnoYCueu9GS0n4wK8K6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SZdb9/btsIFlsNRR5/4ufnoYCueu9GS0n4wK8K6K/img.png&quot; data-alt=&quot;리눅스에서 MySQL 설정파일인 mysqld.conf를 수정하여 포트를 변경하는 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SZdb9/btsIFlsNRR5/4ufnoYCueu9GS0n4wK8K6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSZdb9%2FbtsIFlsNRR5%2F4ufnoYCueu9GS0n4wK8K6K%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; alt=&quot;리눅스에서 MySQL 설정파일인 mysqld.conf를 수정하여 포트를 변경하는 예시&quot; loading=&quot;lazy&quot; width=&quot;664&quot; height=&quot;555&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;555&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;리눅스에서 MySQL 설정파일인 mysqld.conf를 수정하여 포트를 변경하는 예시&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;변경한 포트로 적용하려면 MySQL의 서비스를 재시작해야한다.&lt;/p&gt;
&lt;pre id=&quot;code_1721284588413&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo systemctl restart mysql&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포스팅에서는 예시를 위해 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;4306&lt;/span&gt; 포트로 변경하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;338&quot; data-origin-height=&quot;117&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmk5Cn/btsID5qWWx3/kg1wzTK5Seik9bzc6WbpJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmk5Cn/btsID5qWWx3/kg1wzTK5Seik9bzc6WbpJk/img.png&quot; data-alt=&quot;MySQL 쿼리를 이용하여 글로벌 변수인 포트의 번호를 확인하여 포트가 변경되었는지 확인하는 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmk5Cn/btsID5qWWx3/kg1wzTK5Seik9bzc6WbpJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdmk5Cn%2FbtsID5qWWx3%2Fkg1wzTK5Seik9bzc6WbpJk%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; alt=&quot;MySQL 쿼리를 이용하여 글로벌 변수인 포트의 번호를 확인하여 포트가 변경되었는지 확인하는 예시&quot; loading=&quot;lazy&quot; width=&quot;338&quot; height=&quot;117&quot; data-origin-width=&quot;338&quot; data-origin-height=&quot;117&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MySQL 쿼리를 이용하여 글로벌 변수인 포트의 번호를 확인하여 포트가 변경되었는지 확인하는 예시&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;정상적으로 MySQL 데이터베이스의 포트 번호가 변경된 것을 확인할 수 있다.&lt;/p&gt;</description>
      <category>DevOps/Linux</category>
      <category>Linux</category>
      <category>MySQL</category>
      <category>port</category>
      <category>ubuntu</category>
      <category>리눅스</category>
      <category>우분투</category>
      <category>포트</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/923</guid>
      <comments>https://luvris2.tistory.com/923#entry923comment</comments>
      <pubDate>Thu, 18 Jul 2024 16:18:39 +0900</pubDate>
    </item>
    <item>
      <title>오라클 클라우드를 이용한 무료 워드프레스 웹 사이트 제작하기: 블로그 구축하기 A-Z 가이드</title>
      <link>https://luvris2.tistory.com/922</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GFv0G/btsIzVnOuy3/AcN6MdmBtm7gHK9aTjoWqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GFv0G/btsIzVnOuy3/AcN6MdmBtm7gHK9aTjoWqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GFv0G/btsIzVnOuy3/AcN6MdmBtm7gHK9aTjoWqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGFv0G%2FbtsIzVnOuy3%2FAcN6MdmBtm7gHK9aTjoWqk%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; alt=&quot;오라클 클라우드와 워드프레스 이미지&quot; loading=&quot;lazy&quot; width=&quot;374&quot; height=&quot;293&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;293&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;br /&gt;하지만 막상 시작하려면 걱정부터 앞선다.&lt;br /&gt;그 이유는 우선 서버 구축부터 관리, 비용까지 생각하면 막막하기 때문이다.&lt;br /&gt;심지어 나의 경우에는 이미 AWS 1년 프리티어는 사용한 상황이고,&lt;br /&gt;가벼운 토이 프로젝트를 AWS EC2 서비스를 유료로 사용하자니 돈이 부담되기도 하다.&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;서버 구축에 많은 고민을 하던 중, &lt;b&gt;오라클 클라우드&lt;/b&gt;를 알게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 눈길을 사로 잡은 것은 두 가지였다.&lt;br /&gt;첫 번째로는 &quot;&lt;b&gt;평생 무료&lt;/b&gt;&quot;,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째로는 &quot;&lt;b&gt;인스턴스 2개 제공&lt;/b&gt;&quot;.&lt;br /&gt;&lt;br /&gt;&quot;&lt;b&gt;평생 무료인 인스턴스가 무려 두 개나 제공된다고?&lt;/b&gt;&quot;&lt;br /&gt;&lt;br /&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;br /&gt;그래서 이번 글은...&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;오라클 클라우드를 이용하여 웹 서버를 구축&lt;/b&gt;하고,&lt;/li&gt;
&lt;li&gt;&lt;b&gt;워드프레스를 설치하여 블로그 혹은 쇼핑몰 사이트를 만드는 방법&lt;/b&gt;에&lt;/li&gt;
&lt;/ol&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;b&gt;&lt;span style=&quot;color: #ee2323;&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비용은 도메인 비용 외엔 1원도 들지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; &lt;b&gt;&lt;a href=&quot;https://eunbyeol.co.kr/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://eunbyeol.co.kr/&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1721013057980&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;은별 월드&quot; data-og-description=&quot;프로그래밍과 이런 저런 이야기, 배우고 성장하기 위한 작은 공간&quot; data-og-host=&quot;eunbyeol.co.kr&quot; data-og-source-url=&quot;https://eunbyeol.co.kr/&quot; data-og-url=&quot;https://eunbyeol.co.kr/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://eunbyeol.co.kr/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://eunbyeol.co.kr/&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;은별 월드&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;eunbyeol.co.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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;목차&lt;/b&gt;&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/cloud/oci-sign-up-for-oracle-cloud-for-free/&quot;&gt;오라클 클라우드: 무료로 회원 가입하기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/cloud/oci-virtual-machine-instance-how-to-create/&quot;&gt;오라클 클라우드: 무료 인스턴스(VM) 생성하기 (리눅스 컴퓨터 만들기)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/cloud/oci-how-to-use-reserve-public-ip-address/&quot;&gt;오라클 클라우드: 예약된 퍼블릭 IP 사용하기 (서버를 고정 IP로 변경하기)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/cloud/oci-setting-up-security-for-external-access/&quot;&gt;오라클 클라우드: 가상 네트워크(VCN) 보안 수신 규칙 추가하기 (서버의 외부 접속을 위한 보안 설정하기)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/cloud/oci-how-to-connect-a-linux-instance-with-putty/&quot;&gt;오라클 클라우드: 인스턴스를 SSH로 콘솔에 접속하기 (리눅스 컴퓨터에 접속하기)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/os/linux-installing-wordpress-from-linux-to-lemp/&quot;&gt;오라클 클라우드에 워드프레스 설치하기 (워드프레스 사용을 위한 기술 스택 설명 및 설치 방법: LEMP)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/os/linux-installing-mysql-server-on-inux/&quot;&gt;MySQL 설정 (워드프레스의 사용자와 글 등의 데이터를 저장할 데이터베이스 설치하기)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/os/linux-install-php-and-required-modules-on-linux-and-configure-php-fpm/&quot;&gt;PHP 설정 (워드프레스 사용할 수 있도록 해주는 프로그래밍 언어 설치하기)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/os/linux-install-nginx-on-linux-and-build-web-server/&quot;&gt;Nginx 설정 (워드프레스를 운영할 수 있게 해주는 웹 서버 설치하기)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/os/linux-how-to-access-to-web-erver-from-the-external/&quot;&gt;오라클 클라우드 인스턴스로 구축한 웹 서버를 외부에서 접속하기 (웹 서버 접속 테스트하기)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog/wordpress-how-connect-gabia-domain-to-access-homepage-built-with-wordpress/&quot;&gt;내가 산 도메인으로 워드프레스 사이트 연결 및 접속하기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eunbyeol.co.kr/blog-how-to-apply-free-ssl-certificate-to-domain/&quot;&gt;도메인에 SSL 적용하여 HTTPS로 접속하기&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>일상/블로그 이야기</category>
      <category>구축</category>
      <category>설치형</category>
      <category>오라클 클라우드</category>
      <category>워드프레스</category>
      <category>웹 서버</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/922</guid>
      <comments>https://luvris2.tistory.com/922#entry922comment</comments>
      <pubDate>Mon, 15 Jul 2024 12:50:15 +0900</pubDate>
    </item>
    <item>
      <title>nginx - 윈도우용 nginx 설치 및 실행 방법, 명령어 사용법</title>
      <link>https://luvris2.tistory.com/921</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Nginx란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Nginx는 엔진엑스로 발음하며 경량, 고성능, 안정적으로 유명한 웹 서버이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 사이트, 웹 애플리케이션, API 등 여러 방면에 사용된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;웹 서버&lt;/b&gt; &lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정적 파일 서비스: HTML, CSS, JavaScript 등의 파일을 클라이언트에 제공&lt;/li&gt;
&lt;li&gt;높은 동시성 처리: 많은 연결을 효율적으로 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;리버스&amp;nbsp;프록시&lt;/b&gt; &lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;백엔드 서버 앞에서 요청을 분배하고 캐싱&lt;/li&gt;
&lt;li&gt;로드 밸런싱: 여러 서버에 트래픽 분산&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;로드 밸런서&lt;/b&gt; &lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 서버 간 부하를 분산하여 시스템의 안정성 높임&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;HTTP&amp;nbsp;캐시&lt;/b&gt; &lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자주 요청되는 콘텐츠를 캐싱하여 응답 시간 단축&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보안&amp;nbsp;기능&lt;/b&gt; &lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SSL/TLS 지원: HTTPS 연결 처리&lt;/li&gt;
&lt;li&gt;DDoS 방어: 트래픽 제한 등의 기능 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;가벼운&amp;nbsp;리소스&amp;nbsp;사용&lt;/b&gt; &lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;적은 메모리와 CPU 사용으로 높은 성능 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모듈식&amp;nbsp;구조&lt;/b&gt; &lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다양한 모듈을 통해 기능 확장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Nginx는 이러한 특징으로 인해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 서비스, 마이크로서비스 아키텍처, CDN 등 다양한 환경에서 널리 사용되고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 Spring Boot 애플리케이션의 프론트엔드 서버로 자주 활용되어,&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;윈도우 Nginx 설치하기&lt;/b&gt;&lt;/h2&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;검색 엔진에서 nginx를 검색하여 해당 사이트에 들어가서 다운로드 받을 수 있다.&lt;/span&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; text-align: start;&quot;&gt;☞&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;color: #0070d1; text-align: start;&quot; href=&quot;https://nginx.org/en/download.html&quot;&gt;nginx 다운로드 페이지로 이동하기&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;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;귀찮다면 아래의 링크를 눌러 다운로드를 진행하자.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;☞ &lt;a href=&quot;https://nginx.org/download/nginx-1.26.1.zip&quot;&gt;윈도우용 nginx 1.26.1 (stable version) 다운로드 하기&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;다운로드가 끝나면 압축을 풀고, 놓고 싶은 위치에 저장해두면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장해두는 위치는 Nginx의 root 경로가 되기 때문에 가능하면 삭제가 되지 않을 위치에 두는 것이 좋다.&lt;/p&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;C드라이브에 dev라는 폴더를 만들어서 저장하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 폴더에는 오라클 클라이언트나 nginx 등 여러가지 개발 관련 프로그램을 저장해두고 사용하고 있다.&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;윈도우에서 Nginx 실행하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우에서 nginx를 제어하는 명령어이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령 프롬프트에서 nginx 명령어를 사용하여 NGINX를 시작, 중지 및 제어할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;NGINX 시작&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1720671294734&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nginx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;NGINX 중지&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1720671301824&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nginx -s stop&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;NGINX 다시 로드&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1720671309902&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nginx -s reload&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;NGINX 구성 파일 테스트&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1720671317133&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nginx -t&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DevOps/Server</category>
      <category>nginx</category>
      <category>nginx란</category>
      <category>명령어</category>
      <category>사용법</category>
      <category>설치</category>
      <category>실행</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/921</guid>
      <comments>https://luvris2.tistory.com/921#entry921comment</comments>
      <pubDate>Fri, 12 Jul 2024 00:05:09 +0900</pubDate>
    </item>
    <item>
      <title>Spring Boot - IntelliJ 없이 스프링 부트 프로젝트 실행하기 (JAR 파일 생성부터 빌드, 배포, 실행까지)</title>
      <link>https://luvris2.tistory.com/920</link>
      <description>&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;/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;IntelliJ 혹은 STS IDE 툴 없이 프로젝트를 실행하면 훨씬 가벼울텐데...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;&lt;b&gt;더 가볍고 효율적인 방법으로 스프링 부트 프로젝트를 실행할 수는 없을까?&lt;/b&gt;&quot;&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;이번 포스팅에서는 IDE 툴 없이 프로젝트를 실행할 수 있도록 JAR 파일로 만들어서 빌드 및 배포하는 방법을 다룬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 JAR 파일을 사용해야 하는지, 어떻게 빌드하고 배포하는지에 대해서도 알아보자.&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;스프링부트 프로젝트는 왜 JAR파일로 배포해할까?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JAR(&lt;b&gt;J&lt;/b&gt;ava &lt;b&gt;AR&lt;/b&gt;chive) 파일은 자바 애플리케이션을 패키징하는 표준 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 특성과 운영 환경에 따라 JAR 또는 WAR 중 선택할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;JAR vs WAR 차이점은?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 JAR와 WAR의 차이부터 간단히 알아보자.&lt;/p&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;JAR 파일&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;WAR 파일&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;/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;스프링 부트 문서에도 JAR 형식을 기준으로 기술되어 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 스프링 부트 프로젝트는 JAR 형식을 권장한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.spring.io/spring-boot/specification/executable-jar/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[참고] 스프링 부트 문서 - The Executable Jar Format&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;JAR 파일을 권장하는 이유&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;물론, 스프링 부트는 무조건 JAR 파일로 해야한다는 강제성은 없다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 JAR 파일을 이용할 경우 다음과 같은 이점을 가질 수 있다.&lt;/p&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스프링 부트와 같이 내장 서버를 이용하여 독립적으로 실행할 수 있는 웹 애플리케이션이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;효율성&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;WAR 파일에 비해 JAR 파일이 더 경량화가 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;편의성&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필요한 모든 것을 하나의 파일에 담아 관리가 편리하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배포 용이성&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JAR 파일 하나로 모든 필요한 라이브러리와 코드를 포함하며 간단하게 배포 할 수 있다.&lt;/li&gt;
&lt;li&gt;하지만 상황에 따라 규모가 커질 경우에는 WAR 형식이 더 적합할 수 있다.&lt;/li&gt;
&lt;/ul&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;IDE 개발 툴 없이 스프링 부트의 프로젝트를 실행하려면 위에서 언급한 JAR 혹은 WAR 파일을 이용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 내용은 아래의 기준으로 설명하겠다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Windows 운영체제 사용&lt;/li&gt;
&lt;li&gt;JAR 파일로 패키징&lt;/li&gt;
&lt;li&gt;Gradle 사용&lt;/li&gt;
&lt;/ul&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;gradlew를 사용한 JAR 파일 만드는 방법 (빌드 및 배포 파일 만들기)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 명령 프롬프트를 통해 프로젝트 루트 디렉토리로 이동한다.&lt;/p&gt;
&lt;pre id=&quot;code_1720664718017&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cd 프로젝트 디렉토리

cd C:\WorkSpace\SpringBoot\test-spring-boot-with-kotlin&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;2. 아래의 명령어를 이용하여 그레이들을 통해 빌드를 진행한다.&lt;/p&gt;
&lt;pre id=&quot;code_1720664781842&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gradlew build&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;BUILD SUCCESSFUL&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;504&quot; data-origin-height=&quot;67&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pGv9L/btsIuRfi09L/zkFCoSi1gEv5DxDsE4mfLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pGv9L/btsIuRfi09L/zkFCoSi1gEv5DxDsE4mfLk/img.png&quot; data-alt=&quot;그레이들을 통한 배포 파일 생성 완료 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pGv9L/btsIuRfi09L/zkFCoSi1gEv5DxDsE4mfLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpGv9L%2FbtsIuRfi09L%2FzkFCoSi1gEv5DxDsE4mfLk%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; alt=&quot;그레이들을 통한 배포 파일 생성 완료 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;504&quot; height=&quot;67&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;67&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그레이들을 통한 배포 파일 생성 완료 예시 화면&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;배포 파일(JAR)는 프로젝트 디렉토리에서 &lt;b&gt;&quot;build - libs&quot;&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;490&quot; data-origin-height=&quot;182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBFD2C/btsItJvJ6dg/G6uHGb8PtjR2qr83Wj8ErK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBFD2C/btsItJvJ6dg/G6uHGb8PtjR2qr83Wj8ErK/img.png&quot; data-alt=&quot;jar 파일 생성 확인 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBFD2C/btsItJvJ6dg/G6uHGb8PtjR2qr83Wj8ErK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBFD2C%2FbtsItJvJ6dg%2FG6uHGb8PtjR2qr83Wj8ErK%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; alt=&quot;jar 파일 생성 확인 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;490&quot; height=&quot;182&quot; data-origin-width=&quot;490&quot; data-origin-height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;jar 파일 생성 확인 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&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;JAR 파일 실행하는 방법 (배포 파일 실행하기)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JAR 파일이 위치한 경로로 이동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신이 편한 위치에 파일을 이동시켜도 되지만 포스팅에서는 JAR 파일이 빌드된 위치에서 실행해보겠다.&lt;/p&gt;
&lt;pre id=&quot;code_1720665144306&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cd 프로젝트 디렉토리\build\libs\

cd C:\WorkSpace\SpringBoot\test-spring-boot-with-kotlin\build\libs\&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;java를 통해 jar 파일을 실행한다.&lt;/p&gt;
&lt;pre id=&quot;code_1720665195820&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# java -jar 배포파일명

java -jar devbabys-0.0.1-SNAPSHOT.jar&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1021&quot; data-origin-height=&quot;369&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5kCpe/btsIvuKx2Cg/aHbJoqTmVk0wK8LwQL03jk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5kCpe/btsIvuKx2Cg/aHbJoqTmVk0wK8LwQL03jk/img.png&quot; data-alt=&quot;JAR 파일을 이용하여 스프링 부트 프로젝트를 실행한 화면 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5kCpe/btsIvuKx2Cg/aHbJoqTmVk0wK8LwQL03jk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5kCpe%2FbtsIvuKx2Cg%2FaHbJoqTmVk0wK8LwQL03jk%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; alt=&quot;JAR 파일을 이용하여 스프링 부트 프로젝트를 실행한 화면 예시&quot; loading=&quot;lazy&quot; width=&quot;1021&quot; height=&quot;369&quot; data-origin-width=&quot;1021&quot; data-origin-height=&quot;369&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;JAR 파일을 이용하여 스프링 부트 프로젝트를 실행한 화면 예시&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;위와 같이 하면, IDE 툴에서의 프로젝트 실행 없이 JAR 파일로만 프로젝트를 실행할 수 있다.&lt;/p&gt;</description>
      <category>Back End/Spring Boot</category>
      <category>ide 없이 실행</category>
      <category>JAR</category>
      <category>springboot</category>
      <category>war</category>
      <category>배포</category>
      <category>빌드</category>
      <category>스프링부트</category>
      <category>실행</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/920</guid>
      <comments>https://luvris2.tistory.com/920#entry920comment</comments>
      <pubDate>Thu, 11 Jul 2024 11:37:30 +0900</pubDate>
    </item>
    <item>
      <title>블로그 포스팅 자동 생성기, 글 작성 도우미로 보다 쉽게 글을 작성해보자!</title>
      <link>https://luvris2.tistory.com/919</link>
      <description>&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 말을 해야 할지, 개요와 서론을 어떻게 구성해야 할지, 내용은 어떻게 친근하게 다가가야할지 등으로요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매번 글쓰기가 너무 익숙치가 않아서 이 참에 구글 Gemini API를 이용하여 포스팅 작성에 도움을 받고자 만들었습니다.&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;관련 사이트&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 생성기를 이용하여 글을 작성한 서브 블로그입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://koongkumi.tistory.com/&quot;&gt;티스토리 블로그 - 궁그미의 궁금증 해결(https://koongkumi.tistory.com/)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1720511300023&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;궁그미의 궁금증 해결&quot; data-og-description=&quot;궁금한 것들을 알아보고 파헤치는 궁그미입니다 궁금한 것이 있으면 댓글로 달아주세요!&quot; data-og-host=&quot;koongkumi.tistory.com&quot; data-og-source-url=&quot;https://koongkumi.tistory.com/&quot; data-og-url=&quot;https://koongkumi.tistory.com&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/KQqyV/hyWztwE5V5/rSNko3CG9Wktk58sgpzP9k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/xhCyz/hyWzBhaawR/PsywKqSUwpTRGUZ5jhDfjK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://koongkumi.tistory.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://koongkumi.tistory.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/KQqyV/hyWztwE5V5/rSNko3CG9Wktk58sgpzP9k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/xhCyz/hyWzBhaawR/PsywKqSUwpTRGUZ5jhDfjK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&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;궁그미의 궁금증 해결&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;koongkumi.tistory.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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;사용 스킬&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Language &lt;/b&gt;: Python&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Framework&lt;/b&gt; : Flask&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Web Crawler&lt;/b&gt; : Selenium&lt;/li&gt;
&lt;li&gt;&lt;b&gt;API&lt;/b&gt; : Google Gemini API&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Hot Keyword Reference&lt;/b&gt; : Naver / Google&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Host&lt;/b&gt; : &lt;a href=&quot;https://post.eunbyeol.co.kr/&quot;&gt;https://post.eunbyeol.co.kr/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;2024-06-25&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Gemini API 연동&lt;/li&gt;
&lt;li&gt;프롬프트 엔지니어링&lt;/li&gt;
&lt;li&gt;페이지 구축&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;2024-06-26&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;추천 키워드 시스템 추가 (주제별, 성별/연령별)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;2024-06-28&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;추천 키워드 매일 자동 업데이트 기능 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;2024-07-01&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;인기 키워드 페이지 UX 개선(마우스 오버된 키워드 표시, 클릭 시 입력 창에 키워드 자동 입력)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;2024-07-02&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;추천 키워드 카테고리 추가 (일별)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;2024-09-11&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;임시 도메인에서 서브 도메인으로 이전 &lt;a href=&quot;http://babychat.xyz/blog&quot;&gt;https://babychat.xyz/post&lt;/a&gt; &amp;gt; &lt;a href=&quot;https://post.eunbyeol.co.kr/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://post.eunbyeol.co.kr/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;/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;497&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cro1w2/btsIs0JS7ZS/n87qeoNKlF0GB7qdoUWzpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cro1w2/btsIs0JS7ZS/n87qeoNKlF0GB7qdoUWzpK/img.png&quot; data-alt=&quot;블로그 포스팅 생성기 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cro1w2/btsIs0JS7ZS/n87qeoNKlF0GB7qdoUWzpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcro1w2%2FbtsIs0JS7ZS%2Fn87qeoNKlF0GB7qdoUWzpK%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; alt=&quot;블로그 포스팅 생성기 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;497&quot; height=&quot;382&quot; data-origin-width=&quot;497&quot; data-origin-height=&quot;382&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;블로그 포스팅 생성기 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 블로그 포스팅 내용 생성하기&lt;/b&gt;&lt;/h3&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;(2)&lt;/b&gt; 포스팅 생성 버튼을 누르고 내용이 생성될 때 까지 기다립니다.&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;&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;&lt;b&gt;(1)&lt;/b&gt; 인기 키워드 보기 버튼을 누릅니다.&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;&lt;b&gt;(3)&lt;/b&gt; 인기 키워드를 확인합니다.&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;850&quot; data-origin-height=&quot;775&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLP1pf/btsIrQhbu7Z/KzH6tDkbBmuRWPlfPzKkQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLP1pf/btsIrQhbu7Z/KzH6tDkbBmuRWPlfPzKkQ1/img.png&quot; data-alt=&quot;인기 키워드 페이지 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLP1pf/btsIrQhbu7Z/KzH6tDkbBmuRWPlfPzKkQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLP1pf%2FbtsIrQhbu7Z%2FKzH6tDkbBmuRWPlfPzKkQ1%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; alt=&quot;인기 키워드 페이지 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;850&quot; height=&quot;775&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;775&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인기 키워드 페이지 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&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;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자세한 것은 아래의 &lt;b&gt;예시&lt;/b&gt; 챕터 참조&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;874&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biumW0/btsIr9gufLy/pWZiVcIZsLOT2pfh6EpZK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biumW0/btsIr9gufLy/pWZiVcIZsLOT2pfh6EpZK1/img.png&quot; data-alt=&quot;블로그 자동 포스팅 생성기로 생성된 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biumW0/btsIr9gufLy/pWZiVcIZsLOT2pfh6EpZK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiumW0%2FbtsIr9gufLy%2FpWZiVcIZsLOT2pfh6EpZK1%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; alt=&quot;블로그 자동 포스팅 생성기로 생성된 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;1015&quot; height=&quot;874&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;874&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;블로그 자동 포스팅 생성기로 생성된 예시 화면&lt;/figcaption&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;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;a href=&quot;https://post.eunbyeol.co.kr/&quot;&gt;https://post.eunbyeol.co.kr/&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1726064046049&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;Blog Posting Writer&quot; data-og-description=&quot;&quot; data-og-host=&quot;post.eunbyeol.co.kr&quot; data-og-source-url=&quot;https://post.eunbyeol.co.kr/&quot; data-og-url=&quot;https://post.eunbyeol.co.kr/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://post.eunbyeol.co.kr/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://post.eunbyeol.co.kr/&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;Blog Posting Writer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;post.eunbyeol.co.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;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;* 현재 무료 API를 사용하기 때문에 일일 일정량 이상을 사용하면 사용이 제한되는 단점이 있습니다.&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;&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;* 제작자도 블로그 작성에 참고, 도움이 될 수 있도록 생성된 포스팅에 대한 키워드는 기록됩니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&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;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;블로그 포스팅? 이제 AI가 대신 작성해 드립니다!&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;매일 글감 찾고, 자료 조사하고, 글 쓰느라 머리 아프시죠?&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;  블로그 운영, 생각보다 손이 많이 가는 작업인데요, 이젠&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;블로그 포스팅 자동 생성기&lt;/b&gt;가 그 고민을 덜어드립니다!&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(이미지: 바쁜 현대인이 노트북 앞에서 머리를 싸매고 있는 모습)&lt;/b&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;블로그 포스팅 자동 생성기, 넌 누구냐!  &lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;블로그 포스팅 자동 생성기는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;인공지능 기술을 활용해 여러분이 원하는 주제의 블로그 글을 뚝딱 완성해주는 서비스&lt;/b&gt;입니다. 더 이상 키워드 조사, 자료 수집, 문장 구성에 시간을 쏟을 필요 없이, 여러분의 소중한 시간을 아낄 수 있습니다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;나만을 위한 블로그 포스팅, 이렇게 만들어 드립니다! ✍️&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;간단한 입력:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;블로그 글에 담고 싶은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;주제 또는 키워드&lt;/b&gt;를 입력해주세요. 예를 들어, &quot;반려동물 산책 꿀팁&quot; 또는 &quot;최신 스마트폰 리뷰&quot; 와 같이 원하는 주제를 자유롭게 입력하면 됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AI 마법 발동:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;인공지능이 여러분이 입력한 주제를 분석하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;흥미로운 제목과 내용으로 구성된 블로그 포스팅 초안&lt;/b&gt;을 작성합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;나만의 글 완성:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;AI가 작성한 초안을 바탕으로 자유롭게 내용을 추가하거나 수정하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;나만의 개성이 담긴 블로그 포스팅&lt;/b&gt;을 완성할 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(이미지: 사람이 블로그 포스팅 자동 생성기에 키워드를 입력하면, AI가 글을 작성하는 모습)&lt;/b&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;매일매일 새로운 아이디어, 인기 키워드 추천!  &lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&quot;어떤 주제로 글을 써야 할지 모르겠어요&amp;hellip;&quot;  고민하지 마세요! 블로그 포스팅 자동 생성기는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;매일 오전 6시, 사용자들이 가장 많이 찾는 인기 키워드를 업데이트&lt;/b&gt;하여 새로운 글감을 제시합니다. 트렌드에 맞는 블로그 운영, 이제 어렵지 않습니다!&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(이미지: &quot;오늘의 인기 키워드&quot; 라는 제목으로 여러 키워드들이 화면에 나타나는 모습)&lt;/b&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;블로그 포스팅 자동 생성기, 이런 분들에게 추천합니다!  &lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;바쁜 일상 속 블로그 운영에 어려움을 느끼는 분들&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;글쓰기에 자신이 없어 시작하기 망설여지는 분들&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;트렌드에 맞는 새로운 글감을 찾고 있는 분들&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;블로그 포스팅 자동 생성기와 함께라면 누구나 쉽고 빠르게, 퀄리티 높은 블로그 포스팅을 완성할 수 있습니다. 지금 바로 경험해 보세요!  &lt;/p&gt;</description>
      <category>포트폴리오/블로그 포스팅 자동 생성기</category>
      <category>AI</category>
      <category>Open API</category>
      <category>블로그</category>
      <category>웹 크롤링</category>
      <category>자동 생성기</category>
      <category>작성 도우미</category>
      <category>작업 스케줄러</category>
      <category>포스팅</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/919</guid>
      <comments>https://luvris2.tistory.com/919#entry919comment</comments>
      <pubDate>Tue, 9 Jul 2024 16:50:52 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL - SSMS에서 쿼리로 데이터베이스 용량 확인하는 방법</title>
      <link>https://luvris2.tistory.com/918</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;특정 데이터베이스 디스크 용량 확인 쿼리&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터베이스 행 데이터 확인 쿼리&lt;/h3&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;color: #ef5369; background-color: #dddddd;&quot;&gt;DB_ID()&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;b&gt;메가 바이트 단위로 데이터베이스의 용량을 조회하는 쿼리&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1720415856852&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    name AS logical_name,
    size * 8.0 / 1024 AS size_in_mb
FROM 
    sys.master_files
WHERE 
    database_id = DB_ID('데이터베이스_이름');&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;용량이 클 경우, GB(기가바이트) 단위로 조회하고 싶으면 1024를 또 나누면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;✨ &lt;b&gt;기가&lt;/b&gt; &lt;/span&gt;&lt;b&gt;바이트 단위로 데이터베이스의 용량을 조회하는 쿼리&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1720416738396&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    name AS logical_name,
    size * 8.0 / 1024 / 1024 AS size_in_gb
FROM 
    sys.master_files
WHERE 
    database_id = DB_ID('데이터베이스_이름');&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 접속중인 데이터베이스의 로그 데이터까지 포함한 데이터베이스의 총 용량을 확인하는 쿼리이다.&lt;/p&gt;
&lt;pre id=&quot;code_1720416666591&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    DB_NAME() AS DatabaseName,
    SUM(CASE WHEN type = 0 THEN size END) * 8 / 1024 AS DataFileSizeMB,
    SUM(CASE WHEN type = 1 THEN size END) * 8 / 1024 AS LogFileSizeMB
FROM sys.database_files&lt;/code&gt;&lt;/pre&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;/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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테이블에 할당된 총 공간&lt;/li&gt;
&lt;li&gt;실제 데이터가 저장된 공간&lt;/li&gt;
&lt;li&gt;할당되었지만 현재 사용되지 않는 공간&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1720417164921&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    t.name AS table_name,
    SUM(p.rows) AS row_count,
    SUM(a.total_pages) * 8 / 1024 AS total_space_mb,
    SUM(a.used_pages) * 8 / 1024 AS used_space_mb,
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 / 1024 AS unused_space_mb
FROM 
    sys.tables t
INNER JOIN 
    sys.indexes i ON t.object_id = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.object_id AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
GROUP BY 
    t.name
ORDER BY 
    total_space_mb DESC;&lt;/code&gt;&lt;/pre&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;용량 확인 쿼리에서 8 혹은 8.0을 곱하는 이유는?&lt;/b&gt;&lt;/h2&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;SQL Server에서 각 페이지는 8KB를 차지한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 페이지 수를 실제 크기로 변환하려면 8KB를 곱해야 한다.&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;메가 바이트, 기가 바이트를 구하려면 1024를 나누는 이유는?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터는 2진수를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 우리에게 익숙한 1000 = 1k 와 같이,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터에서는 2진수를 이용하여 가장 근사한 숫자인 1024를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 1024KB는 1MB이기 때문에 메가 바이트, 기가 바이트를 구하려면 1024를 나누는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일상 생활에서 우리가 사용하는 단위는 1000을 단위로 하기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 저장 매체의 디스크가 1테라라고 해도 실제 용량은 1테라가 아닌 것을 많이들 경험해 봤을 것이다.&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;참고&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-catalog-views/sys-master-files-transact-sql?view=sql-server-ver16&quot;&gt;마이크로소프트 공식 사이트 - SQL Server 2022 - sys.master_files(Transact-SQL)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Database/MS-SQL</category>
      <category>MSSQL</category>
      <category>데이터베이스 용량</category>
      <category>디비 용량 확인</category>
      <category>디스크 용량</category>
      <category>테이블 용량</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/918</guid>
      <comments>https://luvris2.tistory.com/918#entry918comment</comments>
      <pubDate>Mon, 8 Jul 2024 14:58:39 +0900</pubDate>
    </item>
    <item>
      <title>Excel - 엑셀에서 글자 가운데 선 줄긋기 (취소선 만들기)</title>
      <link>https://luvris2.tistory.com/917</link>
      <description>&lt;blockquote style=&quot;color: #000000; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p style=&quot;color: #000000; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아니, 자료 정리 다 했는데 뭘 수정해야 하지?&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;지우기엔 조금 아깝고...&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;엑셀에서 깔끔하게 취소선 긋는 방법 없을까?&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;엑셀 작업하다 보면 이런 생각, 한 번쯤 해보았을 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; 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;엑셀 가운데에 선으로 줄긋기 방법&amp;nbsp;&lt;/b&gt;&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1) 셀 서식 메뉴를 이용한 취소선 긋기 및 추가 스타일 적용&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 취소선을 적용할 &lt;b&gt;셀이나 글자를 선택&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;&lt;b&gt;마우스 오른쪽 버튼을 클릭&lt;/b&gt;하여 &quot;&lt;b&gt;셀 서식&lt;/b&gt;&quot; 메뉴를 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;513&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GWsuu/btsIoR09GNu/X8G7Z12SaC4Sn1lznRNux0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GWsuu/btsIoR09GNu/X8G7Z12SaC4Sn1lznRNux0/img.png&quot; data-alt=&quot;셀을 지정하여 셀 서식을 통해 취소선을 만드는 과정1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GWsuu/btsIoR09GNu/X8G7Z12SaC4Sn1lznRNux0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGWsuu%2FbtsIoR09GNu%2FX8G7Z12SaC4Sn1lznRNux0%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; alt=&quot;셀을 지정하여 셀 서식을 통해 취소선을 만드는 과정1&quot; loading=&quot;lazy&quot; width=&quot;513&quot; height=&quot;632&quot; data-origin-width=&quot;513&quot; data-origin-height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;셀을 지정하여 셀 서식을 통해 취소선을 만드는 과정1&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;3. &lt;b&gt;셀 서식 창&lt;/b&gt;에서 &quot;&lt;b&gt;글꼴&lt;/b&gt;&quot; 탭으로 이동하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;효과 옵션에서 &quot;&lt;b&gt;취소선&lt;/b&gt;&quot; 항목을 &lt;b&gt;체크&lt;/b&gt;하고 &lt;b&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;545&quot; data-origin-height=&quot;556&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7d813/btsIo1Jtxww/NcjA8FB9o5FsusKLGKj6ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7d813/btsIo1Jtxww/NcjA8FB9o5FsusKLGKj6ak/img.png&quot; data-alt=&quot;셀을 지정하여 셀 서식을 통해 취소선을 만드는 과정2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7d813/btsIo1Jtxww/NcjA8FB9o5FsusKLGKj6ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7d813%2FbtsIo1Jtxww%2FNcjA8FB9o5FsusKLGKj6ak%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; alt=&quot;셀을 지정하여 셀 서식을 통해 취소선을 만드는 과정2&quot; loading=&quot;lazy&quot; width=&quot;545&quot; height=&quot;556&quot; data-origin-width=&quot;545&quot; data-origin-height=&quot;556&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;셀을 지정하여 셀 서식을 통해 취소선을 만드는 과정2&lt;/figcaption&gt;
&lt;/figure&gt;
&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;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;1. 취소선을 적용할&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;2. 키보드에서 &lt;b&gt;Ctrl + 5 &lt;/b&gt;(컨트롤+5) 키를 누른다.&lt;/p&gt;
&lt;p data-ke-size=&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 alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;53&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciT9wg/btsIorokS0K/fC5IkL6sNankj3UvkCLM1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciT9wg/btsIorokS0K/fC5IkL6sNankj3UvkCLM1k/img.png&quot; data-alt=&quot;취소선이 그어진 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciT9wg/btsIorokS0K/fC5IkL6sNankj3UvkCLM1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciT9wg%2FbtsIorokS0K%2FfC5IkL6sNankj3UvkCLM1k%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; alt=&quot;취소선이 그어진 화면&quot; loading=&quot;lazy&quot; width=&quot;301&quot; height=&quot;53&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;53&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;취소선이 그어진 화면&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;자주 사용하는 기능들은 단축키를 활용하면 시간을 크게 절약할 수 있으니까&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신이 자주 쓸 것 같은 단축키를 꼭 외워두자!&lt;/p&gt;</description>
      <category>Office/Excel</category>
      <category>Excel</category>
      <category>가운데 선 긋기</category>
      <category>엑셀</category>
      <category>취소선 긋기</category>
      <category>취소선 긋는 방법</category>
      <category>취소선 적용하기</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/917</guid>
      <comments>https://luvris2.tistory.com/917#entry917comment</comments>
      <pubDate>Fri, 5 Jul 2024 17:39:49 +0900</pubDate>
    </item>
    <item>
      <title>nginx - 윈도우에서 무료 SSL 발급 및 적용하기 (Let's Encript ACME For Windows)</title>
      <link>https://luvris2.tistory.com/916</link>
      <description>&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;프론트엔드의 서버가 API 서버의 http 문제로 인해 API 통신이 되질 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어차피 언젠가는 해야될 SSL 인증, 이번 기회에 해보자는 마음에 이 글을 작성하려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 NginX를 이용한 웹 서버에 SSL 인증서를 적용하는 방법을 다룬다.&lt;/p&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/914&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;가비아 - 서브 도메인 만들기 (DNS 설정하기, A 레코드 사용)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/915&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;nginx - 서브 도메인 포트 라우팅 가이드 (For Windows)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;SSL 인증서가 왜 필요할까?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;SSL 인증서는 웹사이트와 사용자 사이에 오가는 정보를 암호화하여 안전하게 보호하는 역할을 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;쉽게 말해, 웹사이트와 사용자 사이에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;보안 터널&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&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; text-align: start;&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; text-align: start;&quot;&gt;또한, SSL 인증서를 적용하면 아래와 같은 이점이 발생한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;방문자 입장에서는 SSL 인증서가 없는 웹 사이트는 브라우저 자체에서 경고 문구가 뜨기 때문에 불안할 수 있다. 보안이 강화된 웹사이트는 신뢰감을 줄 수 있다.&lt;/li&gt;
&lt;li&gt;구글을 비롯한 검색 엔진들은 https 프로토콜을 사용하는 웹사이트를 더 높이 평가하기 때문에 SEO(검색 엔진 최적화) 효과를 누릴 수 있다.&lt;/li&gt;
&lt;li&gt;SSL 인증서는 웹사이트 해킹 및 개인정보 유출을 예방하는 가장 기본적인 방법으로 사용된다. 때문에 웹 보안의 가장 첫 단계라고도 볼 수 있다.&lt;/li&gt;
&lt;/ul&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;SSL 인증 기관으로 Let's Encript를 선택한 이유&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;Let's Encrypt는 비영리 기관에서 운영되기 때문에 누구나&lt;span&gt;&amp;nbsp;&lt;/span&gt;무료로 SSL 인증서를 발급받을 수 있다.&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;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;&lt;span&gt;Let's Encript기관은 ACME 프로토콜을 사용하여&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;SSL 인증서의 유무 및 갱신 시기를 확인하고 자동으로 갱신하도록 해주고 있다.&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;b&gt; ✅ 여기서 ACME 프로토콜은 뭘까?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;ACME (Automated Certificate Management Environment)의 준말이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&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: #222222; text-align: start;&quot;&gt;ACME 프로토콜은 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;인증서 자동화 솔루션으로 널리 사용되고 있다. (출처 SSL.com)&lt;/span&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;SSL 인증서 발급을 위한 도구 - Certbot&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;윈도우즈는 2024년 2월부터 지원을 중단&lt;/b&gt;&lt;/u&gt;했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색하면 윈도우에서 Certbot을 사용하여 SSL을 발급받는 것이 많이 나오는데...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금으로서는 사용이 어렵다고 보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Certbot 개발자분의 말에 의하면 윈도우용은 지금도 사용은 가능하다고는 하는데,&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;SSL 인증서 발급을 위한 도구 - win-acme&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우용으로 사용하기 위해서 win-acme툴을 선택하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;종류가 여러가지가 있던데 내 눈에는 딱 이게 눈에 들어오더라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 종류를 사용해볼 의향이 있다면 letsencript 홈페이지에서 종류를 확인해보고 선택해서 진행해도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 이 글은 win-acme에 대한 설명만을 담고있기 때문에 다른 종류의 SSL 설치 방법은 이 글 내용과 해당하지 않는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;종류 보기 : &lt;a href=&quot;https://letsencrypt.org/docs/client-options/&quot;&gt;https://letsencrypt.org/docs/client-options/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;윈도우즈용 ACME 다운로드&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;win-acme 사이트로 접속해서 다운로드를 받을 수 있다.&lt;/p&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://www.win-acme.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;win-acme 페이지 바로가기&lt;/a&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Download - 버전 (recommended) 선택&lt;/li&gt;
&lt;/ul&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;SSL 인증서 발급받기&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p style=&quot;color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이 글은 윈도우 운영 체제를 기반으로 하였다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;또한 사용되는 툴은 win-acme를 사용하여 진행한다.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령 프롬프트(CMD)를 열어 win-acme를 다운로드 받은 폴더로 경로를 이동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;wacs.exe 파일을 열면 정해진 순서에 맞게 진행하는 방법과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어를 통해 SSL 인증서를 발급받는 방법이 있다.&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) wacs.exe 파일을 실행하여 절차에 맞게 SSL 인증서를 발급받는 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;win-acme 2.2.9.1701 버전을 기준으로 차례대로 아래와 같이 입력한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;M&lt;/b&gt;:&amp;nbsp;Create&amp;nbsp;certificate&amp;nbsp;(full&amp;nbsp;options)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;2&lt;/b&gt;:&amp;nbsp;Manual&amp;nbsp;input&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Host&lt;/b&gt;: SSL 인증서를 적용할 도메인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;1&lt;/b&gt;:&amp;nbsp;Separate&amp;nbsp;certificate&amp;nbsp;for&amp;nbsp;each&amp;nbsp;domain&amp;nbsp;(e.g.&amp;nbsp;*.example.com)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;1&lt;/b&gt;:&amp;nbsp;[http]&amp;nbsp;Save&amp;nbsp;verification&amp;nbsp;files&amp;nbsp;on&amp;nbsp;(network)&amp;nbsp;path&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Path&lt;/b&gt;: 웹 루트 디렉토리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;N&lt;/b&gt;: Copy&amp;nbsp;default&amp;nbsp;web.config&amp;nbsp;before&amp;nbsp;validation?&amp;nbsp;(y/n*)&amp;nbsp;-&amp;nbsp;no&lt;/li&gt;
&lt;li&gt;&lt;b&gt;2&lt;/b&gt;: RSA key&lt;/li&gt;
&lt;li&gt;&lt;b&gt;2&lt;/b&gt;: PEM encoded files (Apache, nginx, etc.)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;1&lt;/b&gt;:&amp;nbsp;None&lt;/li&gt;
&lt;li&gt;&lt;b&gt;5&lt;/b&gt;:&amp;nbsp;No&amp;nbsp;(additional)&amp;nbsp;store&amp;nbsp;steps&lt;/li&gt;
&lt;li&gt;&lt;b&gt;3&lt;/b&gt;:&amp;nbsp;No&amp;nbsp;(additional)&amp;nbsp;installation&amp;nbsp;steps&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 뜨면 정상적으로 ssl 인증서 파일(pem)이 생성된 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1026&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l98dt/btsImHRS0ZH/occ0bZByYzwPMSp0fKPtG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l98dt/btsImHRS0ZH/occ0bZByYzwPMSp0fKPtG1/img.png&quot; data-alt=&quot;wacs.exe 파일을 실행하여 절차에 맞게 SSL 인증서를 발급받는 결과 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l98dt/btsImHRS0ZH/occ0bZByYzwPMSp0fKPtG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl98dt%2FbtsImHRS0ZH%2Focc0bZByYzwPMSp0fKPtG1%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; alt=&quot;wacs.exe 파일을 실행하여 절차에 맞게 SSL 인증서를 발급받는 결과 화면&quot; loading=&quot;lazy&quot; width=&quot;1026&quot; height=&quot;216&quot; data-origin-width=&quot;1026&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;wacs.exe 파일을 실행하여 절차에 맞게 SSL 인증서를 발급받는 결과 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&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) 명령어를 통해 SSL 인증서를 발급받는 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 명령어를 자신에 맞게 고친 후, 실행하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1720060729161&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wacs.exe --target manual --host HOSTNAME --webroot C:\dev\nginx-1.26.1\html --store pemfiles --pemfilespath C:\dev\nginx-1.26.1\ssl&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;--target manual&lt;/b&gt; : 수동으로 인증서를 발급받겠다는 의미이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;--host HOSTNAME&lt;/b&gt; : 인증서를 발급받을 도메인 이름을 HOSTNAME 부분에 입력한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;--webroot&lt;/b&gt; : ACME 챌린지 파일을 저장할 웹 서버의 루트 디렉토리로 지정한다. nginx의 경우 \html 경로로 설정해두면 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;--store pemfiles&lt;/b&gt; : 발급받을 인증서를 PEM 파일 형식으로 저장하겠다는 의미이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;--pemfilepath PATH&lt;/b&gt; : PEM 파일을 저장할 경로 PATH를 지정한다. nginx 디렉토리 내의 편의상 SSL 폴더를 만들어 사용하는 것이 편하다.&lt;/li&gt;
&lt;/ul&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;Certificate [Manual] HOSTNAME created&lt;/b&gt;라고 뜰 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 정상적으로 SSL 인증서가 발급된 것이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;명령어의 installation 부분은 내가 스크립트를 잘못 작성하였기 때문에 나타나는 에러로 무시해도 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1099&quot; data-origin-height=&quot;601&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4XkBS/btsImcqoSYV/Qsf0jg0K2mRkh9M7cPlSc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4XkBS/btsImcqoSYV/Qsf0jg0K2mRkh9M7cPlSc0/img.png&quot; data-alt=&quot;명령어를 통해 SSL 인증서를 발급받는 결과 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4XkBS/btsImcqoSYV/Qsf0jg0K2mRkh9M7cPlSc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4XkBS%2FbtsImcqoSYV%2FQsf0jg0K2mRkh9M7cPlSc0%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; alt=&quot;명령어를 통해 SSL 인증서를 발급받는 결과 화면&quot; loading=&quot;lazy&quot; width=&quot;1099&quot; height=&quot;601&quot; data-origin-width=&quot;1099&quot; data-origin-height=&quot;601&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;명령어를 통해 SSL 인증서를 발급받는 결과 화면&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;내가 지정한 경로에 PEM 파일이 생성된 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;255&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdrFHh/btsInlz7wVV/LrFivCbjJ55vZ467IuCjo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdrFHh/btsInlz7wVV/LrFivCbjJ55vZ467IuCjo1/img.png&quot; data-alt=&quot;SSL 인증 파일이 pem 형식으로 생성된 것을 확인한 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdrFHh/btsInlz7wVV/LrFivCbjJ55vZ467IuCjo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdrFHh%2FbtsInlz7wVV%2FLrFivCbjJ55vZ467IuCjo1%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; alt=&quot;SSL 인증 파일이 pem 형식으로 생성된 것을 확인한 화면&quot; loading=&quot;lazy&quot; width=&quot;379&quot; height=&quot;255&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;255&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSL 인증 파일이 pem 형식으로 생성된 것을 확인한 화면&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;nginx에 SSL 적용하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;nginx&lt;/b&gt;가 설치되어 있는 디렉토리에서 &lt;b&gt;conf&lt;/b&gt;&amp;nbsp;폴더로 이동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;nginx.conf&lt;/b&gt; 파일을 열어 아래와 같이 &lt;b&gt;server&lt;/b&gt; 블록을 수정 및 추가해준다.&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;기존 도메인 server 블록 수정하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSL을 적용하면 http의 요청을 https로 바꿔서 응답해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;listen의 80은 기본 http 요청의 기본 포트를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 코드는 nginx의 nginx.conf 파일 내용 중,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;80 포트로 들어오는 http 도메인의 주소를 https 주소로 리다이렉트 시키도록 하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 것은 &lt;b&gt;return 301 부분을 추가&lt;/b&gt;하고, &lt;b&gt;location = / 부분은 삭제&lt;/b&gt;하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1720074488764&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server {
    listen          80; # Flask Babychat
    server_name     babychat.xyz;
    return 301      https://$server_name$request_uri; # 이 부분 추가
    
    # https로 리다이렉트하기 때문에 location / 부분은 삭제
    #location / {
    #    proxy_pass  http://192.168.0.78:3999;
    #}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SSL이 인증된 도메인 server 블록 추가하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSL 인증서를 포함하여 HTTPS 요청을 받을 수 있도록 해주는 코드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;443은 HTTPS 포트의 기본 포트를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ssl 인증을 적용하기 위해서는 win-acme 도구를 통해 생성된 pem 형식의 파일을 이용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새롭게 생성된 pem 형식의 파일(key, crt, chain)을 상황에 맞게 자신의 서버 블록에 넣어주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nginx의 버전 별로 설정 부분이 나뉘긴 하는데, 내용은 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;i&gt;참고 : sslcert.co.kr - 'NginX SSL 인증서 설치/적용 가이드'&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1720075024429&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server {
    listen 443; (1.15 버젼 부터는 listen 443 ssl; 형식으로 변경됨)
    ssl on; (1.15 버젼 부터는 옵션 지원 종료)
    server_name www.sslcert.co.kr sslcert.co.kr; (지정한 서버인증서에 포함(지원)된 도메인)
    ssl_certificate_key /파일경로/www.sslcert.co.kr.key.pem; (개인키 파일 지정)
    ssl_certificate /파일경로/www.sslcert.co.kr.all.crt.pem; (서버인증서+체인+루트 통합 unified 파일 지정)
    ssl_protocols TLSv1.2; (서버 환경에 따라 선택적 적용)

    location /
    root path
    }
}&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;나의 경우, 현 시점의 nginx 안정 버전인 1.26.1 버전을 사용하여 아래와 같이 구상하였다.&lt;/p&gt;
&lt;pre id=&quot;code_1720074792897&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server {
    listen          443 ssl;
    server_name     babychat.xyz;

    ssl_certificate C:/dev/nginx-1.26.1/ssl/babychat.xyz-crt.pem;
    ssl_certificate_key C:/dev/nginx-1.26.1/ssl/babychat.xyz-key.pem;
    ssl_trusted_certificate C:/dev/nginx-1.26.1/ssl/babychat.xyz-chain.pem;

    location / {
        proxy_pass  http://192.168.0.78:3999;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;80 포트와 443 포트에 대한 서버 블록 코드를 추가 및 수정이 완료되었다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 nginx를 실행해서 HTTPS로 정상적으로 접속이 되는지 확인해보면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1720075491694&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# (nginx 설치 경로에서 명령 프롬프트 실행)

# nginx 실행
nginx

# 만약 nginx가 실행되어 있다면 재시작
nginx -s reload&lt;/code&gt;&lt;/pre&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;HTTPS 적용 확인을 위한 사이트 접속&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;https로 정상적으로 잘 접속이 된다!&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;417&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSa4yw/btsIn3TSrxS/Iy1H2VkBGpPXG21Jkkdm2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSa4yw/btsIn3TSrxS/Iy1H2VkBGpPXG21Jkkdm2K/img.png&quot; data-alt=&quot;https로 접속해본 메인 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSa4yw/btsIn3TSrxS/Iy1H2VkBGpPXG21Jkkdm2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSa4yw%2FbtsIn3TSrxS%2FIy1H2VkBGpPXG21Jkkdm2K%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; alt=&quot;https로 접속해본 메인 화면&quot; loading=&quot;lazy&quot; width=&quot;417&quot; height=&quot;468&quot; data-origin-width=&quot;417&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https로 접속해본 메인 화면&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;오류: 트러블 슈팅&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;win-acme 인증서 발급 중 오류1&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Error: &lt;b&gt;this may be because of insufficient rights or a non-Microsoft webserver using port 80 &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;An&amp;nbsp;error&amp;nbsp;occured&amp;nbsp;while&amp;nbsp;commiting&amp;nbsp;validation&amp;nbsp;configuration&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1719992684699&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Authorizing using http-01 validation (SelfHosting)
 Unable to activate listener,
 this may be because of insufficient rights or a non-Microsoft webserver using port 80
 An error occured while commiting validation configuration:
 다른 프로세스가 파일을 사용 중이기 때문에 프로세스가 액세스 할 수 없습니다.
 An error occured during post-validation cleanup: Cannot access a disposed object.
Object name: 'System.Net.HttpListener'.
 Deactivating pending authorization
 Create certificate failed&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;80포트가 이미 사용중이기 때문에 win-acme(wacs)가 접근을 할 수 없다는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 80포트를 사용중인 서비스를 종료한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;nginx를 사용중이라면 nginx가 80포트를 사용할 확률이 매우 높다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;nginx를 종료하고 다시 진행해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;win-acme 인증서 발급 중 오류2&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Error: &lt;b&gt;Timeout during connect (likely firewall problem)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1719992904106&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Authorizing...
Authorizing using http-01 validation (SelfHosting)
Authorization result: invalid
{&quot;type&quot;:&quot;urn:ietf:params:acme:error:connection&quot;,
&quot;detail&quot;:&quot;xx.xxx.xxx.xxx: Fetching http://example.com/.well-known/acme-challenge/3ew_599WKxgh28LFE9hEPIM0rZ2tCg_cCo_gOcrYw8Q:
Timeout during connect (likely firewall problem)&quot;,&quot;status&quot;:400,&quot;instance&quot;:null}
Deactivating pending authorization
Create certificate failed&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오류 내용에서 유추할 수 있듯이 80 포트가 닫혀있을 가능성이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인바운드로 들어오는 80포트를 사용할 수 있도록 열어주자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;555&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/edDnk3/btsIkGTna5m/FCGjl2L9RPov7rBgVV4AJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/edDnk3/btsIkGTna5m/FCGjl2L9RPov7rBgVV4AJK/img.png&quot; data-alt=&quot;인바운드 80 포트 사용 설정 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/edDnk3/btsIkGTna5m/FCGjl2L9RPov7rBgVV4AJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FedDnk3%2FbtsIkGTna5m%2FFCGjl2L9RPov7rBgVV4AJK%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; alt=&quot;인바운드 80 포트 사용 설정 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;582&quot; height=&quot;555&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;555&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인바운드 80 포트 사용 설정 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;시작 - 고급 보안이 포함된 Windows Defender 방화벽 실행&lt;/li&gt;
&lt;li&gt;인바운드 규칙 - 이름(BranchCache 호스트 캐시 서버(HTTP-In)) 더블 클릭&lt;/li&gt;
&lt;li&gt;이름과 설명 및 사용함 체크&lt;/li&gt;
&lt;li&gt;확인&lt;/li&gt;
&lt;/ol&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;HTTPS 접속 오류: 사이트에 연결할 수 없음&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nginx에서 SSL 설정을 다했는데도 http는 정상적으로 처리되는데 https만 사이트 연결이 되지 않은 경우가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴 경우는 위와 같이 '&lt;b&gt;win-acme 인증서 발급 중 오류2&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;인터넷 공유기는 자체 네트워크 설정을 지니는데,&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;내용이 워낙 길어져서 링크로 대체하겠다. 외부에서 로컬 DB에 접속하는 방법을 다룬 글인데,&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;a href=&quot;https://luvris2.tistory.com/720&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MySQL - 외부에서 로컬 DB 서버 접속하기 (DB 서버 구축)&lt;/a&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내부 포트 열기 (방화벽 해제)&lt;/li&gt;
&lt;li&gt;외부&amp;nbsp;포트&amp;nbsp;허용하기&amp;nbsp;(포트&amp;nbsp;포워딩)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>DevOps/Server</category>
      <category>https 사이트 접속</category>
      <category>Lets Encrypt</category>
      <category>nginx</category>
      <category>SSL 인증</category>
      <category>SSL 적용</category>
      <category>win-acme</category>
      <category>무료 ssl 인증서 발급</category>
      <category>윈도우 ssl 인증서 발급</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/916</guid>
      <comments>https://luvris2.tistory.com/916#entry916comment</comments>
      <pubDate>Thu, 4 Jul 2024 16:00:31 +0900</pubDate>
    </item>
    <item>
      <title>nginx - 서브 도메인 포트 라우팅 가이드 (For Windows)</title>
      <link>https://luvris2.tistory.com/915</link>
      <description>&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;/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;여러 개의 웹 서비스를 구축하려면 다음과 같은 문제가 발생한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;도메인을 연결해야 하는데 80 / 8080 포트는 이미 메인 서비스를 제공한다.&lt;/li&gt;
&lt;li&gt;다른 포트를 사용하려니 도메인 뒤에 포트를 입력해야 한다.&lt;/li&gt;
&lt;li&gt;도메인 뒤에 포트를 입력하여 사용하려니 보기가 좋지 않다.&lt;/li&gt;
&lt;/ul&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;b&gt;abc.com&lt;/b&gt;을 기준으로, &lt;b&gt;api 서버&lt;/b&gt;와 &lt;b&gt;개발 서버&lt;/b&gt;를 따로 두고 개발해야 한다고 해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;api 서버 도메인 예시 : &lt;b&gt;api&lt;/b&gt;.abc.com&lt;/li&gt;
&lt;li&gt;개발 서버 도메인 예시 : &lt;b&gt;dev&lt;/b&gt;.abc.com&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이, 한 개의 메인 도메인(abc.com)을 기준으로 구분자를 넣으면 관리 차원에서 보기가 정말 용이하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 실제 서버의 상황을 보면 abc.com:1111, abc.com:2222 이런식으로 진행된다.&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;서브 도메인&lt;/b&gt;과 &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;서브 도메인을 통해 특정 포트로 간편하게 접속할 수 있도록 해야 한다.&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;아파치(apache)&lt;/b&gt;와 &lt;b&gt;엔진엑스(nginx)&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;nginx&lt;/b&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;글을 읽기 전에...&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 다음과 같은 상황을 위한 글이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 개의 웹 서비스를 운영하며 &lt;b&gt;서브도메인 설정&lt;/b&gt;이 필요한 경우&lt;/li&gt;
&lt;li&gt;&lt;b&gt;윈도우 환경&lt;/b&gt;에 익숙하고 &lt;b&gt;Nginx&lt;/b&gt;를 사용해보고 싶은 경우&lt;/li&gt;
&lt;li&gt;&lt;b&gt;복잡한 포트 번호 대신 깔끔한 서브도메인 주소&lt;/b&gt;로 서비스를 운영하고 싶은 경우&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프론트엔드와 백엔드 서버를 분리&lt;/b&gt;하여 사용하고 싶은 경우&lt;/li&gt;
&lt;/ul&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;a href=&quot;https://luvris2.tistory.com/914&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;가비아 - 서브 도메인 만들기 (DNS 설정하기, A 레코드 사용)&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1719986888670&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;가비아 - 서브 도메인 만들기 (DNS 설정하기, A 레코드 사용)&quot; data-og-description=&quot;개요도메인을 구입하여 블로그나 쇼핑몰, 특정 주제를 다루는 웹사이트를 운영하고 있을 때,또 다른 주제로 웹 사이트 확장과 함께 고민해야 할 부분이 있다.그것은 바로 서브 도메인이다.&amp;nbsp;내 &quot; data-og-host=&quot;luvris2.tistory.com&quot; data-og-source-url=&quot;https://luvris2.tistory.com/914&quot; data-og-url=&quot;https://luvris2.tistory.com/914&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gTSvV/hyWvKFupXh/e9EHfBL2mMTasLsH2kCY1k/img.png?width=800&amp;amp;height=313&amp;amp;face=0_0_800_313,https://scrap.kakaocdn.net/dn/bi0E1k/hyWvRLmTw0/zXP9KkEfmkcMdb4TuMt3G0/img.png?width=800&amp;amp;height=313&amp;amp;face=0_0_800_313,https://scrap.kakaocdn.net/dn/szPMa/hyWvWsomSE/XNKaFaFjoR2jhglb1BfdY1/img.png?width=1244&amp;amp;height=412&amp;amp;face=0_0_1244_412&quot;&gt;&lt;a href=&quot;https://luvris2.tistory.com/914&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://luvris2.tistory.com/914&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gTSvV/hyWvKFupXh/e9EHfBL2mMTasLsH2kCY1k/img.png?width=800&amp;amp;height=313&amp;amp;face=0_0_800_313,https://scrap.kakaocdn.net/dn/bi0E1k/hyWvRLmTw0/zXP9KkEfmkcMdb4TuMt3G0/img.png?width=800&amp;amp;height=313&amp;amp;face=0_0_800_313,https://scrap.kakaocdn.net/dn/szPMa/hyWvWsomSE/XNKaFaFjoR2jhglb1BfdY1/img.png?width=1244&amp;amp;height=412&amp;amp;face=0_0_1244_412');&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;가비아 - 서브 도메인 만들기 (DNS 설정하기, A 레코드 사용)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;개요도메인을 구입하여 블로그나 쇼핑몰, 특정 주제를 다루는 웹사이트를 운영하고 있을 때,또 다른 주제로 웹 사이트 확장과 함께 고민해야 할 부분이 있다.그것은 바로 서브 도메인이다.&amp;nbsp;내&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;luvris2.tistory.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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;엔진엑스(NginX)란 무엇인가?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;Nginx는 가볍고 빠른 성능으로 유명한 웹 서버이자,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&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; text-align: start;&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; text-align: start;&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; text-align: start;&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; text-align: start;&quot;&gt;다른 웹 서버에 비해 가볍고 자원을 적게 소모한다는 장점이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; 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;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;검색 엔진에서 nginx를 검색하여 해당 사이트에 들어가서 다운로드 받을 수 있다.&lt;/span&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; text-align: start;&quot;&gt;☞&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;color: #0070d1; text-align: start;&quot; href=&quot;https://nginx.org/en/download.html&quot;&gt;nginx 다운로드 페이지로 이동하기&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;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;귀찮다면 아래의 링크를 눌러 다운로드를 진행하자.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;☞ &lt;a href=&quot;https://nginx.org/download/nginx-1.26.1.zip&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;윈도우용 nginx 1.26.1 (stable version) 다운로드 하기&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;다운로드가 끝나면 압축을 풀고, 놓고 싶은 위치에 저장해두면 된다.&lt;/p&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;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&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;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;참고된 자료 URL : &lt;a href=&quot;https://blog.kronis.dev/tutorials/how-to-use-nginx-to-proxy-your-front-end-and-back-end&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;blog.kronis.dev - How to use Nginx to proxy your front end and back end&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bt36kJ/btsIkE8S3F5/nXk6n7pLudyafDg0Ncipb0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bt36kJ/btsIkE8S3F5/nXk6n7pLudyafDg0Ncipb0/img.jpg&quot; data-alt=&quot;엔진엑스를 적용하기 전의 스프링 부트 앱 프로세스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bt36kJ/btsIkE8S3F5/nXk6n7pLudyafDg0Ncipb0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbt36kJ%2FbtsIkE8S3F5%2FnXk6n7pLudyafDg0Ncipb0%2Fimg.jpg&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; alt=&quot;엔진엑스를 적용하기 전의 스프링 부트 앱 프로세스&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;794&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;엔진엑스를 적용하기 전의 스프링 부트 앱 프로세스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러나 우리가 원하는 것은 한 대의 컴퓨터에서 서브 도메인을 사용하기 위함으로써&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;메인 도메인과 서브 도메인을 구별하는 포트별 요청을 처리하여 각각의 메인/서브 서버에 요청을 전달해야 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아래는 nginx가 적용된 프로세스이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;945&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cekflE/btsImKsQqag/Bi8XsCb3gwmkpZe4ZGN6w1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cekflE/btsImKsQqag/Bi8XsCb3gwmkpZe4ZGN6w1/img.jpg&quot; data-alt=&quot;엔진엑스를 적용한 백엔드, 프론트엔드 라우팅 프로세스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cekflE/btsImKsQqag/Bi8XsCb3gwmkpZe4ZGN6w1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcekflE%2FbtsImKsQqag%2FBi8XsCb3gwmkpZe4ZGN6w1%2Fimg.jpg&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; alt=&quot;엔진엑스를 적용한 백엔드, 프론트엔드 라우팅 프로세스&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;945&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;945&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;엔진엑스를 적용한 백엔드, 프론트엔드 라우팅 프로세스&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;즉, nginx는 웹 서버로서 클라이언트의 요청을 받아 해당 요청을 처리할 서버를 선택하고,&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;&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;/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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;conf 폴더&lt;/span&gt; 하위의 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;nginx.conf&lt;/span&gt; 파일을 연다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;밑으로 내리다보면 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;server&lt;/span&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;서브 도메인을 추가할 때에는 server 파트를 한 번 더 기입한다.&lt;/p&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;도메인
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;메인 도메인 : babychat.xyz&lt;/li&gt;
&lt;li&gt;서브 도메인 : project1.babychat.xyz&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;서버 포트
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메인 : localhost:3999&lt;/li&gt;
&lt;li&gt;서브 : localhost:4001&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1719985404487&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 메인 도메인
server {
    listen	80; # Nginx 기본 포트
    server_name  babychat.xyz;

    location / {
        proxy_pass http://192.168.0.78:3999;
    }
}

# 서브 도메인
server {
    listen       80;
    server_name  project1.babychat.xyz;

    location / {
        proxy_pass http://192.168.0.78:4001;
    }
}&lt;/code&gt;&lt;/pre&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;nginx.exe&lt;/span&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;확인은 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;작업 관리자&lt;/span&gt;에서 할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9E63l/btsInjBOvZP/5y54UidrEBSoTzSrmEdlj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9E63l/btsInjBOvZP/5y54UidrEBSoTzSrmEdlj0/img.png&quot; data-alt=&quot;작업 관리자에서 엔진엑스 실행을 확인한 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9E63l/btsInjBOvZP/5y54UidrEBSoTzSrmEdlj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9E63l%2FbtsInjBOvZP%2F5y54UidrEBSoTzSrmEdlj0%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; alt=&quot;작업 관리자에서 엔진엑스 실행을 확인한 화면 예시&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;258&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;작업 관리자에서 엔진엑스 실행을 확인한 화면&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;작업 끝내기&lt;/span&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;명령 프롬프트(CMD)를 통한 엔진엑스 실행 및 종료&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 개발자스럽게 명령어를 통해 확인해보고 싶다면 아래의 명령어를 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;CMD&lt;/span&gt;에서 입력해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;nginx 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1719986602942&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nginx경로/nginx.exe&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;nginx 실행 여부 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1719986462580&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;tasklist /FI &quot;imagename eq nginx.exe&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;709&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OilcX/btsImNiQUmH/ZSKA1sKlWb2KvQ8k1qG841/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OilcX/btsImNiQUmH/ZSKA1sKlWb2KvQ8k1qG841/img.png&quot; data-alt=&quot;nginx 실행 여부 확인 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OilcX/btsImNiQUmH/ZSKA1sKlWb2KvQ8k1qG841/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOilcX%2FbtsImNiQUmH%2FZSKA1sKlWb2KvQ8k1qG841%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; alt=&quot;nginx 실행 여부 확인 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;709&quot; height=&quot;230&quot; data-origin-width=&quot;709&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;nginx 실행 여부 확인 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;nginx 종료&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1719986713276&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;taskkill /IM nginx.exe /F&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;80&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D4zlv/btsInlM54CN/bvJJ0jegYllO6ciAkDuv3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D4zlv/btsInlM54CN/bvJJ0jegYllO6ciAkDuv3k/img.png&quot; data-alt=&quot;nginx 종료 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D4zlv/btsInlM54CN/bvJJ0jegYllO6ciAkDuv3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD4zlv%2FbtsInlM54CN%2FbvJJ0jegYllO6ciAkDuv3k%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; alt=&quot;nginx 종료 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;544&quot; height=&quot;80&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;80&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;nginx 종료 예시 화면&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;도메인 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인 도메인은 3999번(Python Flask)으로 접속하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서브 도메인은 4001번(Kotlin SpringBoot)으로 접속하게끔 해두었다.&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;h3 data-ke-size=&quot;size23&quot;&gt;메인 도메인 확인&lt;/h3&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;502&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buYwgP/btsIkE19idR/gXX2Awsx10KDGaAq8C1Sp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buYwgP/btsIkE19idR/gXX2Awsx10KDGaAq8C1Sp0/img.png&quot; data-alt=&quot;메인 도메인 주소 확인 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buYwgP/btsIkE19idR/gXX2Awsx10KDGaAq8C1Sp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuYwgP%2FbtsIkE19idR%2FgXX2Awsx10KDGaAq8C1Sp0%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; alt=&quot;메인 도메인 주소 확인 예시&quot; loading=&quot;lazy&quot; width=&quot;502&quot; height=&quot;540&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;메인 도메인 주소 확인 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서브 도메인을 넣어 접속해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링부트로 실행중인 포트로 정상적으로 라우팅되어 API 서버의 테스트 페이지가 잘 표현된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;495&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC9Kgq/btsIkAZJlKa/YJomMMUvaydrYI9GM3OiR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC9Kgq/btsIkAZJlKa/YJomMMUvaydrYI9GM3OiR1/img.png&quot; data-alt=&quot;서브 도메인 주소 확인 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC9Kgq/btsIkAZJlKa/YJomMMUvaydrYI9GM3OiR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC9Kgq%2FbtsIkAZJlKa%2FYJomMMUvaydrYI9GM3OiR1%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; alt=&quot;서브 도메인 주소 확인 예시&quot; loading=&quot;lazy&quot; width=&quot;634&quot; height=&quot;495&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;495&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;서브 도메인 주소 확인 예시&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;출처&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EB%A6%AC%EB%B2%84%EC%8A%A4_%ED%94%84%EB%A1%9D%EC%8B%9C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;위키백과 - 리버스 프록시&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.kronis.dev/tutorials/how-to-use-nginx-to-proxy-your-front-end-and-back-end&quot;&gt;blog.kronis.dev - How to use Nginx to proxy your front end and back end&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>DevOps/Server</category>
      <category>nginx</category>
      <category>백엔드</category>
      <category>서버 설정</category>
      <category>서브 도메인</category>
      <category>포트 라우팅</category>
      <category>포트 분기</category>
      <category>프론트엔드</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/915</guid>
      <comments>https://luvris2.tistory.com/915#entry915comment</comments>
      <pubDate>Wed, 3 Jul 2024 15:10:57 +0900</pubDate>
    </item>
    <item>
      <title>가비아 - 서브 도메인 만들기 (DNS 설정하기, A 레코드 사용)</title>
      <link>https://luvris2.tistory.com/914</link>
      <description>&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;/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;b&gt;내 경우를 예로 들어보자면...&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대화를 나눌 수 있는 채팅 토이 프로젝트를 도메인을 구입하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;포트폴리오 겸&lt;span&gt;&amp;nbsp;&lt;/span&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&gt;&amp;nbsp;&lt;/span&gt;변태 같지만&lt;span&gt;&amp;nbsp;&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&gt;&amp;nbsp;&lt;/span&gt;다른 토이 프로젝트를 진행하려니&lt;span&gt;&amp;nbsp;&lt;/span&gt;또다시&lt;span&gt;&amp;nbsp;&lt;/span&gt;도메인을&lt;span&gt;&amp;nbsp;&lt;/span&gt;사야 하는가에&lt;span&gt;&amp;nbsp;&lt;/span&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;대개 귀찮으니 이미 존재하는 도메인 뒤의 path 부분에 추가적으로 url을 붙여 사용하는 경우가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나 또한 그렇다.&lt;span&gt;&amp;nbsp;&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나 자체를&lt;span&gt;&amp;nbsp;&lt;/span&gt;브랜딩 하기&lt;span&gt;&amp;nbsp;&lt;/span&gt;위해 서브 도메인을 이용하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;체계적으로 주제에 맞는 프로젝트들을 하나씩 붙여나가는 방식으로 해보려 한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&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 style=&quot;color: #333333; text-align: start;&quot; 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;가비아 서브 도메인 만들기&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;가비아 홈페이지 로그인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가비아 웹 사이트에 접속하여 계정에 로그인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;☞ &lt;a href=&quot;https://www.gabia.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;가비아 홈페이지 바로가기&lt;/a&gt;&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;DNS 관리 페이지로 이동하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그인이 되면 오른쪽 상단의 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;My가비아&lt;/span&gt; 버튼으로 마우스를 이동하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나타나는 하위 메뉴 중 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;서비스 조회&lt;/span&gt;의 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;서비스 관리&lt;/span&gt;를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1244&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nbkmq/btsIlasL5AE/egB5F5Xv3XIGKvzG1I4Dtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nbkmq/btsIlasL5AE/egB5F5Xv3XIGKvzG1I4Dtk/img.png&quot; data-alt=&quot;서비스 관리 페이지 이동 경로 설명 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nbkmq/btsIlasL5AE/egB5F5Xv3XIGKvzG1I4Dtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnbkmq%2FbtsIlasL5AE%2FegB5F5Xv3XIGKvzG1I4Dtk%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; alt=&quot;서비스 관리 페이지 이동 경로 설명 화면&quot; loading=&quot;lazy&quot; width=&quot;1244&quot; height=&quot;412&quot; data-origin-width=&quot;1244&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;서비스 관리 페이지 이동 경로 설명 화면&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;DNS 관리툴&lt;/span&gt;을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;790&quot; data-origin-height=&quot;228&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VbyUE/btsIlbynvWo/Ye7iBP3giJFKC6XDVOY0DK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VbyUE/btsIlbynvWo/Ye7iBP3giJFKC6XDVOY0DK/img.png&quot; data-alt=&quot;DNS 관리툴 페이지 이동 경로 설명 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VbyUE/btsIlbynvWo/Ye7iBP3giJFKC6XDVOY0DK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVbyUE%2FbtsIlbynvWo%2FYe7iBP3giJFKC6XDVOY0DK%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; alt=&quot;DNS 관리툴 페이지 이동 경로 설명 화면&quot; loading=&quot;lazy&quot; width=&quot;790&quot; height=&quot;228&quot; data-origin-width=&quot;790&quot; data-origin-height=&quot;228&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DNS 관리툴 페이지 이동 경로 설명 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서브 도메인을 만들 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;도메인 체크&lt;/span&gt;(선택)하고, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;DNS 설정&lt;/span&gt; 버튼을 누른다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;323&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwByUu/btsIkqCPq5k/jfFRRN3UOw5FoOiAYJ9EGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwByUu/btsIkqCPq5k/jfFRRN3UOw5FoOiAYJ9EGk/img.png&quot; data-alt=&quot;DNS 설정을 위한 도메인 선택 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwByUu/btsIkqCPq5k/jfFRRN3UOw5FoOiAYJ9EGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwByUu%2FbtsIkqCPq5k%2FjfFRRN3UOw5FoOiAYJ9EGk%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; alt=&quot;DNS 설정을 위한 도메인 선택 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;825&quot; height=&quot;323&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;323&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DNS 설정을 위한 도메인 선택 예시 화면&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;예를 들어서 &lt;b&gt;babychat.xyz&lt;/b&gt;가 메인 도메인이고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞에 &lt;b&gt;project1&lt;/b&gt;이라는 서브 도메인을 붙여서&amp;nbsp;&lt;b&gt;project1.babychat.xyz&lt;/b&gt;를 사용하려 한다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하단의 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;레코드 추가&lt;/span&gt; 버튼을 누른 후, 아래와 같이 입력한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;레코드 타입&lt;/b&gt; : A&lt;/li&gt;
&lt;li&gt;&lt;b&gt;호스트&lt;/b&gt; : project1&lt;/li&gt;
&lt;li&gt;&lt;b&gt;값/위치&lt;/b&gt; : 서버가 돌아가고 있는 외부 IP 주소&lt;/li&gt;
&lt;/ul&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;416&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qhCQf/btsIlP2xqQX/4ECdklK4KokXZEGQFOQII1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qhCQf/btsIlP2xqQX/4ECdklK4KokXZEGQFOQII1/img.png&quot; data-alt=&quot;서브 도메인 DNS 설정 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qhCQf/btsIlP2xqQX/4ECdklK4KokXZEGQFOQII1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqhCQf%2FbtsIlP2xqQX%2F4ECdklK4KokXZEGQFOQII1%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; alt=&quot;서브 도메인 추가를 위한 DNS 설정 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;1014&quot; height=&quot;416&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;416&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;서브 도메인 DNS 설정 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&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;여기서 잠깐!&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서브 도메인 설정 시, 레코드 타입이 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;A&lt;/span&gt; 또는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;CNAME&lt;/span&gt; 둘 중 무엇을 선택해야 할지 모르겠다 싶으면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차이점을 이해하고 자신의 상황에 맞는 타입을 선택하도록 하자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;A&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;도메인 주소와 서버의 주소를 IPv4 주소로 직접 매핑하는 방식이다.&lt;/li&gt;
&lt;li&gt;호스트의 값/위치가 아이피 주소일 경우 사용한다.&lt;/li&gt;
&lt;li&gt;프로그램이 도메인 이름을 통해 웹 서버의 IP 주소를 찾기 위해 사용한다.&lt;/li&gt;
&lt;li&gt;예시 : example.com A 192.168.0.1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CNAME&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;도메인의 별명(별칭)을 다른 도메인 이름으로 매핑하는 방식이다.&lt;/li&gt;
&lt;li&gt;여러 도메인이 같은 IP 주소를 가리킬 때 사용한다.&lt;/li&gt;
&lt;li&gt;즉, 다른 주소를 입력해도 지정한 주소로 접속되도록 하는 것을 의미한다.&lt;/li&gt;
&lt;li&gt;예시 : www.example.com CNAME example.com&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;h3 data-ke-size=&quot;size23&quot;&gt;확인하기 전에!&lt;/h3&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;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;nginx를 이용한 포트 분기 처리 설정을 하고 싶다면 아래의 글을 참고하자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;☞ &lt;b&gt;&lt;a href=&quot;https://luvris2.tistory.com/915&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;nginx - 서브 도메인 포트 라우팅 가이드 (For Windows)&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&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;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;접속 URL : &lt;/b&gt;babychat.xyz&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Flask로 만든 채팅 서버(포트번호 5000)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PQUuZ/btsImiDu6E5/cvPNcEQj8KAsz5ol9pOwQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PQUuZ/btsImiDu6E5/cvPNcEQj8KAsz5ol9pOwQ1/img.png&quot; data-alt=&quot;메인 도메인 주소 확인 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PQUuZ/btsImiDu6E5/cvPNcEQj8KAsz5ol9pOwQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPQUuZ%2FbtsImiDu6E5%2FcvPNcEQj8KAsz5ol9pOwQ1%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; alt=&quot;메인 도메인 주소 확인 예시&quot; loading=&quot;lazy&quot; width=&quot;502&quot; height=&quot;540&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;메인 도메인 주소 확인 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&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;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;접속 URL&lt;/b&gt; : project1.babychat.xyz&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Spring Boot로 만든 API 테스트 서버(포트번호 5001)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;495&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpBJM7/btsImBQmkIn/o7wWlTfnXWwO7OpP6Bbn90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpBJM7/btsImBQmkIn/o7wWlTfnXWwO7OpP6Bbn90/img.png&quot; data-alt=&quot;서브 도메인 주소 확인 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpBJM7/btsImBQmkIn/o7wWlTfnXWwO7OpP6Bbn90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpBJM7%2FbtsImBQmkIn%2Fo7wWlTfnXWwO7OpP6Bbn90%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; alt=&quot;서브 도메인 주소 확인 예시&quot; loading=&quot;lazy&quot; width=&quot;634&quot; height=&quot;495&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;495&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;서브 도메인 주소 확인 예시&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>DevOps/그 외</category>
      <category>DNS 설정</category>
      <category>가비아</category>
      <category>레코드 a</category>
      <category>레코드 cname</category>
      <category>서브 도메인 만들기</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/914</guid>
      <comments>https://luvris2.tistory.com/914#entry914comment</comments>
      <pubDate>Wed, 3 Jul 2024 14:13:11 +0900</pubDate>
    </item>
    <item>
      <title>JS - 마크다운 문법 html 웹 페이지와 호환하기 (마크다운 html 변환, markdown to html)</title>
      <link>https://luvris2.tistory.com/913</link>
      <description>&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;마크다운 문법으로 구성된 문서를 HTML에 표시하고 싶을 때 어떻게 해야할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접 구현하는 것도 좋지만, 보편적으로 이미 만들어져있는 것을 사용하는 것이 생산성면에서 훨씬 이득이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보편적으로 사용되는 Markdown &amp;gt; HTML로 변환하는 라이브러리는 Marked를 이용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 Marked 라이브러리를 이용하여 Markdown 형식의 문서를 HTML 로 변환하는 방법에 대해 가볍게 다뤄본다. 단, 단순히 파싱만 하는 과정을 소개하며 자세한 옵션에 대한 처리는 다루지 않는다.&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;Marked 라이브러리란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Marked&lt;/b&gt;는 JavaScript 기반의 Markdown 파서(parser)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 라이브러리는 Markdown 형식의 텍스트를 HTML로 변환하는 데 사용되도록 설계되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Markdown&lt;/b&gt;은 문서를 작성할 때 간단한 텍스트 기반의 형식으로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitHub, Reddit, 블로그, 문서 작성 등에 널리 사용된다.&lt;/p&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로 변환하기 위해서는 parse() 메소드를 이용하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1719803949332&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;marked.parse(변환할 마크다운 문법 내용);&lt;/code&gt;&lt;/pre&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;사용 예제 (Sample)&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;라이브러리 호출&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Marked 라이브러리를 사용하기 위해 해당 라이브러리를 호출하여야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Marked 공식 홈페이지에서 제공하는 CND 주소는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1719803802562&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;script src=&quot;https://cdn.jsdelivr.net/npm/marked/marked.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마크다운으로 구성된 내용이 다음과 같이 있다고 해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1719803864455&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 마크다운 헤더1
**마크다운 문법**을 **HTML**로 변환하는 샘플 페이지
* JavaScript를 통해 쉽게 사용할 수 있다.&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;#&lt;/b&gt; : 헤더를 나타낸다. HTML에서는 &amp;lt;H1&amp;gt;을 의미한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;** 글자 **&lt;/b&gt; : 글자를 굵게하는 효과를 지닌다. HTML에서는 &amp;lt;B&amp;gt;를 의미한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;*&lt;/b&gt; : 리스트의 목록을 나타낸다. HTML에서는 &amp;lt;UL&amp;gt;, &amp;lt;LI&amp;gt;를 의미한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;샘플 HTML 페이지&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서의 마크다운 문법의 내용을 이해를 돕기 위해 자바스크립트 변수로 저장하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;marked.parse() 메서드를 통해 HTML로 변환해본다.&lt;/p&gt;
&lt;pre id=&quot;code_1719804003777&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&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;Marked in the browser&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;div id=&quot;content&quot;&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;!-- Marked 라이브러리 --&amp;gt;
  &amp;lt;script src=&quot;https://cdn.jsdelivr.net/npm/marked/marked.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;script&amp;gt;
  	// 마크다운 문법을 변수로 저장
    let title = &quot;# 마크다운 헤더1\n\n&quot;;
    let summary = &quot;**마크다운 문법**을 **HTML**로 변환하는 샘플 페이지\n&quot;;
    let content = &quot;* JavaScript를 통해 쉽게 사용할 수 있다.&quot;;

	// div 요소에 마크다운 문법을 HTML로 변환하여 표시
    let element = document.getElementById('content');
    element.innerHTML = marked.parse(title+summary+content);
  &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
  &amp;lt;div id=&quot;content&quot;&amp;gt;&amp;lt;/div&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;h3 data-ke-size=&quot;size23&quot;&gt;샘플 페이지 브라우저 실행 화면&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 보이기는 정상적으로 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTML로 정상적으로 변환이 되었을까?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;281&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d1FLaV/btsIhwQwFMX/R4rhqRuQQXMVGZWrP4Mn51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d1FLaV/btsIhwQwFMX/R4rhqRuQQXMVGZWrP4Mn51/img.png&quot; data-alt=&quot;브라우저에서 샘플 페이지를 확인하여 마크다운 문법이 HTML로 파싱되었는지 확인한 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d1FLaV/btsIhwQwFMX/R4rhqRuQQXMVGZWrP4Mn51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd1FLaV%2FbtsIhwQwFMX%2FR4rhqRuQQXMVGZWrP4Mn51%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; alt=&quot;브라우저에서 샘플 페이지를 확인하여 마크다운 문법이 HTML로 파싱되었는지 확인한 화면&quot; loading=&quot;lazy&quot; width=&quot;619&quot; height=&quot;281&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;281&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;브라우저에서 샘플 페이지를 확인하여 마크다운 문법이 HTML로 파싱되었는지 확인한 화면&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;태그가 정상적으로 변환되어 구조를 이루는 것을 확인해볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eTvPN9/btsIhgUtT2t/LNXA8rE2z4TvVgEkdpsAQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eTvPN9/btsIhgUtT2t/LNXA8rE2z4TvVgEkdpsAQ0/img.png&quot; data-alt=&quot;HTML로 파싱된 태그를 개발자 도구로 확인한 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eTvPN9/btsIhgUtT2t/LNXA8rE2z4TvVgEkdpsAQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeTvPN9%2FbtsIhgUtT2t%2FLNXA8rE2z4TvVgEkdpsAQ0%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; alt=&quot;HTML로 파싱된 태그를 개발자 도구로 확인한 화면&quot; loading=&quot;lazy&quot; width=&quot;508&quot; height=&quot;544&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;544&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;HTML로 파싱된 태그를 개발자 도구로 확인한 화면&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://marked.js.org/#installation&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Marked Documentation - Getting Started - Installation&lt;/a&gt;&lt;/p&gt;</description>
      <category>Web/Javascript</category>
      <category>HTML</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>markdown</category>
      <category>marked</category>
      <category>마크다운 html 변환</category>
      <category>마크다운 파싱</category>
      <category>자바스크립트</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/913</guid>
      <comments>https://luvris2.tistory.com/913#entry913comment</comments>
      <pubDate>Mon, 1 Jul 2024 12:26:03 +0900</pubDate>
    </item>
    <item>
      <title>JS - iframe 페이지에서 부모 페이지 요소 제어하기, 샘플 포함</title>
      <link>https://luvris2.tistory.com/912</link>
      <description>&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;iframe&lt;/span&gt;에서 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;부모 페이지의 요소&lt;/span&gt;를 제어해야 할 때가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 상황으로 예를 들자면, &lt;b&gt;iframe&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;보통 다른 페이지간 데이터 전달은 URL 주소 뒤에 물음표(?) 기호를 이용하는 쿼리 스트링을 사용하지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지 내에 구성되어 있는 iframe은 조금 경우가 다르다.&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;document.getElementId&lt;/span&gt;를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 부모 요소를 의미하는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;window.parent&lt;/span&gt; 키워드를 추가적으로 이용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;window.parent&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;window.parent는 현재 iframe의 부모 창을 참조하는 것을 의미한다.&lt;/li&gt;
&lt;li&gt;iframe 내부에서 실행될 때 window.parent를 통해 부모 문서의 window 객체에 접근할 수 있다.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;* 윈도우 객체는 브라우저 창을 나타내는 전역 개체를 의미한다.&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;document&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;document 객체는 HTML 문서 전체를 나타내며, DOM(Document Object Model)의 루트 노드를 의미한다.&lt;/li&gt;
&lt;li&gt;즉, DOM을 접근하고 다룬다는 것은 document 객체를 이용한다는 것과 같은 표현이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;getElementById&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;주어진 ID 값을 가진 요소를 선택하는 메서드이다.&lt;/li&gt;
&lt;li&gt;만약 일치하는 요소가 없으면 null을 반환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&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;부모 페이지와 iframe 페이지를 간단히 구성해보자.&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;iframe을 구성할 요소&lt;/b&gt;와 &lt;b&gt;값을 넘겨 받아 출력할 textarea 요소&lt;/b&gt;, 단 두 개로 구성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1719563228191&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- main.html --&amp;gt;

&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;ko&quot;&amp;gt;
&amp;lt;head&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.0&quot;&amp;gt;
    &amp;lt;title&amp;gt;Document&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;!-- iframe 표시 영역 --&amp;gt;
    &amp;lt;div name=&quot;iframeContainer&quot;&amp;gt;
        &amp;lt;iframe src=&quot;iframe.html&quot;&amp;gt;&amp;lt;/iframe&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;!-- iframe의 값을 넘겨 받은 값을 보여줄 영역 --&amp;gt;
    &amp;lt;div name=&quot;textContainer&quot;&amp;gt;
        &amp;lt;textarea id=&quot;textField&quot; cols=&quot;45&quot;&amp;gt;&amp;lt;/textarea&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;h3 data-ke-size=&quot;size23&quot;&gt;아이프레임 페이지&lt;/h3&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;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;자바스크립트 함수명 : &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;sendParent&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1719563306962&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- iframe.html --&amp;gt;

&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;ko&quot;&amp;gt;
&amp;lt;head&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.0&quot;&amp;gt;
    &amp;lt;title&amp;gt;Document&amp;lt;/title&amp;gt;
    &amp;lt;!-- 함수 실행을 위한 자바스크립트 파일 --&amp;gt;
    &amp;lt;script src=&quot;iframe.js&quot;&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;button id=&quot;iframeContent&quot; onclick=&quot;sendParent(this)&quot;&amp;gt;이 데이터를 부모 페이지의 요소로 전달해보자.&amp;lt;/button&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;요소의 값을 부모 요소에게로 전달해주는 역할을 하는 함수&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1719563775406&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// iframe.js

function sendParent(element) {
    parentElement = window.parent.document.getElementById(&quot;textField&quot;);
    parentElement.textContent = element.textContent;
}&lt;/code&gt;&lt;/pre&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;/h3&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;이 페이지를 만약 로컬에서 html 파일로 만들고 브라우저에서 간단히 확인하려는 사람이 있다면 멈추자.&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;pre id=&quot;code_1719564456700&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Uncaught DOMException:
Failed to read a named property 'document' from 'Window':
Blocked a frame with origin &quot;null&quot; from accessing a cross-origin frame.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bikD2n/btsIhzLZw2g/S05Om52tpWrB5GhVzuO0bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bikD2n/btsIhzLZw2g/S05Om52tpWrB5GhVzuO0bk/img.png&quot; data-alt=&quot;로컬 html 파일을 브라우저에서 실행한 후 기능을 수행하면 위와 같은 에러가 발생한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bikD2n/btsIhzLZw2g/S05Om52tpWrB5GhVzuO0bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbikD2n%2FbtsIhzLZw2g%2FS05Om52tpWrB5GhVzuO0bk%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; alt=&quot;오류 화면&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;91&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;로컬 html 파일을 브라우저에서 실행한 후 기능을 수행하면 위와 같은 에러가 발생한다.&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;자신이 사용할 수 있는 로컬 서버를 구축해서 위의 테스트 코드를 확인해보아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버의 경우 Node, Spring 등 여러가지가 있으므로 자신이 편한 것으로 사용하면된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나같은 경우는 Flask를 이용하여 간단히 확인해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;아이프레임의 버튼 클릭 전의 화면&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;204&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fwvfn/btsIhTwyih7/jaq1Q77GdtCqqSCrXt3Pkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fwvfn/btsIhTwyih7/jaq1Q77GdtCqqSCrXt3Pkk/img.png&quot; data-alt=&quot;버튼은 iframe 페이지 내, textarea는 부모 페이지에 위치해있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fwvfn/btsIhTwyih7/jaq1Q77GdtCqqSCrXt3Pkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFwvfn%2FbtsIhTwyih7%2Fjaq1Q77GdtCqqSCrXt3Pkk%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; alt=&quot;예시 테스트 화면 - 전&quot; loading=&quot;lazy&quot; width=&quot;353&quot; height=&quot;204&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;204&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;버튼은 iframe 페이지 내, textarea는 부모 페이지에 위치해있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;아이프레임의 버튼 클릭 후의 화면&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;348&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhiWdt/btsIhjWWWUB/Y5nkbqMxoxlhV5RIf7auw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhiWdt/btsIhjWWWUB/Y5nkbqMxoxlhV5RIf7auw0/img.png&quot; data-alt=&quot;부모 페이지의 textarea 요소에 전달한 글자가 정상적으로 표현되는 것을 확인할 수 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhiWdt/btsIhjWWWUB/Y5nkbqMxoxlhV5RIf7auw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhiWdt%2FbtsIhjWWWUB%2FY5nkbqMxoxlhV5RIf7auw0%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; alt=&quot;예시 화면 - 후&quot; loading=&quot;lazy&quot; width=&quot;348&quot; height=&quot;202&quot; data-origin-width=&quot;348&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;부모 페이지의 textarea 요소에 전달한 글자가 정상적으로 표현되는 것을 확인할 수 있다.&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>Web/Javascript</category>
      <category>iframe</category>
      <category>JavaScript</category>
      <category>JS</category>
      <category>데이터 전달</category>
      <category>부모 요소 제어</category>
      <category>부모 페이지</category>
      <category>자바스크립트</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/912</guid>
      <comments>https://luvris2.tistory.com/912#entry912comment</comments>
      <pubDate>Sat, 29 Jun 2024 00:30:32 +0900</pubDate>
    </item>
    <item>
      <title>Windows - 매일 혹은 주기적으로 자동 실행되는 작업 스케줄러를 구성해보자 (스케줄 자동화)</title>
      <link>https://luvris2.tistory.com/911</link>
      <description>&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;/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;이럴 때, 내가 특정 시간에 맞춰 일일이 인기 키워드 업데이트를 진행시켜주는 것보다는,&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&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-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/We8jb/btsIfIbjOeZ/4Tn0DUEBctspPlRemKHIoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/We8jb/btsIfIbjOeZ/4Tn0DUEBctspPlRemKHIoK/img.png&quot; data-alt=&quot;작업 스케줄러 실행 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/We8jb/btsIfIbjOeZ/4Tn0DUEBctspPlRemKHIoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWe8jb%2FbtsIfIbjOeZ%2F4Tn0DUEBctspPlRemKHIoK%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; alt=&quot;작업 스케줄러 실행 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;592&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;592&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;작업 스케줄러 실행 예시 화면&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;윈도우 키를 누르고 &quot;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;작업 스케줄러&lt;/span&gt;&quot;를 검색한다.&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;작업 스케줄러의 스케줄 설정하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상단 메뉴의 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;동작&lt;/span&gt; 탭을 눌러 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;작업 만들기&lt;/span&gt;를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;318&quot; data-origin-height=&quot;275&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w29b8/btsIfythNf0/TkMwmY0YF3RizSjYoeQFr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w29b8/btsIfythNf0/TkMwmY0YF3RizSjYoeQFr0/img.png&quot; data-alt=&quot;스케줄러 추가하는 예시 화면1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w29b8/btsIfythNf0/TkMwmY0YF3RizSjYoeQFr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw29b8%2FbtsIfythNf0%2FTkMwmY0YF3RizSjYoeQFr0%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; alt=&quot;스케줄러 추가하는 예시 화면1&quot; loading=&quot;lazy&quot; width=&quot;318&quot; height=&quot;275&quot; data-origin-width=&quot;318&quot; data-origin-height=&quot;275&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케줄러 추가하는 예시 화면1&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;새 작업 만들기 팝업&lt;/span&gt;이 출력된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;일반&lt;/span&gt; 탭에서 스케줄러의 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;이름&lt;/span&gt;과 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;설명&lt;/span&gt;을 입력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름과 설명은 자신이 구별할 수 있는 식별자이므로 편한대로 입력하자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;만약 작업 스케줄러의 작업이 관리자 권한이 필요한 경우는 '&lt;b&gt;가장 높은 수준의 권한으로 실행&lt;/b&gt;' 옵션을 선택하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DaH90/btsIfuEpfwu/nKUKjk971xT58QiTdkhNqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DaH90/btsIfuEpfwu/nKUKjk971xT58QiTdkhNqk/img.png&quot; data-alt=&quot;스케줄러 추가 시 일반 설정 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DaH90/btsIfuEpfwu/nKUKjk971xT58QiTdkhNqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDaH90%2FbtsIfuEpfwu%2FnKUKjk971xT58QiTdkhNqk%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; alt=&quot;스케줄러 추가 시 일반 설정 예시&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;480&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케줄러 추가 시 일반 설정 예시&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;트리거&lt;/span&gt; 탭에서 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;새로 만들기&lt;/span&gt; 버튼을 클릭한다.&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;632&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oWfFS/btsIgj90Dqp/vo4GvKBn2BRMdEXkOVtXs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oWfFS/btsIgj90Dqp/vo4GvKBn2BRMdEXkOVtXs1/img.png&quot; data-alt=&quot;스케줄러 추가 시 트리거 설정 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oWfFS/btsIgj90Dqp/vo4GvKBn2BRMdEXkOVtXs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoWfFS%2FbtsIgj90Dqp%2Fvo4GvKBn2BRMdEXkOVtXs1%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; alt=&quot;스케줄러 추가 시 트리거 설정 예시&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;480&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케줄러 추가 시 트리거 설정 예시&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;트리거 편집&lt;/span&gt; 팝업이 출력된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;자신의 상황에 맞게 스케줄러의 일정을 설정&lt;/span&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;아래 첨부된 이미지 화면에서의 예시는 1분 뒤 자동으로 설정되게끔 트리거를 설정한 예시 화면이다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;반드시 하단 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;고급 설정&lt;/span&gt;의 '&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;사용&lt;/span&gt;' 메뉴가 체크 되어 있어야만 트리거가 작동하므로 주의하자.&amp;nbsp;&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;590&quot; data-origin-height=&quot;574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baIQwG/btsIfjXrfc4/NUL1cxKBnyu3O53HmZkmp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baIQwG/btsIfjXrfc4/NUL1cxKBnyu3O53HmZkmp1/img.png&quot; data-alt=&quot;트리거 편집 설정 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baIQwG/btsIfjXrfc4/NUL1cxKBnyu3O53HmZkmp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaIQwG%2FbtsIfjXrfc4%2FNUL1cxKBnyu3O53HmZkmp1%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; alt=&quot;트리거 편집 설정 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;590&quot; height=&quot;574&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;574&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;트리거 편집 설정 예시 화면&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;트리거 탭에 내가 새로 추가한 트리거가 추가되었음을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqCaJf/btsIf0v5aYV/vlq0GcfkmUoyDoRBBzhic0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqCaJf/btsIf0v5aYV/vlq0GcfkmUoyDoRBBzhic0/img.png&quot; data-alt=&quot;트리거 추가 확인 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqCaJf/btsIf0v5aYV/vlq0GcfkmUoyDoRBBzhic0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqCaJf%2FbtsIf0v5aYV%2Fvlq0GcfkmUoyDoRBBzhic0%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; alt=&quot;트리거 추가 확인 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;480&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;트리거 추가 확인 예시 화면&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;동작&lt;/span&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;color: #ef5369; background-color: #dddddd;&quot;&gt;새로 만들기&lt;/span&gt;를 눌러 동작을 만들어보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kN7ej/btsIe0qjjGT/hhTDCSZqc8EuW7Mv1RSkPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kN7ej/btsIe0qjjGT/hhTDCSZqc8EuW7Mv1RSkPk/img.png&quot; data-alt=&quot;스케줄러 추가 시 동작 설정 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kN7ej/btsIe0qjjGT/hhTDCSZqc8EuW7Mv1RSkPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkN7ej%2FbtsIe0qjjGT%2FhhTDCSZqc8EuW7Mv1RSkPk%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; alt=&quot;스케줄러 추가 시 동작 설정 예시&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;480&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케줄러 추가 시 동작 설정 예시&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;새 동작 만들기&lt;/span&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;나 같은 경우, 데이터를 매일 자동으로 업데이트하도록 프로그래밍 코드를 만들어놓았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 매일 자동으로 업데이트 하려면 해당 소스 코드를 실행하도록 해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러기 위해 bat 확장자 파일을 이용하였으나,&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;454&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFaH2f/btsIfYSxmYr/4noTHWzjihIOlMQ9MLMZG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFaH2f/btsIfYSxmYr/4noTHWzjihIOlMQ9MLMZG1/img.png&quot; data-alt=&quot;새 동작 만들기 설정 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFaH2f/btsIfYSxmYr/4noTHWzjihIOlMQ9MLMZG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFaH2f%2FbtsIfYSxmYr%2F4noTHWzjihIOlMQ9MLMZG1%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; alt=&quot;새 동작 만들기 설정 예시&quot; loading=&quot;lazy&quot; width=&quot;454&quot; height=&quot;500&quot; data-origin-width=&quot;454&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;새 동작 만들기 설정 예시&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;조건&lt;/span&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;&lt;b&gt;이 설정은 모두가 같을 수 없으므로 본인에 맞게 설정&lt;/b&gt;하자.&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;632&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czOyUs/btsIghRTRwU/lC8SRffVzLL7wx9Iovdqrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czOyUs/btsIghRTRwU/lC8SRffVzLL7wx9Iovdqrk/img.png&quot; data-alt=&quot;스케줄러 추가 시 조건 설정 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czOyUs/btsIghRTRwU/lC8SRffVzLL7wx9Iovdqrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczOyUs%2FbtsIghRTRwU%2FlC8SRffVzLL7wx9Iovdqrk%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; alt=&quot;스케줄러 추가 시 조건 설정 예시&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;480&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케줄러 추가 시 조건 설정 예시&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;설정&lt;/span&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;u&gt;추천하는 메뉴는 '&lt;b&gt;예약된 시작 시간을 놓친 경우 가능한 대로 빨리 작업 시작&lt;/b&gt;'이다.&lt;/u&gt;&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;632&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blTaLe/btsIeTEH96B/oR1AosgidxR4k2gZo5KhBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blTaLe/btsIeTEH96B/oR1AosgidxR4k2gZo5KhBK/img.png&quot; data-alt=&quot;스케줄러 추가 시 설정 탭 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blTaLe/btsIeTEH96B/oR1AosgidxR4k2gZo5KhBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblTaLe%2FbtsIeTEH96B%2FoR1AosgidxR4k2gZo5KhBK%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; alt=&quot;스케줄러 추가 시 설정 탭 예시&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;480&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케줄러 추가 시 설정 탭 예시&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lw6qW/btsIeUDDmec/CpvpLjXSetYG0ywIm8uQJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lw6qW/btsIeUDDmec/CpvpLjXSetYG0ywIm8uQJK/img.png&quot; data-alt=&quot;작업 스케줄러 생성 확인 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lw6qW/btsIeUDDmec/CpvpLjXSetYG0ywIm8uQJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flw6qW%2FbtsIeUDDmec%2FCpvpLjXSetYG0ywIm8uQJK%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; alt=&quot;작업 스케줄러 생성 확인 예시&quot; loading=&quot;lazy&quot; width=&quot;551&quot; height=&quot;244&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;작업 스케줄러 생성 확인 예시&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;작업 스케줄러 수행 여부 확인&lt;/b&gt;&lt;/h2&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;수집된 키워드를 데이터베이스에 저장하며 내가 만든 웹 페이지에 뿌려주도록 프로그래밍 해놨다.&lt;/p&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;88&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XOKPj/btsIgEzlJkh/thZJDuQoVU2veSQmWJJLpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XOKPj/btsIgEzlJkh/thZJDuQoVU2veSQmWJJLpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XOKPj/btsIgEzlJkh/thZJDuQoVU2veSQmWJJLpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXOKPj%2FbtsIgEzlJkh%2FthZJDuQoVU2veSQmWJJLpk%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;432&quot; height=&quot;88&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;88&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;/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;832&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V118x/btsIgDHddB5/wm6nwozGp9KXqV99b2PdRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V118x/btsIgDHddB5/wm6nwozGp9KXqV99b2PdRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V118x/btsIgDHddB5/wm6nwozGp9KXqV99b2PdRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV118x%2FbtsIgDHddB5%2Fwm6nwozGp9KXqV99b2PdRk%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;832&quot; height=&quot;661&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;661&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;/p&gt;</description>
      <category>DevOps/Windows</category>
      <category>Windows</category>
      <category>윈도우</category>
      <category>자동화</category>
      <category>작업 스케줄러</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/911</guid>
      <comments>https://luvris2.tistory.com/911#entry911comment</comments>
      <pubDate>Fri, 28 Jun 2024 11:47:17 +0900</pubDate>
    </item>
    <item>
      <title>Python - 파일 입출력 관련 에러 , 'cp949' codec can't decode byte 0x84 in position 10: illegal multibyte sequence</title>
      <link>https://luvris2.tistory.com/910</link>
      <description>&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;748&quot; data-origin-height=&quot;72&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nW3pU/btsIdQgzzOf/cQmAtWmzIWHA75JAoAy9w1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nW3pU/btsIdQgzzOf/cQmAtWmzIWHA75JAoAy9w1/img.png&quot; data-alt=&quot;오류 발생 예시 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nW3pU/btsIdQgzzOf/cQmAtWmzIWHA75JAoAy9w1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnW3pU%2FbtsIdQgzzOf%2FcQmAtWmzIWHA75JAoAy9w1%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; alt=&quot;오류 발생 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;748&quot; height=&quot;72&quot; data-origin-width=&quot;748&quot; data-origin-height=&quot;72&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;오류 발생 예시 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1719458592014&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;file read/write error :
'cp949' codec can't decode byte 0x84 in position 10: illegal multibyte sequence&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;/p&gt;
&lt;pre id=&quot;code_1719458651912&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;try :
    with open(filepath, 'r') as f:
        read_data = f.read()
        return read_data
except Exception as e :
    return &quot;file read/write error : &quot; + str(e)&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;/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;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-1484169609317244&quot; data-ad-slot=&quot;2004881032&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오류가 무엇을 의미하는지는 이전에 MySQL때 같은 경험이 있어서 대략 짐작은 간다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/874&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MySQL CSV Import Error) Unhandled exception: 'cp949' codec can't decode byte : illegal multibyte sequence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;color: #ef5369; background-color: #dddddd;&quot;&gt;cp949&lt;/span&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;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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일을 읽고 쓰는 로직에서 인코딩 타입만 지정해주면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1719458970386&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with open(filepath, 'r', encoding='utf-8') as f:
	# code&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;encoding = 'utf-8'&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;/p&gt;
&lt;pre id=&quot;code_1719459055448&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;try :
    with open(filepath, 'r', encoding='utf-8') as f:
        read_data = f.read()
        return read_data
except Exception as e :
    return &quot;file read/write error : &quot; + str(e)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/Python</category>
      <category>cp949 인코딩</category>
      <category>Python</category>
      <category>파이썬</category>
      <category>파일 입출력 에러</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/910</guid>
      <comments>https://luvris2.tistory.com/910#entry910comment</comments>
      <pubDate>Thu, 27 Jun 2024 12:32:37 +0900</pubDate>
    </item>
    <item>
      <title>Spring Boot JPA - 페이지 1부터 시작하도록 설정하기, Pageable 페이징 처리 (Kotlin)</title>
      <link>https://luvris2.tistory.com/909</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Pageable 이란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Pageable&lt;/span&gt;은 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Spring Data JPA&lt;/span&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;즉, 페이징 처리를 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;Pageable&lt;/span&gt; 인터페이스를 통해 쉽게 구현 가능하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;PageNumber&lt;/b&gt; : 가져오려는 페이지의 번호, 기본적으로 0부터 시작한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;PageSize&lt;/b&gt; : 한 페이지에 포함될 데이터의 개수를 의미한다. 기본 개수는 2000개이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Sort&lt;/b&gt; : 결과를 정렬하는 기준을 의미한다. 정렬 기준을 명시하지 않으면 정렬을 하지 않고, 데이터베이스에 가져온 순서대로 결과를 반환한다.&lt;/li&gt;
&lt;/ul&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;Pageable의 페이지를 1부터 시작하게 하려면?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;PageNumber&lt;/span&gt;는 0부터 시작한다.&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;백엔드에서는 페이징 처리 시, 페이지 넘버는 0페이지부터 시작한다는 뜻이다.&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;지금부터 페이지를 1부터 시작하게 하는 방법으로 내가 아는 두 가지를 소개하려 한다.&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;1) Spring Boot 애플리케이션에서 Pageable 커스터마이징&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지 번호를 0이 아닌 1부터 시작하도록 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;Pageable&lt;/span&gt;을 커스터마이징 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;PageableHandlerMethodArgumentResolverCustomizer&lt;/span&gt;는 Spring Boot에서 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;Pageable&lt;/span&gt;의 매개변수를 자동으로 매핑하는데 사용되는 인터페이스로, 이를 통해 페이지 요청의 기본 값을 설정하거나 페이지의 인덱스를 조정하는 등 다양한 커스터마이징 작업을 수행할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1718606359904&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Bean
import org.springframework.data.web.config.PageableHandlerMethodArgumentResolverCustomizer

@SpringBootApplication
class DevbabysApplication

fun main(args: Array&amp;lt;String&amp;gt;) {
	runApplication&amp;lt;DevbabysApplication&amp;gt;(*args)
}

// Pageable 커스터마이징
@Bean
fun customize(): PageableHandlerMethodArgumentResolverCustomizer {
	return PageableHandlerMethodArgumentResolverCustomizer { p -&amp;gt;
		p.setOneIndexedParameters(true) // 페이지 1부터 시작
		p.setMaxPageSize(20) // 페이지 크기를 20으로 설정
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;setOneIndexedParameters(boolean&amp;nbsp;oneIndexedParameters)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;페이지 번호를 1부터 시작하도록 설정하는 속성&lt;/li&gt;
&lt;li&gt;기본값은 false이며, 이는 페이지가 0부터 시작함을 의미한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;setMaxPageSize(int maxPageSize)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;기본 페이지 크기를 설정하는 속성&lt;/li&gt;
&lt;li&gt;한 페이지에 표시할 항목의 수를 설정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) 서비스 로직에서 Pageable 페이지 조정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트롤러에서 받은 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;Pageable&lt;/span&gt;의 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;PageNumber&lt;/span&gt;를 서비스 로직에서 재조정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트엔드에서 전달받은 1페이지는 백엔드에서는 0페이지를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 1의 값을 받게 되면 0이 될 수 있도록 -1씩 재조정해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;Pageable&lt;/span&gt; 객체를 생성하기 위해 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;PageRequest.of&lt;/span&gt; 메서드를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1718608023945&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val pageable: Pageable = PageRequest.of(page, size, sort);&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;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;Pageable&lt;/span&gt;의 페이지 수가 조정된 코드를 간소화한 코드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1페이지부터 시작하도록하며, 페이지의 크기는 프론트엔드에서 원하는 수에 따라 조정 없이 불러올 수 있도록 하였다.&lt;/p&gt;
&lt;pre id=&quot;code_1718608290353&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// RestController
@GetMapping(&quot;product/list&quot;)
fun listAllProduct(pageable: Pageable): ResponseEntity&amp;lt;Page&amp;lt;Product&amp;gt;&amp;gt; {
    val page = productService.getProductAllList(pageable)
    return ResponseEntity.ok(page)
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1718607794662&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Service
fun getProductAllList(pageable: Pageable): Page&amp;lt;Product&amp;gt; {
    val customPage = PageRequest.of(pageable.pageNumber - 1, pageable.pageSize)
    val productList = productRepo.findAll(customPage)

    return productList
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1페이지가 1부터 조회되는지 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1페이지를 조회했을 때, 2페이지가 아닌 1페이지의 값을 불러오도록 설정이 완료되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 API 응답 결과를 보면 데이터베이스의 첫 번째 값(productId=1)이 불러온 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;557&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bH98Zc/btsH2rOpamX/woPB4eq5O3C4ArMf2tNN9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bH98Zc/btsH2rOpamX/woPB4eq5O3C4ArMf2tNN9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bH98Zc/btsH2rOpamX/woPB4eq5O3C4ArMf2tNN9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbH98Zc%2FbtsH2rOpamX%2FwoPB4eq5O3C4ArMf2tNN9k%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;671&quot; height=&quot;557&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;557&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Back End/Spring Boot</category>
      <category>Kotlin</category>
      <category>Pageable</category>
      <category>Spring Boot</category>
      <category>Spring Data JPA</category>
      <category>스프링부트</category>
      <category>코틀린</category>
      <category>페이지 1부터</category>
      <category>페이징 처리</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/909</guid>
      <comments>https://luvris2.tistory.com/909#entry909comment</comments>
      <pubDate>Tue, 18 Jun 2024 00:05:01 +0900</pubDate>
    </item>
    <item>
      <title>Hugging Face - 인공지능 모델 로컬에 다운로드 받기</title>
      <link>https://luvris2.tistory.com/908</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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; huggingface_hub 라이브러리 설치&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;허깅 페이스에서의 공개된 리파지토리는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;huggingface_hub&lt;/span&gt; 라이브러리를 통해 파일을 다운로드 받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 huggingface_hub 라이브러리가 설치되어 있지 않다면 설치를 진행한다.&lt;/p&gt;
&lt;pre id=&quot;code_1718586715613&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install huggingface_hub&lt;/code&gt;&lt;/pre&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;hf_hub_download&lt;/span&gt; 혹은 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;snapshot_download&lt;/span&gt; 함수를 이용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로는 함수에 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;repo_id&lt;/span&gt;와 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;repo_type&lt;/span&gt;을 인자로 넘겨주면 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;repo_type
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;매개변수를 생략하면 기본적으로 모델 리파지토리로 인식한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;revision
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;파일 다운로드는 기본적으로 최신 버전의 파일을 다운로드한다.&lt;/li&gt;
&lt;li&gt;만약 특정 버전의 파일을 다운로드 받으려면 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;revision&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; 매개 변수를 이용하면 된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;local_dir&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;특정 위치에 저장하고 싶을 때 사용한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;h3 data-ke-size=&quot;size23&quot;&gt;hf_hub_download 구문&lt;/h3&gt;
&lt;pre id=&quot;code_1718587225071&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from huggingface_hub import hf_hub_download
hf_hub_download(repo_id=&quot;lysandre/arxiv-nlp&quot;, filename=&quot;config.json&quot;)

### 리파지토리의 타입이 다를 경우 ###
# 데이터세트의 경우
hf_hub_download(repo_id=&quot;google/fleurs&quot;, filename=&quot;fleurs.py&quot;, repo_type=&quot;dataset&quot;)

### 특정 버전에서 파일 다운로드를 할 경우 ###
# `v1.0` 태그에서 다운로드하기
hf_hub_download(repo_id=&quot;lysandre/arxiv-nlp&quot;, filename=&quot;config.json&quot;, revision=&quot;v1.0&quot;)
# `test-branch` 브랜치에서 다운로드하기
hf_hub_download(repo_id=&quot;lysandre/arxiv-nlp&quot;, filename=&quot;config.json&quot;, revision=&quot;test-branch&quot;)
# PR #3에서 다운로드하기
hf_hub_download(repo_id=&quot;lysandre/arxiv-nlp&quot;, filename=&quot;config.json&quot;, revision=&quot;refs/pr/3&quot;)
# 특정 커밋 해시에서 다운로드하기
hf_hub_download(repo_id=&quot;lysandre/arxiv-nlp&quot;, filename=&quot;config.json&quot;, revision=&quot;877b84a8f93f2d619faa2a6e514a32beef88ab0a&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;snapshot_download 구문&lt;/h3&gt;
&lt;pre id=&quot;code_1718587368907&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from huggingface_hub import snapshot_download
snapshot_download(repo_id=&quot;lysandre/arxiv-nlp&quot;)

### 리파지토리의 타입이 다를 경우 ###
# 데이터세트의 경우
snapshot_download(repo_id=&quot;google/fleurs&quot;, repo_type=&quot;dataset&quot;)

### 특정 버전의 리파지토리를 다운로드 할 경우 ###
from huggingface_hub import snapshot_download
snapshot_download(repo_id=&quot;lysandre/arxiv-nlp&quot;, revision=&quot;refs/pr/1&quot;)&lt;/code&gt;&lt;/pre&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;사용 예시 - MMLU 데이터셋 다운로드 받아보기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용 예시로 mmlu 데이터셋을 특정 위치에 다운로드 받아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mmlu는 인공지능 언어 모델의 기능을 평가하기 위한 방법 중 하나이다.&lt;/p&gt;
&lt;pre id=&quot;code_1718588875644&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from huggingface_hub import snapshot_download
snapshot_download(repo_id=&quot;lighteval/mmlu&quot;, repo_type=&quot;dataset&quot;, local_dir=&quot;C:\\dataset\\&quot;)&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-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1079&quot; data-origin-height=&quot;173&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uISL3/btsHZWvyOdy/i1FDpYMqJADIpJq7VKL690/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uISL3/btsHZWvyOdy/i1FDpYMqJADIpJq7VKL690/img.png&quot; data-alt=&quot;MMLU 데이터셋 다운로드 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uISL3/btsHZWvyOdy/i1FDpYMqJADIpJq7VKL690/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuISL3%2FbtsHZWvyOdy%2Fi1FDpYMqJADIpJq7VKL690%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; alt=&quot;MMLU 데이터셋 다운로드 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;1079&quot; height=&quot;173&quot; data-origin-width=&quot;1079&quot; data-origin-height=&quot;173&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MMLU 데이터셋 다운로드 예시 화면&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;283&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0nUuj/btsH01vMwYd/f1ONOdC2ePj72La91bFgUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0nUuj/btsH01vMwYd/f1ONOdC2ePj72La91bFgUk/img.png&quot; data-alt=&quot;다운로드 받은 데이터셋을 로컬 경로에서 확인한 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0nUuj/btsH01vMwYd/f1ONOdC2ePj72La91bFgUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0nUuj%2FbtsH01vMwYd%2Ff1ONOdC2ePj72La91bFgUk%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; alt=&quot;다운로드 받은 데이터셋을 로컬 경로에서 확인한 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;430&quot; height=&quot;283&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;283&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;다운로드 받은 데이터셋을 로컬 경로에서 확인한 예시 화면&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>AI &amp;amp; ML/Hugging Face</category>
      <category>Huggingface</category>
      <category>model download</category>
      <category>모델 다운로드</category>
      <category>인공지능 모델 다운로드</category>
      <category>허깅 페이스</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/908</guid>
      <comments>https://luvris2.tistory.com/908#entry908comment</comments>
      <pubDate>Mon, 17 Jun 2024 10:55:18 +0900</pubDate>
    </item>
    <item>
      <title>MySQL - 외래 키 제약 조건으로 업데이트가 되지 않는 행 강제 업데이트 하기 (외래 키 제약 조건 비활성화)</title>
      <link>https://luvris2.tistory.com/907</link>
      <description>&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;A테이블&lt;/span&gt;의 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;id컬럼&lt;/span&gt;을 참조하는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;B테이블&lt;/span&gt;이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;A테이블&lt;/span&gt;의 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;id컬럼&lt;/span&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;FK 때문에 참조 관계로 엮여있어서 계속 오류가 발생하여 값을 업데이트하지 못한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;발생되는 오류는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1718343308260&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Error Code: 1451.
Cannot delete or update a parent row:
	a foreign key constraint fails
    (`database`.`FK table`, CONSTRAINT `FK Name` FOREIGN KEY (`id`)
    REFERENCES `table` (`id`))&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt; ON UPDATE CASCADE&lt;/span&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;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;/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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;외래 키 제약 조건 비활성화 쿼리&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1718343663105&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SET FOREIGN_KEY_CHECKS = 0;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;외래 키 제약 조건 활성화 쿼리&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1718343681194&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SET FOREIGN_KEY_CHECKS = 1;&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;/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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;외래 키 제약 조건이 걸린 행 업데이트 예시&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;예시를 위한 샘플 테이블&lt;/h3&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;product 테이블&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;product_id, int, PK&lt;/li&gt;
&lt;li&gt;name, varchar(255)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;product_image 테이블&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;image_id, int, PK&lt;/li&gt;
&lt;li&gt;url, varchar(255)&lt;/li&gt;
&lt;li&gt;product_id, int, FK ( product(product_id) )&lt;/li&gt;
&lt;/ul&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;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;product 테이블&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 46.278%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.1767%; text-align: center;&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.7346%; text-align: center;&quot;&gt;&lt;b&gt; product_id &lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 30.5052%; text-align: center;&quot;&gt;&lt;b&gt; name &lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.1767%; text-align: center;&quot;&gt;1행&lt;/td&gt;
&lt;td style=&quot;width: 26.7346%; text-align: center;&quot;&gt;999&lt;/td&gt;
&lt;td style=&quot;width: 30.5052%; text-align: center;&quot;&gt;아이템1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;product_image 테이블&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 65.2326%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.8837%; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 17.2093%; text-align: center;&quot;&gt;&lt;b&gt; image_id &lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 18.9382%; text-align: center;&quot;&gt;&lt;b&gt; url &lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.2014%; text-align: center;&quot;&gt;&lt;b&gt; product_id &lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.8837%; text-align: center;&quot;&gt;1행&lt;/td&gt;
&lt;td style=&quot;width: 17.2093%; text-align: center;&quot;&gt;123&lt;/td&gt;
&lt;td style=&quot;width: 18.9382%; text-align: center;&quot;&gt;https:~~&lt;/td&gt;
&lt;td style=&quot;width: 19.2014%; text-align: center;&quot;&gt;999&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외래 키로 참조하는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;product_id&lt;/span&gt;의 값이 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;999&lt;/span&gt;이지만, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;1&lt;/span&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;h3 data-ke-size=&quot;size23&quot;&gt;작성 쿼리&lt;/h3&gt;
&lt;pre id=&quot;code_1718344274260&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 외래 키 제약 조건 비활성화
SET FOREIGN_KEY_CHECKS = 0;

-- product 테이블 강제 업데이트
update product
set product_id = 1;

-- product_image 테이블 강제 업데이트
update product_image
set product_id = 1;

-- 외래 키 제약 조건 활성화
SET FOREIGN_KEY_CHECKS = 1;&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;변경 전: product_id 999&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;565&quot; data-origin-height=&quot;199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uv5hF/btsH0cDqBrZ/JepqmaAA0OMHk1sJ5O0Ji0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uv5hF/btsH0cDqBrZ/JepqmaAA0OMHk1sJ5O0Ji0/img.png&quot; data-alt=&quot;외래 키 걸려 있는 행을 강제 업데이트 하기 전의 예시 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uv5hF/btsH0cDqBrZ/JepqmaAA0OMHk1sJ5O0Ji0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuv5hF%2FbtsH0cDqBrZ%2FJepqmaAA0OMHk1sJ5O0Ji0%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; alt=&quot;외래 키 걸려 있는 행을 강제 업데이트 하기 전의 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;565&quot; height=&quot;199&quot; data-origin-width=&quot;565&quot; data-origin-height=&quot;199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;외래 키 걸려 있는 행을 강제 업데이트 하기 전의 예시 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;변경 후: product_id 1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5Da9S/btsHZS6oYJe/kka49I2YPLIRyKwAqy7N70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5Da9S/btsHZS6oYJe/kka49I2YPLIRyKwAqy7N70/img.png&quot; data-alt=&quot;외래 키 걸려 있는 행을 강제 업데이트 한 후의 예시 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5Da9S/btsHZS6oYJe/kka49I2YPLIRyKwAqy7N70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5Da9S%2FbtsHZS6oYJe%2Fkka49I2YPLIRyKwAqy7N70%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; alt=&quot;외래 키 걸려 있는 행을 강제 업데이트 한 후의 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;576&quot; height=&quot;199&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;외래 키 걸려 있는 행을 강제 업데이트 한 후의 예시 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Database/MySQL</category>
      <category>fk 업데이트</category>
      <category>fk 참조 관계</category>
      <category>MySQL</category>
      <category>외래 키</category>
      <category>외래 키 제약 조건</category>
      <category>참조 무결성</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/907</guid>
      <comments>https://luvris2.tistory.com/907#entry907comment</comments>
      <pubDate>Fri, 14 Jun 2024 15:03:47 +0900</pubDate>
    </item>
    <item>
      <title>Git - 저장소에 이미 Commit/Push 된 이전 커밋 버전 삭제하기 (커밋 히스토리 제거하기)</title>
      <link>https://luvris2.tistory.com/906</link>
      <description>&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;/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;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;/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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;git log&lt;/span&gt;를 통해서 확인할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1718173833486&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;git log&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;/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;842&quot; data-origin-height=&quot;329&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kUSMh/btsHWRlnkk5/YMkOEdIs5VBL3tk4JGpPs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kUSMh/btsHWRlnkk5/YMkOEdIs5VBL3tk4JGpPs1/img.png&quot; data-alt=&quot;커밋 이전 버전을 확인하기 위한 경로 표시 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kUSMh/btsHWRlnkk5/YMkOEdIs5VBL3tk4JGpPs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkUSMh%2FbtsHWRlnkk5%2FYMkOEdIs5VBL3tk4JGpPs1%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; alt=&quot;커밋 이전 버전을 확인하기 위한 경로 표시 이미지&quot; loading=&quot;lazy&quot; width=&quot;842&quot; height=&quot;329&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;329&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;커밋 이전 버전을 확인하기 위한 경로 표시 이미지&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;622&quot; data-origin-height=&quot;421&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IcAGs/btsHVvjwIBx/ZkxyboBTWoo60VHT0pxUJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IcAGs/btsHVvjwIBx/ZkxyboBTWoo60VHT0pxUJ1/img.png&quot; data-alt=&quot;깃허브에 이전 버전을 확인하는 목록 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IcAGs/btsHVvjwIBx/ZkxyboBTWoo60VHT0pxUJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIcAGs%2FbtsHVvjwIBx%2FZkxyboBTWoo60VHT0pxUJ1%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; alt=&quot;깃허브에 이전 버전을 확인하는 목록 예시&quot; loading=&quot;lazy&quot; width=&quot;622&quot; height=&quot;421&quot; data-origin-width=&quot;622&quot; data-origin-height=&quot;421&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;깃허브에 이전 버전을 확인하는 목록 예시&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;특정 커밋 시점으로 되돌리기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 커밋 버전으로 되돌리려면 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;git reset&lt;/span&gt;이라는 명령어를 이용하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1718157979443&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# option #
# --soft
# --mixed
# --hard
git reset --soft #commit hash&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;/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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgvimC/btsHUqctoHg/YJInxCZeTZuJC7eKLO2oF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgvimC/btsHUqctoHg/YJInxCZeTZuJC7eKLO2oF0/img.png&quot; data-alt=&quot;커밋 버전 복사 경로 예시 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgvimC/btsHUqctoHg/YJInxCZeTZuJC7eKLO2oF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgvimC%2FbtsHUqctoHg%2FYJInxCZeTZuJC7eKLO2oF0%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; alt=&quot;커밋 버전 복사 경로 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;432&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;커밋 버전 복사 경로 예시 이미지&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;b&gt;리셋&amp;nbsp;옵션에 따라 디렉토리의 파일이 변경될 수 있는데 주의&lt;/b&gt;하여야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 작업한 내용은 그대로 유지하고 커밋만 삭제할 예정이기 때문에 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;--soft&lt;/span&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;color: #ef5369; background-color: #dddddd;&quot;&gt;--hard&lt;/span&gt; 옵션을 사용하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 현재 작업 중인 내용은 사라질 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1718172045932&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 예시
git reset --soft e0d9adff8932b05bf864d~&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;add index page&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;/p&gt;
&lt;pre id=&quot;code_1718172498563&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push -f&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;/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;645&quot; data-origin-height=&quot;235&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAsemd/btsHWeBZoxS/BF5Aa0yRmE5C4UoKvkIbS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAsemd/btsHWeBZoxS/BF5Aa0yRmE5C4UoKvkIbS0/img.png&quot; data-alt=&quot;특정 커밋 상태로 되돌아 간 후, 이후의 커밋은 삭제된 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAsemd/btsHWeBZoxS/BF5Aa0yRmE5C4UoKvkIbS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAsemd%2FbtsHWeBZoxS%2FBF5Aa0yRmE5C4UoKvkIbS0%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; alt=&quot;특정 커밋 상태로 되돌아 간 후, 이후의 커밋은 삭제된 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;645&quot; height=&quot;235&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;235&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;특정 커밋 상태로 되돌아 간 후, 이후의 커밋은 삭제된 예시 화면&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;&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;reset 옵션 설명&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;--soft&lt;/h3&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;b&gt;예시)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;A 커밋 -&amp;gt; B 커밋이 있는데, B 커밋을 취소하고 싶을 때 사용&lt;/li&gt;
&lt;li&gt;B 커밋의 내용은 그대로 스테이징 영역에 남아 있어서 다시 커밋하거나 수정할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;--mixed&lt;/h3&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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;A 커밋 -&amp;gt; B 커밋이 있는데, B 커밋을 취소하고 싶을 때 사용&lt;/li&gt;
&lt;li&gt;B 커밋의 내용은 스테이징 영역에서 사라지고, 작업 디렉토리에 그대로 남아 있어서 다시 스테이징해서 커밋할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;--hard&lt;/h3&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;b&gt;되돌릴 수 없는 변경을 초래할 수 있으므로 신중하게 사용&lt;/b&gt;해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;A 커밋 -&amp;gt; B 커밋이 있는데, B 커밋을 취소하고 싶을 때 사용&lt;/li&gt;
&lt;li&gt;B 커밋의 내용은 스테이징과 작업 디렉토리에서 모두 사라져서 다시 커밋할 수 없고, 변경 사항 모두 사라진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps/Git</category>
      <category>commit</category>
      <category>git</category>
      <category>github</category>
      <category>깃</category>
      <category>깃허브</category>
      <category>커밋 되돌리기</category>
      <category>커밋 삭제하기</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/906</guid>
      <comments>https://luvris2.tistory.com/906#entry906comment</comments>
      <pubDate>Wed, 12 Jun 2024 15:28:17 +0900</pubDate>
    </item>
    <item>
      <title>Spring Boot - application.properties의 민감 정보 분리하기</title>
      <link>https://luvris2.tistory.com/905</link>
      <description>&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;application.properties&lt;/span&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기본 설정 파일의 민감 정보 분리하기&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;추가 설정 파일 만들기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 설정 파일인 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;application.properties&lt;/span&gt;가 존재하는 같은 경로에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;민감 정보를 따로 저장할 설정 파일(&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;*.properties&lt;/span&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;포스팅에서는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;application-database.properties&lt;/span&gt;라고 하겠다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;215&quot; data-origin-height=&quot;60&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JLM7g/btsHUcLSxCu/Eb1Xdtbu9DoP5tp9CYfcR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JLM7g/btsHUcLSxCu/Eb1Xdtbu9DoP5tp9CYfcR1/img.png&quot; data-alt=&quot;프로젝트 내 속성 파일을 추가한 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JLM7g/btsHUcLSxCu/Eb1Xdtbu9DoP5tp9CYfcR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJLM7g%2FbtsHUcLSxCu%2FEb1Xdtbu9DoP5tp9CYfcR1%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; alt=&quot;프로젝트 내 속성 파일을 추가한 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;215&quot; height=&quot;60&quot; data-origin-width=&quot;215&quot; data-origin-height=&quot;60&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로젝트 내 속성 파일을 추가한 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로 만든 설정 파일(&lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;application-database.properties&lt;/span&gt;)에 데이터베이스 접속 정보를 입력한다.&lt;/p&gt;
&lt;pre id=&quot;code_1718094592121&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# application-database.properties #
spring.datasource.url = jdbc:mysql://~
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.datasource.username = ~
spring.datasource.password = ~&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D8aFY/btsHVX0xBy4/nJrPkLHOqiYRHl4vkhGiWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D8aFY/btsHVX0xBy4/nJrPkLHOqiYRHl4vkhGiWK/img.png&quot; data-alt=&quot;데이터베이스 접속 설정 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D8aFY/btsHVX0xBy4/nJrPkLHOqiYRHl4vkhGiWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD8aFY%2FbtsHVX0xBy4%2FnJrPkLHOqiYRHl4vkhGiWK%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; alt=&quot;데이터베이스 접속 설정 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;703&quot; height=&quot;156&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;156&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;데이터베이스 접속 설정 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 기본 설정 파일(&lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;application.properties&lt;/span&gt;)에 추가 설정 파일(&lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;application-database.properties&lt;/span&gt;)을 포함시켜 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가 설정 파일을 가져오는 구문은 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1718094986057&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring.config.import = 추가 설정 파일명 입력&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;pre id=&quot;code_1718094966898&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# application.properties #

# 기본 설정
server.port=8080
logging.level.root=DEBUG

# 데이터베이스 설정
spring.config.import=application-database.properties&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Back End/Spring Boot</category>
      <category>application.properties</category>
      <category>Spring Boot</category>
      <category>기본 설정 파일</category>
      <category>민감 정보 분리</category>
      <category>스프링 부트</category>
      <category>추가 설정 파일 만들기</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/905</guid>
      <comments>https://luvris2.tistory.com/905#entry905comment</comments>
      <pubDate>Tue, 11 Jun 2024 17:39:38 +0900</pubDate>
    </item>
    <item>
      <title>Kotlin - Data Class에 대해 (Class와의 차이점, 샘플 코드, 생성 메서드 직접 구현해보기)</title>
      <link>https://luvris2.tistory.com/904</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;간단히 알아보는 Data Class란?&lt;/b&gt;&lt;/h2&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;전반적으로 데이터 클래스는 데이터 모델 및 DTO를 만들고 관리하기 위해 사용된다.&lt;/p&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: #ef5369; background-color: #dddddd;&quot;&gt;data class&lt;/span&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;자동으로 생성되는 메서드는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;equals() : 객체의 내용 비교&lt;/li&gt;
&lt;li&gt;hashCode() : 해시 기반 자료구조에서 사용&lt;/li&gt;
&lt;li&gt;toString() : 객체를 문자열로 표현&lt;/li&gt;
&lt;li&gt;copy() : 객체의 일부 속성만 변경한 새 객체 생성&lt;/li&gt;
&lt;li&gt;componentN() : 구조 분해 할당&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Q. 일반 Class와의 차이는?&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;일반 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;class&lt;/span&gt;는 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;data class&lt;/span&gt;와 달리 위의 기능들이 자동으로 생성되지 않기 때문에 직접 구현해야 한다.&lt;/li&gt;
&lt;/ul&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;Data Class는 왜 쓰는걸까?&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;코드의 간결성 제공 및 반복적인 코드 감소&lt;/h3&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;명시적으로 작성할 필요 없이 데이터 모델을 간결하게 정의하는 방법을 제공한다.&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;h3 data-ke-size=&quot;size23&quot;&gt;안정적인 데이터 제공&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 기본 생성자 매개 변수는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;val&lt;/span&gt; 또는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;var&lt;/span&gt;로 선언된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 클래스는 불변성(Immutability)을 제공하도록 설계되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 기본적으로 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;data class&lt;/span&gt;의 속성은&amp;nbsp;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;val(읽기 전용)&lt;/span&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;Q. var로 선언하면 불변성이 제공되는 것이 아니지 않을까?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 명시적으로 속성을 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;var&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;/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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;예시로 알아보는 데이터 클래스 사용법&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터 클래스 선언&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 앞에 data 키워드를 선언한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 생성자로 생성될 매개 변수를 정의한다.&lt;/p&gt;
&lt;pre id=&quot;code_1718006804608&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;data class User (
	val name: String,
    val age: Int
)&lt;/code&gt;&lt;/pre&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;/h3&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;pre id=&quot;code_1718006921814&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun main() {
	// User 데이터 클래스에 값 추가
    val user1 = User(&quot;Eunbyeol&quot;, 35)
    val user2 = User(&quot;tester&quot;, 1)
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;위와 같이 코드를 작성하게 되면 각각 user1, user2에 대한 유용한 메서드가 자동으로 생성된다.&lt;/li&gt;
&lt;/ul&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;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;주석을 보고 어떻게 작동하는지 이해해보자.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1718007136973&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun main() {
	// User 데이터 클래스에 값 추가
    val user1 = User(&quot;Eunbyeol&quot;, 35)
    val user2 = User(&quot;Eunbyeol&quot;, 35)
    
    // equals() 메서드 자동 생성
    println(user1 == user2) // true

    // hashCode() 메서드 자동 생성
    println(user1.hashCode() == user2.hashCode()) // true

    // toString() 메서드 자동 생성
    println(user1) // User(name=Eunbyeol, age=35)

    // copy() 메서드 자동 생성
    val user3 = user1.copy(age = 999)
    println(user3) // User(name=Eunbyeol, age=999)

    // componentN() 메서드 자동 생성
    val (name, age) = user1
    println(&quot;Name: $name, Age: $age&quot;) // Name: Eunbyeol, Age: 35
}&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;&lt;b&gt;일반 클래스로 위와 같은 메서드를 사용하면 어떤 결과가 나올까?&lt;/b&gt;&lt;/h2&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;h3 data-ke-size=&quot;size23&quot;&gt;일반 클래스 선언&lt;/h3&gt;
&lt;pre id=&quot;code_1718007688217&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class RegularUser(
	val name: String,
    val age: Int
) { }&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;데이터 클래스에서 확인했던 메서드의 결과값과 전혀 다른 값이 출력되는 것을 확인할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1718007768250&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun main() {
    // User 일반 클래스에 값 추가
    val user4 = RegularUser(&quot;Eunbyeol&quot;, 35)
    val user5 = RegularUser(&quot;Eunbyeol&quot;, 35)

    // equals() 메서드
    println(user4 == user5) // false

    // hashCode() 메서드
    println(user4.hashCode() == user5.hashCode()) // false

    // toString() 메서드
    println(user4) // org.example.RegularUser@79fc0f2f
}&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;일반 클래스 equals(), hashCode(), toString() 메서드 직접 구현 코드&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;생성자의 매개변수를 확인하여 오버라이딩한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1718007821601&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class RegularUser(val name: String, val age: Int) {

    // equals() 메서드 직접 구현
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other !is RegularUser) return false
        return name == other.name &amp;amp;&amp;amp; age == other.age
    }

    // hashCode() 메서드 직접 구현
    override fun hashCode(): Int {
        return name.hashCode() * 31 + age
    }

    // toString() 메서드 직접 구현
    override fun toString(): String {
        return &quot;RegularUser(name=$name, age=$age)&quot;
    }
}&lt;/code&gt;&lt;/pre&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;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;데이터 클래스에서 확인했던 값과 동일한 것을 확인할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1718007974859&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun main() {
    // User 일반 클래스에 값 추가
    val user4 = RegularUser(&quot;Eunbyeol&quot;, 35)
    val user5 = RegularUser(&quot;Eunbyeol&quot;, 35)

    // equals() 메서드
    println(user4 == user5) // true

    // hashCode() 메서드
    println(user4.hashCode() == user5.hashCode()) // true

    // toString() 메서드
    println(user4) // RegularUser(name=Eunbyeol, age=35)
}&lt;/code&gt;&lt;/pre&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;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;추가 정보. 해시 코드를 구할 때 31을 사용하는 이유는?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단히 요약하면 31이라는 숫자는 소수(Prime Number)로,&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;문자열과 같은 일반적인 데이터에 대해 좋은 분포를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 Java의 String. Integer 등 많은 핵심 클래스들도 31이라는 숫자를 사용한다.&lt;/p&gt;</description>
      <category>Programming/Kotlin</category>
      <category>class</category>
      <category>data class</category>
      <category>Kotlin</category>
      <category>데이터 클래스</category>
      <category>코틀린</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/904</guid>
      <comments>https://luvris2.tistory.com/904#entry904comment</comments>
      <pubDate>Mon, 10 Jun 2024 17:38:48 +0900</pubDate>
    </item>
    <item>
      <title>MySQL Workbench - ERD 추출하여 그리기, 추출된 ERD를 이미지로 저장하기</title>
      <link>https://luvris2.tistory.com/903</link>
      <description>&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;/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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;ERD(Entity Relationship Diagram)&lt;/span&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;이번 포스팅에서는 ERD를 직접 그리는 방법보다는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 MySQL 데이터베이스 내에 설계되어 있는 데이터 테이블을 추출하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ERD로 자동으로 그려주는 방법에 대해 설명하고자 한다.&lt;/p&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;u&gt;MySQL Workbench의 기능을 이용하여 ERD를 그리는 것을 목적&lt;/u&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;실제 데이터베이스의 테이블을 ERD로 그리기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;MySQL Workbench&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;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Database&lt;/span&gt; - &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Reverse Engineer&lt;/span&gt; 선택&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;494&quot; data-origin-height=&quot;247&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3dn0A/btsHOL8uSOQ/uygntLOhPKXMeaZfFFlmM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3dn0A/btsHOL8uSOQ/uygntLOhPKXMeaZfFFlmM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3dn0A/btsHOL8uSOQ/uygntLOhPKXMeaZfFFlmM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3dn0A%2FbtsHOL8uSOQ%2FuygntLOhPKXMeaZfFFlmM1%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;494&quot; height=&quot;247&quot; data-origin-width=&quot;494&quot; data-origin-height=&quot;247&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: #ef5369; background-color: #dddddd;&quot;&gt;MySQL Connections&lt;/span&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;접속할 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Hostname&lt;/span&gt;, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Port&lt;/span&gt;, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Username&lt;/span&gt;, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Password&lt;/span&gt;를 확인하고 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Next&lt;/span&gt; 버튼을 누른다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIN2Np/btsHOCDWwuv/LRgXaMrRWNwkhgKn2rOn8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIN2Np/btsHOCDWwuv/LRgXaMrRWNwkhgKn2rOn8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIN2Np/btsHOCDWwuv/LRgXaMrRWNwkhgKn2rOn8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIN2Np%2FbtsHOCDWwuv%2FLRgXaMrRWNwkhgKn2rOn8k%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;886&quot; height=&quot;693&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;693&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;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Stored Connection&lt;/span&gt;을 눌러 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Manage Stored Connections&lt;/span&gt;을 통해 프로필을 새로 지정하거나&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;671&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7lv7v/btsHPe99AUc/PTxqxqd3ayVLEVQeJUDkY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7lv7v/btsHPe99AUc/PTxqxqd3ayVLEVQeJUDkY1/img.png&quot; data-alt=&quot;프로필을 새로 지정하기 위한 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7lv7v/btsHPe99AUc/PTxqxqd3ayVLEVQeJUDkY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7lv7v%2FbtsHPe99AUc%2FPTxqxqd3ayVLEVQeJUDkY1%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; alt=&quot;프로필을 새로 지정하기 위한 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;671&quot; height=&quot;220&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로필을 새로 지정하기 위한 예시 화면&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Next&lt;/span&gt;를 눌러 다음 단계로 진입해준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cO0vZm/btsHQdbAnHK/qUah48KirzTNkN41zWssQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cO0vZm/btsHQdbAnHK/qUah48KirzTNkN41zWssQK/img.png&quot; data-alt=&quot;데이터베이스 접속 확인 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cO0vZm/btsHQdbAnHK/qUah48KirzTNkN41zWssQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcO0vZm%2FbtsHQdbAnHK%2FqUah48KirzTNkN41zWssQK%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; alt=&quot;데이터베이스 접속 확인 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;886&quot; height=&quot;693&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;693&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;데이터베이스 접속 확인 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&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: #ef5369; background-color: #dddddd;&quot;&gt;ERD&lt;/span&gt;를 추출할 데이터베이스를 선택 한 후, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Next&lt;/span&gt;를 눌러 다음 단계로 진입한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포스팅에서는 토이 프로젝트를 위해 간이 설계된 &quot;&lt;b&gt;devbabys_shoppingmall&lt;/b&gt;&quot;라는 이름의 데이터베이스를 선택하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKCVDo/btsHOI5dt36/Uy8oXX4ElP8bDbGdVKvswK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKCVDo/btsHOI5dt36/Uy8oXX4ElP8bDbGdVKvswK/img.png&quot; data-alt=&quot;ERD를 추출할 데이터베이스 선택 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKCVDo/btsHOI5dt36/Uy8oXX4ElP8bDbGdVKvswK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKCVDo%2FbtsHOI5dt36%2FUy8oXX4ElP8bDbGdVKvswK%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; alt=&quot;ERD를 추출할 데이터베이스 선택 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;886&quot; height=&quot;693&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;693&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ERD를 추출할 데이터베이스 선택 예시 화면&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;ERD&lt;/span&gt;를 그릴 스키마를 찾았다는 문구가 출력된다. &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Next&lt;/span&gt;를 눌러 다음 단계로 진입하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oZzSN/btsHPP3bsrU/L52FqNHsTSWHotLEoxImtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oZzSN/btsHPP3bsrU/L52FqNHsTSWHotLEoxImtK/img.png&quot; data-alt=&quot;ERD를 만들 스키마를 찾았다는 내용의 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oZzSN/btsHPP3bsrU/L52FqNHsTSWHotLEoxImtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoZzSN%2FbtsHPP3bsrU%2FL52FqNHsTSWHotLEoxImtK%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; alt=&quot;ERD를 그릴 스키마를 찾았다는 내용의 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;886&quot; height=&quot;693&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;693&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ERD를 만들 스키마를 찾았다는 내용의 예시 화면&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;ERD&lt;/span&gt;를 구성할 테이블 목록을 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Show Filter&lt;/span&gt; 버튼을 누르면 테이블의 목록이 출력된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 내가 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;ERD&lt;/span&gt;로 그릴 테이블만 선택할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포스팅에서는 모든 테이블의 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;ERD&lt;/span&gt;를 그릴 예정이므로 따로 제외하지 않고 진행하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;ERD&lt;/span&gt;를 구성할 때에는 각 주제의 성격에 맞는 테이블들로 구성하여 문서화하는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구성할 테이블 목록을 선택하였으면 하단의 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Execute&lt;/span&gt; 버튼을 누른다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q9nCk/btsHP2BeBiQ/9tBh07AOt2Y5Fjmy3aPK0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q9nCk/btsHP2BeBiQ/9tBh07AOt2Y5Fjmy3aPK0k/img.png&quot; data-alt=&quot;ERD를 구성할 테이블 선택 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q9nCk/btsHP2BeBiQ/9tBh07AOt2Y5Fjmy3aPK0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ9nCk%2FbtsHP2BeBiQ%2F9tBh07AOt2Y5Fjmy3aPK0k%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; alt=&quot;ERD를 구성할 테이블 선택 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;886&quot; height=&quot;693&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;693&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ERD를 구성할 테이블 선택 예시 화면&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Reverse Engineer Database 팝업&lt;/span&gt;은 ERD가 생성되었다는 문구들로 구성되어있기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따로 설정할 필요 없이 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Next&lt;/span&gt; - &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Finish&lt;/span&gt;를 눌러 팝업을 닫는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;MySQL Workbench&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;ERD 다이어그램&lt;/span&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;700&quot; data-origin-height=&quot;444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/73SEK/btsHQLTeV8u/1lxqhvKWokcYNHJu6DdWB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/73SEK/btsHQLTeV8u/1lxqhvKWokcYNHJu6DdWB1/img.png&quot; data-alt=&quot;MySQL 워크벤치를 통해 ERD 다이어그램을 자동 생성한 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/73SEK/btsHQLTeV8u/1lxqhvKWokcYNHJu6DdWB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F73SEK%2FbtsHQLTeV8u%2F1lxqhvKWokcYNHJu6DdWB1%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; alt=&quot;MySQL 워크벤치를 통해 ERD 다이어그램을 자동 생성한 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;444&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;444&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MySQL 워크벤치를 통해 ERD 다이어그램을 자동 생성한 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&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;ERD 이미지로 저장하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;ERD 다이어그램&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: #ef5369; background-color: #dddddd;&quot;&gt;MySQL 워크벤치 상단 메뉴&lt;/span&gt;에서 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;File&lt;/span&gt; - &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Export&lt;/span&gt;를 선택하고, 생성할 파일의 종류를 선택한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포스팅에서는 이미지 파일로 만드는 것이 목적이기 때문에 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;Export as PNG&lt;/span&gt;를 선택하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;609&quot; data-origin-height=&quot;431&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pM316/btsHPg1ltAL/5NdqoCe3rQwO50QpscDi1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pM316/btsHPg1ltAL/5NdqoCe3rQwO50QpscDi1k/img.png&quot; data-alt=&quot;생성된 ERD 다이어그램을 이미지로 변환화는 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pM316/btsHPg1ltAL/5NdqoCe3rQwO50QpscDi1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpM316%2FbtsHPg1ltAL%2F5NdqoCe3rQwO50QpscDi1k%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; alt=&quot;생성된 ERD 다이어그램을 이미지로 변환화는 과정&quot; loading=&quot;lazy&quot; width=&quot;609&quot; height=&quot;431&quot; data-origin-width=&quot;609&quot; data-origin-height=&quot;431&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;생성된 ERD 다이어그램을 이미지로 변환화는 과정&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;&quot;&lt;b&gt;test erd.png&lt;/b&gt;&quot;란 이름으로 내 컴퓨터에 저장하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장된 ERD 이미지는 이상 없이 깔끔하게 잘 저장되었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;958&quot; data-origin-height=&quot;798&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MIgvL/btsHPX1b3Kn/B6eAZnvkR5V9ffKCAPTg81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MIgvL/btsHPX1b3Kn/B6eAZnvkR5V9ffKCAPTg81/img.png&quot; data-alt=&quot;추출된 ERD 이미지 파일을 불러온 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MIgvL/btsHPX1b3Kn/B6eAZnvkR5V9ffKCAPTg81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMIgvL%2FbtsHPX1b3Kn%2FB6eAZnvkR5V9ffKCAPTg81%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; alt=&quot;추출된 ERD 이미지 파일을 불러온 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;958&quot; height=&quot;798&quot; data-origin-width=&quot;958&quot; data-origin-height=&quot;798&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;추출된 ERD 이미지 파일을 불러온 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Database/MySQL</category>
      <category>ERD</category>
      <category>erd 다이어그램</category>
      <category>MySQL</category>
      <category>Workbench</category>
      <category>데이터 모델링</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/903</guid>
      <comments>https://luvris2.tistory.com/903#entry903comment</comments>
      <pubDate>Wed, 5 Jun 2024 17:07:34 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL - 스케줄러 사용법 (스케줄 생성, 작업 일정 설정, 스케줄러 실행)</title>
      <link>https://luvris2.tistory.com/902</link>
      <description>&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 실제로 서비스 중인 데이터베이스 서버에 대량의 값을 넣으려면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다량의 I/O 작업으로 인해 과부하가 발생되어 데이터베이스의 성능이 저하되므로 함부로 작업을 수행하기는 어렵다.&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;&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;/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;SQL Server Agent 가 없거나 중지 상태 일 경우 해결 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/901&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MSSQL - SQL Server Agent 활성화하기 (SQL Server 에이전트 설치)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SQL Server Agent을 설정하려고 하는데 SQL Server 구성 관리자가 없을 경우 해결 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/900&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MSSQL - SQL Server 구성 관리자 없음, 설치, 다운로드, SQL Server Configuration Manager 위치&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;367&quot; data-origin-height=&quot;516&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TLZXR/btsHFIRswEf/znBIiSGisKNCjfXrLlsfA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TLZXR/btsHFIRswEf/znBIiSGisKNCjfXrLlsfA0/img.png&quot; data-alt=&quot;스케줄러 생성 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TLZXR/btsHFIRswEf/znBIiSGisKNCjfXrLlsfA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTLZXR%2FbtsHFIRswEf%2FznBIiSGisKNCjfXrLlsfA0%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; alt=&quot;작업 스케줄러 생성 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;367&quot; height=&quot;516&quot; data-origin-width=&quot;367&quot; data-origin-height=&quot;516&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케줄러 생성 예시 화면&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;스케줄러 설정하기 - 기본 설정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;New Job&lt;/b&gt; - &lt;b&gt;General&lt;/b&gt; (새 작업 - 일반)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Name&lt;/b&gt;(이름) : test&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Category&lt;/b&gt;(범주) : 테스트이므로 따로 지정하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;579&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7R9Rv/btsHIb5Iy2a/McNRW0Bkde63kaFOxK27yK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7R9Rv/btsHIb5Iy2a/McNRW0Bkde63kaFOxK27yK/img.png&quot; data-alt=&quot;스케줄러 일반 설정 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7R9Rv/btsHIb5Iy2a/McNRW0Bkde63kaFOxK27yK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7R9Rv%2FbtsHIb5Iy2a%2FMcNRW0Bkde63kaFOxK27yK%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; alt=&quot;작업 스케줄러 일반 설정 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;805&quot; height=&quot;579&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;579&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케줄러 일반 설정 예시 화면&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;스케줄러 설정하기 - 수행할 작업 설정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;New Job&lt;/b&gt; - &lt;b&gt;Steps&lt;/b&gt; (새 작업 - 단계)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;New&lt;/b&gt;(새로 만들기)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;579&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kw49S/btsHHkbip94/Bngk1ZyeqZebYzegm7J97k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kw49S/btsHHkbip94/Bngk1ZyeqZebYzegm7J97k/img.png&quot; data-alt=&quot;스케줄러 단계 설정 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kw49S/btsHHkbip94/Bngk1ZyeqZebYzegm7J97k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fkw49S%2FbtsHHkbip94%2FBngk1ZyeqZebYzegm7J97k%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; alt=&quot;작업 스케줄러 단계 설정 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;805&quot; height=&quot;579&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;579&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케줄러 단계 설정 예시 화면&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;b&gt; New Job&lt;/b&gt; - &lt;b&gt;Steps&lt;/b&gt; - &lt;b&gt;New Job Step&lt;/b&gt; (새 작업 - 단계 - 새 작업 단계)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Step name&lt;/b&gt;(단계 이름) : 사용자가 식별이 가능한 이름 정의&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Database&lt;/b&gt;(데이터베이스) : 사용할 데이터베이스&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Command&lt;/b&gt;(명령) : 데이터베이스 내에서 실행할 쿼리 내용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;포스팅에서는 테스트 테이블에 값 하나를 추가하는 내용의 스케줄러를 작성하였음.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1717041674124&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 예시 작성 쿼리
insert into t1 (col1, col2)
	values (val1, val2)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;579&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwBMFN/btsHHNxhPx1/kBx17fxxM4WNQIFAKPbIrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwBMFN/btsHHNxhPx1/kBx17fxxM4WNQIFAKPbIrk/img.png&quot; data-alt=&quot;스케줄러 수행할 작업 정의 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwBMFN/btsHHNxhPx1/kBx17fxxM4WNQIFAKPbIrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwBMFN%2FbtsHHNxhPx1%2FkBx17fxxM4WNQIFAKPbIrk%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; alt=&quot;작업 스케줄러 수행할 작업 정의 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;805&quot; height=&quot;579&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;579&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케줄러 수행할 작업 정의 예시 화면&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;스케줄러 설정하기 - 작업을 수행할 시간 및 빈도 설정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;New&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Job&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Schedules&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(새 작업 - 일정)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;New&lt;/b&gt;(새로 만들기)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;579&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cboTpJ/btsHG8I26He/U8NHZE0LLvkB4mOskiUIzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cboTpJ/btsHG8I26He/U8NHZE0LLvkB4mOskiUIzK/img.png&quot; data-alt=&quot;스케줄러 일정 설정 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cboTpJ/btsHG8I26He/U8NHZE0LLvkB4mOskiUIzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcboTpJ%2FbtsHG8I26He%2FU8NHZE0LLvkB4mOskiUIzK%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; alt=&quot;작업 스케줄러 일정 설정 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;805&quot; height=&quot;579&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;579&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케줄러 일정 설정 예시 화면&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;b&gt;New Job&lt;/b&gt; - &lt;b&gt;Schedules&lt;/b&gt; - &lt;b&gt;New&lt;/b&gt; &lt;b&gt;Job&lt;/b&gt; &lt;b&gt;Schedule&lt;/b&gt; (새 작업 - 일정 - 새 작업 일정)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Name&lt;/b&gt;(이름) : 사용자가 식별 가능한 작업 일정 이름 정의&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Schedule&lt;/b&gt; &lt;b&gt;type&lt;/b&gt;(일정 유형)
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Start automatically when SQL Server Agent starts&lt;/b&gt; (SQL Server 에이전트가 시작될 때 자동으로 시작)
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;서버 재부팅 후 초기화 작업을 수행할 때 사용 (예: 로그 파일 초기화)&lt;/li&gt;
&lt;li&gt;서버 중단 및 재개를 할 때 필요한 작업을 자동으로 실행하도록 할 때 사용 (예: 시스템 상태 점검)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Start whenever the CPUs become idle&lt;/b&gt; (CPU가 유휴 상태로 될 때마다 시작)
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;서버의 CPU 사용률이 낮아져 유휴 상태가 될 때 작업 실행&lt;/li&gt;
&lt;li&gt;유휴 상태를 감지하여 시스템 성능에 미치는 영향을 최소화하기 위해 리소스 집약적인 작업을 수행할 때 사용 (예: 인덱스 재구성)&lt;/li&gt;
&lt;li&gt;정기적인 유지보수 작업이나 백업 작업을 CPU가 유휴 상태일 때 실행하여 사용자가 활동 중인 시간대에도 영향을 주지 않도록 하기 위해 사용 (예: 데이터 백업)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Recuring&lt;/b&gt; (되풀이)
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;해당 옵션 선택 시 &lt;b&gt;Frequency&lt;/b&gt;(빈도)에서 일정을 시작할 날짜를 지정해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;One time&lt;/b&gt;(한 번)
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;해당 옵션 선택 시 &lt;b&gt;One-time occurrence&lt;/b&gt;(한 번 발생)에서 일정을 시작할 날짜를 지정해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;포스팅에서는 한 번 실행으로 설정하고, 1분 뒤에 값이 추가되도록 설정하였음.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkczve/btsHHty3Px8/IphuvC2KLEQUGe9nc9CFPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkczve/btsHHty3Px8/IphuvC2KLEQUGe9nc9CFPK/img.png&quot; data-alt=&quot;스케줄러 일정 세부 설정 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkczve/btsHHty3Px8/IphuvC2KLEQUGe9nc9CFPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbkczve%2FbtsHHty3Px8%2FIphuvC2KLEQUGe9nc9CFPK%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; alt=&quot;작업 스케줄러 일정 세부 설정 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;763&quot; height=&quot;535&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;535&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케줄러 일정 세부 설정 예시 화면&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;b&gt;OK&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 경로에서 생성한 스케줄러를 확인해 볼 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Object Exploer&lt;/b&gt; (개체 탐색기)
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;SQL Server Agent&lt;/b&gt; (SQL Server 에이전트)
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Jobs&lt;/b&gt; (일정)
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;생성한 스케줄러 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;369&quot; data-origin-height=&quot;503&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pjSVH/btsHIuKRmKJ/wlkvBbdjbJA95i5Q00qZ1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pjSVH/btsHIuKRmKJ/wlkvBbdjbJA95i5Q00qZ1k/img.png&quot; data-alt=&quot;개체 탐색기에서 생성한 스케줄러 확인 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pjSVH/btsHIuKRmKJ/wlkvBbdjbJA95i5Q00qZ1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpjSVH%2FbtsHIuKRmKJ%2FwlkvBbdjbJA95i5Q00qZ1k%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; alt=&quot;개체 탐색기에서 생성한 스케줄러 확인 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;369&quot; height=&quot;503&quot; data-origin-width=&quot;369&quot; data-origin-height=&quot;503&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;개체 탐색기에서 생성한 스케줄러 확인 예시 화면&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;스케줄러 일정 작동 확인 테스트&lt;/b&gt;&lt;/h2&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;1분 뒤에는 값이 추가되어야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;초기 테스트 테이블의 값&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;198&quot; data-origin-height=&quot;86&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IfFzt/btsHGggDkdz/Lrrm2PwkkJ4kGKKYet6iik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IfFzt/btsHGggDkdz/Lrrm2PwkkJ4kGKKYet6iik/img.png&quot; data-alt=&quot;테스트 테이블의 초기 값&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IfFzt/btsHGggDkdz/Lrrm2PwkkJ4kGKKYet6iik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIfFzt%2FbtsHGggDkdz%2FLrrm2PwkkJ4kGKKYet6iik%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; alt=&quot;테스트 테이블의 초기 값&quot; loading=&quot;lazy&quot; width=&quot;198&quot; height=&quot;86&quot; data-origin-width=&quot;198&quot; data-origin-height=&quot;86&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;테스트 테이블의 초기 값&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;1분 뒤 스케줄러가 실행되어 작업을 수행한 테스트 테이블의 값
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;스케줄러의 일정에 맞게 설정한 작업이 정상적으로 실행되어 값이 추가됨을 확인할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;210&quot; data-origin-height=&quot;109&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxNdr2/btsHGdEhGL2/UbDIW8B4TkTpwrd2KNCLSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxNdr2/btsHGdEhGL2/UbDIW8B4TkTpwrd2KNCLSk/img.png&quot; data-alt=&quot;스케줄러가 작업을 수행하여 값이 추가된 테이블 조회 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxNdr2/btsHGdEhGL2/UbDIW8B4TkTpwrd2KNCLSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxNdr2%2FbtsHGdEhGL2%2FUbDIW8B4TkTpwrd2KNCLSk%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; alt=&quot;스케줄러가 작업을 수행하여 값이 추가된 테이블 조회 화면&quot; loading=&quot;lazy&quot; width=&quot;210&quot; height=&quot;109&quot; data-origin-width=&quot;210&quot; data-origin-height=&quot;109&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케줄러가 작업을 수행하여 값이 추가된 테이블 조회 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Database/MS-SQL</category>
      <category>job schedules</category>
      <category>MSSQL</category>
      <category>Scheduler</category>
      <category>SQL Server</category>
      <category>sql server agent</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/902</guid>
      <comments>https://luvris2.tistory.com/902#entry902comment</comments>
      <pubDate>Thu, 30 May 2024 13:13:59 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL - SQL Server Agent 활성화하기 (SQL Server 에이전트 설치)</title>
      <link>https://luvris2.tistory.com/901</link>
      <description>&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;MSSQL에서 스케줄러 사용을 위해 SQL Server Agent를 확인해보았더니 비활성화가 되어있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btDrMe/btsHGYZTcdQ/75hgQZdY9lA47BX30tT5cK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btDrMe/btsHGYZTcdQ/75hgQZdY9lA47BX30tT5cK/img.png&quot; data-alt=&quot;MSSQL에서 SQL Server 에이전트가 비활성화된 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btDrMe/btsHGYZTcdQ/75hgQZdY9lA47BX30tT5cK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtDrMe%2FbtsHGYZTcdQ%2F75hgQZdY9lA47BX30tT5cK%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; alt=&quot;MSSQL에서 SQL Server 에이전트가 비활성화된 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;371&quot; height=&quot;290&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MSSQL에서 SQL Server 에이전트가 비활성화된 예시 화면&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;SQL Server 에이전트가 비활성화(중지)가 되어 있다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSSQL의 개체 탐색기에서 SQL Server Agent가 다음 이미지와 같은 빨간색을 하고 있거나 아예 없을 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;37&quot; data-origin-height=&quot;38&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tlcpy/btsHGB4QSA7/kO6RlpE0kB16VSj8M4VLn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tlcpy/btsHGB4QSA7/kO6RlpE0kB16VSj8M4VLn0/img.png&quot; data-alt=&quot;중지 예시 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tlcpy/btsHGB4QSA7/kO6RlpE0kB16VSj8M4VLn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftlcpy%2FbtsHGB4QSA7%2FkO6RlpE0kB16VSj8M4VLn0%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; alt=&quot;중지 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;37&quot; height=&quot;38&quot; data-origin-width=&quot;37&quot; data-origin-height=&quot;38&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;중지 예시 이미지&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;SQL Server 에이전트 활성화하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL Server 구성 관리자 도구를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;만약 SQL Server 구성 관리자 도구를 찾지 못하겠다면 아래의 링크를 확인해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://luvris2.tistory.com/900&quot;&gt;MSSQL - SQL Server 구성 관리자 없음, 설치, 다운로드, SQL Server Configuration Manager 위치&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1716959914237&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;MSSQL - SQL Server 구성 관리자 없음, 설치, 다운로드, SQL Server Configuration Manager 위치&quot; data-og-description=&quot;이 글은 윈도우 운영체제를 기반으로 설명이 작성되었습니다.경로 확인은 윈도우의 경로를 기준으로 합니다.&amp;nbsp;SQL Server 구성 관리자란?연결된 서비스를 관리하고, 네트워크 프로토콜을 구성하며&quot; data-og-host=&quot;luvris2.tistory.com&quot; data-og-source-url=&quot;https://luvris2.tistory.com/900&quot; data-og-url=&quot;https://luvris2.tistory.com/900&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/XrhGQ/hyV90jiX4Y/nSIispQFuQ0mZFaYiKP2XK/img.png?width=677&amp;amp;height=405&amp;amp;face=0_0_677_405,https://scrap.kakaocdn.net/dn/4llHA/hyWdjaurUh/0oIgBDtJDzg0hJW1U04Tj0/img.png?width=677&amp;amp;height=405&amp;amp;face=0_0_677_405,https://scrap.kakaocdn.net/dn/d0eCPu/hyWdlzngCb/CLBZuu3ov2pwxbawGcHfu0/img.png?width=801&amp;amp;height=750&amp;amp;face=0_0_801_750&quot;&gt;&lt;a href=&quot;https://luvris2.tistory.com/900&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://luvris2.tistory.com/900&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/XrhGQ/hyV90jiX4Y/nSIispQFuQ0mZFaYiKP2XK/img.png?width=677&amp;amp;height=405&amp;amp;face=0_0_677_405,https://scrap.kakaocdn.net/dn/4llHA/hyWdjaurUh/0oIgBDtJDzg0hJW1U04Tj0/img.png?width=677&amp;amp;height=405&amp;amp;face=0_0_677_405,https://scrap.kakaocdn.net/dn/d0eCPu/hyWdlzngCb/CLBZuu3ov2pwxbawGcHfu0/img.png?width=801&amp;amp;height=750&amp;amp;face=0_0_801_750');&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;MSSQL - SQL Server 구성 관리자 없음, 설치, 다운로드, SQL Server Configuration Manager 위치&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이 글은 윈도우 운영체제를 기반으로 설명이 작성되었습니다.경로 확인은 윈도우의 경로를 기준으로 합니다.&amp;nbsp;SQL Server 구성 관리자란?연결된 서비스를 관리하고, 네트워크 프로토콜을 구성하며&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;luvris2.tistory.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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;445&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvdhiY/btsHHiQ8fMf/lEy1K93RCnmNcTFnwmxLMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvdhiY/btsHHiQ8fMf/lEy1K93RCnmNcTFnwmxLMK/img.png&quot; data-alt=&quot;SQL Server 구성 관리자 실행 화면 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvdhiY/btsHHiQ8fMf/lEy1K93RCnmNcTFnwmxLMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvdhiY%2FbtsHHiQ8fMf%2FlEy1K93RCnmNcTFnwmxLMK%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; alt=&quot;SQL Server 구성 관리자 실행 화면 예시&quot; loading=&quot;lazy&quot; width=&quot;853&quot; height=&quot;445&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;445&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SQL Server 구성 관리자 실행 화면 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&gt;
&lt;script&gt;     (adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;좌측의 목록에서 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;SQL Server 서비스&lt;/span&gt;를 선택&lt;/li&gt;
&lt;li&gt;이름이 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;SQL Server 에이전트 (MSSQLSERVER)&lt;/span&gt;인 항목 마우스 우클릭 - &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;시작&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;361&quot; data-origin-height=&quot;196&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTNCoe/btsHGxBuTyi/1RC6CWSuBtNHUCA6bQvY01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTNCoe/btsHGxBuTyi/1RC6CWSuBtNHUCA6bQvY01/img.png&quot; data-alt=&quot;SQL Server 에이전트 시작 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTNCoe/btsHGxBuTyi/1RC6CWSuBtNHUCA6bQvY01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTNCoe%2FbtsHGxBuTyi%2F1RC6CWSuBtNHUCA6bQvY01%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; alt=&quot;SQL Server 에이전트 시작 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;361&quot; height=&quot;196&quot; data-origin-width=&quot;361&quot; data-origin-height=&quot;196&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SQL Server 에이전트 시작 예시 화면&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;시작이 된 후, MSSQL 개체 탐색기를 확인해보면 SQL Server Agent가 정상적으로 시작되어 활성화됨을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL Server 에이전트에서 빨간색이 아닌 초록색을 띄면 정상적으로 시작되고 있다는 의미이다.&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;344&quot; data-origin-height=&quot;201&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC2DsD/btsHFL1Jr6p/1gf4YErl6lPAPqSWtwGVDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC2DsD/btsHFL1Jr6p/1gf4YErl6lPAPqSWtwGVDK/img.png&quot; data-alt=&quot;SQL Server에서 SQL Server 에이전트가 정상적으로 실행되고 있음을 확인하는 예시 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC2DsD/btsHFL1Jr6p/1gf4YErl6lPAPqSWtwGVDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC2DsD%2FbtsHFL1Jr6p%2F1gf4YErl6lPAPqSWtwGVDK%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; alt=&quot;SQL Server에서 SQL Server 에이전트가 정상적으로 실행되고 있음을 확인하는 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;344&quot; height=&quot;201&quot; data-origin-width=&quot;344&quot; data-origin-height=&quot;201&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SQL Server에서 SQL Server 에이전트가 정상적으로 실행되고 있음을 확인하는 예시 이미지&lt;/figcaption&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;size26&quot;&gt;&lt;b&gt;SQL Server 에어전트 자동 활성화 하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번엔 수동이 아닌 다음번부터는 자동으로 SQL Server Agent가 시작되도록 설정해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 이 것도 SQL Server 구성 관리자(SQL Server Configuration Manager)에서 할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;좌측의 목록에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;SQL Server 서비스&lt;/span&gt;를 선택&lt;/li&gt;
&lt;li&gt;이름이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;SQL Server 에이전트 (MSSQLSERVER)&lt;/span&gt;인 항목 마우스 우클릭 -&lt;span&gt; &lt;/span&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;속성&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;204&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5OFjC/btsHHdvF0kE/ZMlxb8u37p4oo6trrT9gD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5OFjC/btsHHdvF0kE/ZMlxb8u37p4oo6trrT9gD1/img.png&quot; data-alt=&quot;SQL Server 에이전트 자동 시작 설정 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5OFjC/btsHHdvF0kE/ZMlxb8u37p4oo6trrT9gD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5OFjC%2FbtsHHdvF0kE%2FZMlxb8u37p4oo6trrT9gD1%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; alt=&quot;SQL Server 에이전트 자동 시작 설정 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;459&quot; height=&quot;204&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;204&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SQL Server 에이전트 자동 시작 설정 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;서비스 탭&lt;/span&gt;으로 이동&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;시작 모드&lt;/span&gt; : &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;자동&lt;/span&gt;으로 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;477&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dgvugg/btsHGvXYr3u/2i1YgXkkwtWmU6boSJskvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dgvugg/btsHGvXYr3u/2i1YgXkkwtWmU6boSJskvk/img.png&quot; data-alt=&quot;SQL Server 에이전트 자동 시작 속성 설정 예시 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dgvugg/btsHGvXYr3u/2i1YgXkkwtWmU6boSJskvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdgvugg%2FbtsHGvXYr3u%2F2i1YgXkkwtWmU6boSJskvk%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; alt=&quot;SQL Server 에이전트 자동 시작 속성 설정 예시 화면&quot; loading=&quot;lazy&quot; width=&quot;416&quot; height=&quot;477&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;477&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SQL Server 에이전트 자동 시작 속성 설정 예시 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Database/MS-SQL</category>
      <category>sql server agent</category>
      <category>sql server 에이전트</category>
      <category>비활성화</category>
      <category>활성화</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/901</guid>
      <comments>https://luvris2.tistory.com/901#entry901comment</comments>
      <pubDate>Thu, 30 May 2024 00:30:38 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL - SQL Server 구성 관리자 없음, 설치, 다운로드, SQL Server Configuration Manager 위치</title>
      <link>https://luvris2.tistory.com/900</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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SQL Server 구성 관리자란?&lt;/b&gt;&lt;/h2&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SQL Server 구성 관리자가 없을 경우&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt; 윈도우 키&lt;/span&gt;를 눌러 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;SQL Server 구성 관리자 도구&lt;/span&gt;를 찾아보았지만 검색되지 않는다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dM3vWH/btsHFcrxtfj/PgP8L8ttvklrLLMOKJnNtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dM3vWH/btsHFcrxtfj/PgP8L8ttvklrLLMOKJnNtK/img.png&quot; data-alt=&quot;sql server 구성 관리자 도구를 찾는 예시 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dM3vWH/btsHFcrxtfj/PgP8L8ttvklrLLMOKJnNtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdM3vWH%2FbtsHFcrxtfj%2FPgP8L8ttvklrLLMOKJnNtK%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; alt=&quot;sql server 구성 관리자 도구를 찾는 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;801&quot; height=&quot;750&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;750&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;sql server 구성 관리자 도구를 찾는 예시 이미지&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;SQL Server(MS-SQL)&lt;/span&gt; 설치 시 기본적으로 함께 제공되는 도구이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;때문에 따로 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;SQL Server 구성 관리자 도구&lt;/span&gt;를 다운로드 받거나 설치할 필요가 없다.&lt;/b&gt;&lt;/u&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;SQL Server 구성 관리자 도구 실행하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 표는 버전에 따른 &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;SQL Server 구성 관리자 도구&lt;/span&gt;의 설치 경로이다.&lt;/p&gt;
&lt;table style=&quot;background-color: #ffffff; color: #161616; text-align: start; border-collapse: collapse; width: 100%; height: 122px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: right; height: 20px; width: 25.6977%;&quot;&gt;&lt;b&gt; 버전 &lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 74.186%;&quot;&gt;&lt;b&gt; Path &lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;text-align: right; height: 17px; width: 25.6977%;&quot;&gt;&lt;b&gt;SQL Server 2022&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 17px; width: 74.186%;&quot;&gt;C:\Windows\SysWOW64\SQLServerManager16.msc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;text-align: right; height: 17px; width: 25.6977%;&quot;&gt;&lt;b&gt;SQL Server 2019&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 17px; width: 74.186%;&quot;&gt;C:\Windows\SysWOW64\SQLServerManager15.msc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;text-align: right; height: 17px; width: 25.6977%;&quot;&gt;&lt;b&gt;SQL Server 2017&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 17px; width: 74.186%;&quot;&gt;C:\Windows\SysWOW64\SQLServerManager14.msc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;text-align: right; height: 17px; width: 25.6977%;&quot;&gt;&lt;b&gt;SQL Server 2016&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 17px; width: 74.186%;&quot;&gt;C:\Windows\SysWOW64\SQLServerManager13.msc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;text-align: right; height: 17px; width: 25.6977%;&quot;&gt;&lt;b&gt;SQL Server 2014(12.x)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 17px; width: 74.186%;&quot;&gt;C:\Windows\SysWOW64\SQLServerManager12.msc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;text-align: right; height: 17px; width: 25.6977%;&quot;&gt;&lt;b&gt;SQL Server 2012(11.x)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left; height: 17px; width: 74.186%;&quot;&gt;C:\Windows\SysWOW64\SQLServerManager11.msc&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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: #dddddd; color: #ef5369; text-align: start;&quot;&gt;SQL Server&lt;/span&gt; 의 버전을 잘 모른다면 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;CMD&lt;/span&gt;(명령 프롬프트)에서 아래의 명령어를 쳐보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신 컴퓨터에 설치되어 있는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;SQL Server 구성 관리자 도구&lt;/span&gt;를 확인할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1716955924372&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dir C:\Windows\SysWOW64\SQLServerManager*.msc /S /B&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;나의 경우를 예로 들자면,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;SQL Server 2019&lt;/span&gt;가 설치되어 있어서 구성관리자의 파일명은 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;SQLServerManager15.msc&lt;/span&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;655&quot; data-origin-height=&quot;172&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l8uww/btsHGxOQY6q/CgMZg9IPv5C0YMveMyiMXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l8uww/btsHGxOQY6q/CgMZg9IPv5C0YMveMyiMXk/img.png&quot; data-alt=&quot;SQLServerManager, SQL Server 구성 관리자 도구의 파일 경로를 찾는 예시 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l8uww/btsHGxOQY6q/CgMZg9IPv5C0YMveMyiMXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl8uww%2FbtsHGxOQY6q%2FCgMZg9IPv5C0YMveMyiMXk%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; alt=&quot;SQLServerManager, SQL Server 구성 관리자 도구의 파일 경로를 찾는 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;655&quot; height=&quot;172&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;172&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SQLServerManager, SQL Server 구성 관리자 도구의 파일 경로를 찾는 예시 이미지&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;혹은 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;CMD&lt;/span&gt;로 경로를 확인한 후, 아래의 명령어를 통해 실행하면 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;참고 : mmc 명령어는 윈도우 운영체제에서 다양한 시스템 관리 도구들을 하나의 통합된 인터페이스에서 관리할 수 있게 해주는 콘솔 애플리케이션을 뜻한다.&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1716956600980&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mmc 구성 관리자 경로

# 예시
# mmc C:\Windows\SysWOW64\SQLServerManager15.msc&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRr0jl/btsHEYGT4DB/66EvjlwvKnhWdvFP4hdOZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRr0jl/btsHEYGT4DB/66EvjlwvKnhWdvFP4hdOZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRr0jl/btsHEYGT4DB/66EvjlwvKnhWdvFP4hdOZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRr0jl%2FbtsHEYGT4DB%2F66EvjlwvKnhWdvFP4hdOZ1%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;655&quot; height=&quot;267&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;267&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: #ef5369; background-color: #dddddd;&quot;&gt;SQL Server Configuration Manager&lt;/span&gt;가 정상적으로 잘 실행됨을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;677&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFxO4F/btsHGkWuKF6/85sXjuCmPdFPI3KEV6feF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFxO4F/btsHGkWuKF6/85sXjuCmPdFPI3KEV6feF0/img.png&quot; data-alt=&quot;SQL Server 구성 관리자 실행 화면 예시 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFxO4F/btsHGkWuKF6/85sXjuCmPdFPI3KEV6feF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFxO4F%2FbtsHGkWuKF6%2F85sXjuCmPdFPI3KEV6feF0%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; alt=&quot;SQL Server 구성 관리자 실행 화면 예시 이미지&quot; loading=&quot;lazy&quot; width=&quot;677&quot; height=&quot;405&quot; data-origin-width=&quot;677&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SQL Server 구성 관리자 실행 화면 예시 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Database/MS-SQL</category>
      <category>sql server manager</category>
      <category>sql server 구성 관리자</category>
      <category>구성 관리자 실행</category>
      <category>설치</category>
      <category>없음</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/900</guid>
      <comments>https://luvris2.tistory.com/900#entry900comment</comments>
      <pubDate>Wed, 29 May 2024 13:31:09 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL Error) ntext 데이터 형식은 비교할 수 없으므로 DISTINCT로 선택할 수 없습니다.</title>
      <link>https://luvris2.tistory.com/899</link>
      <description>&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;SELECT&lt;/span&gt; 구문에 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;DISTINCT&lt;/span&gt; 키워드를 추가하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 다음과 같은 오류가 출력되었다.&lt;/p&gt;
&lt;pre id=&quot;code_1716856149651&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Msg 421, Level 16, State 1, Line 76
ntext 데이터 형식은 비교할 수 없으므로 DISTINCT로 선택할 수 없습니다.&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;ntext&lt;/span&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;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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;ntext&lt;/span&gt;&amp;nbsp;데이터타입은 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;SQL Server&lt;/span&gt;에서 &lt;u&gt;&lt;b&gt;직접적으로 비교하는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;DISTINCT&lt;/span&gt;, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;GROUP BY&lt;/span&gt;와 같은 비교 연산자와&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;u&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;UNION&lt;/span&gt;, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;EXCEPT&lt;/span&gt; 같은 집합 연산과 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;COUNT&lt;/span&gt;, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;SUM&lt;/span&gt;과 같은 집계 함수(집계 연산)을 수행할 수 없다.&lt;/u&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;/p&gt;
&lt;pre id=&quot;code_1716856806181&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Msg 5335, Level 16, State 1, Line 97
데이터 형식 ntext은(는) 비교할 수 없으므로 UNION, INTERSECT 또는 EXCEPT 연산자의 피연산자로 사용할 수 없습니다.&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;/p&gt;
&lt;pre id=&quot;code_1716856437308&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Msg 8117, Level 16, State 1, Line 86
max 연산자에 대한 피연산자 데이터 형식 ntext이(가) 잘못되었습니다.&lt;/code&gt;&lt;/pre&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;CAST&lt;/span&gt; 또는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;CONVERT&lt;/span&gt;를 사용하여 데이터 타입을 비교할 수 있도록 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;nvarchar&lt;/span&gt; 타입으로 변환하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1716857021805&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* TABLE NAME 	: t1
    COLUMNS     : col1 (ntext)
*/
SELECT DISTINCT
	CONVERT(NVARCHAR(MAX), col1)
FROM
	t1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;혹시라도 데이터 타입을 변환하였을 때 데이터의 손실(문자 타입 변경으로 인한)이 우려된다면 걱정하지 않아도 된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;ntext&lt;/span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;nvarchar&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;모두 유니코드를 지원하므로 문자 집합의 차이로 인한 데이터 손실은 없다.&lt;/p&gt;</description>
      <category>Database/MS-SQL</category>
      <category>cast</category>
      <category>convert</category>
      <category>MSSQL</category>
      <category>ntext</category>
      <category>ntext 데이터 형식은 비교할 수 없으므로 distinct로 선택할 수 없습니다.</category>
      <category>nvarchar</category>
      <category>SQL Server</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/899</guid>
      <comments>https://luvris2.tistory.com/899#entry899comment</comments>
      <pubDate>Tue, 28 May 2024 09:48:25 +0900</pubDate>
    </item>
    <item>
      <title>윈도우 명령 프롬프트(CMD) - 파일 복사 명령어, copy/xcopy 차이점과 관련 옵션</title>
      <link>https://luvris2.tistory.com/898</link>
      <description>&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;color: #333333; text-align: start;&quot;&gt;개인적으로 생각보다 많이 사용하고 있는데 xcopy 옵션이 자주 헷갈려서 찾아보는 김에 정리 해보았다.&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;/span&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;copy 사용법&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;구문&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 한 위치에서 하나 이상의 파일을 복사하는 데 사용된다.&lt;/p&gt;
&lt;pre id=&quot;code_1716770524289&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;copy 원본파일 대상파일&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 다음과 같은 디렉토리를 가정할 경우,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;test 폴더 하위에 있는 test.txt 텍스트 파일을 다른 'a' 폴더에 복사하는 방법을 예시로 들어보자&lt;/p&gt;
&lt;pre id=&quot;code_1716770662764&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 예시 디렉토리
c:\	- test	- test.txt
	ㄴa&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1716770720636&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;copy c:\test\test.txt c:\a\test.txt&lt;/code&gt;&lt;/pre&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;xcopy 사용법&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;구문&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #161616; text-align: start;&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: #161616; text-align: start;&quot;&gt;추가적으로 지정하는 옵션에 따라 복사를 제어할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1716770779707&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;xcopy 원본경로 대상경로 [/옵션지정]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;옵션&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옵션은 주관적으로 자주 쓰는 옵션에 대해서만 설명하겠다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;/e&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 하위 디렉토리 구조를 포함하여 모든 파일과 디렉토리를 복사한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;/i&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 대상 폴더가 없으면 새로 만든다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;대상이 디렉토리일 경우를 가정한다. 이 옵션이 없으면 대상이 파일인지 디렉토리인지 묻는 메시지가 나타난다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;/y&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 기존 파일을 덮어쓸지 묻는 메시지를 표시하지 않고 자동으로 덮어쓰기를 한다.&lt;/li&gt;
&lt;/ul&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 다음과 같은 디렉토리를 가정할 경우,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;test 폴더 하위에 있는 test.txt 텍스트 파일과 'a' 폴더를 'xcopy' 폴더로 복사하는 방법을 예시로 들어보자&lt;/p&gt;
&lt;pre id=&quot;code_1716770902658&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 예시 디렉토리
c:\	- test	- test.txt
		ㄴa
    ㄴxcopy&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1716771164535&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;xcopy c:\test c:\xcopy /e&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;/e 옵션은 모든 하위 디렉토리가 비어있더라도 복사하는 기능을 한다.&lt;/li&gt;
&lt;/ul&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;copy VS xcopy&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주요 차이점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;copy와 xcopy의 차이점을 간단히 요약하면 다음과 같다.&lt;/p&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;copy&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다른 한 위치에서 하나 이상의 파일을 복사한다.&lt;/li&gt;
&lt;li&gt;옵션이 제한적이며, 디렉토리 구조 복사 기능이 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;xcopy&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하위 디렉토리를 포함하여 파일 및 디렉토리를 복사한다.&lt;/li&gt;
&lt;li&gt;디렉토리 구조를 복사할 수 있다.&lt;/li&gt;
&lt;li&gt;옵션을 사용하여 복사 작업을 제어할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단히 말하면, xcopy는 copy에 옵션이 더 붙은 업그레이드된 형태로 이해해도 된다.&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 copy가 xcopy보다 빠르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;copy 명령어는 단일 파일 복사하는 데 최적화되어 있다.&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;h3 data-ke-size=&quot;size23&quot;&gt;사용 용도&lt;/h3&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;작은 파일 및 단일 파일을 복사할 경우에는 copy 명령어가 더 빠르기 때문에 효율적이다.&lt;/p&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;대규모 파일 복사 작업에서는 xcopy 명령어가 더 효율적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;xcopy 명령어는 대량의 파일을 처리하고 디렉토리 구조를 유지하며 복사하는데 설계되어 있다.&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;참고&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/windows-server/administration/windows-commands/copy&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;마이크로소프트 공식 문서 - Windows Server - copy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/windows-server/administration/windows-commands/xcopy&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;마이크로소프트 공식 문서 - Windows Server - xcopy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>DevOps/Windows</category>
      <category>cmd</category>
      <category>copy</category>
      <category>xcopy</category>
      <category>xcopy copy 차이</category>
      <category>사용법</category>
      <category>옵션</category>
      <category>윈도우 터미널 복사</category>
      <category>윈도우 파일 복사</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/898</guid>
      <comments>https://luvris2.tistory.com/898#entry898comment</comments>
      <pubDate>Mon, 27 May 2024 10:07:22 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL - 저장 프로시저 문자열 검색하기, 프로시저 내용 조회하기 (시스템 뷰 활용)</title>
      <link>https://luvris2.tistory.com/897</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d; text-align: start;&quot;&gt;SQL Server에서 저장 프로시저의 내용을 검색하는 방법에는&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d; text-align: start;&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: #0d0d0d; text-align: start;&quot;&gt;주로 시스템 뷰인 &lt;/span&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;sys.procedures&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d; text-align: start;&quot;&gt;와 &lt;/span&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;sys.sql_modules&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d; text-align: start;&quot;&gt;를 사용한다.&lt;/span&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;/h2&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;/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;i&gt;&lt;b&gt;[참고]&lt;/b&gt; 뷰에 대한 이해가 어렵다면, 아래의 페이지를 참고하는 것을 추천한다.&lt;/i&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/448&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MSSQL - View - 뷰의 개념과 사용 방법, 분할 뷰 사용법&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;span style=&quot;background-color: #ffffff; color: #0d0d0d; text-align: start;&quot;&gt;시스템 뷰인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;sys.procedures&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d; text-align: start;&quot;&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;sys.sql_modules&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d; text-align: start;&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: #0d0d0d; text-align: start;&quot;&gt;각 시스템 뷰의 역할을 알아보면 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;sys.procedures&lt;/b&gt;: 저장 프로시저에 대한 정보를 제공한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;sys.sql_modules&lt;/b&gt;: 저장 프로시저, 함수, 트리거 등의 정의를 포함한 정보를 제공한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;sys.procedures&lt;/span&gt;를 통해 프로시저의 이름을 확인하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;sys.sql_modules&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;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&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;pre id=&quot;code_1716436059766&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT p.name AS ProcedureName, -- 프로시저 이름
       m.definition AS ProcedureDefinition -- 프로시저 정의 내용
FROM sys.procedures AS p
INNER JOIN sys.sql_modules AS m
    ON p.object_id = m.object_id
WHERE m.definition LIKE '%검색내용%'&lt;/code&gt;&lt;/pre&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;sp_helptext&lt;/span&gt;를 이용하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1716436220962&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;EXEC sp_helptext '프로시저명';&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;/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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/443&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SQL - 프로시저와 함수의 차이&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/381&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MSSQL - 저장 프로시저의 개념, 장점, 실행 과정 (Stored Procedure)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용법 : MS-SQL&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/384&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MSSQL - 사용자 저장 프로시저의 사용 방법(생성/호출/수정/삭제) (Stored Procedure)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/385&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MSSQL - 프로시저 매개변수(IN/OUT) 입력, 출력 활용하기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/750&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MSSQL - 프로시저에 테이블 자체를 매개변수로 전달하기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용법 : MySQL&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/440&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MySQL - 프로시저 문법(생성, 수정, 삭제, 호출), 프로시저 확인, 사용 예제&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#mssql #sql server #stored procedure #search #text&lt;/p&gt;</description>
      <category>Database/MS-SQL</category>
      <category>MSSQL</category>
      <category>sp_helptext</category>
      <category>SQL Server</category>
      <category>sys.procedures</category>
      <category>sys.sql_modules</category>
      <category>내용 검색</category>
      <category>내용 조회</category>
      <category>저장 프로시저</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/897</guid>
      <comments>https://luvris2.tistory.com/897#entry897comment</comments>
      <pubDate>Thu, 23 May 2024 12:55:31 +0900</pubDate>
    </item>
    <item>
      <title>SQL - WHERE 1=1 사용 이유에 대해 알아보자 (+ WHERE 1=2 사용 이유)</title>
      <link>https://luvris2.tistory.com/896</link>
      <description>&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;가끔 SQL 쿼리를 보면 WHERE절 맨 앞에 1=1이 있는 것을 볼 수가 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1716249413148&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM t1 WHERE 1=1
	AND col1 = 'eunbyeol'&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;/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;color: #ef5369; background-color: #dddddd;&quot;&gt;WHERE 1=1&lt;/span&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;WHERE 1=1 사용 이유, 왜 사용할까?&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;동적 쿼리 조건 구성의 단순화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론부터 말하자면, &lt;span style=&quot;background-color: #dddddd; color: #ef5369; text-align: start;&quot;&gt;WHERE 1=1&lt;/span&gt; 은 주로 동적 쿼리를 작성할 때 많이 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 조건에 따라 동적으로 추가되거나 제거되는 조건절을 위한 기본 쿼리 구조로 많이 사용된다.&lt;/p&gt;
&lt;pre id=&quot;code_1716249985113&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM t1 WHERE 1=1&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조에서 프로그래머는 필요에 따라 &lt;span style=&quot;background-color: #dddddd; color: #ef5369;&quot;&gt;AND&lt;/span&gt;&amp;nbsp;또는 &lt;span style=&quot;background-color: #dddddd; color: #ef5369;&quot;&gt;OR&lt;/span&gt;&amp;nbsp;연산자를 사용하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건을 추가하면 쿼리를 훨씬 더 수월하게 작성할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1716250115628&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM t1 WHERE 1=1
-- 조건에 따라 조건식을 AND 또는 OR 로 추가해주자
    AND col1 = 'eunbyeol'
    AND col2 = 'incheon'&lt;/code&gt;&lt;/pre&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;/h3&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;아래의 예시 쿼리를 봐보자.&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: #dddddd; color: #ef5369;&quot;&gt;AND 조건&lt;/span&gt;으로만 작성되었다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;프로시저로 들어온 값이 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;1&lt;/span&gt;일 경우, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;col1&lt;/span&gt; 컬럼에 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;은별&lt;/span&gt;이라는 데이터를 조회하고,&lt;/li&gt;
&lt;li&gt;프로시저로 들어온 값이 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;2&lt;/span&gt;일 경우, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;col2&lt;/span&gt; 컬럼에 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;인천&lt;/span&gt;이라는 데이터를 조회한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;b&gt;&lt;i&gt;[참고] 해당 프로시저는 예시를 위한 쿼리이며, MS-SQL(SSMS)을 기반으로 작성하였다.&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1716250839145&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* 테스트 프로시저
*	파라미터에 전달 받은 값으로 특정 쿼리를 실행하는 프로시저
*	외부에서 받는 값은 숫자 1 또는 2로 한정
*/
CREATE PROC test
	@val INT -- 외부에서 전달 받는 값
AS BEGIN
	-- 동적 쿼리 기본 구조 설정
    DECLARE @sql NVARCHAR(MAX)
    SET @sql = 'SELECT * FROM t1 WHERE 1=1'

	-- 조건에 따라 쿼리 작성
	IF @val = 1
    		SET @sql = @sql + ' AND col1 = ''eunbyeol'''
   	ELSE IF @val = 2
    		SET @sql = @sql + ' AND col2 = ''incheon'''
        
    -- 쿼리 실행
    EXEC sp_executesql @sql
END&lt;/code&gt;&lt;/pre&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;/h3&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;color: #ef5369; background-color: #dddddd;&quot;&gt;WHERE절&lt;/span&gt;에 조건절을 위한 기본 쿼리 구조를 구성(예를 들어 1=1) 해두지 않고 쿼리를 작성하다 보면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각보다 많이 조건절의 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;AND&lt;/span&gt; 혹은 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;OR&lt;/span&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;pre id=&quot;code_1716251684350&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;SELECT * FROM t1
WHERE 
	col1 = 'eunbyeol'
    AND col2 = 'incheon'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&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;그렇다면 내가 수정해야 될 부분은 조건절의 특정 조건만 주석처리하는 것이 가장 빠를 것이다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1716251734209&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM t1
WHERE 
	-- col1 = 'eunbyeol'
    col2 = 'incheon' -- AND 키워드 삭제
    
 /* 혹은 */
 
SELECT * FROM t1
WHERE 
	col1 = 'eunbyeol'
    -- AND col2 = 'incheon'&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;AND&lt;/span&gt; 또는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;OR&lt;/span&gt; 키워드가 있거나 없는 조건은 때때로 지우거나 오히려 덧붙여서 작성해야 될 때가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 간단하게도 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;WHERE 1=1&lt;/span&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;pre id=&quot;code_1716252069947&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM t1
WHERE 1=1
	-- AND col1 = 'eunbyeol'
    AND col2 = 'incheon'
    
/* 혹은 */
    
SELECT * FROM t1
WHERE 1=1
	AND col1 = 'eunbyeol'
    -- AND col2 = 'incheon'&lt;/code&gt;&lt;/pre&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;WHERE 1=1 쿼리 실행 속도, 데이터베이스 과부하 여부는?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 SQL 쿼리 최적화 엔진(옵티마이저)은 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;WHERE 1=1&lt;/span&gt; 조건을 무시한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;1=1&lt;/span&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;단, 매우 복잡한 쿼리거나 데이터가 매우 많은 데이터베이스일 경우에는&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;WHERE 1=2 사용 이유, 얘는 어떨 때 사용될까?&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터를 제외한 테이블 구조만 복사&lt;/h3&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;color: #ef5369; background-color: #dddddd;&quot;&gt;t1&lt;/span&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;/span&gt;이라는 테이블은 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;col1&lt;/span&gt;, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;col2&lt;/span&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;/span&gt;라는 컬럼이 존재하고, 약 천 개 정도의 데이터를 가지고 있다고 가정해 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 여기서 테이블의 구조만 복사하고 싶다면 아래와 같이 쿼리를 작성할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1716253633051&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- SQL Server, MS-SQL
SELECT * INTO new_t1 FROM t1 WHERE 1=2&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;t1&lt;/span&gt; 테이블의 데이터는 포함하지 않고 구조만 그대로 가진 빈 테이블 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;new_t1&lt;/span&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;이는 본인 편의에 맞게 사용하도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1716253828668&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- SQL Server, MS-SQL
SELECT TOP 0 * INTO new_t1 FROM t1;

-- MySQL
CREATE new_t1 LIKE t1 LIMIT 0;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건절의 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;WHERE 1=2&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;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;데이터가 많은 데이터베이스를 조회할 때에 부하가 일어날 수 있다.&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;b&gt;두 번째, 특정 조건에서만 데이터를 반환하도록 제어할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 쿼리는 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;WHERE 1=2&lt;/span&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;/span&gt;를 이용하여 쿼리를 작성한 예시 코드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;AND&lt;/span&gt;로만 구성되어 있기 때문에 모든 조건이 맞는 데이터만 조회되도록 설계되어 있지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건절의 시작 부분에 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;거짓(1=2)&lt;/span&gt;이 존재하기 때문에 데이터가 반환되지 않는다.&lt;/p&gt;
&lt;pre id=&quot;code_1716252870402&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM t1 WHERE 1=2
	AND col1 = 'eunbyeol'&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;/p&gt;
&lt;pre id=&quot;code_1716254652490&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM t1 WHERE 1=2
	AND col1 = 'eunbyeol'
   	OR  col2 = 'incheon'&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;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;WHERE 1=2 &lt;b&gt;AND&lt;/b&gt; col1 = 'eunbyeol'&lt;/span&gt;은 거짓이므로 조건을 조회하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면, 추가된 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;&lt;b&gt;OR&lt;/b&gt; col2 = 'incheon'&lt;/span&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;color: #ef5369; background-color: #dddddd;&quot;&gt;WHERE 1=1&lt;/span&gt;)의 논리식을 거짓(&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;1=2&lt;/span&gt;)으로 바꾸어 처리하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리는 수정 없이 그대로 둔 채 다른 조건을 추가하여 테스트 및 디버깅으로 데이터를 제어할 수 있다.&lt;/p&gt;</description>
      <category>Database/SQL</category>
      <category>MSSQL</category>
      <category>MySQL</category>
      <category>SQL</category>
      <category>SQL Server</category>
      <category>where 1=1</category>
      <category>where 1=2</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/896</guid>
      <comments>https://luvris2.tistory.com/896#entry896comment</comments>
      <pubDate>Tue, 21 May 2024 10:35:14 +0900</pubDate>
    </item>
    <item>
      <title>Kotlin, Spring Boot - 코프링 시작하기, 페이지에 HelloWorld 출력하기 (인텔리제이, JDK 설치 및 기본 개발 환경 구축)</title>
      <link>https://luvris2.tistory.com/895</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;179&quot; data-origin-height=&quot;125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ze2zM/btsHgpR3sqC/9kIOWsBaNaEvlfFNay3e50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ze2zM/btsHgpR3sqC/9kIOWsBaNaEvlfFNay3e50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ze2zM/btsHgpR3sqC/9kIOWsBaNaEvlfFNay3e50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fze2zM%2FbtsHgpR3sqC%2F9kIOWsBaNaEvlfFNay3e50%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; alt=&quot;코틀린 스프링부트 로고&quot; loading=&quot;lazy&quot; width=&quot;179&quot; height=&quot;125&quot; data-origin-width=&quot;179&quot; data-origin-height=&quot;125&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;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Java Version : Open JDK 21&lt;/li&gt;
&lt;li&gt;Gradle 8.5&lt;/li&gt;
&lt;li&gt;Spring Boot 3.2.5&lt;/li&gt;
&lt;li&gt;Port Number : 8080&lt;/li&gt;
&lt;li&gt;IDE : IntelliJ Community Edition&lt;/li&gt;
&lt;/ul&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/luvris2/kotlin-spring-boot-example&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/luvris2/kotlin-spring-boot-example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;하위 디렉토리 : &lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;a style=&quot;color: #0593d3;&quot; href=&quot;https://github.com/luvris2/kotlin-spring-boot-example/tree/main/01_helloworld&quot;&gt;01_helloworld&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1715152113786&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - luvris2/kotlin-spring-boot-example&quot; data-og-description=&quot;Contribute to luvris2/kotlin-spring-boot-example development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/luvris2/kotlin-spring-boot-example&quot; data-og-url=&quot;https://github.com/luvris2/kotlin-spring-boot-example&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Uyed9/hyVZeWbsv7/xU4miDFboLBzfs0pSJOrJK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/luvris2/kotlin-spring-boot-example&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/luvris2/kotlin-spring-boot-example&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Uyed9/hyVZeWbsv7/xU4miDFboLBzfs0pSJOrJK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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;GitHub - luvris2/kotlin-spring-boot-example&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to luvris2/kotlin-spring-boot-example development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;개발 환경 구축&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;JDK 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코틀린은 자바(JVM) 기반이기 때문에 자바가 설치되어 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenJDK에서 &lt;b&gt;JDK 21&lt;/b&gt;을 다운로드 받아 설치하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 JDK 21을 기반으로 할 것이기 때문이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://jdk.java.net/21/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://jdk.java.net/21/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;527&quot; data-origin-height=&quot;501&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mJovx/btsHgAMmo3W/ajs87qXDeikFB2vNTy6STk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mJovx/btsHgAMmo3W/ajs87qXDeikFB2vNTy6STk/img.png&quot; data-alt=&quot;자바 JDK 환경 변수 등록 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mJovx/btsHgAMmo3W/ajs87qXDeikFB2vNTy6STk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmJovx%2FbtsHgAMmo3W%2Fajs87qXDeikFB2vNTy6STk%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; alt=&quot;자바 JDK 환경 변수 등록 이미지&quot; loading=&quot;lazy&quot; width=&quot;527&quot; height=&quot;501&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;501&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;자바 JDK 환경 변수 등록 이미지&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;i&gt;&lt;b&gt;[참고]&lt;/b&gt; 자바 설치 및 환경 변수 등록하는 방법을 자세히 보려면 아래의 포스팅을 참고하자.&lt;/i&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/218&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Java - 자바와 이클립스 설치하기, 환경 변수 설정하기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인텔리제이를 굳이 선택한 이유는 내가 편해서이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 IDE툴은 자기가 편한 것을 선택하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인텔리제이를 검색하고 jetbrains 홈페이지를 들어가서 다운로드를 받는다.&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;i&gt;&lt;b&gt;[참고]&lt;/b&gt; 윈도우 사용자 빠른 다운로드 링크&lt;/i&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jetbrains.com/ko-kr/idea/download/?section=windows&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.jetbrains.com/ko-kr/idea/download/?section=windows&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;h3 data-ke-size=&quot;size23&quot;&gt;프로젝트 생성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트는 편의상 &lt;b&gt;spring boot initializer&lt;/b&gt;를 이용하여 생성한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://start.spring.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://start.spring.io/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Project&lt;/b&gt; : Gradle - Kotlin&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Language&lt;/b&gt; : Kotlin&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Spring Boot&lt;/b&gt; : 3.2.5&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Dependencies&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Spring Web&lt;/b&gt; : 웹 개발을 위한 MVC 패턴, RESTful API, 웹 리소스 처리, 쿠키 및 세션 관리 등의 기능 존재, 웹 내장 서버 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;624&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Co6gm/btsHiqPHzvk/KupkrjIz7f3NZKzcxKOFRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Co6gm/btsHiqPHzvk/KupkrjIz7f3NZKzcxKOFRK/img.png&quot; data-alt=&quot;코틀린 프로젝트 초기 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Co6gm/btsHiqPHzvk/KupkrjIz7f3NZKzcxKOFRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCo6gm%2FbtsHiqPHzvk%2FKupkrjIz7f3NZKzcxKOFRK%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; alt=&quot;코틀린 프로젝트 초기 설정&quot; loading=&quot;lazy&quot; width=&quot;1014&quot; height=&quot;624&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;624&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;코틀린 프로젝트 초기 설정&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;b&gt;GENERATE&lt;/b&gt;를 누르면 다운로드가 시작된다.&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;792&quot; data-origin-height=&quot;625&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EAOE7/btsHg8B87sC/Con8Q10ESbYnxkVqEMFvyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EAOE7/btsHg8B87sC/Con8Q10ESbYnxkVqEMFvyk/img.png&quot; data-alt=&quot;다운로드 받은 코틀린 프로젝트를 인텔리제이에서 불러온 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EAOE7/btsHg8B87sC/Con8Q10ESbYnxkVqEMFvyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEAOE7%2FbtsHg8B87sC%2FCon8Q10ESbYnxkVqEMFvyk%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; alt=&quot;다운로드 받은 코틀린 프로젝트를 인텔리제이에서 불러온 화면&quot; loading=&quot;lazy&quot; width=&quot;792&quot; height=&quot;625&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;625&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;다운로드 받은 코틀린 프로젝트를 인텔리제이에서 불러온 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1484169609317244&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&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;HelloWorld 페이지 출력해보기&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HelloWorld 파일 생성하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 경로에서 &lt;b&gt;src - main - kotlin - 패키지&lt;/b&gt; 경로로 이동하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패키지 경로에서 &lt;b&gt;마우스 우클릭 - New - Kotlin Class/File&lt;/b&gt; 을 선택하여 파일을 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 이름은 &lt;b&gt;HelloWorldController&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;887&quot; data-origin-height=&quot;793&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnHw5x/btsHgD3DCly/s1DkIBlTzWr5OXCaBPfsJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnHw5x/btsHgD3DCly/s1DkIBlTzWr5OXCaBPfsJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnHw5x/btsHgD3DCly/s1DkIBlTzWr5OXCaBPfsJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnHw5x%2FbtsHgD3DCly%2Fs1DkIBlTzWr5OXCaBPfsJk%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;887&quot; height=&quot;793&quot; data-origin-width=&quot;887&quot; data-origin-height=&quot;793&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;h3 data-ke-size=&quot;size23&quot;&gt;HelloWorld 내용 작성하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 서버에 접속하면 HelloWorld라는 데이터를 반환해줄 내용을 구성해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;헬로월드를 보여줄 페이지 URL 경로는 &lt;b&gt;/helloworld&lt;/b&gt; 로 해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;HelloWorld&quot;라는 문자열을 반환하기 위해서 두 개의 컨트롤러 중 하나 사용하여 구성할 수 있다.&lt;/p&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;[ Controller VS RestController 차이 비교해보기 ]&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;@Controller
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전통적인 웹 사용 컨트롤러이다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;일반적으로&lt;span&gt; &lt;/span&gt;&lt;/span&gt;HTTP 요청에 대한 응답을 HTML 페이지로 반환한다.&lt;/li&gt;
&lt;li&gt;@GetMapping 어노테이션을 사용하여 특정 URL에 대한 GET 요청을 처리하는 메소드를 정의할 수 있다.&lt;/li&gt;
&lt;li&gt;@ResponseBody 어노테이션을 사용하여 RESTful 웹 서비스처럼 컨트롤러 메소드에 직접 JSON, XML 또는 기타 형식의 데이터를 반환할 때 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;@RestController
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RESTful 웹 서비스를 제공하는 컨트롤러이다.&lt;/li&gt;
&lt;li&gt;HTTP 요청에 대한 JSON 또는 XML 응답과 같은 RESTful 응답에 적합하도록 동작한다.&lt;/li&gt;
&lt;li&gt;@GetMapping 어노테이션을 사용하여 특정 URL에 대한 GET 요청을 처리하는 메소드를 정의할 수 있다.&lt;/li&gt;
&lt;li&gt;@RestController는 @ResponseBody를 포함하고 있으므로 따로 사용할 필요는 없다.&lt;/li&gt;
&lt;/ul&gt;
&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;코틀링 스프링부트의 HelloWorld 찍먹(맛보기)이기 때문에 페이지를 따로 구축하지 않고 문자열만 반환하도록 한다.&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;h4 data-ke-size=&quot;size20&quot;&gt;@Controller를 사용할 경우&lt;/h4&gt;
&lt;pre id=&quot;code_1715150785643&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// HelloWorldController.kt
package com.eunbyeol.helloworld

import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.ResponseBody

@Controller
class HelloWorldController {
    @GetMapping(&quot;/helloworld&quot;) // 해당 URL GET 요청 메소드 정의
    @ResponseBody // RESTful HTTP
    fun hello(): String {
        return &quot;Hello, World!&quot; // Hello World 문자열 반환
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;@RestController를 사용할 경우&lt;/h4&gt;
&lt;pre id=&quot;code_1715150993728&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// HelloWorldController.kt
package com.eunbyeol.helloworld

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

@RestController // RESTful 컨트롤러
class HelloWorldController {
    @GetMapping(&quot;/helloworld&quot;) // 해당 URL GET 요청 메소드 정의
    fun hello(): String {
        return &quot;Hello, World!&quot; // Hello World 문자열 반환
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;서버 실행 및 HelloWorld 페이지 확인하기&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;내장 웹 서버 시작하기&lt;/h4&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;메인 파일(~~~Application.kt)로 이동하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상단 메뉴에서 &lt;b&gt;Run - Run '~~~Application.kt'&lt;/b&gt;을 눌러 애플리케이션을 실행한다.&lt;b&gt;&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;650&quot; data-origin-height=&quot;385&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEwxhe/btsHgXgB61W/7rTK9O6ZC4FevAn2XzNDf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEwxhe/btsHgXgB61W/7rTK9O6ZC4FevAn2XzNDf1/img.png&quot; data-alt=&quot;스프링부트 애플리케이션 실행 경로 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEwxhe/btsHgXgB61W/7rTK9O6ZC4FevAn2XzNDf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEwxhe%2FbtsHgXgB61W%2F7rTK9O6ZC4FevAn2XzNDf1%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; alt=&quot;스프링부트 애플리케이션 실행 경로 이미지&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;385&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;385&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스프링부트 애플리케이션 실행 경로 이미지&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;아래와 같이 뜨고 메시지가 쭈욱 생성된다면 웹 서버가 성공적으로 실행된 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;765&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buTWO0/btsHf0ruqrs/cuK3RXdN7lanKaAwznLeQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buTWO0/btsHf0ruqrs/cuK3RXdN7lanKaAwznLeQK/img.png&quot; data-alt=&quot;인텔리제이에서 Spring Boot 웹 서버 실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buTWO0/btsHf0ruqrs/cuK3RXdN7lanKaAwznLeQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuTWO0%2FbtsHf0ruqrs%2FcuK3RXdN7lanKaAwznLeQK%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; alt=&quot;인텔리제이에서 Spring Boot 웹 서버 실행 화면&quot; loading=&quot;lazy&quot; width=&quot;1072&quot; height=&quot;765&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;765&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인텔리제이에서 Spring Boot 웹 서버 실행 화면&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;웹 서버 기본 포트는 8080을 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1715151727371&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;http://localhost:8080/&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;Whitelabel Error Page&lt;/b&gt;라고 출력된다. 이는 에러가 아니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위의 내용에서 &lt;b&gt;HelloWorldController.kt&lt;/b&gt; 파일에서 매핑되는 GET 주소를 &lt;b&gt;/helloworld&lt;/b&gt;로 지정하였다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;현재 웹 서버에서는 /helloworld 를 제외하고 다른 URL 주소는 존재하지 않기 때문에 아무런 페이지도 출력되지 않는다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기본 URL에 우리는 따로 설정한게 없으니 아무것도 출력되지 않는 것이 당연하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdkb5M/btsHi5dvZFA/frJTwrWY2yAMVww06fGvb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdkb5M/btsHi5dvZFA/frJTwrWY2yAMVww06fGvb0/img.png&quot; data-alt=&quot;스프링부트 로컬 접속 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdkb5M/btsHi5dvZFA/frJTwrWY2yAMVww06fGvb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcdkb5M%2FbtsHi5dvZFA%2FfrJTwrWY2yAMVww06fGvb0%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; alt=&quot;스프링부트 로컬 접속 화면&quot; loading=&quot;lazy&quot; width=&quot;502&quot; height=&quot;293&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스프링부트 로컬 접속 화면&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;이제 /helloworld 로 이동해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1715151908474&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;http://localhost:8080/helloworld&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dytrPq/btsHgam7Z3M/XMi8q8eGkwiXl9OpqMJOU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dytrPq/btsHgam7Z3M/XMi8q8eGkwiXl9OpqMJOU0/img.png&quot; data-alt=&quot;코틀린 스프링부트, Hello World 페이지 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dytrPq/btsHgam7Z3M/XMi8q8eGkwiXl9OpqMJOU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdytrPq%2FbtsHgam7Z3M%2FXMi8q8eGkwiXl9OpqMJOU0%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; alt=&quot;코틀린 스프링부트, Hello World 페이지 화면&quot; loading=&quot;lazy&quot; width=&quot;502&quot; height=&quot;293&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;코틀린 스프링부트, Hello World 페이지 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Back End/Spring Boot</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/895</guid>
      <comments>https://luvris2.tistory.com/895#entry895comment</comments>
      <pubDate>Wed, 8 May 2024 16:09:51 +0900</pubDate>
    </item>
    <item>
      <title>SQL - LIKE 조건에 와일드카드 문자 자체를 검색에 포함하기</title>
      <link>https://luvris2.tistory.com/892</link>
      <description>&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;131&quot; data-origin-height=&quot;86&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2OYVx/btsG4xIBwCH/QvCbhbOxAHETWGVaiZ1Qtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2OYVx/btsG4xIBwCH/QvCbhbOxAHETWGVaiZ1Qtk/img.png&quot; data-alt=&quot;테이블 예시 데이터&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2OYVx/btsG4xIBwCH/QvCbhbOxAHETWGVaiZ1Qtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2OYVx%2FbtsG4xIBwCH%2FQvCbhbOxAHETWGVaiZ1Qtk%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; alt=&quot;테이블 예시 데이터&quot; loading=&quot;lazy&quot; width=&quot;131&quot; height=&quot;86&quot; data-origin-width=&quot;131&quot; data-origin-height=&quot;86&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;테이블 예시 데이터&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;1, 'eunbyeol'&lt;/li&gt;
&lt;li&gt;2, 'e_nbyeol'&lt;/li&gt;
&lt;li&gt;3, 'e__byeol'&lt;/li&gt;
&lt;/ul&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;'e_nbyeol'&lt;/b&gt; 데이터를 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;like&lt;/span&gt; 키워드로 조회하고 싶다.&lt;/p&gt;
&lt;pre id=&quot;code_1714453572228&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM t1 WHERE name LIKE 'e_nbyeol'&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;128&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Pg6q6/btsG2mOWbEc/0y3NDk770t4svhPKbAjRp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Pg6q6/btsG2mOWbEc/0y3NDk770t4svhPKbAjRp1/img.png&quot; data-alt=&quot;LIKE 조회 결과 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Pg6q6/btsG2mOWbEc/0y3NDk770t4svhPKbAjRp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPg6q6%2FbtsG2mOWbEc%2F0y3NDk770t4svhPKbAjRp1%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; alt=&quot;LIKE 조회 결과 화면&quot; loading=&quot;lazy&quot; width=&quot;128&quot; height=&quot;62&quot; data-origin-width=&quot;128&quot; data-origin-height=&quot;62&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;LIKE 조회 결과 화면&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;때문에 다음과 같이 쿼리를 작성하면 예시 데이터의 모든 데이터가 조회된다.&lt;/p&gt;
&lt;pre id=&quot;code_1714453699697&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM t1 WHERE name LIKE 'e_%'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;131&quot; data-origin-height=&quot;86&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2OYVx/btsG4xIBwCH/QvCbhbOxAHETWGVaiZ1Qtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2OYVx/btsG4xIBwCH/QvCbhbOxAHETWGVaiZ1Qtk/img.png&quot; data-alt=&quot;LIKE 조회 결과 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2OYVx/btsG4xIBwCH/QvCbhbOxAHETWGVaiZ1Qtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2OYVx%2FbtsG4xIBwCH%2FQvCbhbOxAHETWGVaiZ1Qtk%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; alt=&quot;LIKE 조회 결과 화면&quot; loading=&quot;lazy&quot; width=&quot;131&quot; height=&quot;86&quot; data-origin-width=&quot;131&quot; data-origin-height=&quot;86&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;LIKE 조회 결과 화면&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;이 글은 와일드카드 문자를 검색하기 위해 작성되었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;LIKE 조건자 ESCAPE 구문&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;설명&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LIKE 조건절에 ESCAPE 구문을 사용하여 모든 문자를 표현할 수 있다.&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;h3 data-ke-size=&quot;size23&quot;&gt;구문&lt;/h3&gt;
&lt;pre id=&quot;code_1714454118736&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
	*
FROM
	t1
WHERE
	name LIKE '\abc' {escape '\'} -- {} 중괄호는 생략해도 무방&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;데이터가 '\abc'인 문자를 조회한다.&lt;/li&gt;
&lt;/ul&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다음 데이터에서 'e_nbyeol' 데이터 조회하기&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1, 'eunbyeol'&lt;/li&gt;
&lt;li&gt;2, 'e_nbyeol'&lt;/li&gt;
&lt;li&gt;3, 'e__byeol'&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1714454241707&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
	*
FROM
	t1
WHERE
	name LIKE 'e\_nbyeol%' escape '\'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;128&quot; data-origin-height=&quot;44&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ezIbkF/btsG4hy8Pb7/9MX7JoXOcW3sesLdz8Cx81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ezIbkF/btsG4hy8Pb7/9MX7JoXOcW3sesLdz8Cx81/img.png&quot; data-alt=&quot;LIKE 조건에 와일드카드 문자 포함 검색 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ezIbkF/btsG4hy8Pb7/9MX7JoXOcW3sesLdz8Cx81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FezIbkF%2FbtsG4hy8Pb7%2F9MX7JoXOcW3sesLdz8Cx81%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; alt=&quot;LIKE 조건에 와일드카드 문자 포함 검색 결과&quot; loading=&quot;lazy&quot; width=&quot;128&quot; height=&quot;44&quot; data-origin-width=&quot;128&quot; data-origin-height=&quot;44&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;LIKE 조건에 와일드카드 문자 포함 검색 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;만약 &lt;b&gt;이스케이프 구문이 없다면&lt;/b&gt;, 와일드카드 문자로 인해 &lt;b&gt;'eunbyeol'&lt;/b&gt;, &lt;b&gt;'e_nbyeol'&lt;/b&gt; 데이터가 조회된다.&lt;/li&gt;
&lt;/ul&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;데이터에서 'e_ _byeol' 데이터 조회하기&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1714454477390&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
	*
FROM
	t1
WHERE
	name LIKE 'e\_\_byeol%' escape '\'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;128&quot; data-origin-height=&quot;45&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pYQU0/btsG1fCH6TW/MsxWd0Ar8K5Y173jndh6IK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pYQU0/btsG1fCH6TW/MsxWd0Ar8K5Y173jndh6IK/img.png&quot; data-alt=&quot;LIKE 조건에 와일드카드 문자 2개 포함 검색 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pYQU0/btsG1fCH6TW/MsxWd0Ar8K5Y173jndh6IK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpYQU0%2FbtsG1fCH6TW%2FMsxWd0Ar8K5Y173jndh6IK%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; alt=&quot;LIKE 조건에 와일드카드 문자 2개 포함 검색 결과&quot; loading=&quot;lazy&quot; width=&quot;128&quot; height=&quot;45&quot; data-origin-width=&quot;128&quot; data-origin-height=&quot;45&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;LIKE 조건에 와일드카드 문자 2개 포함 검색 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;만약 &lt;b&gt;이스케이프 구문이 없다면&lt;/b&gt;, 와일드카드 문자로 인해 &lt;b&gt;'eunbyeol', 'e_nbyeol', 'e_ _byeol'&lt;/b&gt; 모든 데이터가 조회된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;편법 사용하기 (replace)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조회해야 할 문자 조건이 많을 경우,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일일이 LIKE 검색을 OR 연산시켜서 쿼리를 작성하기는 솔직히 너무 귀찮다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럴 경우에는 IN 구문을 사용하여 한꺼번에 처리하기 위해 편법을 사용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;REPLACE로 특정 문자열로 바꿔서 찾아보는 방법도 나쁘지 않다.&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;b&gt;[찾는 문자열 예시]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;1_1&lt;/li&gt;
&lt;li&gt;1_2&lt;/li&gt;
&lt;li&gt;1_3&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1714454985397&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
	col1
FROM
	t1
WHERE
	REPLACE(col1, '_', '-') IN ('1-1', '1-2', '1-3')&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Database/SQL</category>
      <category>like</category>
      <category>SQL</category>
      <category>Wildcard</category>
      <category>와일드카드 문자 포함 검색</category>
      <category>와일드카드 처리</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/892</guid>
      <comments>https://luvris2.tistory.com/892#entry892comment</comments>
      <pubDate>Wed, 1 May 2024 00:05:24 +0900</pubDate>
    </item>
    <item>
      <title>SQL - LIKE 와일드 카드 사용 가이드(%, [], ^, _) 및 예시 샘플 코드</title>
      <link>https://luvris2.tistory.com/891</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;와일드카드란? 와일드카드 문자란? (WildCard)&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;와일드카드는 패턴 매칭을 위해 사용되는 문자&lt;/li&gt;
&lt;li&gt;패턴에 일치하는 문자열을 효과적으로 검색하거나 필터링하기 위해 사용&lt;/li&gt;
&lt;li&gt;SQL에서 주로 WHERE 절의 LIKE 연산자와 함께 사용&lt;/li&gt;
&lt;li&gt;여러 가지 와일드카드 문자(%, [], ^, _)가 존재&lt;/li&gt;
&lt;li&gt;즉, 데이터를 더 쉽게 검색하여 원하는 결과를 얻기 위한 목적으로 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;와일드카드 : % (백분율 문자)&amp;nbsp;&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;h3 data-ke-size=&quot;size23&quot;&gt;개념&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0개 이상의 문자를 나타낸다.&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;'a%'&lt;/b&gt;는 &lt;b&gt;'a'&lt;/b&gt;로 시작하는 모든 문자열을 나타낸다.&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'e%'&lt;/b&gt; : 문자 'e'로 시작하는 모든 문자열을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'%e'&lt;/b&gt; : 문자 'e로 끝나는 모든 문자열을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'%e%'&lt;/b&gt; : 문자 'e'가 중간에 포함되는 모든 문자열을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'e%l'&lt;/b&gt; : 문자 'e'로 시작하고 'l'로 끝나는 모든 문자열을 나타낸다.&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;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;130&quot; data-origin-height=&quot;87&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqfnqX/btsG3dcSD5r/pFGw0FUkNZl0pZLKqgFhpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqfnqX/btsG3dcSD5r/pFGw0FUkNZl0pZLKqgFhpk/img.png&quot; data-alt=&quot;와일드카드 %를 설명하기 위한 예시 테이블 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqfnqX/btsG3dcSD5r/pFGw0FUkNZl0pZLKqgFhpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqfnqX%2FbtsG3dcSD5r%2FpFGw0FUkNZl0pZLKqgFhpk%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; alt=&quot;와일드카드 %를 설명하기 위한 예시 테이블 이미지&quot; loading=&quot;lazy&quot; width=&quot;130&quot; height=&quot;87&quot; data-origin-width=&quot;130&quot; data-origin-height=&quot;87&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;와일드카드 %를 설명하기 위한 예시 테이블 이미지&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;b&gt;'cheon'으로 끝나는 문자열을 like 조회해보기&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1714450040897&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
	*
FROM
	t1
WHERE
	address LIKE '%cheon'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;129&quot; data-origin-height=&quot;65&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHr86f/btsG11cQlLP/dkPSIoOzZZiNBysIpTtHv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHr86f/btsG11cQlLP/dkPSIoOzZZiNBysIpTtHv1/img.png&quot; data-alt=&quot;와일드카드 %를 사용하여 like 조회한 테이블 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHr86f/btsG11cQlLP/dkPSIoOzZZiNBysIpTtHv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHr86f%2FbtsG11cQlLP%2FdkPSIoOzZZiNBysIpTtHv1%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; alt=&quot;와일드카드 %를 사용하여 like 조회한 테이블 결과&quot; loading=&quot;lazy&quot; width=&quot;129&quot; height=&quot;65&quot; data-origin-width=&quot;129&quot; data-origin-height=&quot;65&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;와일드카드 %를 사용하여 like 조회한 테이블 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개념&lt;/h3&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;b&gt;'t[ae]st'&lt;/b&gt;는 &lt;b&gt;'tast'&lt;/b&gt;와 &lt;b&gt;'test'&lt;/b&gt; 두 문자열과 일치한다.&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'[abc]'&lt;/b&gt; : 단일 문자를 매칭하는 방법으로, 'a', 'b', 'c' 중 하나와 일치하는 문자열을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'[a-z]'&lt;/b&gt; : 범위를 지정하여 매칭하는 방법으로, 대괄호 안에 두 문자 사이에 하이픈(-)을 사용하여 문자 범위를 지정할 수 있다. 알파벳 소문자 a부터 z까지 일치하는 문자열을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'[a-zA-Z0-9]'&lt;/b&gt; : 여러 조합을 사용하여 매칭하는 방법으로, 영어 소문자와 대문자, 숫자 중 하나와 일치하는 문자열을 나타낸다.&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;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;130&quot; data-origin-height=&quot;87&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqfnqX/btsG3dcSD5r/pFGw0FUkNZl0pZLKqgFhpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqfnqX/btsG3dcSD5r/pFGw0FUkNZl0pZLKqgFhpk/img.png&quot; data-alt=&quot;와일드카드 []를 설명하기 위한 예시 테이블 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqfnqX/btsG3dcSD5r/pFGw0FUkNZl0pZLKqgFhpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqfnqX%2FbtsG3dcSD5r%2FpFGw0FUkNZl0pZLKqgFhpk%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; alt=&quot;와일드카드 []를 설명하기 위한 예시 테이블 이미지&quot; loading=&quot;lazy&quot; width=&quot;130&quot; height=&quot;87&quot; data-origin-width=&quot;130&quot; data-origin-height=&quot;87&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;와일드카드 []를 설명하기 위한 예시 테이블 이미지&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;b&gt;'i', 's'로 시작하는 문자열을 like 조회해보기&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1714451152377&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
	*
FROM
	t1
WHERE
	address LIKE '[is]%'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;127&quot; data-origin-height=&quot;65&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CHChg/btsG49N5EJs/1kl58drOl7IAcvx478ofh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CHChg/btsG49N5EJs/1kl58drOl7IAcvx478ofh0/img.png&quot; data-alt=&quot;와일드카드 []를 사용하여 like 조회한 테이블 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CHChg/btsG49N5EJs/1kl58drOl7IAcvx478ofh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCHChg%2FbtsG49N5EJs%2F1kl58drOl7IAcvx478ofh0%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; alt=&quot;와일드카드 []를 사용하여 like 조회한 테이블 결과&quot; loading=&quot;lazy&quot; width=&quot;127&quot; height=&quot;65&quot; data-origin-width=&quot;127&quot; data-origin-height=&quot;65&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;와일드카드 []를 사용하여 like 조회한 테이블 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개념&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대괄호 안에서 ^를 사용하면 해당 문자를 제외한 나머지 문자를 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, '[^0-9]'는 숫자가 아닌 문자와 일치하는 문자열을 찾는다.&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'[^0-9]'&lt;/b&gt; : 숫자를 포함하지 않는 문자열을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'[^0-9]abc'&lt;/b&gt; : 숫자를 포함하지 않고 'abc'가 포함된 문자열을 나타낸다.&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;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;130&quot; data-origin-height=&quot;87&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqfnqX/btsG3dcSD5r/pFGw0FUkNZl0pZLKqgFhpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqfnqX/btsG3dcSD5r/pFGw0FUkNZl0pZLKqgFhpk/img.png&quot; data-alt=&quot;와일드카드 [^]를 설명하기 위한 예시 테이블 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqfnqX/btsG3dcSD5r/pFGw0FUkNZl0pZLKqgFhpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqfnqX%2FbtsG3dcSD5r%2FpFGw0FUkNZl0pZLKqgFhpk%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; alt=&quot;와일드카드 [^]를 설명하기 위한 예시 테이블 이미지&quot; loading=&quot;lazy&quot; width=&quot;130&quot; height=&quot;87&quot; data-origin-width=&quot;130&quot; data-origin-height=&quot;87&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;와일드카드 [^]를 설명하기 위한 예시 테이블 이미지&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;b&gt;문자 중간에 'eo'가 포함되며, 'eo' 뒤에 'u' 문자열이 포함되지 않는 문자열을 like 조회해보기 (eou는 검색하지 않기)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1714452081493&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
	*
FROM
	t1
WHERE
	address LIKE '%eo[^u]%'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;129&quot; data-origin-height=&quot;65&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHr86f/btsG11cQlLP/dkPSIoOzZZiNBysIpTtHv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHr86f/btsG11cQlLP/dkPSIoOzZZiNBysIpTtHv1/img.png&quot; data-alt=&quot;와일드카드 [^]를 사용하여 like 조회한 테이블 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHr86f/btsG11cQlLP/dkPSIoOzZZiNBysIpTtHv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHr86f%2FbtsG11cQlLP%2FdkPSIoOzZZiNBysIpTtHv1%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; alt=&quot;와일드카드 [^]를 사용하여 like 조회한 테이블 결과&quot; loading=&quot;lazy&quot; width=&quot;129&quot; height=&quot;65&quot; data-origin-width=&quot;129&quot; data-origin-height=&quot;65&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;와일드카드 [^]를 사용하여 like 조회한 테이블 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개념&lt;/h3&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;b&gt;'t_st'&lt;/b&gt;는 &lt;b&gt;'test', 'tast', 'tost'&lt;/b&gt; 등과 일치한다.&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'c_t'&lt;/b&gt; : c와 t로 된 세 글자 문자에서 중간 문자는 상관없이 문자열을 조회한다. 'cat', 'cAt', 'cut' 등, 어떠한 문자든 하나의 문자로 대응한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'_ _34'&lt;/b&gt; : 앞 두 글자가 어떠한 문자가 와도 34가 포함된 네 글자의 문자열을 조회한다. '1234', 'AB34' 등을 일치하지만 '234'를 일치시키진 않는다.&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;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;130&quot; data-origin-height=&quot;87&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqfnqX/btsG3dcSD5r/pFGw0FUkNZl0pZLKqgFhpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqfnqX/btsG3dcSD5r/pFGw0FUkNZl0pZLKqgFhpk/img.png&quot; data-alt=&quot;와일드카드 [_]를 설명하기 위한 예시 테이블 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqfnqX/btsG3dcSD5r/pFGw0FUkNZl0pZLKqgFhpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqfnqX%2FbtsG3dcSD5r%2FpFGw0FUkNZl0pZLKqgFhpk%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; alt=&quot;와일드카드 [_]를 설명하기 위한 예시 테이블 이미지&quot; loading=&quot;lazy&quot; width=&quot;130&quot; height=&quot;87&quot; data-origin-width=&quot;130&quot; data-origin-height=&quot;87&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;와일드카드 [_]를 설명하기 위한 예시 테이블 이미지&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;b&gt;문자 중간에 'e'로 시작하고 'u'로 끝나는 세 글자 문자열을 like 조회해보기 (exu에서 x는 어떤 문자가 와도 상관하지 않음)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1714452798496&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
	*
FROM
	t1
WHERE
	address LIKE '%e_u%'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;129&quot; data-origin-height=&quot;45&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6Z7IP/btsG4idEaNl/Yq8k3k5my5ZpJ8f5HjOOm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6Z7IP/btsG4idEaNl/Yq8k3k5my5ZpJ8f5HjOOm0/img.png&quot; data-alt=&quot;와일드카드 [_]를 사용하여 like 조회한 테이블 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6Z7IP/btsG4idEaNl/Yq8k3k5my5ZpJ8f5HjOOm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6Z7IP%2FbtsG4idEaNl%2FYq8k3k5my5ZpJ8f5HjOOm0%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; alt=&quot;와일드카드 [_]를 사용하여 like 조회한 테이블 결과&quot; loading=&quot;lazy&quot; width=&quot;129&quot; height=&quot;45&quot; data-origin-width=&quot;129&quot; data-origin-height=&quot;45&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;와일드카드 [_]를 사용하여 like 조회한 테이블 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/t-sql/language-elements/percent-character-wildcard-character-s-to-match-transact-sql?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;마이크로 소프트 공식 문서 - SQL Server 2022 - 백분율 문자 (와일드카드 - 일치하는 문자)(Transact-SQL)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/t-sql/language-elements/wildcard-character-s-to-match-transact-sql?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; 마이크로 소프트 공식 문서 - SQL Server 2022 - [] (와일드카드 - 일치하는 문자)(Transact-SQL) &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/t-sql/language-elements/wildcard-character-s-not-to-match-transact-sql?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;마이크로 소프트 공식 문서 - SQL Server 2022 - [^] (와일드카드 - 일치하는 문자)(Transact-SQL)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/t-sql/language-elements/wildcard-match-one-character-transact-sql?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;마이크로 소프트 공식 문서 - SQL Server 2022 - _ (와일드카드 - 일치하는 문자)(Transact-SQL)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-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>Database/SQL</category>
      <category>like 조회</category>
      <category>SQL</category>
      <category>Wildcard</category>
      <category>문자열 찾기</category>
      <category>와일드카드</category>
      <category>와일드카드문자</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/891</guid>
      <comments>https://luvris2.tistory.com/891#entry891comment</comments>
      <pubDate>Tue, 30 Apr 2024 13:56:08 +0900</pubDate>
    </item>
    <item>
      <title>Flutter/Dart - 채팅 앱 만들기(4) - 앱에서 소켓 서버와 통신하여 채팅 기능 구현하기</title>
      <link>https://luvris2.tistory.com/890</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ 시리즈 포스팅 내용 보기 ]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://luvris2.tistory.com/860&quot;&gt;Flutter/Dart - 채팅 앱 만들기(1) - 다트로 웹 소켓 서버/클라이언트 만들기 (WebSocket)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://luvris2.tistory.com/872&quot;&gt;Flutter/Dart - 채팅 앱 만들기(2) - 앱 UI 레이아웃 디자인 및 기능 설계하기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://luvris2.tistory.com/889&quot;&gt;Flutter/Dart - 채팅 앱 만들기(3) - 다트 웹 소켓 서버 기능 구현하기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://luvris2.tistory.com/890&quot;&gt;Flutter/Dart - 채팅 앱 만들기(4) - 앱에서 소켓 서버와 통신하여 채팅 기능 구현하기&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;b&gt;클라이언트에서 메시지를 보내는 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;단순히 모든 클라이언트에게 메시지를 보내는 방법&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;특정 클라이언트에게 메시지를 보내는 방법&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;포스팅에서는 '귓속말'이라는 기능으로 구현하였다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ 각각의 클라이언트 1, 2, 3의 유저가 접속하여 메시지를 나누고 1과 2의 유저가 단 둘만의 메시지를 전달하는 예시 화면 ]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-height=&quot;573&quot; data-origin-width=&quot;784&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2Qge4/btsGra9THJs/M0bL9UxEn9LPjuBA7YsWdk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/c2Qge4/btsGra9THJs/M0bL9UxEn9LPjuBA7YsWdk/img.gif&quot; data-origin-height=&quot;573&quot; data-origin-width=&quot;784&quot; /&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-height=&quot;547&quot; data-origin-width=&quot;784&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8RLjZ/btsGq3C3jI9/PBVdxdl3g0Ydmm9XFlflTk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/b8RLjZ/btsGq3C3jI9/PBVdxdl3g0Ydmm9XFlflTk/img.gif&quot; data-origin-height=&quot;547&quot; data-origin-width=&quot;784&quot; /&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;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/luvris2/flutter_chatting_app&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/luvris2/flutter_chatting_app&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1713844157227&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - luvris2/flutter_chatting_app&quot; data-og-description=&quot;Contribute to luvris2/flutter_chatting_app development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/luvris2/flutter_chatting_app&quot; data-og-url=&quot;https://github.com/luvris2/flutter_chatting_app&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/X9eCq/hyVSUXreAo/mskFwsHKr64ql8nMuyRyt1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/luvris2/flutter_chatting_app&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/luvris2/flutter_chatting_app&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/X9eCq/hyVSUXreAo/mskFwsHKr64ql8nMuyRyt1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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;GitHub - luvris2/flutter_chatting_app&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to luvris2/flutter_chatting_app development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;웹소켓 클라이언트&lt;/h2&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;구조 설계&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ 파일 구조 ]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;main.dart&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;플러터 앱이 실행되는 메인 함수를 포함하는 파일&lt;/li&gt;
&lt;li&gt;사용자의 식별을 위해 닉네임을 입력 받아 채팅 페이지로 이동하는 페이지를 포함하고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;socket.dart&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;웹 소켓 서버에 연결하고, 소켓 서버 데이터를 송수신하는 기능을 포함하고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;chat 폴더
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;chat_main.dart&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;채팅 페이지를 구성할 메인 뼈대 역할을 하는 파일&lt;/li&gt;
&lt;li&gt;해당 페이지에서 채팅 내용을 입력할 영역과 채팅 내용을 보여줄 영역을 지정한다.&lt;/li&gt;
&lt;li&gt;클라이언트로 전달 받은 데이터를 하위 요소들에게 데이터를 전달하는 역할을 한다.&lt;/li&gt;
&lt;li&gt;또한,&amp;nbsp;&lt;b&gt;setState&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수를 하위 요소로 전달하여 상태값을 각 클래스와 공유한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;chat_area.dart&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;채팅 내용을 보여줄 영역을 구성하는 파일&lt;/li&gt;
&lt;li&gt;서버에서 전달 받은 데이터를 토대로 채팅 메시지 내용을 구성하는 역할을 한다.&lt;/li&gt;
&lt;li&gt;메시지의 내용은 생성자를 통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;chat_main.dart&lt;/b&gt;로부터 전달 받는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;input_text_area.dart&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;채팅 내용을 입력하는 기능으로 구성된 파일&lt;/li&gt;
&lt;li&gt;작성한 메시지 내용을 사용자와 상호작용하여 서버로 요청하는 역할을 한다.&lt;/li&gt;
&lt;li&gt;사용자의 이름과 메시지의 내용을 생성자를 통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;chat_main.dart&lt;/b&gt;으로부터 전달받고, 해당 값을 전달받은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;setState&lt;/b&gt;(포스팅에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;updateMessage&lt;/b&gt;로 지정) 함수를 통해 값을 공유한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;main.dart&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;chat_main.dart&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;chat_area.dart&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;input_text_area.dart&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;socket.dart&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;기능 구현&lt;/h3&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;main.dart (MainPage)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;메인 함수 (main)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메인 함수를 통해 메인 파일의 메인 페이지를 처음으로 보여주도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1713423899275&quot; class=&quot;cs&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;void main() async {
  runApp(
    const MaterialApp(
      home: MainPage(), //ChatMainPage(),
    ),
  );
}&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;size18&quot;&gt;메인 페이지 (MainPage)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자의 이름을 입력 받고, 확인 버튼을 누르면 채팅 페이지로 이동하는 기능을 하는 페이지&lt;/li&gt;
&lt;li&gt;텍스트 에디팅 컨트롤러로 입력 받은 사용자 이름을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;chat_main.dart&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;파일의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;ChatMainPage&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;클래스로 값을 넘겨준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1713423899275&quot; class=&quot;properties&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;class MainPage extends StatelessWidget {
  const MainPage({super.key});

  @override
  Widget build(BuildContext context) {
    // 텍스트필드 컨트롤러
    TextEditingController textEditingController = TextEditingController();

    return Scaffold(
      body: Center(
        child: Container(
          width: 250,
          height: 200,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(20),
            border: Border.all(
              color: Colors.grey,
              width: 2,
            ),
          ),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              // 유저 이름 입력
              SizedBox(
                width: 200,
                child: TextField(
                  controller: textEditingController,
                  decoration: const InputDecoration(
                    label: Center(child: Text(&quot;사용자 이름 입력&quot;)),
                  ),
                  textAlign: TextAlign.center,
                ),
              ),
              ElevatedButton(
                onPressed: () {
                  String txtValue = textEditingController.text;
                  txtValue = txtValue.trim();
                  if (txtValue != &quot;&quot;) {
                    Navigator.push(context,
                        MaterialPageRoute(builder: (context) {
                      return ChatMainPage(
                        username: txtValue,
                      );
                    }));
                  }
                },
                child: const Text(&quot;확인&quot;),
              )
            ],
          ),
        ),
      ),
    );
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;socket.dart (FlutterWebSocket)&lt;/h3&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;size18&quot;&gt;웹 소켓 서버에 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 소켓 서버를 연결하기 위한 함수 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;getSocket&lt;/span&gt;을 정의한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반환 값으로 연결된 소켓 인스턴스를 반환한다.&lt;/p&gt;
&lt;pre id=&quot;code_1713427831979&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  List messageList = [];
  String SERVER = &quot;ws://192.168.10.103:4001&quot;;

  // 웹 소켓 서버 연결
  Future&amp;lt;WebSocket&amp;gt; getSocket() async {
    WebSocket socket = await WebSocket.connect(SERVER);
    return socket;
  }&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;size18&quot;&gt;소켓 서버에 데이터 송신&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소켓 서버에 데이터를 보낼 함수 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;addMessage&lt;/span&gt;를 정의한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 함수에서는 JSON 데이터로 내보내기 위해 맵 형식으로 구성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 소켓 서버에 데이터를 보내는 구성 형식은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;username : 서버로 보낼 식별 가능한 유저의 이름&lt;/li&gt;
&lt;li&gt;message : 서버로 보낼 메시지 내용&lt;/li&gt;
&lt;li&gt;type : 서버에서 기능을 구행하기 위한 유형
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;유형에는 3가지로 나누었다.&lt;/li&gt;
&lt;li&gt;init : 클라이언트 접속 정보 초기화, 맨 처음 소켓 서버에 연결할 때 접속 정보를 넘겨주기 위해 사용한다.&lt;/li&gt;
&lt;li&gt;all : 모든 클라이언트에게 메시지 전송&lt;/li&gt;
&lt;li&gt;whisper : 특정 클라이언트에게 메시지 전송, '|' 기호를 구분자로 처리하여 뒤의 문자열을 특정 클라이언트의 정보를 기입하도록 하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1713427911963&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  // 소켓 서버에 데이터 송신
  addMessage(socket, username, message, type) {
    Map&amp;lt;String, dynamic&amp;gt; data = {
      'username': username,
      'message': message,
      'type': type,
      // [type]
      //    - init    :   클라이언트 접속 정보 초기화
      //    - all     :   모든 클라이언트에게 메시지 전송
      //    - whisper|username :   특정 클라이언트에게 메시지 전송
    };
    print(&quot;[socket.dart] 메시지 전송 : $username : $message&quot;);
    socket?.add(jsonEncode(data));
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;chat_main.dart (ChatMainPage)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;상태 값을 공유할 변수 및 함수 선언&lt;/p&gt;
&lt;pre id=&quot;code_1713423899277&quot; class=&quot;dart&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;  // 메시지 내용을 저장하는 변수
  List messageList = [];

  // 메시지 내용을 setState 함수를 통해 상태를 업데이트하는 함수
  void setStateMessage(data) {
    print(&quot;[chat_main.dart] (setStateMessage) 업데이트 할 값 : $data&quot;);
    setState(() =&amp;gt; messageList.add(data));
  }&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;size18&quot;&gt;채팅 영역과 메시지 내용 입력 영역 구분 및 각 생성자 데이터 할당&lt;/p&gt;
&lt;pre id=&quot;code_1713423899277&quot; class=&quot;less&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Column(
          children: &amp;lt;Widget&amp;gt;[
            // 메시지 내용 표시 영역
            ChatArea(
              messageList: messageList,
            ),
            // 메시지 입력 영역
            InputTextArea(
              username: widget.username,
              messageList: messageList,
              updateMessage: setStateMessage,
            )
          ],
        ),
      ),
    );
  }&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;input_text_area.dart (InputTextArea)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;웹소켓 서버 연결 및 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹소켓 서버를 연결하기 위해 위에서 정의한 FlutterWebSocket 클래스를 이용하여 소켓 서버에 연결한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;위젯이 초기화 될 때(initState) 소켓 서버를 연결하기 위해 FlutterWebSocket 클래스의 getSocket() 메서드를 이용하여 소켓 서버를 연결한다.&lt;/li&gt;
&lt;li&gt;소켓 인스턴스를 반환받은 소켓의 listen 함수를 이용하여 메시지를 수신 받도록 한다.&lt;/li&gt;
&lt;li&gt;서버에서 메시지를 수신 받을 경우, 메시지의 값을 업데이트한다. (setState)
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;updateMessage 함수는 상위 요소로 전달한 값을 setState 함수를 통해 상태 값을 업데이트 하는 역할을 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1713423899277&quot; class=&quot;reasonml&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;// 웹소켓 할당을 위한 변수
  final FlutterWebSocket flutterWebSocket = FlutterWebSocket();
  WebSocket? socket;

  @override
  void initState() {
    super.initState();

    createSocket(); // 웹소켓 서버 연결하기
  }

  // 서버 연결
  void createSocket() async {
    try {
      socket = await flutterWebSocket.getSocket();

      // 클라이언트 초기 설정 (서버측 클라이언트 정보 알림용 메시지 전송)
      flutterWebSocket.addMessage(socket, widget.username, &quot;&quot;, &quot;init&quot;);

      socket?.listen((data) {
        print(&quot;[input_text_area.dart] (createSocket) 서버로부터 받은 값 : $data&quot;);
        setState(() {
          widget.updateMessage(data);
        });
      });
    } catch (e) {
      print(&quot;[input_text_area.dart] (createSocket) 소켓 서버 접속 오류&quot;);
    }
  }&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;채팅앱 클라이언트 전체 소스 코드&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;main.dart&lt;/h3&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1713428472506&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import 'package:flutter/material.dart';
import 'chat/chat_main.dart';

void main() async {
  runApp(
    const MaterialApp(
      home: MainPage(), //ChatMainPage(),
    ),
  );
}

class MainPage extends StatelessWidget {
  const MainPage({super.key});

  @override
  Widget build(BuildContext context) {
    // 텍스트필드 컨트롤러
    TextEditingController textEditingController = TextEditingController();

    return Scaffold(
      body: Center(
        child: Container(
          width: 250,
          height: 200,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(20),
            border: Border.all(
              color: Colors.grey,
              width: 2,
            ),
          ),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              // 유저 이름 입력
              SizedBox(
                width: 200,
                child: TextField(
                  controller: textEditingController,
                  decoration: const InputDecoration(
                    label: Center(child: Text(&quot;사용자 이름 입력&quot;)),
                  ),
                  textAlign: TextAlign.center,
                ),
              ),
              ElevatedButton(
                onPressed: () {
                  String txtValue = textEditingController.text;
                  txtValue = txtValue.trim();
                  if (txtValue != &quot;&quot;) {
                    Navigator.push(context,
                        MaterialPageRoute(builder: (context) {
                      return ChatMainPage(
                        username: txtValue,
                      );
                    }));
                  }
                },
                child: const Text(&quot;확인&quot;),
              )
            ],
          ),
        ),
      ),
    );
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;socket.dart&lt;/h3&gt;
&lt;div style=&quot;background-color: #fafafa; color: #333333;&quot; data-text-less=&quot;닫기&quot; data-text-more=&quot;더보기&quot; data-ke-type=&quot;moreLess&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1713428487223&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import 'dart:convert';
import 'dart:io';

class FlutterWebSocket {
  List messageList = [];
  String SERVER = &quot;ws://192.168.10.103:4001&quot;;

  // 웹 소켓 서버 연결
  Future&amp;lt;WebSocket&amp;gt; getSocket() async {
    WebSocket socket = await WebSocket.connect(SERVER);
    return socket;
  }

  // 소켓 서버에 데이터 송신
  addMessage(socket, username, message, type) {
    Map&amp;lt;String, dynamic&amp;gt; data = {
      'username': username,
      'message': message,
      'type': type,
      // [type]
      //    - init    :   클라이언트 접속 정보 초기화
      //    - all     :   모든 클라이언트에게 메시지 전송
      //    - whisper|username :   특정 클라이언트에게 메시지 전송
    };
    print(&quot;[socket.dart] 메시지 전송 : $username : $message&quot;);
    socket?.add(jsonEncode(data));
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;chat_main.dart&lt;/h3&gt;
&lt;div style=&quot;background-color: #fafafa; color: #333333;&quot; data-text-less=&quot;닫기&quot; data-text-more=&quot;더보기&quot; data-ke-type=&quot;moreLess&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1713428489736&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import 'package:flutter/material.dart';

import 'chat_area.dart';
import 'input_text_area.dart';

class ChatMainPage extends StatefulWidget {
  final String username;
  const ChatMainPage({super.key, required this.username});

  @override
  State&amp;lt;ChatMainPage&amp;gt; createState() =&amp;gt; _ChatMainPageState();
}

class _ChatMainPageState extends State&amp;lt;ChatMainPage&amp;gt; {
  // 메시지 내용을 저장하는 변수
  List messageList = [];

  // 메시지 내용을 setState 함수를 통해 상태를 업데이트하는 함수
  void setStateMessage(data) {
    print(&quot;[chat_main.dart] (setStateMessage) 업데이트 할 값 : $data&quot;);
    setState(() =&amp;gt; messageList.add(data));
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Column(
          children: &amp;lt;Widget&amp;gt;[
            // 메시지 내용 표시 영역
            ChatArea(
              messageList: messageList,
            ),
            // 메시지 입력 영역
            InputTextArea(
              username: widget.username,
              messageList: messageList,
              updateMessage: setStateMessage,
            )
          ],
        ),
      ),
    );
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;chat_area.dart&lt;/h3&gt;
&lt;div style=&quot;background-color: #fafafa; color: #333333;&quot; data-text-less=&quot;닫기&quot; data-text-more=&quot;더보기&quot; data-ke-type=&quot;moreLess&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1713428490557&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import 'dart:convert';
import 'package:flutter/material.dart';

class ChatArea extends StatefulWidget {
  final List messageList;
  const ChatArea({super.key, required this.messageList});

  @override
  State&amp;lt;ChatArea&amp;gt; createState() =&amp;gt; _ChatAreaState();
}

class _ChatAreaState extends State&amp;lt;ChatArea&amp;gt; {
  ScrollController scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    // 리스트뷰에 메시지가 추가되면 스크롤을 가장 아래로 이동
    WidgetsBinding.instance.addPostFrameCallback((_) {
      scrollController.animateTo(scrollController.position.maxScrollExtent,
          duration: const Duration(milliseconds: 500), curve: Curves.ease);
    });

    return Expanded(
      child: ListView.builder(
        controller: scrollController,
        itemCount: widget.messageList.length,
        itemBuilder: (BuildContext context, int index) {
          // 추가된 메시지 내용
          print(
              &quot;[chat_area.dart] (build) 추가된 메시지 내용 : ${widget.messageList[index]}&quot;);

          // JSON 문자열을 맵으로 변환
          Map&amp;lt;String, dynamic&amp;gt; data = jsonDecode(widget.messageList[index]);

          return Stack(
            children: [
              Text(&quot;${data['username']}&quot;),
              Card(
                margin: const EdgeInsets.fromLTRB(0, 20, 0, 10),
                child: Padding(
                  padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
                  child: Text(data['message']),
                ),
              ),
            ],
          );
        },
      ),
    );
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;input_text_area.dart&lt;/h3&gt;
&lt;div style=&quot;background-color: #fafafa; color: #333333;&quot; data-text-less=&quot;닫기&quot; data-text-more=&quot;더보기&quot; data-ke-type=&quot;moreLess&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1713428491323&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import 'dart:io';
import 'package:flutter/material.dart';
import '../socket.dart';

class InputTextArea extends StatefulWidget {
  final String username;
  final List messageList;
  final Function updateMessage;
  const InputTextArea(
      {super.key,
      required this.username,
      required this.messageList,
      required this.updateMessage});

  @override
  State&amp;lt;InputTextArea&amp;gt; createState() =&amp;gt; _InputTextAreaState();
}

class _InputTextAreaState extends State&amp;lt;InputTextArea&amp;gt; {
  final TextEditingController _controller = TextEditingController();

  // 웹소켓 할당을 위한 변수
  final FlutterWebSocket flutterWebSocket = FlutterWebSocket();
  WebSocket? socket;

  @override
  void initState() {
    super.initState();

    createSocket(); // 웹소켓 서버 연결하기
  }

  // 서버 연결
  void createSocket() async {
    try {
      socket = await flutterWebSocket.getSocket();

      // 클라이언트 초기 설정 (서버측 클라이언트 정보 알림용 메시지 전송)
      flutterWebSocket.addMessage(socket, widget.username, &quot;&quot;, &quot;init&quot;);

      socket?.listen((data) {
        print(&quot;[input_text_area.dart] (createSocket) 서버로부터 받은 값 : $data&quot;);
        setState(() {
          widget.updateMessage(data);
        });
      });
    } catch (e) {
      print(&quot;[input_text_area.dart] (createSocket) 소켓 서버 접속 오류&quot;);
    }
  }

  // 메시지 보내기
  void sendMessage() {
    if (_controller.text.trim().isNotEmpty) {
      String message = _controller.text; // 메시지 내용
      String messageType = &quot;&quot;; // 메시지 타입

      // 귓속말 명령어 확인
      //    예) /w 사용자 내용
      //        - /w : 귓속말 명령어
      //        - 사용자 : 귓속말 보낼 사용자
      //        - 내용 : 귓속말 내용
      if (_controller.text.split(&quot; &quot;)[0] == &quot;/w&quot;) {
        messageType = &quot;whisper|${_controller.text.split(&quot; &quot;)[1]}&quot;;
        String excludeString =
            &quot;${_controller.text.split(&quot; &quot;)[0]} ${_controller.text.split(&quot; &quot;)[1]}&quot;;

        message = &quot;(귓속말)${_controller.text.replaceFirst(excludeString, &quot;&quot;)}&quot;;
      }
      // 귓속말 명령어가 없으면 모두에게 메시지 보내기
      else {
        messageType = &quot;all&quot;;
      }

      // 웹소켓 서버에 메시지 내용 전송
      flutterWebSocket.addMessage(
          socket, widget.username, message, messageType);

      _controller.clear();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Row(
        children: &amp;lt;Widget&amp;gt;[
          // 메시지 입력란
          Expanded(
            child: TextField(
              controller: _controller,
              decoration:
                  const InputDecoration(labelText: 'Enter your message'),
            ),
          ),
          // 전송버튼
          IconButton(
            icon: const Icon(Icons.send),
            onPressed: () =&amp;gt; sendMessage(), // 메시지 보내기
          ),
        ],
      ),
    );
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Mobile/Flutter</category>
      <category>Chat App</category>
      <category>chatting app</category>
      <category>Flutter</category>
      <category>플러터 채팅 앱</category>
      <category>플러터 채팅앱 만들기</category>
      <category>플러터 챗 앱</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/890</guid>
      <comments>https://luvris2.tistory.com/890#entry890comment</comments>
      <pubDate>Tue, 23 Apr 2024 12:49:34 +0900</pubDate>
    </item>
    <item>
      <title>Flutter/Dart - 채팅 앱 만들기(3) - 다트 웹 소켓 서버 기능 구현하기</title>
      <link>https://luvris2.tistory.com/889</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 포스팅에서 다뤘던 기능들과 플러터 앱의 UI를 결합하여,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 웹소켓 서버와 통신 하여 실제 실시간 채팅이 이루어지도록 기능을 구현해보자.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;웹소켓과 채팅 기능의 이해를 돕기 위해 최대한의 최대한... 간소화 하였다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;UUID와 Shared Preference를 활용한 조금 더 정밀한 개인 메시지 전송 방법을 설명하려했지만,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러면 포스팅의&lt;span&gt;&amp;nbsp;&lt;/span&gt;내용이 너무 길어지고 복잡해질꺼 같아서 전부 다 뺐다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트를 간단히 초기 설정된 닉네임으로만 통하여 메시지를 보내도록 수정하였다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 같은 닉네임을 사용한다면 사실상 1:1 개인 메시지의 기능이 아니게 되는 허점이 존재하지만 이해하길 바란다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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;[ 시리즈 포스팅 내용 보기 ]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/860&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Flutter/Dart - 채팅 앱 만들기(1) - 다트로 웹 소켓 서버/클라이언트 만들기 (WebSocket)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/872&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Flutter/Dart - 채팅 앱 만들기(2) - 앱 UI 레이아웃 디자인 및 기능 설계하기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href=&quot;https://luvris2.tistory.com/889&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Flutter/Dart - 채팅 앱 만들기(3) - 다트 웹 소켓 서버 기능 구현하기&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/890&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Flutter/Dart - 채팅 앱 만들기(4) - 앱에서 소켓 서버와 통신하여 채팅 기능 구현하기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;b&gt;서버에 접속한 클라이언트 관리하는 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;클라이언트의 초기 접속 시 기능 수행 방법&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;포스팅에서는 접속 시 사용자의 이름과 클라이언트의 정보를 서버에 저장한다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;클라이언트의 접속 종료 시 기능 수행 방법&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;포스팅에서는 접속 종료 시 서버에 저장된 목록에서 접속 종료한 클라이언트를 제거한다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ 각각의 클라이언트 1, 2, 3의 유저가 접속하여 메시지를 나누고 1과 2의 유저가 단 둘만의 메시지를 전달하는 예시 화면 ]&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;784&quot; data-origin-height=&quot;573&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2Qge4/btsGra9THJs/M0bL9UxEn9LPjuBA7YsWdk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2Qge4/btsGra9THJs/M0bL9UxEn9LPjuBA7YsWdk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2Qge4/btsGra9THJs/M0bL9UxEn9LPjuBA7YsWdk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/c2Qge4/btsGra9THJs/M0bL9UxEn9LPjuBA7YsWdk/img.gif&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;784&quot; height=&quot;573&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;573&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-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;547&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8RLjZ/btsGq3C3jI9/PBVdxdl3g0Ydmm9XFlflTk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8RLjZ/btsGq3C3jI9/PBVdxdl3g0Ydmm9XFlflTk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8RLjZ/btsGq3C3jI9/PBVdxdl3g0Ydmm9XFlflTk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/b8RLjZ/btsGq3C3jI9/PBVdxdl3g0Ydmm9XFlflTk/img.gif&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;784&quot; height=&quot;547&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;547&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/luvris2/flutter_chatting_app&quot;&gt;https://github.com/luvris2/flutter_chatting_app&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1713844335454&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/X9eCq/hyVSUXreAo/mskFwsHKr64ql8nMuyRyt1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot; data-og-url=&quot;https://github.com/luvris2/flutter_chatting_app&quot; data-og-source-url=&quot;https://github.com/luvris2/flutter_chatting_app&quot; data-og-host=&quot;github.com&quot; data-og-description=&quot;Contribute to luvris2/flutter_chatting_app development by creating an account on GitHub.&quot; data-og-title=&quot;GitHub - luvris2/flutter_chatting_app&quot; data-og-type=&quot;object&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://github.com/luvris2/flutter_chatting_app&quot; data-source-url=&quot;https://github.com/luvris2/flutter_chatting_app&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/X9eCq/hyVSUXreAo/mskFwsHKr64ql8nMuyRyt1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - luvris2/flutter_chatting_app&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to luvris2/flutter_chatting_app development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;웹소켓 서버&lt;/h2&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;통신 구조 설계&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;클라이언트의 데이터를 서버에서 받아 처리할 구조를 만들어보자.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;포스팅에서의 서버는 클라이언트로부터 3가지의 정보를 받아 처리하도록 설계하였다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ 서버에서 클라이언트 접속 정보 저장에 필요한 요소 ]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;클라이언트의 웹소켓 인스턴스&lt;/li&gt;
&lt;li&gt;사용자의 닉네임&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ 서버에서 클라이언트의 요청 처리에 필요한 요소 ]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;클라이언트의 웹소켓 인스턴스&lt;/li&gt;
&lt;li&gt;클라이언트의 데이터
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자의 닉네임&lt;/li&gt;
&lt;li&gt;메시지 내용&lt;/li&gt;
&lt;li&gt;데이터 분류 코드&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;기능 구현&lt;/h3&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;변수 선언 및 초기화&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;서버에서 사용될 변수를 선언하고 초기화 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사용될 변수는 서버가 구동될 호스트 주소와 포트 번호,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 클라이언트 접속 목록을 관리할 리스트 타입의 변수이다.&lt;/p&gt;
&lt;pre id=&quot;code_1712627649328&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* 환경에 맞게 변경 */
String HOST = '192.168.10.103'; // 서버 호스트
int PORT = 4001; // 서버 포트
List&amp;lt;dynamic&amp;gt; clients = []; // 클라이언트 목록&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;서버 설정 및 생성&lt;/h4&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;color: #ef5369; background-color: #dddddd;&quot;&gt;main&lt;/span&gt; 함수에서 서버를 설정하고 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;createServer&lt;/span&gt; 함수를 이용하여 생성된 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;HttpServer&lt;/span&gt;를 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러면 HttpServer가 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(HttpServer는 이 후 클라이언트의 요청에 따라 웹 소켓으로 프로토콜을 업그레이드 한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 수행될 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;clientConnections&lt;/span&gt; 함수는 밑에서 자세히 다룬다.&lt;/p&gt;
&lt;pre id=&quot;code_1712627748651&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void main() async {
  // 서버 설정
  HttpServer server = await createServer();

  // 클라이언트 요청 및 메시지 처리
  clientConnections(server);
}

// 서버 생성
createServer() {
  print(&quot;서버가 생성되었습니다. $HOST:$PORT&quot;);
  return HttpServer.bind(HOST, PORT);
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;클라이언트 접속 처리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트가 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;HttpServer&lt;/span&gt;로 요청을 하면, 요청을 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;WebSocket&lt;/span&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;color: #ef5369; background-color: #dddddd;&quot;&gt;webSocketActions&lt;/span&gt; 함수를 정의하여 기능을 수행하도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트가 접속 할 경우 print를 통해 다음과 같은 메시지가 서버 콘솔에 출력된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;예) 클라이언트 접속 : 192.168.10.103&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1712628149793&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 클라이언트 요청 및 메시지 처리
clientConnections(HttpServer server) async {
  // 클라이언트 요청 비동기 처리
  await for (var req in server) {
    // HTTP 요청을 웹 소켓 프로토콜로 업그레이드
    await WebSocketTransformer.upgrade(req).then((WebSocket websocket) async {
      // 디버그용 클라이언트 식별 print
      print(&quot;클라이언트 접속 : ${req.connectionInfo!.remoteAddress.address}&quot;);

      // 클라이언트 통신
      await webSocketActions(websocket);
    });
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;클라이언트 상호작용 처리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트와 상호작용을 하는 임의의 함수인 &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;webSocketActions&lt;/span&gt;를 정의한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 함수에서는 다음과 같은 기능을 수행하도록 설계하였다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;클라이언트 초기 접속 시 접속 정보 저장 (addClient 함수)&lt;/li&gt;
&lt;li&gt;메시지 데이터 송수신 처리 (webSocketListen 함수)&lt;/li&gt;
&lt;li&gt;클라이언트 연결 종료 시 접속 정보 삭제 (removeClient 함수)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1712628552749&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 클라이언트와 상호작용하는 함수
webSocketActions(WebSocket websocket) {
  // 클라이언트로 받은 데이터 메시지 처리
  websocket.listen((data) {
    // JSON 데이터 파싱
    var dataInfo = convertToJson(data);
    String messageType = dataInfo['type'].split(&quot;|&quot;)[0];

    // 초기 접속 시 클라이언트 접속 정보 저장
    if (messageType == &quot;init&quot;) {
      addClient(websocket, dataInfo['username']);
    }
    // 연결되어 있는 클라이언트에게 보낼 데이터 송신 처리
    else {
      webSocketListen(websocket, data);
    }
  },
      // 클라이언트 연결 종료 시 서버 목록에 제거
      onDone: () {
    removeClient(websocket);
  },
      // 에러 처리
      onError: (e) {
    print(&quot;[server.dart] (webSocketActions) onError : $e&quot;);
  });
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;클라이언트 초기 접속 시 접속 정보 저장&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;webSocketActions&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp;함수에서&lt;span&gt; 수행되는 기능 중 하나로, &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;addClient&lt;/span&gt;라고 함수명을 명명하였다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;접속한 클라이언트의 접속 정보를 사전에 정의한 리스트 타입의 변수인 clients 에 저장한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;접속 정보는 클라이언트의 웹소켓 인스턴스 정보와 사용자가 지정한 닉네임으로 구성한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1713421266008&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 클라이언트 초기 접속 정보 저장
addClient(client, username) {
  print(&quot;클라이언트 접속 정보 : username($username)&quot;);
  clients.add([client, username]);
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;클라이언트측 메시지 데이터 송수신 처리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;webSocketActions&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp;함수에서&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;수행되는 기능 중 하나로, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;webSocketListen&lt;/span&gt;이라고 함수명을 명명하였다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트측에서 받은 JSON 데이터를 파싱하여, 사전에 정의한 데이터 유형을 파악 한 후, 유형에 맞는 대상 클라이언트에게 메시지를 다시 보내는 역할을 한다. 클라이언트에서 보내는 데이터의 내용은 다음과 같다.&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;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;username : &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;사용자의 닉네임&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;message : 메시지 내용&lt;/li&gt;
&lt;li&gt;type : 데이터 분류 코드
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;init : 클라이언트 접속 정보 초기화&lt;/li&gt;
&lt;li&gt;all : 모든 클라이언트에게 메시지 전송&lt;/li&gt;
&lt;li&gt;whisper|username : 특정 클라이언트에게 메시지 전송, '|'(or) 기호를 구분자로 뒤에 위치하는 문자열로 특정 클라이언트를 지정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1713421488497&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 클라이언트로 받은 데이터 메시지 처리
webSocketListen(WebSocket websocket, data) {
  // JSON 데이터 파싱
  print(&quot;클라이언트로부터의 메시지 : $data&quot;);
  var dataInfo = convertToJson(data);
  String messageType = dataInfo['type'].split(&quot;|&quot;)[0];

  for (var client in clients) {
    // 전체 사용자에게 메시지 보내기
    if (messageType == &quot;all&quot;) {
      client[0].add(data);
    }
    // 귓속말 대상과 자신에게만 메시지를 보내기
    else if (messageType == &quot;whisper&quot;) {
      String whisper = dataInfo['type'].split(&quot;|&quot;)[1];
      if (client[1] == whisper || client[1] == dataInfo['username']) {
        client[0].add(data);
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;클라이언트 연결 종료 시 접속 정보 삭제&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;webSocketActions&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp;함수에서&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;수행되는 기능 중 하나로, &lt;span style=&quot;color: #ef5369; background-color: #dddddd;&quot;&gt;removeClient&lt;/span&gt;라고 함수명을 명명하였다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버에서 접속한 클라이언트들의 정보를 가지고 있는 리스트 변수인 clients 에서 접속을 종료한 클라이언트의 정보를 제거한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트를 식별하기 위해서 포스팅에서는 간단히 유저의 이름을 식별하여 유저 이름에 맞는 클라이언트의 정보를 리스트에서 제외하였다.&lt;/p&gt;
&lt;pre id=&quot;code_1713421317724&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 클라이언트 연결 종료 시 서버 목록에서 제거
removeClient(WebSocket websocket) {
  for (var i = 0; i &amp;lt; clients.length; i++) {
    var client = clients[i];
    if (client[0] == websocket) {
      print(&quot;클라이언트 접속 종료 : ${client[1]}&quot;);
      clients.removeAt(i); // 해당 클라이언트 목록에서 제거
      print(&quot;접속중인 클라이언트 목록 : $clients&quot;);
      break; // 클라이언트를 찾았으므로 반복문 종료
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;JSON 데이터 파싱 함수&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트측에서 받은 JSON 데이터를 파싱하는 함수이다.&lt;/p&gt;
&lt;pre id=&quot;code_1713421874358&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// JSON 데이터 파싱 함수
convertToJson(data) {
  Map&amp;lt;String, dynamic&amp;gt; converData = jsonDecode(data);
  return converData;
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;소켓 서버 전체 소스 코드&lt;/h3&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1713421996949&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import 'dart:convert';
import 'dart:io';

String HOST = '192.168.10.103'; // 서버 호스트
int PORT = 4001; // 서버 포트
List&amp;lt;dynamic&amp;gt; clients = []; // 클라이언트 목록

void main() async {
  // 서버 설정
  HttpServer server = await createServer();

  // 클라이언트 요청 및 메시지 처리
  clientConnections(server);
}

// 서버 생성
createServer() {
  print(&quot;서버가 생성되었습니다. $HOST:$PORT&quot;);
  return HttpServer.bind(HOST, PORT);
}

// 클라이언트 요청 및 메시지 처리
clientConnections(HttpServer server) async {
  // 클라이언트 요청 비동기 처리
  await for (var req in server) {
    // HTTP 요청을 웹 소켓 프로토콜로 업그레이드
    await WebSocketTransformer.upgrade(req).then((WebSocket websocket) async {
      // 디버그용 클라이언트 식별 print
      print(&quot;클라이언트 접속 : ${req.connectionInfo!.remoteAddress.address}&quot;);

      // 클라이언트 통신
      await webSocketActions(websocket);
    });
  }
}

// 클라이언트 초기 접속 정보 저장
addClient(client, username) {
  print(&quot;클라이언트 접속 정보 : username($username)&quot;);
  clients.add([client, username]);
}

// 클라이언트 연결 종료 시 서버 목록에서 제거
removeClient(WebSocket websocket) {
  for (var i = 0; i &amp;lt; clients.length; i++) {
    var client = clients[i];
    if (client[0] == websocket) {
      print(&quot;클라이언트 접속 종료 : ${client[1]}&quot;);
      clients.removeAt(i); // 해당 클라이언트 목록에서 제거
      print(&quot;접속중인 클라이언트 목록 : $clients&quot;);
      break; // 클라이언트를 찾았으므로 반복문 종료
    }
  }
}

// 클라이언트와 상호작용하는 함수
webSocketActions(WebSocket websocket) {
  // 클라이언트로 받은 데이터 메시지 처리
  websocket.listen((data) {
    // JSON 데이터 파싱
    var dataInfo = convertToJson(data);
    String messageType = dataInfo['type'].split(&quot;|&quot;)[0];

    // 초기 접속 시 클라이언트 접속 정보 저장
    if (messageType == &quot;init&quot;) {
      addClient(websocket, dataInfo['username']);
    }
    // 연결되어 있는 클라이언트에게 보낼 데이터 송신 처리
    else {
      webSocketListen(websocket, data);
    }
  },
      // 클라이언트 연결 종료 시 서버 목록에 제거
      onDone: () {
    removeClient(websocket);
  },
      // 에러 처리
      onError: (e) {
    print(&quot;[server.dart] (webSocketActions) onError : $e&quot;);
  });
}

// JSON 데이터 파싱 함수
convertToJson(data) {
  Map&amp;lt;String, dynamic&amp;gt; converData = jsonDecode(data);
  return converData;
}

// 클라이언트로 받은 데이터 메시지 처리
webSocketListen(WebSocket websocket, data) {
  // JSON 데이터 파싱
  print(&quot;클라이언트로부터의 메시지 : $data&quot;);
  var dataInfo = convertToJson(data);
  String messageType = dataInfo['type'].split(&quot;|&quot;)[0];

  for (var client in clients) {
    // 전체 사용자에게 메시지 보내기
    if (messageType == &quot;all&quot;) {
      client[0].add(data);
    }
    // 귓속말 대상과 자신에게만 메시지를 보내기
    else if (messageType == &quot;whisper&quot;) {
      String whisper = dataInfo['type'].split(&quot;|&quot;)[1];
      if (client[1] == whisper || client[1] == dataInfo['username']) {
        client[0].add(data);
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>Mobile/Flutter</category>
      <category>Flutter</category>
      <category>다트 소켓 서버</category>
      <category>채팅 앱</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/889</guid>
      <comments>https://luvris2.tistory.com/889#entry889comment</comments>
      <pubDate>Thu, 18 Apr 2024 16:08:09 +0900</pubDate>
    </item>
    <item>
      <title>MS-SQL - NEWID() 함수의 랜덤 값 액세스에 관해서, 랜덤 값 중복 여부 트러블 슈팅</title>
      <link>https://luvris2.tistory.com/888</link>
      <description>&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;MS-SQL(SQL Server) 에서는 NEWID() 함수를 이용하여 임의의 데이터를 조회할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들면, 1부터 10까지의 숫자가 있을 경우 NEWID() 함수를 통해 1~10 사이의 임의의 값을 출력하여 조회할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1713334918484&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 테이블 변수 생성
DECLARE @temp_table TABLE(
	num int
)

-- 테이블 변수에 1~10의 값 추가
DECLARE @i int = 1
WHILE @i &amp;lt;=10 BEGIN
	INSERT INTO @temp_table
		SELECT @i
        
	SET @i += 1
END

-- 1~10 사이의 랜덤 값 추출
SELECT TOP 1 * FROM @temp_table ORDER BY NEWID();&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;위의 쿼리를 실행하면 'num' 컬럼의 값이 1에서 10 사이의 값이 랜덤하게 나오는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 NEWID() 함수를 통해 데이터베이스 내의 임의의 값을 쿼리로 추출할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;혹시나 테이블 변수, NEWID() 함수에 대해 자세히 알고 싶으면 아래의 포스팅을 참고하자.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/407&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MSSQL - 테이블 반환 매개 변수 (테이블 변수)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://luvris2.tistory.com/404&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MSSQL - 무작위 행 추출하기 (newid)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램으로 짜면 쉬운데 굳이 왜 이런 로직을 데이터베이스에서 쿼리를 작성해야하는지 의문이 들 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 여러 환경에 의해 SQL 쿼리로 로직을 짜야할 때도 있다.&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;요구 사항은 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;데이터베이스 숫자 테이블 내의 데이터에서 여러 개의 값 중 랜덤으로 특정 값을 추출해야한다.&lt;/li&gt;
&lt;li&gt;첫 번째로 뽑은 랜덤 값을 토대로, 두 번째로 뽑은 값은 첫 번째 값과 중복이 되지 않아야 한다.&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;내가 쿼리로 작성했던 내용은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;WITH 구문을 사용
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;첫 번째 테이블에 랜덤의 첫 번째 값을 구함&lt;/li&gt;
&lt;li&gt;두 번째 테이블에 첫 번째로 구한 값을 WHERE 조건절에 NOT IN을 이용하여 해당 중복값을 제거하고 새로 랜덤의 두 번째 값을 구함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;두 랜덤한 결과값을 UNION 을 통해 데이터 통합&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;극단적으로 1과 2의 숫자만 있다고 하고, 위의 내용대로 쿼리를 작성해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ 주의! 꼭 확인해야 할 것 ]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예제 쿼리에서 사용되는 테이블 변수는 실행 시에만 존재하는 변수로, 하나의 단위로 실행시켜야 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;즉, 아래의 쿼리를 모두 한꺼번에 실행해야 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1713337405006&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 테이블 변수 생성
DECLARE @temp_table TABLE(
	num int
)

-- 테이블 변수에 1~2의 값 추가
DECLARE @i int = 1
WHILE @i &amp;lt;=2 BEGIN
	INSERT INTO @temp_table
		select @i

	SET @i += 1
END

;WITH
	-- 첫 번째 랜덤 값 추출
	cte_first AS (
		SELECT TOP 1 * FROM @temp_table ORDER BY NEWID()
	),
	-- 두 번째 랜덤 값 추출
	cte_second AS (
		SELECT TOP 1 * FROM @temp_table
		WHERE
			num not in (
				SELECT num FROM cte_first
			)
		ORDER BY NEWID()
	)
-- 랜덤 데이터 조회
SELECT * FROM cte_first
UNION
SELECT * FROM cte_second&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분명히 결과 값은 무조건 1과 2가 모두 나와야 한다.&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;141&quot; data-origin-height=&quot;76&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRAfHC/btsGFqkqJ3k/oBxrQkVJoRNFfVEDkfb040/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRAfHC/btsGFqkqJ3k/oBxrQkVJoRNFfVEDkfb040/img.png&quot; data-alt=&quot;&amp;amp;lt;랜덤 쿼리 실행 결과&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRAfHC/btsGFqkqJ3k/oBxrQkVJoRNFfVEDkfb040/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRAfHC%2FbtsGFqkqJ3k%2FoBxrQkVJoRNFfVEDkfb040%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;141&quot; height=&quot;76&quot; data-origin-width=&quot;141&quot; data-origin-height=&quot;76&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;랜덤 쿼리 실행 결과&amp;gt;&lt;/figcaption&gt;
&lt;/figure&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;여러 번을 조회해보면 실제로는 무조건적으로 1과 2의 값이 모두 나오지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리를 실행하면 다음과 같은 결과 중 하나의 결과를 마주하게 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;1과 2 모두 출력&lt;/li&gt;
&lt;li&gt;1만 출력&lt;/li&gt;
&lt;li&gt;2만 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 그럴까?&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;NEWID() 함수의 랜덤 액세스의 원리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;NEWID() 함수는 쿼리가 실행 될 때마다 매번 다른 결과값을 호출&lt;/b&gt;&lt;/u&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;이해하기 쉽게 더 쉬운 쿼리로 작성해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WITH 구문을 사용하여 무조건 하나의 랜덤 값만을 뽑도록 해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 해당 테이블을 중복이 있도록 UNION ALL로 합쳐 두 번 조회해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 아래의 쿼리는 상사님께서 이해를 시켜주기 위해 쿼리를 쉽게 작성해주신 예제이다 :)&lt;/p&gt;
&lt;pre id=&quot;code_1713338900088&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 테이블 변수 생성
DECLARE @temp_table TABLE(
	num int
)

-- 테이블 변수에 1~2의 값 추가
DECLARE @i int = 1
WHILE @i &amp;lt;=2 BEGIN
	INSERT INTO @temp_table
		select @i

	SET @i += 1
END

;WITH test AS (
	SELECT TOP 1 num FROM @temp_table ORDER BY NEWID()
)
SELECT * FROM test
UNION ALL
SELECT * FROM test&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;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;각각 1, 2&lt;/li&gt;
&lt;li&gt;각각 2, 1&lt;/li&gt;
&lt;li&gt;각각 1, 1&lt;/li&gt;
&lt;li&gt;각각 2, 2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;83&quot; data-origin-height=&quot;83&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTILud/btsGHuzcjK9/84ed4i7jPpOnj9RPARWDC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTILud/btsGHuzcjK9/84ed4i7jPpOnj9RPARWDC1/img.png&quot; data-alt=&quot;&amp;amp;lt;랜던 쿼리 실행 결과&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTILud/btsGHuzcjK9/84ed4i7jPpOnj9RPARWDC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTILud%2FbtsGHuzcjK9%2F84ed4i7jPpOnj9RPARWDC1%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;83&quot; height=&quot;83&quot; data-origin-width=&quot;83&quot; data-origin-height=&quot;83&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;랜던 쿼리 실행 결과&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정답은 하나의 쿼리 내에서 NEWID() 함수를 각각 독립적으로 실행되지 않게 하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 극단적인 1과 2만 있는 숫자 테이블에서,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 값이 서로 중복되지 않도록 랜덤으로 출력하는 쿼리를 다시 작성해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1713339733438&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 테이블 변수 생성
DECLARE @temp_table TABLE(
	num int
)

-- 테이블 변수에 1~2의 값 추가
DECLARE @i int = 1
WHILE @i &amp;lt;=2 BEGIN
	INSERT INTO @temp_table
		select @i

	SET @i += 1
END

-- 랜덤값을 저장할 테이블 변수 생성
DECLARE @rand_table TABLE(
	rand_num int
)

-- 첫 번째 랜덤 값 테이블 변수에 저장
INSERT INTO @rand_table
	SELECT TOP 1 * FROM @temp_table ORDER BY NEWID()

-- 두 번째 랜덤 값 테이블 변수에 저장 : 테이블 변수에서 첫 번째 값을 확인하여 제외
INSERT INTO @rand_table
	SELECT TOP 1 * FROM @temp_table
	WHERE
		num NOT IN (
			SELECT rand_num FROM @rand_table
		)
	ORDER BY NEWID()

-- 랜덤 데이터 조회
SELECT * FROM @rand_table&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;첫 번째 NEWID() 함수로 추출된 램덤의 값을 테이블에 저장하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 두 번째 랜덤 값 호출에서 데이터 중복 검사를 할 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NEWID() 함수를 독립적으로 실행되게 하지 않고 저장된 테이블에서 랜덤 값을 확인하여 중복을 제거하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 값은 이제 중복이 되지 않고 1과 2 혹은 2와 1만 출력된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;119&quot; data-origin-height=&quot;71&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xG7Fu/btsGIMTJEae/OWcMrzavNcRAO37KRBupPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xG7Fu/btsGIMTJEae/OWcMrzavNcRAO37KRBupPK/img.png&quot; data-alt=&quot;&amp;amp;lt;랜덤 쿼리 실행 결과&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xG7Fu/btsGIMTJEae/OWcMrzavNcRAO37KRBupPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxG7Fu%2FbtsGIMTJEae%2FOWcMrzavNcRAO37KRBupPK%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;119&quot; height=&quot;71&quot; data-origin-width=&quot;119&quot; data-origin-height=&quot;71&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;랜덤 쿼리 실행 결과&amp;gt;&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;프로시저 내에서 짠 쿼리문의 결과가 자꾸 중복이 제거되지 않고 중복된 데이터가 함께 조회되는 문제로&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;</description>
      <category>Database/MS-SQL</category>
      <category>MS-SQL</category>
      <category>MSSQL 랜덤 값 중복 없이 추출</category>
      <category>MSSQL 랜덤 값 추출</category>
      <category>NEWID() 함수</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/888</guid>
      <comments>https://luvris2.tistory.com/888#entry888comment</comments>
      <pubDate>Wed, 17 Apr 2024 17:17:33 +0900</pubDate>
    </item>
    <item>
      <title>1분 만에 해결하는 티스토리 블로그 사이트맵, RSS 제출하기 (+RSS 설정)</title>
      <link>https://luvris2.tistory.com/887</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;u&gt;블로그의 구글 서치 콘솔, 네이버 서치 어드바이저에 등록하기 위해&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;RSS, 사이트맵을 제출&lt;/u&gt;하는 과정에서 최대한 간단히, 바로 적용할 수 있게 정리해 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요점만 간단히 읽고 빠르게 사이트맵, RSS 제출해보자.&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;/h2&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;자신의 블로그 주소 뒤에 &lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;https://블로그&amp;nbsp;주소/sitemap.xml&lt;/span&gt;&lt;/b&gt; &lt;/span&gt;&lt;span style=&quot;color: #666666; text-align: start;&quot;&gt;를 입력하면 내 티스토리 블로그의 사이트맵을 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666; text-align: start;&quot;&gt;사이트맵을 요구하는 곳에 예시와 같이 뒤에 &lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;/sitemap.xml&lt;/b&gt;&lt;/span&gt;만 붙여서 기입하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;예시) &lt;a href=&quot;https://luvris2.tistory.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://luvris2.tistory.com/sitemap.xml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;RSS 제출하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RSS 또한 사이트맵과 동일하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신의 블로그 주소 뒤에 &lt;b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;https://블로그 주소&lt;/span&gt;&lt;/b&gt;&lt;b&gt;/rss&lt;/b&gt; 경로를 입력하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RSS를 요구하는 곳에 예시와 같이 뒤에 &lt;b&gt;/rss&lt;/b&gt;만 붙여서 기입하면 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;예시) &lt;a href=&quot;https://luvris2.tistory.com/rss&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://luvris2.tistory.com/rss&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;+ 사이트맵 주소 확인하기, RSS 설정하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사이트맵 주소와 RSS 설정을 확인하려면,&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;size18&quot;&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 alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1013&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxSUlH/btsGu3P7ZEw/o31pM50w8MehfI0P13Ukb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxSUlH/btsGu3P7ZEw/o31pM50w8MehfI0P13Ukb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxSUlH/btsGu3P7ZEw/o31pM50w8MehfI0P13Ukb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxSUlH%2FbtsGu3P7ZEw%2Fo31pM50w8MehfI0P13Ukb0%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;1013&quot; height=&quot;466&quot; data-origin-width=&quot;1013&quot; data-origin-height=&quot;466&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;size18&quot;&gt;RSS 설정하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RSS도 사이트맵 주소와 같은 경로에서 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'&lt;b&gt;티스토리 관리 페이지 - 관리 - 블로그 - 기타 설정&lt;/b&gt;'에서 확인 가능하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RSS는 &lt;b&gt;전체 공개로 설정&lt;/b&gt;하며, 공개될 &lt;b&gt;RSS를 50개로 갱신&lt;/b&gt;하도록 설정해 주는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RSS 설정을 변경하면 반드시 &lt;b&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;1151&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ppSUJ/btsGwtm1qjS/4EjM3IB5GZei4JvIaFbfKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ppSUJ/btsGwtm1qjS/4EjM3IB5GZei4JvIaFbfKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ppSUJ/btsGwtm1qjS/4EjM3IB5GZei4JvIaFbfKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FppSUJ%2FbtsGwtm1qjS%2F4EjM3IB5GZei4JvIaFbfKk%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;1151&quot; height=&quot;418&quot; data-origin-width=&quot;1151&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://notice.tistory.com/2537&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;티스토리 블로그 공지 - [안내] 블로그 사이트맵이 자동으로 생성됩니다.&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>일상/블로그 이야기</category>
      <category>티스토리 rss</category>
      <category>티스토리 RSS 설정</category>
      <category>티스토리 rss 제출</category>
      <category>티스토리 블로그</category>
      <category>티스토리 사이트맵</category>
      <category>티스토리 사이트맵 제출</category>
      <author>luvris2</author>
      <guid isPermaLink="true">https://luvris2.tistory.com/887</guid>
      <comments>https://luvris2.tistory.com/887#entry887comment</comments>
      <pubDate>Thu, 11 Apr 2024 13:22:17 +0900</pubDate>
    </item>
  </channel>
</rss>