<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발 기록이</title>
    <link>https://studyingbackhoe.tistory.com/</link>
    <description>개발 기록 정리하기</description>
    <language>ko</language>
    <pubDate>Sat, 4 Jul 2026 12:12:47 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>studyingbackhoe</managingEditor>
    <image>
      <title>개발 기록이</title>
      <url>https://tistory1.daumcdn.net/tistory/5503637/attach/e8ac208bc1854e3ebcbe9944007d8336</url>
      <link>https://studyingbackhoe.tistory.com</link>
    </image>
    <item>
      <title>[Claude] Claude Code 결제하기(Pro/Max 구독, API 크레딧)</title>
      <link>https://studyingbackhoe.tistory.com/94</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Claude Code로 레거시 코드를 수정해 보려다가, 초반에 결제 구조랑 사용 방식이 생각보다 헷갈려서 정리해 봤다.&lt;br&gt;&amp;nbsp;&lt;br&gt;1. 우선 터미널에서 아래와 같이 npm으로 설치를 진행한다.&lt;/p&gt;&lt;div&gt; 
 &lt;div&gt; 
  &lt;pre class=&quot;css&quot; style=&quot;color: #14181f;&quot;&gt;&lt;code&gt;npm install -g @anthropic-ai/claude-code&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;2. 프로젝트 폴더 경로에서 &lt;b&gt;claude라고&lt;/b&gt; 입력한 후에 테마 선택을 해주고&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Welcome to Claude Code v2.1.114
…………………………………………………………………………………………………………………………………………………………
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; █████▓▓░
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ███▓░&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ░░
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;░░░░░░&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;███▓░
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;░░░&amp;nbsp;&amp;nbsp; ░░░░░░░░░░&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;███▓░
&amp;nbsp;&amp;nbsp; ░░░░░░░░░░░░░░░░░░░&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;██▓░░&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▓
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ░▓▓███▓▓░
 *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ░░░░
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ░░░░░░░░
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ░░░░░░░░░░░░░░░░
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; █████████&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;██▄█████▄██&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; █████████&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*
…………………█ █&amp;nbsp;&amp;nbsp; █ █………………………………………………………………………………………………………………
 Let's get started.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
 Choose the text style that looks best with your terminal
 To change this later, run /theme
&amp;nbsp;&amp;nbsp; 1. Auto (match terminal)
 ❯ 2. Dark mode ✔
Welcome to Claude Code v2.1.114
…………………………………………………………………………………………………………………………………………………………
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; █████▓▓░
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ███▓░&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ░░
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;░░░░░░&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;███▓░
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;░░░&amp;nbsp;&amp;nbsp; ░░░░░░░░░░&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;███▓░
&amp;nbsp;&amp;nbsp; ░░░░░░░░░░░░░░░░░░░&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;██▓░░&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▓
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ░▓▓███▓▓░
 *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ░░░░
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ░░░░░░░░
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ░░░░░░░░░░░░░░░░
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; █████████&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;██▄█████▄██&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; █████████&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*
…………………█ █&amp;nbsp;&amp;nbsp; █ █………………………………………………………………………………………………………………
 Let's get started.
 Choose the text style that looks best with your terminal
 To change this later, run /theme
&amp;nbsp;&amp;nbsp; 1. Auto (match terminal)
 ❯ 2. Dark mode ✔
&amp;nbsp;&amp;nbsp; 3. Light mode
&amp;nbsp;&amp;nbsp; 4. Dark mode (colorblind-friendly)
&amp;nbsp;&amp;nbsp; 5. Light mode (colorblind-friendly)
&amp;nbsp;&amp;nbsp; 6. Dark mode (ANSI colors only)
&amp;nbsp;&amp;nbsp; 7. Light mode (ANSI colors only)
 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ 
&amp;nbsp;&amp;nbsp;1&amp;nbsp;&amp;nbsp;function greet() {
&amp;nbsp;&amp;nbsp;2 -&amp;nbsp;&amp;nbsp;console.log(&quot;Hello, World!&quot;);
&amp;nbsp;&amp;nbsp;2 +&amp;nbsp;&amp;nbsp;console.log(&quot;Hello, Claude!&quot;);
&amp;nbsp;&amp;nbsp;3&amp;nbsp;&amp;nbsp;}
 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ 
&amp;nbsp;&amp;nbsp;Syntax theme: Monokai Extended (ctrl+t to disable)&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;3. 로그인 방법을 고르는 화면이 나온다.&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; 1번 - Claude account with subscription&lt;/b&gt;: claude.ai Pro/Max 구독이 있으면 이걸 선택. API 키 없이 구독으로 Claude Code를 쓸 수 있다.&lt;/li&gt;&lt;li&gt;&lt;b&gt;2번 - Anthropic Console account&lt;/b&gt;: API 크레딧 충전 방식. 쓴 만큼 차감되는 종량제.&lt;/li&gt;&lt;/ul&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Claude Code can be used with your Claude subscription or billed based on API usage through your Console account.
 Select login method:
&amp;nbsp;&amp;nbsp; 1. Claude account with subscription · Pro, Max, Team, or Enterprise
 ❯ 2. Anthropic Console account · API usage billing
&amp;nbsp;&amp;nbsp; 3. 3rd-party platform · Amazon Bedrock, Microsoft Foundry, or Vertex AI&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;2번을 선택한 후에도 계속&amp;nbsp; 에러가 뜨면서 명령어가 적용되지 않는데&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Credit balance too low · Add funds:
https://platform.claude.com/settings/billing&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&lt;a href=&quot;https://platform.claude.com/settings/billing&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://platform.claude.com/settings/billing&lt;/span&gt;&lt;/a&gt;&amp;nbsp;페이지로 이동하면 아래와 같은 화면이 뜬다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;283&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6qlfL/dJMcabYdaRb/x8M5egt3qFwyyNloWE9kqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6qlfL/dJMcabYdaRb/x8M5egt3qFwyyNloWE9kqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6qlfL/dJMcabYdaRb/x8M5egt3qFwyyNloWE9kqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6qlfL%2FdJMcabYdaRb%2Fx8M5egt3qFwyyNloWE9kqk%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;595&quot; height=&quot;283&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;283&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;이건 요금제가 아니라 &lt;/b&gt;&lt;u&gt;&lt;b&gt;선불 크레딧 충전 금액&lt;/b&gt;&lt;/u&gt;&lt;b&gt;을 고르는 화면이다.&lt;/b&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;결제를 진행한 후에도 &lt;/b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;Claude Code(클로드 CLI)는&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;b&gt;세션 기반 로그인을 쓰는 경우가 많아서 로그인 안 되어 있으면 401에러가 발생한다고 한다.&lt;/b&gt;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Please run /login · API Error: 401 {&quot;type&quot;:&quot;error&quot;,&quot;error&quot;:{&quot;type&quot;:&quot;authentication_error&quot;,&quot;message&quot;:&quot;Invalid authentication credentials&quot;},&quot;request_id&quot;:&quot;에러코드&quot;}&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그래서 터미널에서 &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;/login&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt; 입력한 후 로그인만 해주면, 그다음부터는 원하는 명령을 바로 사용할 수 있다. &lt;/span&gt;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot;&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;claude.ai 구독(Pro/Max)과 API 크레딧 차이가 뭘까?&lt;/h2&gt;&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. claude.ai 구독 (자동 결제)&lt;/h4&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;Claude 채팅 서비스&lt;/li&gt;&lt;li&gt;매달 자동 결제 + 사용량 리셋&lt;/li&gt;&lt;li&gt;Claude Code도 사용 가능하지만 &lt;b&gt;채팅과 동일한 사용량 제한을 공유한다&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. API 크레딧 (충전식)&amp;nbsp;&amp;nbsp;&lt;/h4&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;개발자용 API&lt;/li&gt;&lt;li&gt;선불 충전, 쓴 만큼 차감&lt;/li&gt;&lt;li&gt;자동 결제 없음. 다 쓰면 다시 충전&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;+ 결제 방법 (API 크레딧 기준)&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;console.anthropic.com 접속 → 로그인&lt;/li&gt;&lt;li&gt;Billing → 카드 등록 → 크레딧 충전 ($20부터, 신규 $5 무료  충전 후에 추가로 주는 크레딧이지 결제할 때 $15 로 할인해주는건 아님 )&lt;/li&gt;&lt;li&gt;프로젝트 폴더에서 &lt;b&gt;claude 실행&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;/login으로 로그인&lt;/b&gt;하면 바로 사용 가능&lt;/li&gt;&lt;/ol&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&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;claude.ai 구독 = OTT처럼 매달 자동 결제&lt;/li&gt;&lt;li&gt;API 크레딧 = 교통카드처럼 미리 충전해서 쓴 만큼 차감&lt;/li&gt;&lt;li&gt;&lt;b&gt;claude ai, claude 같은 계정으로 로그인 가능 &lt;/b&gt;&lt;/li&gt;&lt;li&gt;대신 &lt;u&gt;&lt;b&gt;결제 방식이 분리&lt;/b&gt;&lt;/u&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;br&gt;claude.ai 구독과 API 크레딧은 같은 계정을 쓰지만, 과금 방식이 따로 운영된다. 처음 시작해 보는 경우라면 가볍게는 API 크레딧으로 시작하는 게 더 편할 것 같다.&lt;br&gt;&amp;nbsp;&lt;br&gt;그래서 API 크레딧으로 계속 써보면서, 실제로 코드 작업에 어느 정도까지 활용할 수 있을지 더 써볼 생각이다☺️&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot;&gt;&lt;div id=&quot;code_1776578762052&quot; data-ke-type=&quot;html&quot; data-source=&quot;&lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;https://icons8.com/icon/zQjzFjPpT2Ek/claude-ai&amp;quot;&gt;클로드&lt;/a&gt; 작가: &lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;https://icons8.com&amp;quot;&gt;Icons8&lt;/a&gt;&quot;&gt;
 &lt;a href=&quot;https://icons8.com/icon/zQjzFjPpT2Ek/claude-ai&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;클로드&lt;/a&gt; 작가: &lt;a href=&quot;https://icons8.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Icons8&lt;/a&gt;
&lt;/div&gt;</description>
      <category>기록/Claude</category>
      <category>Claude</category>
      <category>결제방식</category>
      <author>studyingbackhoe</author>
      <guid isPermaLink="true">https://studyingbackhoe.tistory.com/94</guid>
      <comments>https://studyingbackhoe.tistory.com/94#entry94comment</comments>
      <pubDate>Sun, 19 Apr 2026 15:07:30 +0900</pubDate>
    </item>
    <item>
      <title>MyBatis 자동 증가 키 가져오기 (useGeneratedKeys, keyProperty)</title>
      <link>https://studyingbackhoe.tistory.com/93</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;MyBatis를 사용할 때 INSERT 이후 생성된 PK 값을 바로 사용해야 하는 경우가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 사용할 수 있는 옵션인 useGeneratedKeys와 keyProperty에 대해 알아보자.&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;1. useGeneratedKeys &lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB에서 자동 생성된 키를 가져올지 여부를 설정하는 옵션.&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;useGeneratedKeys=&quot;true&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. keyProperty&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 키 값을 매핑할 &lt;b&gt;객체의 필드명&lt;/b&gt;을 지정.&lt;/p&gt;
&lt;pre class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;keyProperty=&quot;가져오고 싶은 PK 필드명&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;&lt;b&gt;3. 사용 예시&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;✔ DB 테이블 생성(MySQL 기준)&lt;/p&gt;
&lt;pre id=&quot;code_1775280199567&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE TABLE mybatis_users (
    user_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50),
    email VARCHAR(100)
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;✔ Java 객체&lt;/p&gt;
&lt;pre class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;public class User {
    private Integer userId;
    private String name;
    private String email;

    // getter, setter도 생성해주기
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;✔ Mapper XML&lt;/p&gt;
&lt;pre style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;&amp;lt;insert id=&quot;insertUser&quot; useGeneratedKeys=&quot;true&quot; keyProperty=&quot;userId&quot;&amp;gt;
    INSERT INTO users (name, email)
    VALUES (#{name}, #{email})
&amp;lt;/insert&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;✔ &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Java&lt;span&gt; &lt;/span&gt;&lt;/span&gt;실행코드&lt;/p&gt;
&lt;pre class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;User user = new User();
user.setName(&quot;홍길동&quot;);
user.setEmail(&quot;test@test.com&quot;);

userMapper.insertUser(user);

System.out.println(user.getUserId());&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;INSERT 이후에는 user.getUserId()를 통해 생성된 PK 값을 바로 확인할 수 있다. &lt;br /&gt;&lt;br /&gt;기본적으로&amp;nbsp;useGeneratedKeys는&amp;nbsp;false이지만,&amp;nbsp;true로&amp;nbsp;설정하면&amp;nbsp;DB가&amp;nbsp;자동으로&amp;nbsp;생성한&amp;nbsp;키&amp;nbsp;값을&amp;nbsp;함께&amp;nbsp;가져오고,&amp;nbsp;MyBatis가&amp;nbsp;이를&amp;nbsp;user&amp;nbsp;객체의&amp;nbsp;id&amp;nbsp;필드에&amp;nbsp;자동으로&amp;nbsp;설정해 준다. &lt;br /&gt;&lt;br /&gt;즉, 별도로 PK를 조회하는 로직 없이도, INSERT 이후 바로 userId 값을 사용할 수 있게 된다.&lt;/p&gt;
&lt;pre class=&quot;pf&quot;&gt;&lt;code&gt;userMapper.insertUser(user);
&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;전달한 객체(user)&lt;/b&gt;에 직접 설정된다.&lt;/p&gt;</description>
      <category>웹 개발/Back-end</category>
      <category>mybatis</category>
      <category>mysql</category>
      <category>웹개발</category>
      <author>studyingbackhoe</author>
      <guid isPermaLink="true">https://studyingbackhoe.tistory.com/93</guid>
      <comments>https://studyingbackhoe.tistory.com/93#entry93comment</comments>
      <pubDate>Sat, 4 Apr 2026 14:32:41 +0900</pubDate>
    </item>
    <item>
      <title>[Java] POI 엑셀 다운로드 하기(셀 병합)</title>
      <link>https://studyingbackhoe.tistory.com/92</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;springboot, java, gradle, IntelliJ 환경에서 엑셀 다운로드하는 방법에 대해 알아보자.&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;table style=&quot;border-collapse: collapse; width: 100%; height: 63px;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;border: none; text-align: center; height: 21px;&quot;&gt;0행&lt;/td&gt;
&lt;td style=&quot;border: none; text-align: center; height: 21px;&quot;&gt;0열&lt;/td&gt;
&lt;td style=&quot;border: none; text-align: center; height: 21px;&quot; colspan=&quot;2&quot;&gt;1 ~ 2열&lt;/td&gt;
&lt;td style=&quot;border: none; text-align: center; height: 21px;&quot; colspan=&quot;5&quot;&gt;3 ~ 7열&lt;/td&gt;
&lt;td style=&quot;border: none; text-align: center; height: 21px;&quot;&gt;8 열&lt;/td&gt;
&lt;td style=&quot;border: none; text-align: center; height: 21px;&quot;&gt;9 열&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;border: none; text-align: center; height: 42px;&quot; rowspan=&quot;2&quot;&gt;1행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; height: 42px;&quot; rowspan=&quot;2&quot;&gt;&lt;b&gt;No&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; height: 21px;&quot; colspan=&quot;2&quot;&gt;&lt;b&gt;도서상세정보&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; height: 21px;&quot; colspan=&quot;5&quot;&gt;&lt;b&gt;도서대여자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; height: 42px;&quot; rowspan=&quot;2&quot;&gt;&lt;b&gt;대여상태&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; height: 42px;&quot; rowspan=&quot;2&quot;&gt;&lt;b&gt;비고&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; height: 21px;&quot;&gt;&lt;b&gt;제목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; height: 21px;&quot;&gt;&lt;b&gt;저자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; height: 21px;&quot;&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; height: 21px;&quot;&gt;&lt;b&gt;연락처&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; height: 21px;&quot;&gt;&lt;b&gt;회원등급&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; height: 21px;&quot;&gt;&lt;b&gt;회원가입일시&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; height: 21px;&quot;&gt;&lt;b&gt;관심도서유형&lt;/b&gt;&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;&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;No, 대여상태, 비고&lt;/b&gt;는 2행이 병합되고 &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;b&gt;도서상세정보, 도서대여자&lt;/b&gt;는 각각 2열, 5열이 병합되어야 한다.&lt;/span&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. build.gradle에 엑셀 다운로드를 위한 POI 의존성 추가&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1769836851735&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dependencies {
	implementation 'org.apache.poi:poi-ooxml:5.2.5'
}&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;b&gt;4. 엑셀 파일과 시트 생성(&lt;/b&gt;Workbook, Sheet&lt;b&gt;)&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1769837136932&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet(&quot;도서대여현황&quot;);&lt;/code&gt;&lt;/pre&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;XSSF : .xlsx 형식을 지원&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CellStyle : 엑셀의 폰트, 정렬, 색상, 테두리를 설정할 수 있음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스타일 지정&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1769837168860&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 헤더 스타일
CellStyle headStyle = workbook.createCellStyle();

headStyle.setAlignment(HorizontalAlignment.CENTER); 
headStyle.setVerticalAlignment(VerticalAlignment.CENTER);
headStyle.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE.getIndex());
headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
headStyle.setBorderTop(BorderStyle.THIN);
headStyle.setBorderBottom(BorderStyle.THIN);
headStyle.setBorderLeft(BorderStyle.THIN);
headStyle.setBorderRight(BorderStyle.THIN);


// 데이터 영역 스타일
CellStyle bodyStyle = workbook.createCellStyle();

bodyStyle.setAlignment(HorizontalAlignment.CENTER);
bodyStyle.setVerticalAlignment(VerticalAlignment.CENTER); 
bodyStyle.setBorderTop(BorderStyle.THIN);
bodyStyle.setBorderBottom(BorderStyle.THIN);
bodyStyle.setBorderLeft(BorderStyle.THIN);
bodyStyle.setBorderRight(BorderStyle.THIN);&lt;/code&gt;&lt;/pre&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 data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8,0,0&quot;&gt;좌표 기준&lt;/b&gt;: CellRangeAddress(시작행, 끝행, 시작열, 끝열)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8,1,0&quot;&gt;세로 병합&lt;/b&gt;: No, 대여상태처럼 하위 항목이 없는 경우 위아래 칸을 합친다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8,2,0&quot;&gt;가로 병합&lt;/b&gt;: 도서상세정보(2칸), 도서 대여자(5칸)처럼 소분류가 있는 경우 옆으로 합친다.&lt;/span&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;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;(주의⚠️) 0부터 시작&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769837272251&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 행 생성 (2개 행)
Row row0 = sheet.createRow(0);
Row row1 = sheet.createRow(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;&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_1769837613528&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;row0.getCell(0).setCellValue(&quot;No&quot;); //0행 0열 데이터값
sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 0));

row0.getCell(1).setCellValue(&quot;도서상세정보&quot;); // 0행 1열 데이터값
sheet.addMergedRegion(new CellRangeAddress(0, 0, 1, 2)); 
row1.getCell(1).setCellValue(&quot;제목&quot;); // 1행 1열 데이터값
row1.getCell(2).setCellValue(&quot;저자&quot;); // 1행 2열 데이터값

row0.getCell(3).setCellValue(&quot;도서 대여자&quot;); // 0행 3열 데이터값
sheet.addMergedRegion(new CellRangeAddress(0, 0, 3, 7));
row1.getCell(3).setCellValue(&quot;이름&quot;);     // 1행 3열 데이터값
row1.getCell(4).setCellValue(&quot;전화번호&quot;); // 1행 4열 데이터값
row1.getCell(5).setCellValue(&quot;회원등급&quot;); // 1행 5열 데이터값
row1.getCell(6).setCellValue(&quot;회원가입일시&quot;); // 1행 6열 데이터값
row1.getCell(7).setCellValue(&quot;관심유형&quot;); // 1행 7열 데이터값

row0.getCell(8).setCellValue(&quot;대여상태&quot;); // 0행 8열 데이터값
sheet.addMergedRegion(new CellRangeAddress(0, 1, 8, 8)); 

row0.getCell(9).setCellValue(&quot;비고&quot;); // 0행 9열 데이터값
sheet.addMergedRegion(new CellRangeAddress(0, 1, 9, 9));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이중 셀 병합 부분을 상세히 살펴보면 다음과 같다. &lt;b&gt;*CellRangeAddress(시작행, 끝행, 시작열, 끝열)&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) sheet.addMergedRegion(new CellRangeAddress(&lt;b&gt;0, 1, 0, 0&lt;/b&gt;));&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; 0행 0열&lt;/b&gt;과&lt;b&gt; 1행 0열&lt;/b&gt;을 합친다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;&lt;!-- 0행 (첫 행 → top 제거) --&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; border-left: none;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;0열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;1 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;2 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;3 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;4 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;5 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;6 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;7 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;8 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; border-right: none; text-align: center;&quot;&gt;9 열&lt;/td&gt;
&lt;/tr&gt;
&lt;!-- 1행 --&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-left: none;&quot;&gt;0행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: blue;&quot;&gt;&lt;b&gt;No&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;도서상세정보&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;도서대여자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;대여상태&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;비고&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;!-- 2행 (마지막 행 → bottom 제거) --&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-left: none; border-bottom: none;&quot;&gt;1행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: blue;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;제목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;저자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;연락처&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;회원등급&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;회원가입일시&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;관심도서유형&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) sheet.addMergedRegion(new CellRangeAddress(&lt;b&gt;0, 0, 1, 2&lt;/b&gt;));&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; 0행 1열&lt;/b&gt;과&lt;b&gt; 0행 2열&lt;/b&gt;을 합친다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 63px;&quot; border=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;&lt;!-- 0행 (첫 행 → top 제거) --&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;border-right: 1px solid black; border-bottom: 1px solid black; border-image: initial; border-top: none; border-left: none; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border-right: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-image: initial; border-top: none; height: 21px; text-align: center;&quot;&gt;0열&lt;/td&gt;
&lt;td style=&quot;border-right: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-image: initial; border-top: none; height: 21px; text-align: center;&quot;&gt;1 열&lt;/td&gt;
&lt;td style=&quot;border-right: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-image: initial; border-top: none; height: 21px; text-align: center;&quot;&gt;2 열&lt;/td&gt;
&lt;td style=&quot;border-right: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-image: initial; border-top: none; height: 21px; text-align: center;&quot;&gt;3 열&lt;/td&gt;
&lt;td style=&quot;border-right: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-image: initial; border-top: none; height: 21px; text-align: center;&quot;&gt;4 열&lt;/td&gt;
&lt;td style=&quot;border-right: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-image: initial; border-top: none; height: 21px; text-align: center;&quot;&gt;5 열&lt;/td&gt;
&lt;td style=&quot;border-right: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-image: initial; border-top: none; height: 21px; text-align: center;&quot;&gt;6 열&lt;/td&gt;
&lt;td style=&quot;border-right: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-image: initial; border-top: none; height: 21px; text-align: center;&quot;&gt;7 열&lt;/td&gt;
&lt;td style=&quot;border-right: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-image: initial; border-top: none; height: 21px; text-align: center;&quot;&gt;8 열&lt;/td&gt;
&lt;td style=&quot;border-bottom: 1px solid black; border-left: 1px solid black; border-image: initial; border-top: none; border-right: none; height: 21px; text-align: center;&quot;&gt;9 열&lt;/td&gt;
&lt;/tr&gt;
&lt;!-- 1행 --&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;border-top: 1px solid black; border-right: 1px solid black; border-bottom: 1px solid black; border-image: initial; border-left: none; height: 21px;&quot;&gt;0행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: blue; height: 21px;&quot;&gt;&lt;b&gt;No&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: red; height: 21px;&quot;&gt;&lt;b&gt;도서상세정보&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: red; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&lt;b&gt;도서대여자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&lt;b&gt;대여상태&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-image: initial; height: 21px;&quot;&gt;&lt;b&gt;비고&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;!-- 2행 (마지막 행 → bottom 제거) --&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;border-top: 1px solid black; border-right: 1px solid black; border-image: initial; border-left: none; border-bottom: none; height: 21px;&quot;&gt;1행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: blue; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&lt;b&gt;제목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&lt;b&gt;저자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&lt;b&gt;연락처&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&lt;b&gt;회원등급&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&lt;b&gt;회원가입일시&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&lt;b&gt;관심도서유형&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-image: initial; height: 21px;&quot;&gt;&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;3) sheet.addMergedRegion(new CellRangeAddress(&lt;b&gt;0,&amp;nbsp;0,&amp;nbsp;3,&amp;nbsp;7&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;&amp;nbsp; &amp;nbsp; 0행 3열&lt;/b&gt;과&lt;b&gt; 0행 7열&lt;/b&gt;을 합친다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;&lt;!-- 0행 (첫 행 → top 제거) --&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; border-left: none;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;0열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;1 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;2 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;3 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;4 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;5 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;6 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;7 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;8 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; border-right: none; text-align: center;&quot;&gt;9 열&lt;/td&gt;
&lt;/tr&gt;
&lt;!-- 1행 --&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-left: none;&quot;&gt;0행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: blue;&quot;&gt;&lt;b&gt;No&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: red;&quot;&gt;&lt;b&gt;도서상세정보&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: red;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&lt;b&gt;도서대여자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;대여상태&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;비고&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;!-- 2행 (마지막 행 → bottom 제거) --&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-left: none; border-bottom: none;&quot;&gt;1행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: blue;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;제목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;저자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;연락처&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;회원등급&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;회원가입일시&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;관심도서유형&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&amp;nbsp;&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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4) sheet.addMergedRegion(new CellRangeAddress(&lt;b&gt;0,&amp;nbsp;1,&amp;nbsp;8,&amp;nbsp;8&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;&amp;nbsp; &amp;nbsp; 0행 8열&lt;/b&gt;과&lt;b&gt; 1행 8열&lt;/b&gt;을 합친다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;&lt;!-- 0행 (첫 행 → top 제거) --&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; border-left: none;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;0열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;1 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;2 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;3 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;4 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;5 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;6 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;7 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;8 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; border-right: none; text-align: center;&quot;&gt;9 열&lt;/td&gt;
&lt;/tr&gt;
&lt;!-- 1행 --&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-left: none;&quot;&gt;0행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: blue;&quot;&gt;&lt;b&gt;No&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: red;&quot;&gt;&lt;b&gt;도서상세정보&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: red;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&lt;b&gt;도서대여자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: green;&quot;&gt;&lt;b&gt;대여상태&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;비고&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;!-- 2행 (마지막 행 → bottom 제거) --&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-left: none; border-bottom: none;&quot;&gt;1행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: blue;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;제목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;저자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;연락처&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;회원등급&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;회원가입일시&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;관심도서유형&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: green;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&amp;nbsp;&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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5) sheet.addMergedRegion(new CellRangeAddress(&lt;b&gt;0,&amp;nbsp;1,&amp;nbsp;9,&amp;nbsp;9&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;&amp;nbsp; &amp;nbsp; 0행 9열&lt;/b&gt;과&lt;b&gt; 1행 9열&lt;/b&gt;을 합친다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;&lt;!-- 0행 (첫 행 → top 제거) --&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; border-left: none;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;0열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;1 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;2 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;3 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;4 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;5 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;6 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;7 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;8 열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; border-right: none; text-align: center;&quot;&gt;9 열&lt;/td&gt;
&lt;/tr&gt;
&lt;!-- 1행 --&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-left: none;&quot;&gt;0행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: blue;&quot;&gt;&lt;b&gt;No&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: red;&quot;&gt;&lt;b&gt;도서상세정보&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: red;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&lt;b&gt;도서대여자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: orange;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: green;&quot;&gt;&lt;b&gt;대여상태&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: purple;&quot;&gt;&lt;b&gt;비고&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;!-- 2행 (마지막 행 → bottom 제거) --&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-left: none; border-bottom: none;&quot;&gt;1행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: blue;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;제목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;저자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;연락처&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;회원등급&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;회원가입일시&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;관심도서유형&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: green;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: purple;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-path-to-node=&quot;9&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*최종&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; border-left: none;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;0열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;1열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;2열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;3열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;4열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;5열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;6열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;7열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; text-align: center;&quot;&gt;8열&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; border-top: none; border-right: none; text-align: center;&quot;&gt;9열&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-left: none;&quot;&gt;0행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: blue;&quot; rowspan=&quot;2&quot;&gt;&lt;b&gt;No&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; background-color: red;&quot; colspan=&quot;2&quot;&gt;&lt;b&gt;도서상세정보&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; text-align: center; background-color: orange;&quot; colspan=&quot;5&quot;&gt;&lt;b&gt;도서대여자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: green;&quot; rowspan=&quot;2&quot;&gt;&lt;b&gt;대여상태&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; background-color: purple;&quot; rowspan=&quot;2&quot;&gt;&lt;b&gt;비고&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; border-left: none; border-bottom: none;&quot;&gt;1행&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;제목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;저자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;연락처&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;회원등급&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;회원가입일시&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black;&quot;&gt;&lt;b&gt;관심도서유형&lt;/b&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. 엑셀 데이터 넣기&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1771304991113&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String[] sampleData = {&quot;1&quot;, &quot;자바의 정석 기초편&quot;, &quot;남궁성&quot;, &quot;홍길동&quot;, &quot;010-1234-5678&quot;, &quot;VIP&quot;, &quot;2024-05-01 14:00&quot;, &quot;IT/프로그래밍&quot;, &quot;대여중&quot;, &quot;연체 주의 바랍니다.&quot;};

for(int i=0; i &amp;lt; sampleData.length; i++) {
  Cell cell = bodyRow.createCell(i);
  cell.setCellValue(sampleData[i]);
  cell.setCellStyle(bodyStyle);
}

// 셀 간격(너비) 수동 및 자동 조절
for (int i = 0; i &amp;lt;= 9; i++) {
  sheet.autoSizeColumn(i); // 먼저 내용에 맞게 자동 조절
  int currentWidth = sheet.getColumnWidth(i);
  sheet.setColumnWidth(i, currentWidth + 1500);
}&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. 만들어진 엑셀 다운로드 하기&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1771305410001&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String fileName = &quot;책대여현황.xlsx&quot;;
resp.setContentType(&quot;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet&quot;);
resp.setHeader(&quot;Content-Disposition&quot;, &quot;attachment;filename=&quot; + fileName);
workbook.write(resp.getOutputStream());
workbook.close();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(엑셀 다운로드 화면)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6e0mg/dJMcaiPL7xH/Q5q1B5eWE1bJAYiUN7v2S0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6e0mg/dJMcaiPL7xH/Q5q1B5eWE1bJAYiUN7v2S0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6e0mg/dJMcaiPL7xH/Q5q1B5eWE1bJAYiUN7v2S0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6e0mg%2FdJMcaiPL7xH%2FQ5q1B5eWE1bJAYiUN7v2S0%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;1102&quot; height=&quot;118&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;118&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고: OpenAI&amp;nbsp;ChatGPT&amp;nbsp;(&lt;a href=&quot;https://openai.com)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://openai.com)&lt;/a&gt;&lt;/p&gt;</description>
      <category>웹 개발/Back-end</category>
      <category>Java</category>
      <category>poi</category>
      <category>셀병합</category>
      <category>엑셀다운로드</category>
      <author>studyingbackhoe</author>
      <guid isPermaLink="true">https://studyingbackhoe.tistory.com/92</guid>
      <comments>https://studyingbackhoe.tistory.com/92#entry92comment</comments>
      <pubDate>Tue, 17 Feb 2026 14:26:38 +0900</pubDate>
    </item>
    <item>
      <title>[IntelliJ] 무료 인텔리제이로 springboot, gradle 프로젝트 실행하기</title>
      <link>https://studyingbackhoe.tistory.com/91</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1. springboot initializer 로 프로젝트 생성하기&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&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;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; 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;/span&gt;&lt;/li&gt; 
 &lt;/ul&gt; 
&lt;/ul&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1319&quot; data-origin-height=&quot;807&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8zdNH/dJMcajug9PP/eCHvZs7ft7TjB3ktvfmz4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8zdNH/dJMcajug9PP/eCHvZs7ft7TjB3ktvfmz4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8zdNH/dJMcajug9PP/eCHvZs7ft7TjB3ktvfmz4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8zdNH%2FdJMcajug9PP%2FeCHvZs7ft7TjB3ktvfmz4K%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;742&quot; height=&quot;454&quot; data-origin-width=&quot;1319&quot; data-origin-height=&quot;807&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2. 원하는 언어, 빌드 도구, 의존성 선택&lt;/b&gt;&lt;/span&gt;&lt;/span&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;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Project &lt;span style=&quot;text-align: start;&quot;&gt;: &lt;/span&gt;&lt;/b&gt;&amp;nbsp;gradle - groovy&amp;nbsp; 선택&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Language &lt;span style=&quot;text-align: start;&quot;&gt;:&amp;nbsp;&lt;/span&gt; &lt;/b&gt;Java 선택&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Spring Boot&lt;/b&gt; &lt;span style=&quot;text-align: start;&quot;&gt;&lt;b&gt;:&lt;/b&gt;&amp;nbsp;&lt;/span&gt; 안정화된 버전으로 선택 (괄호 없는 버전 선택)&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Group, Artifact (Name)&lt;/b&gt; 입력&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Packaging&lt;/b&gt; - Jar&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Configuration&lt;/b&gt; - YAML&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Java&lt;/b&gt; - 17&amp;nbsp;&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;의존성 추가&lt;/b&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;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Spring Web&lt;/span&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Lombok&lt;/span&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;...&lt;/span&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;GENERATE 클릭 후 프로젝트 생성하기&lt;/span&gt;&lt;/li&gt; 
&lt;/ol&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3. 인텔리제이로 프로젝트 열기&lt;/b&gt;&lt;/span&gt;&lt;/span&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;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;generate로 생성한 프로젝트 압축을 해제한 후 인텔리제이로 열기&lt;/span&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;4. 프로젝트 SpringBoot 실행하기&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&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;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1. bootRun 으로 실행하기&lt;/b&gt;&lt;/span&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;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;[File] - [Settings] - [Build, Execution, Deployment] - [Build Tools] - [Gradle]&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 이동&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Build and run using / Run tests using 을 &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;u&gt;Gradle (Default)&lt;/u&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;선택&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1089&quot; data-origin-height=&quot;803&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TGhac/dJMcafZJJnG/DZB0OHMsSBK2KtuB8x7KSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TGhac/dJMcafZJJnG/DZB0OHMsSBK2KtuB8x7KSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TGhac/dJMcafZJJnG/DZB0OHMsSBK2KtuB8x7KSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTGhac%2FdJMcafZJJnG%2FDZB0OHMsSBK2KtuB8x7KSk%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;737&quot; height=&quot;543&quot; data-origin-width=&quot;1089&quot; data-origin-height=&quot;803&quot;/&gt;&lt;/span&gt;&lt;/figure&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;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우측 Gradle 탭에서 &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;[Tasks] - [application] - [bootRun]&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 으로 프로젝트 실행&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;http://localhost:8080 으로 접속 가능&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k1IgZ/dJMcahXzGlL/dWJnW3IX2mry8wEd0Lje81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k1IgZ/dJMcahXzGlL/dWJnW3IX2mry8wEd0Lje81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k1IgZ/dJMcahXzGlL/dWJnW3IX2mry8wEd0Lje81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk1IgZ%2FdJMcahXzGlL%2FdWJnW3IX2mry8wEd0Lje81%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;767&quot; height=&quot;322&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2. Application으로 실행하기&lt;/b&gt;&lt;/span&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;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;[File]&amp;nbsp;-&amp;nbsp;[Settings]&amp;nbsp;-&amp;nbsp;[Build,&amp;nbsp;Execution,&amp;nbsp;Deployment]&amp;nbsp;-&amp;nbsp;[Build&amp;nbsp;Tools]&amp;nbsp;-&amp;nbsp;[Gradle]&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;이동&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Build&amp;nbsp;and&amp;nbsp;run&amp;nbsp;using&amp;nbsp;/&amp;nbsp;Run&amp;nbsp;tests&amp;nbsp;using&amp;nbsp;을&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;u&gt;IntelliJ&amp;nbsp;IDEA&lt;/u&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;선택&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;[Run] - [Edit Configurations...]&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 클릭 후 좌측 &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;[+]&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 선택&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MFLDx/dJMcafyHanB/8ojAHPJO9MlTkTi4FhSTw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MFLDx/dJMcafyHanB/8ojAHPJO9MlTkTi4FhSTw0/img.png&quot; data-alt=&quot;Edit Configurations...&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MFLDx/dJMcafyHanB/8ojAHPJO9MlTkTi4FhSTw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMFLDx%2FdJMcafyHanB%2F8ojAHPJO9MlTkTi4FhSTw0%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;687&quot; height=&quot;425&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Edit Configurations...&lt;/figcaption&gt;
&lt;/figure&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;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실행할 application 이름 지정 : PracApplication&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Runtime Environment(실행환경) 선택 : jbr-17 (&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;jdk 선택)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;application 실행에 필요한 소스 및 라이브러리 위치 지정(Classpath)&amp;nbsp; : -cp prac.main&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;메인 클래스 지정(public static void main(String[] args) 메소드 경로) : com.test.prac.PracApplication&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;[Apply]&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 클릭&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1199&quot; data-origin-height=&quot;771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FdrWH/dJMcahQNwn7/9j22WAWry6Ld6CFWU9rUzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FdrWH/dJMcahQNwn7/9j22WAWry6Ld6CFWU9rUzK/img.png&quot; data-alt=&quot;Run/Debug Configurations&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FdrWH/dJMcahQNwn7/9j22WAWry6Ld6CFWU9rUzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFdrWH%2FdJMcahQNwn7%2F9j22WAWry6Ld6CFWU9rUzK%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;491&quot; height=&quot;316&quot; data-origin-width=&quot;1199&quot; data-origin-height=&quot;771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Run/Debug Configurations&lt;/figcaption&gt;
&lt;/figure&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;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;생성한 &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Application Run(&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;▶&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Nanum Gothic;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 시키기&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;441&quot; data-origin-height=&quot;59&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qxqN1/dJMcacopTUF/AaMJ5VBHcKt1buE0wLHsxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qxqN1/dJMcacopTUF/AaMJ5VBHcKt1buE0wLHsxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qxqN1/dJMcacopTUF/AaMJ5VBHcKt1buE0wLHsxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqxqN1%2FdJMcacopTUF%2FAaMJ5VBHcKt1buE0wLHsxK%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;441&quot; height=&quot;59&quot; data-origin-width=&quot;441&quot; data-origin-height=&quot;59&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot;&gt;&lt;div id=&quot;code_1769227315225&quot; data-ke-type=&quot;html&quot; data-source=&quot;&lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;https://icons8.com/icon/61466/intellij-idea&amp;quot;&gt;IntelliJ IDEA&lt;/a&gt; 작가: &lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;https://icons8.com&amp;quot;&gt;Icons8&lt;/a&gt;&quot;&gt;
 &lt;a href=&quot;https://icons8.com/icon/61466/intellij-idea&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;IntelliJ IDEA&lt;/a&gt; 작가: &lt;a href=&quot;https://icons8.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Icons8&lt;/a&gt;
&lt;/div&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>웹 개발</category>
      <category>gradle</category>
      <category>SpringBoot</category>
      <category>무료인텔리제이</category>
      <author>studyingbackhoe</author>
      <guid isPermaLink="true">https://studyingbackhoe.tistory.com/91</guid>
      <comments>https://studyingbackhoe.tistory.com/91#entry91comment</comments>
      <pubDate>Tue, 27 Jan 2026 20:10:48 +0900</pubDate>
    </item>
    <item>
      <title>[MySQL] WITH RECURSIVE(재귀 쿼리)</title>
      <link>https://studyingbackhoe.tistory.com/90</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;WITH RECURSIVE(재귀 쿼리)&lt;/b&gt;&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;MySQL 8.0 버전부터 CTE(Common Table Expression)으로 재귀 쿼리를 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CTE (Common Table Expression) 란?&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: #000000;&quot;&gt;SQL 문법에서 &lt;b&gt;WITH&lt;/b&gt; 로 시작하는 구문.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&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: #000000;&quot;&gt;ex)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1768625467015&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;WITH 임시테이블명 AS (

   // 사용할 SELECT 문

) 
SELECT * FROM 임시테이블명;&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;재귀 CTE는 &lt;b&gt;자기 자신을 참조&lt;/b&gt;하는 CTE를 의미하며 &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&gt;&lt;/p&gt;
&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;ex)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 기술팀&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ㄴ 인프라팀&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ㄴ네트워크&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ㄴ 개발팀&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ....&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768626762926&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH RECURSIVE temp_dept_table AS (
    -- 1. 최상위 부서
    SELECT 
        dept_id
        , parent_id
        , dept_name AS level1
        , CAST(NULL AS CHAR(50)) AS level2
        , CAST(NULL AS CHAR(50)) AS level3
        , depth
    FROM dept_table
    WHERE depth = 1

    UNION ALL

    -- 2. 하위 부서 연결
    SELECT 
        child.dept_id
        , child.parent_id
        , parent.level1
        , IF(child.depth = 2, child.dept_name, parent.level2)
        , IF(child.depth = 3, child.dept_name, parent.level3)
        , child.depth
    FROM dept_table child
    INNER JOIN temp_dept_table parent
    ON child.parent_id = parent.dept_id
)

SELECT CONCAT_WS(' &amp;gt; ', level1, level2, level3) AS total_level
FROM temp_dept_table
ORDER BY level1, level2, level3;&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: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;RECURSIVE 를 사용한 &lt;/b&gt;쿼리를 상세히 뜯어보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. 재귀 쿼리를 사용하기 위해 WITH RECURSIVE temp_dept_table로 임시테이블명을 정해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2.&amp;nbsp;최상위 부서로 사용될 부서 목록을 먼저 조회해 준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. 최상위 부서에 는 별도의 하위부서 값이 없기 때문에 level2, level3 값은 NULL 로 처리해 준다.&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&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(현재 temp_dept_table 내에는 상위 부서 목록인 총무팀, 기술팀 목록만 추가된 상태)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1768626780851&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 1. 최상위 부서
SELECT 
    dept_id
    , parent_id
    , dept_name AS level1
    , CAST(NULL AS CHAR(50)) AS level2
    , CAST(NULL AS CHAR(50)) AS level3
    , depth
FROM dept_table
WHERE depth = 1&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;442&quot; data-origin-height=&quot;97&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bojdgn/dJMcahXunkv/AvSS99Tt38wXLm87nXkNl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bojdgn/dJMcahXunkv/AvSS99Tt38wXLm87nXkNl0/img.png&quot; data-alt=&quot;최상위 부서 목록 조회&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bojdgn/dJMcahXunkv/AvSS99Tt38wXLm87nXkNl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbojdgn%2FdJMcahXunkv%2FAvSS99Tt38wXLm87nXkNl0%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;442&quot; height=&quot;97&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;97&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;&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;letter-spacing: 0px;&quot;&gt;상위 부서인 총무팀과 기술팀 하위 부서를 연결하여 조회하기 위한 &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&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;4. temp_dept_table 내에는 상위 부서 목록인 총무팀, 기술팀 목록만 추가된 상태에서 child.parent_id = parent.dept_id JOIN을 통해서 자기 자신을 FROM에서 참조하여(&lt;b&gt;재귀&lt;/b&gt;) Recursive SELECT이 실행된다.&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 style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;5. JOIN 결과가 없을 때까지 누적하여 UNION ALL로 결과가 합쳐진다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot;&gt;즉, 이미 찾은 부서를 부모로 삼아서 그 하위 부서들을 계속 찾아 내려간다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1768627268374&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;     UNION ALL

    -- 2. 하위 부서 연결
    SELECT 
        child.dept_id
        , child.parent_id
        , parent.level1
        , IF(child.depth = 2, child.dept_name, parent.level2)
        , IF(child.depth = 3, child.dept_name, parent.level3)
        , child.depth
    FROM dept_table child
    INNER JOIN temp_dept_table parent
    ON child.parent_id = parent.dept_id&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;  재귀 CTE 공식문서에 의하면,&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;최상위 데이터를 가져오는 SELECT를 &lt;b&gt;Anchor 쿼리&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자기 자신을 다시 참조하는 SELECT를 &lt;b&gt;Recursive 쿼리&lt;/b&gt;라고 명칭 한다고 한다.&lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;생성한 임시테이블 temp_dept_table 로 원하는 쿼리 형태로 조회해 준다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1768628804264&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT CONCAT_WS(' &amp;gt; ', level1, level2, level3) AS total_level
FROM temp_dept_table
ORDER BY level1, level2, level3;&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;211&quot; data-origin-height=&quot;332&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHfyDh/dJMcafZDQ2v/uYKTU4SABOW2HyrCfP90oK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHfyDh/dJMcafZDQ2v/uYKTU4SABOW2HyrCfP90oK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHfyDh/dJMcafZDQ2v/uYKTU4SABOW2HyrCfP90oK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHfyDh%2FdJMcafZDQ2v%2FuYKTU4SABOW2HyrCfP90oK%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;211&quot; height=&quot;332&quot; data-origin-width=&quot;211&quot; data-origin-height=&quot;332&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/wIDz7/dJMcacaNDoL/2UhKgtuGkXxE0kgAsbmwW1/%ED%85%8C%EC%8A%A4%ED%8A%B8%EC%9A%A9%20%EC%BD%94%EB%93%9C.txt?attach=1&amp;amp;knm=tfile.txt&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;테스트용 코드.txt&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;OpenAI ChatGPT (&lt;/span&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://openai.com&quot;&gt;https://openai.com&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div id=&quot;code_1769227386681&quot; data-ke-type=&quot;html&quot; data-source=&quot;&amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;https://icons8.com/icon/hYoELNwniGhi/mysql&amp;quot;&amp;gt;MySQL&amp;lt;/a&amp;gt; 작가: &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;https://icons8.com&amp;quot;&amp;gt;Icons8&amp;lt;/a&amp;gt;&quot;&gt;&lt;a href=&quot;https://icons8.com/icon/hYoELNwniGhi/mysql&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MySQL&lt;/a&gt; 작가: &lt;a href=&quot;https://icons8.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Icons8&lt;/a&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기록/DB</category>
      <category>mysql</category>
      <category>recursive</category>
      <category>재귀</category>
      <author>studyingbackhoe</author>
      <guid isPermaLink="true">https://studyingbackhoe.tistory.com/90</guid>
      <comments>https://studyingbackhoe.tistory.com/90#entry90comment</comments>
      <pubDate>Sat, 17 Jan 2026 15:39:11 +0900</pubDate>
    </item>
    <item>
      <title>[ERROR] Get from Version Control git clone 오류 해결</title>
      <link>https://studyingbackhoe.tistory.com/86</link>
      <description>&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;윈도우 환경에서 IntelliJ [File] &amp;gt; [New] &amp;gt; [Get from Version Control]에서 git clone으로 프로젝트 소스를 가져오려고 했더니 다음과 같은 에러가 발생했다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;clone failed unable to read askpass reponse from C:\User\AppData\Local\JetBrains\IntelliJIdea2023.2\tmp\intellij-git-askpass-local.sh'
bash line 1: \dev\tty : No such device or address ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이 에러는 IntelliJ에서 git clone을 수행할 때 인증 창(Git 자격 증명 입력창)을 띄우는 과정에서 실패하여 발생하는 에러라고 한다.&lt;br /&gt;&lt;b&gt;unable to read askpass response&lt;/b&gt;&amp;nbsp;또는 &lt;b&gt;No such device or address&lt;/b&gt; 등의 에러 메시지는 Git이 사용자 인증 정보를 요청했지만, 입력을 받을 터미널이나 GUI 창이 제대로 작동하지 못했다는 의미다.&lt;br /&gt;&lt;br /&gt;IntelliJ는 Git 인증을 위해 아래 스크립트를 실행하게 되는데&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;C:\User\AppData\Local\JetBrains\IntelliJIdea2023.2\tmp\intellij-git-askpass-local.sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이 스크립트 내부에서 /dev/tty(리눅스 터미널 장치)를 사용하려 하지만,&lt;br /&gt;현재 IntelliJ를 실행하고 있는 윈도우 환경에서는 /dev/tty가 존재하지 않으므로 에러가 발생하게 된다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 해결 방법&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제를 해결할 수 있는 방법은 크게 두 가지가 있다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 터미널에서 직접 clone 하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IntelliJ GUI를 통하는 대신 터미널(cmd나 Git Bash)에서 직접 git clone 명령어를 실행하는 방법이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1755316416001&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git clone https://my-repo-url.git&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그다음 IntelliJ에서 File &amp;gt; Open으로 해당 디렉터리를 열어주면 정상적으로 사용 가능하다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. IntelliJ Git 설정 변경하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IntelliJ 자체에서 인증을 처리하도록 설정을 바꿔준다.&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: #333333;&quot;&gt;[File] &amp;gt; [Settings] &amp;gt; [Version Control] &amp;gt; [Git]으로 이동&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;화면 맨 아래에 있는 &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;Use credential helper&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt; 체크 후 Apply&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 옵션을 켜주면 IntelliJ가 Git Credential Manager를 사용해서 인증을 처리하기 때문에 /dev/tty 에러가 발생하지 않게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;721&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NizpH/btsPUZcmAOt/XoLt9XpwzJbmGlEdFegxH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NizpH/btsPUZcmAOt/XoLt9XpwzJbmGlEdFegxH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NizpH/btsPUZcmAOt/XoLt9XpwzJbmGlEdFegxH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNizpH%2FbtsPUZcmAOt%2FXoLt9XpwzJbmGlEdFegxH1%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;649&quot; height=&quot;479&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;721&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr 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;환경에 따라 이미 Credential Manager가 설정돼 있거나, SSH 키를 등록한&amp;nbsp;경우에는 별다른 문제없이 clone이 되는 경우도 있으나 만약 같은 오류가 반복된다면 &lt;b&gt;방법 2 (Use credential helper 설정)을&lt;/b&gt; 가장 먼저 확인해면 좋을 것 같다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;code_1755317690336&quot; data-ke-type=&quot;html&quot; data-source=&quot;&amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;https://icons8.com/icon/61466/intellij-idea&amp;quot;&amp;gt;IntelliJ IDEA&amp;lt;/a&amp;gt; 작가: &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;https://icons8.com&amp;quot;&amp;gt;Icons8&amp;lt;/a&amp;gt;&quot;&gt;&lt;a href=&quot;https://icons8.com/icon/61466/intellij-idea&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;IntelliJ IDEA&lt;/a&gt; 작가: &lt;a href=&quot;https://icons8.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Icons8&lt;/a&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고: OpenAI&amp;nbsp;ChatGPT&amp;nbsp;(&lt;a href=&quot;https://openai.com)&quot; target=&quot;_self&quot;&gt;&lt;span&gt;https://openai.com)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <category>Error 모음집</category>
      <category>git clone</category>
      <category>IntelliJ</category>
      <author>studyingbackhoe</author>
      <guid isPermaLink="true">https://studyingbackhoe.tistory.com/86</guid>
      <comments>https://studyingbackhoe.tistory.com/86#entry86comment</comments>
      <pubDate>Sat, 16 Aug 2025 13:04:28 +0900</pubDate>
    </item>
    <item>
      <title>[IntelliJ] 정규식을 이용한 문자열 일괄 치환 방법</title>
      <link>https://studyingbackhoe.tistory.com/85</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;IntelliJ는 &lt;b&gt;파일이나 폴더를 옮기면 import 하는 부분의 경로를 자동으로 바꿔준다.&lt;/b&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하지만 JSP, JSX 내 이미지 경로나 CSS, 하드코딩된 &lt;b&gt;정적 리소스 경로는 자동 추적이 안 되기 때문에 수동으로 변경&lt;/b&gt;해줘야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;278&quot; data-start=&quot;250&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;278&quot; data-start=&quot;250&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;프로젝트 내 특정 문자열 경로 일괄 변경 방법 &lt;b&gt; &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt; &lt;/b&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p 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 style=&quot;text-align: start;&quot;&gt;예를 들어, 큰따옴표(&quot;), 작은따옴표('), 괄호(()) 안에 포함된 경로만 바꾸거나, 특정 위치에 있는 문자열만 선택적으로 변경하고 싶을 때가 있는데 이러한 경우에는&amp;nbsp;&lt;/span&gt;&lt;b&gt;정규식을 활용&lt;/b&gt;하면 원하는 부분만 골라내어 한꺼번에 변경할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;276&quot; data-start=&quot;229&quot; 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: #000000;&quot;&gt;&lt;b&gt;1. 치환을 적용하려는 최상위 폴더에서 오른쪽 클릭 &amp;rarr; [Replace in Files] 선택&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;667&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dY9bfs/btsOOCCyErK/1jAnG5wTA1Rugb44tjROX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dY9bfs/btsOOCCyErK/1jAnG5wTA1Rugb44tjROX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dY9bfs/btsOOCCyErK/1jAnG5wTA1Rugb44tjROX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdY9bfs%2FbtsOOCCyErK%2F1jAnG5wTA1Rugb44tjROX0%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;500&quot; height=&quot;425&quot; data-origin-width=&quot;667&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2. 정규식(Regex) 옵션 켜기 (오른쪽 상단 .*&amp;nbsp; ✔️ )&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3. 치환할 패턴 예시&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1751697892529&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(?&amp;lt;=[&quot;'\(])(/components/)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* 큰따옴표, 작은따옴표, 괄호 뒤에 나오는 /components/ 경로를 찾는다.&lt;/span&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: #000000;&quot;&gt;&lt;b&gt;4. 치환 대상 예시 문자열&lt;/b&gt;&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;&quot;/components/ ~&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;. /components/ ~ &quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;.. /components/ ~ &quot;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;701&quot; data-start=&quot;686&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실제 치환 예시)&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;781&quot; data-start=&quot;703&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;740&quot; data-start=&quot;703&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;찾기: (?&amp;lt;=[&quot;'\(])(\/components\/)&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;781&quot; data-start=&quot;741&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;바꾸기: /newcomponents/ (변경하고자 하는 새 경로)&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;1064&quot; data-origin-height=&quot;672&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dVx8za/btsOPK05GQg/0beWcYs9mKPiKTdLZP6KyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dVx8za/btsOPK05GQg/0beWcYs9mKPiKTdLZP6KyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dVx8za/btsOPK05GQg/0beWcYs9mKPiKTdLZP6KyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdVx8za%2FbtsOPK05GQg%2F0beWcYs9mKPiKTdLZP6KyK%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;550&quot; height=&quot;347&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;672&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;code_1755317666471&quot; data-ke-type=&quot;html&quot; data-source=&quot;&amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;https://icons8.com/icon/61466/intellij-idea&amp;quot;&amp;gt;IntelliJ IDEA&amp;lt;/a&amp;gt; 작가: &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;https://icons8.com&amp;quot;&amp;gt;Icons8&amp;lt;/a&amp;gt;&quot;&gt;&lt;a href=&quot;https://icons8.com/icon/61466/intellij-idea&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;IntelliJ IDEA&lt;/a&gt; 작가: &lt;a href=&quot;https://icons8.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Icons8&lt;/a&gt;&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고: IntelliJ 공식 문서(&lt;a href=&quot;https://www.jetbrains.com/help/idea/refactoring.html)&quot;&gt;https://www.jetbrains.com/help/idea/refactoring.html)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://regex101.com/&quot;&gt;https://regex101.com/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenAI&amp;nbsp;ChatGPT&amp;nbsp;(&lt;a href=&quot;https://openai.com)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://openai.com)&lt;/a&gt;&lt;/p&gt;</description>
      <category>웹 개발</category>
      <category>IntelliJ</category>
      <category>문자열치환</category>
      <author>studyingbackhoe</author>
      <guid isPermaLink="true">https://studyingbackhoe.tistory.com/85</guid>
      <comments>https://studyingbackhoe.tistory.com/85#entry85comment</comments>
      <pubDate>Sat, 5 Jul 2025 16:02:07 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Base64 인코딩을 이용해서 암복호화하기</title>
      <link>https://studyingbackhoe.tistory.com/82</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1. AES 알고리즘&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대칭키 암호화 방식으로 암호화와 복호화에 동일한 키를 사용한다. 이 키는 비밀로 유지되어야 하며 암호화된 데이터는 키를 알고 있는 사람만 복호화할 수 있다. AES 알고리즘 중 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;AES-256&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;을 사용하여 256비트(32바이트) 키로 더 강력한 보안 방법을 적용해보려고 한다.&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2. 암복호화하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;Java&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;Java&quot;&gt;&lt;code&gt;import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class CipherExample {

	public static void main(String[] args) throws Exception {

		// AES-256을 사용하려면 키 길이가 32바이트(256비트)여야 함.
		String myKey = &quot;[개발|기록이|AES|암호화]&quot;;
		int bytesLength = myKey.getBytes().length;
		System.err.println(&quot;myKey 바이트 값 ::: &quot; + bytesLength);
		
		// myKey값이 32바이트가 아닌 경우 32바이트로 변환
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/* if (myKey.getBytes().length &amp;lt; 32) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while (myKey.getBytes().length &amp;lt; 32) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myKey += &quot;\0&quot;; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
		System.err.println(&quot;myKey를 32바이트로 변환 ::: &quot; + myKey.getBytes().length); */
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
		SecretKeySpec key = new SecretKeySpec(myKey.getBytes(), &quot;AES&quot;);
		String email = &quot;studyingbackhoe@test.com&quot;;
		String encrypt = encrypt(email, key);
		System.err.println(&quot;암호화 &amp;gt;&amp;gt;&amp;gt; &quot; + encrypt);

		String decrypt = decrypt(encrypt, key);
		System.err.println(&quot;복호화 &amp;gt;&amp;gt;&amp;gt; &quot; + decrypt);
	}
	
	// 암호화
	public static String encrypt(String data, SecretKeySpec key) throws Exception {
		Cipher cipher = Cipher.getInstance(&quot;AES&quot;);
		cipher.init(Cipher.ENCRYPT_MODE, key);
		byte[] encryptedBytes = cipher.doFinal(data.getBytes());
		return Base64.getEncoder().encodeToString(encryptedBytes);
	}
	
	// 복호화
	public static String decrypt(String encryptData, SecretKeySpec key) throws Exception {
		Cipher cipher = Cipher.getInstance(&quot;AES&quot;);
		cipher.init(Cipher.DECRYPT_MODE, key);
		byte[] encryptedBytes = Base64.getDecoder().decode(encryptData);
		byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
		return new String(decryptedBytes);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1) SecretKeySpec &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;AES 알고리즘에서 사용할 비밀키를 생성한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AES-256 방식을 사용하기 위해서는 myKey의 길이는 32바이트(256비트)여야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2)&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt; Cipher.getInstance(&quot;AES&quot;)&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;AES 암복호화를 위한 Cipher 객체를 생성한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 Cipher 객체는 나중에 실제로 암호화 및 복호화 작업을 수행하는 데 사용된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3)&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt; cipher.init(Cipher.ENCRYPT_MODE, key)&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;&amp;nbsp;init() 메서드는 Cipher 객체를 초기화하는 역할을 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(Cipher.ENCRYPT_MODE : 암호화 모드)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;4)&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;cipher.doFinal(data.getBytes())&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;doFinal() 메서드는 암호화 작업을&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실제로 수행한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;data.getBytes()로 변환된 원본 데이터를 암호화하여 encryptedBytes에 저장한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이때 반환된 encryptedBytes는 암호화된 바이트 배열이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;5)&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt; Base64.getEncoder().encodeToString(encryptedBytes)&amp;nbsp;&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;암호화된 바이트 배열인 encryptedBytes를 Base64 인코딩하여 문자열로 변환한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;반환된 값은 암호화된 데이터를 Base64 인코딩한 문자열이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;   Base64 인코딩을 사용하는 이유&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 바이트 배열을 텍스트로 변환하여 저장하거나 전송할 때 더 편리하게 사용하기 위함.&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;6) Base64.getDecoder().decode(encryptedData)&amp;nbsp;&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;Base64 디코딩하여 바이트 배열로 변환한다. 암호화된 데이터를 복호화하려면 먼저 Base64에서 원래의 바이트 배열로 변환해야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;encryptedBytes는 디코딩된 암호화된 바이트 배열이다.&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;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3. 실행 결과&lt;/b&gt;&lt;/span&gt;&lt;/h3&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;521&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sixK1/btsMbrYPU6i/eC4JhaA4vejWgOq0KnlZ9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sixK1/btsMbrYPU6i/eC4JhaA4vejWgOq0KnlZ9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sixK1/btsMbrYPU6i/eC4JhaA4vejWgOq0KnlZ9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsixK1%2FbtsMbrYPU6i%2FeC4JhaA4vejWgOq0KnlZ9k%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;521&quot; height=&quot;62&quot; data-origin-width=&quot;521&quot; data-origin-height=&quot;62&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;출처 : OpenAI&amp;nbsp;ChatGPT&amp;nbsp;(&lt;/span&gt;&lt;a href=&quot;https://openai.com)&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;https://openai.com)&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>웹 개발/Back-end</category>
      <category>AES</category>
      <category>base64</category>
      <category>Java</category>
      <author>studyingbackhoe</author>
      <guid isPermaLink="true">https://studyingbackhoe.tistory.com/82</guid>
      <comments>https://studyingbackhoe.tistory.com/82#entry82comment</comments>
      <pubDate>Sun, 9 Feb 2025 16:16:28 +0900</pubDate>
    </item>
    <item>
      <title>[Java] public, private, static, final 정리</title>
      <link>https://studyingbackhoe.tistory.com/81</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. public vs private &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;public: 누구나(어디서든) 접근 가능&lt;/li&gt;
&lt;li&gt;private:&lt;span&gt; private이 선언된 메서드나 변수가 속한 클래스 &lt;/span&gt;안에서만&lt;span&gt;&amp;nbsp;&lt;/span&gt;접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1738206454308&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class PrivateTest {

    public static void main(String[] args) {
        Cafe cafe = new Cafe();
        cafe.orderCoffee();  // 커피 주문하기(호출 가능)
        // cafe.makeCoffee();  // private라서 호출 불가
    }

    public static class Cafe {
        private void makeCoffee() {  // 카페 관계자만 사용 가능(커피 만들기)
            System.out.println(&quot; === ☕ 커피 만드는 중 === &quot;);
        }

        public void orderCoffee() {  // 누구나 호출 가능 (커피 주문하기)
            makeCoffee(); 
            System.out.println(&quot; === 커피 주문 완료 === &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;&lt;b&gt;2. static&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 메서드나 변수는 객체(new로 만든 인스턴스)에 속하는데, static을 붙이면 &lt;u&gt;&lt;b&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;p data-ke-size=&quot;size16&quot;&gt;ex) CafeOrder order = new CafeOrder(); 없이도 바로 호출이 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1738206498634&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class StaticTest {
	public static void main(String[] args) {
    	System.out.println(&quot; 주문번호1 : &quot; + CafeOrder.getOrderNum());
        System.out.println(&quot; 주문번호2 : &quot; + CafeOrder.getOrderNum());
    }
    
    public class CafeOrder {
        private static int orderNumber = 0;  // 모든 주문에서 공유되는 번호

        public static String getOrderNum() {  // 객체 없이 호출 가능
            String str = &quot;ORDER&quot;;
            orderNumber++;  // 주문번호 증가
            return str + orderNumber;
        }
    }
}&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;b&gt;3. final &lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;final을 쓰면 &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;final 변수: 값 변경 불가&lt;/li&gt;
&lt;li&gt;final 메서드: 오버라이딩 불가&lt;/li&gt;
&lt;li&gt;final 클래스: 상속 불가&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1738206529445&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class FinalTest {

    public static void main(String[] args) {
        System.out.println(&quot;☕ 아메리카노 가격: &quot; + CafeMenu.AMERICANO_PRICE + &quot;원&quot;);
    }

    public class CafeMenu {
        public static final int AMERICANO_PRICE = 3000;  // 아메리카노 가격 (변경 불가)
    }
}&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;b&gt;정리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ public vs private &amp;rarr; 누가 이 코드를 쓸 수 있는지&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;public: 누구나 이 코드를 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;private: 오직 이 클래스 안에서만 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ static &amp;rarr; 객체 없이도 호출 가능&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;클래스 이름으로&lt;/b&gt; 바로 호출할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ final &amp;rarr; 값, 메서드, 클래스가 절대 변경되지 않음&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;변경 불가&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;p data-ke-size=&quot;size16&quot;&gt;출처 : OpenAI&amp;nbsp;ChatGPT&amp;nbsp;(&lt;a href=&quot;https://openai.com)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://openai.com)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>웹 개발/Back-end</category>
      <category>final</category>
      <category>Java</category>
      <category>private</category>
      <category>Public</category>
      <category>Static</category>
      <author>studyingbackhoe</author>
      <guid isPermaLink="true">https://studyingbackhoe.tistory.com/81</guid>
      <comments>https://studyingbackhoe.tistory.com/81#entry81comment</comments>
      <pubDate>Thu, 30 Jan 2025 17:14:00 +0900</pubDate>
    </item>
    <item>
      <title>[Java] ExecutorService 비동기 처리</title>
      <link>https://studyingbackhoe.tistory.com/80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;여러 사람에게 메일 발송을 하는 것처럼 반복적인 작업을 동기 방식으로 처리하면, 각 작업이 완료될 때까지 블로킹이 발생하여 전체 처리 시간이 늘어날 수 있다. ExecutorService를 활용한 비동기 처리에 대해 알아보자.&lt;br /&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;병렬 작업(여러 작업을 동시에 처리) 증가 &amp;rarr; 스레드 개수 증가 &amp;rarr; CPU, 메모리 사용량&lt;b&gt;&amp;uarr;&lt;/b&gt; &amp;rarr; &lt;u&gt;&lt;b&gt;성능 저하&lt;/b&gt;&lt;/u&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;스레드풀(ThreadPool)의 동작&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 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;ExecutorService 인터페이스를 통해 스레드풀을 관리한다.&lt;/li&gt;
&lt;li&gt;Executors 클래스를 사용하여 다양한 유형의 스레드풀을 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;* Executors의 다양한 정적 메서드를 이용해서 &lt;span style=&quot;color: #333333;&quot;&gt;ExecutorService&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt; 구현 객체를 만들 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&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;table style=&quot;border-collapse: collapse; width: 99.7682%; height: 50px;&quot; border=&quot;1&quot; data-ke-style=&quot;style15&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 35.0234%; height: 20px; text-align: center;&quot;&gt;메소드명&lt;/td&gt;
&lt;td style=&quot;width: 17.7738%; height: 20px; text-align: center;&quot;&gt;초기 스레드 수&lt;/td&gt;
&lt;td style=&quot;width: 20.8042%; height: 20px; text-align: center;&quot;&gt;코어 스레드 수&lt;/td&gt;
&lt;td style=&quot;width: 27.4451%; height: 20px; text-align: center;&quot;&gt;최대 스레드 수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 35.0234%; height: 17px;&quot;&gt;newCachedThreadPool()&lt;/td&gt;
&lt;td style=&quot;width: 17.7738%; height: 17px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 20.8042%; height: 17px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 27.4451%; height: 17px; text-align: center;&quot;&gt;Integer.MAX_VALUE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 13px;&quot;&gt;
&lt;td style=&quot;width: 35.0234%; height: 13px;&quot;&gt;newFixedThreadPool(int n Threads)&lt;/td&gt;
&lt;td style=&quot;width: 17.7738%; height: 13px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 20.8042%; height: 13px; text-align: center;&quot;&gt;nThreads&lt;/td&gt;
&lt;td style=&quot;width: 27.4451%; height: 13px; text-align: center;&quot;&gt;nThreads&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;size14&quot;&gt;* 초기 스레드 수 : &lt;span style=&quot;color: #333333;&quot;&gt;ExecutorService 객체가 생성될 때 기본적으로 생성되는 스레드 수.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #333333;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;코어 스레드 수 : 스레드 수가 증가된 후 사용되지 않는 스레드를 스레드풀에서 제거할 때 최소한 유지해야 할 스레드 수.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;java&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;ExecutorService executorService = Executors.newCachedThreadPool();

ExecutorService executorService2 = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());&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;b&gt;2. 스레드풀 종료&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드풀의 스레드는 데몬 스레드가 아니기 때문에 main 스레드가 종료되더라도 작업을 처리하기 위해 계속 실행 상태로 남아있다,. 그래서 main() 매소드가 실행이 끝나도 애플리케이션 프로세스는 종료되지 않는다. 애플리케이션을 종료하려면 스레드풀을 종료시켜 스레드들이 종료 상태가 되도록 처리해줘야 한다.&lt;/p&gt;
&lt;pre class=&quot;java&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;executorService.shutdown();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 남아있는 작업을 마무리하고 스레드풀 종료
executorService.shutdownNow(); // 남아있는 작업과 상관없이 강제종료&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 작업 처리 요청&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;exceute()&amp;nbsp;&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;submit()&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;작업 처리 결과를 받을 수 있도록 Future를 리턴.&lt;/li&gt;
&lt;li&gt;작업 처리 도중 예외가 발생하더라도 스레드는&amp;nbsp; 종료되지 않고 다음 작업을 위해 재사용된다.&lt;/li&gt;
&lt;li&gt;스레드의 생성 오버헤더를 줄이기 위해서 submit()을 사용하는 것이 더 효율적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;java&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;executorService.execute();
executorService.submit();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;br /&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;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;package threadTest;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadTest {

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public static void main(String[] args) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ExecutorService executorSv = Executors.newCachedThreadPool();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 요청1) API 요청
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;executorSv.submit(() -&amp;gt; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;processMessage(&quot;요청1) API 요청 시작&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String apiResponse = apiRequest();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;processMessage(&quot;요청1-결과) API 요청 완료: &quot; + apiResponse);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 요청2) DB 쿼리 실행
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;executorSv.submit(() -&amp;gt; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;processMessage(&quot;요청2) DB 쿼리 시작&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String queryResult = executeDbQuery();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;processMessage(&quot;요청2-결과) DB 쿼리 결과: &quot; + queryResult);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 요청3) 파일 저장 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;processMessage(&quot;요청3) 파일 저장 시작&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;boolean fileSaved = saveFile(&quot;sample.txt&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (fileSaved) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;	processMessage(&quot;요청3-결과) 파일 저장 완료&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} else {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;	processMessage(&quot;요청3-결과) 파일 저장 실패&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;executorSv.shutdown();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private static String apiRequest() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread.sleep(3000); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} catch (InterruptedException e) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.printStackTrace();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return &quot;API 응답 데이터입니다.&quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private static String executeDbQuery() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread.sleep(1500); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} catch (InterruptedException e) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.printStackTrace();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return &quot;DB 쿼리 실행 결과입니다.&quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private static boolean saveFile(String fileName) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread.sleep(1000);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} catch (InterruptedException e) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.printStackTrace();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return true;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// static 메서드: 객체 생성 없이 호출 가능
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private static void processMessage(String content) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.out.println(Thread.currentThread().getName() + &quot; :::::::: &quot; + content);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&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;size14&quot;&gt;* 실행순서 : 요청3) 파일 저장 -&amp;gt; 요청2) DB 쿼리 시작 -&amp;gt; 요청1) 파일 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&lt;b&gt;1) 비동기 작업&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;&quot;요청1) API 요청&quot; 과 &quot;요청2) DB 쿼리&quot; 실행이 ExecutorService를 이용해 비동기로 처리된다. 각각 별도의 스레드에서 실행되고 2초, 1.5초 후에 결과가 출력된다.&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) 비동기 작업&lt;/b&gt;:&amp;nbsp;&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;&quot;요청3) 파일 저장&quot;은 메인 스레드에서 동기적으로 실행되며, 1초 후에 결과가 출력된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TlcbI/btsLRn3M9Ou/WXMw0aKWtJpFgky1p0fwCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TlcbI/btsLRn3M9Ou/WXMw0aKWtJpFgky1p0fwCK/img.png&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TlcbI/btsLRn3M9Ou/WXMw0aKWtJpFgky1p0fwCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTlcbI%2FbtsLRn3M9Ou%2FWXMw0aKWtJpFgky1p0fwCK%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;729&quot; height=&quot;156&quot; data-origin-width=&quot;729&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;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고: 이것이 자바다(한빛미디어) - 12.9 스레드풀&lt;br /&gt;&lt;a href=&quot;https://velog.io/@pllap/Java에서의-비동기-프로그래밍&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://velog.io/@pllap/Java에서의-비동기-프로그래밍&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;OpenAI&amp;nbsp;ChatGPT&amp;nbsp;(&lt;a href=&quot;https://openai.com)&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://openai.com)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <category>웹 개발/Back-end</category>
      <category>ExecutorService</category>
      <category>Java</category>
      <category>비동기처리</category>
      <author>studyingbackhoe</author>
      <guid isPermaLink="true">https://studyingbackhoe.tistory.com/80</guid>
      <comments>https://studyingbackhoe.tistory.com/80#entry80comment</comments>
      <pubDate>Sun, 19 Jan 2025 14:12:49 +0900</pubDate>
    </item>
  </channel>
</rss>