<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>크리드보이 - Backend Server Developer</title>
    <link>https://series.tistory.com/</link>
    <description>Backend Server Developer</description>
    <language>ko</language>
    <pubDate>Mon, 11 May 2026 12:23:55 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>크리드보이</managingEditor>
    <image>
      <title>크리드보이 - Backend Server Developer</title>
      <url>https://tistory1.daumcdn.net/tistory/76315/attach/649cba5a1ed243d5861dad5a34016630</url>
      <link>https://series.tistory.com</link>
    </image>
    <item>
      <title>AI 도입해야 한다는 건 아는데, 사내에서 어디부터 시작해야 할지 모르시는 분 있으세요?</title>
      <link>https://series.tistory.com/entry/AI-%EB%8F%84%EC%9E%85%ED%95%B4%EC%95%BC-%ED%95%9C%EB%8B%A4%EB%8A%94-%EA%B1%B4-%EC%95%84%EB%8A%94%EB%8D%B0-%EC%82%AC%EB%82%B4%EC%97%90%EC%84%9C-%EC%96%B4%EB%94%94%EB%B6%80%ED%84%B0-%EC%8B%9C%EC%9E%91%ED%95%B4%EC%95%BC-%ED%95%A0%EC%A7%80-%EB%AA%A8%EB%A5%B4%EC%8B%9C%EB%8A%94-%EB%B6%84-%EC%9E%88%EC%9C%BC%EC%84%B8%EC%9A%94</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;AI&amp;nbsp;도입해야&amp;nbsp;한다는&amp;nbsp;건&amp;nbsp;아는데,&amp;nbsp;사내에서&amp;nbsp;어디부터&amp;nbsp;시작해야&amp;nbsp;할지&amp;nbsp;모르시는&amp;nbsp;분&amp;nbsp;있으세요?&lt;br /&gt;현장에서&amp;nbsp;AX가&amp;nbsp;막히는&amp;nbsp;지점은&amp;nbsp;딱&amp;nbsp;두&amp;nbsp;가지라고&amp;nbsp;해요.&lt;br /&gt;첫째,&amp;nbsp;복잡한&amp;nbsp;실무는&amp;nbsp;멀티에이전트&amp;nbsp;자동화가&amp;nbsp;필요한데&amp;nbsp;내부에서&amp;nbsp;구축하기가&amp;nbsp;어렵다는&amp;nbsp;것.&lt;br /&gt;둘째,&amp;nbsp;AI가&amp;nbsp;잘&amp;nbsp;일하려면&amp;nbsp;비즈니스&amp;nbsp;데이터가&amp;nbsp;공급되어야&amp;nbsp;하는데,&amp;nbsp;어떻게&amp;nbsp;넣을지&amp;nbsp;모르거나&amp;nbsp;쌓아둔&amp;nbsp;데이터&amp;nbsp;자체가&amp;nbsp;없는&amp;nbsp;경우가&amp;nbsp;많다는&amp;nbsp;것.&lt;br /&gt;그래서&amp;nbsp;현장에서&amp;nbsp;효과적인&amp;nbsp;접근은&amp;nbsp;&quot;가장&amp;nbsp;귀찮은&amp;nbsp;반복&amp;nbsp;업무&amp;nbsp;1개부터&amp;nbsp;AI에&amp;nbsp;연결하는&amp;nbsp;것&quot;이에요.&lt;br /&gt;작은&amp;nbsp;효용을&amp;nbsp;한&amp;nbsp;번&amp;nbsp;경험하면,&amp;nbsp;사람들은&amp;nbsp;스스로&amp;nbsp;데이터를&amp;nbsp;더&amp;nbsp;넣으려&amp;nbsp;한다고&amp;nbsp;해요.&lt;br /&gt;AX는&amp;nbsp;거창한&amp;nbsp;선언이&amp;nbsp;아니에요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04-key-2.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coLREj/dJMb99TLOg8/I1udmuTqG3OrVdKBIea05k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coLREj/dJMb99TLOg8/I1udmuTqG3OrVdKBIea05k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coLREj/dJMb99TLOg8/I1udmuTqG3OrVdKBIea05k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoLREj%2FdJMb99TLOg8%2FI1udmuTqG3OrVdKBIea05k%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;04-key-2.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05-quote-1.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lyaWR/dJMcab47PiP/5qbkRZf4tclHzDvC6vF2fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lyaWR/dJMcab47PiP/5qbkRZf4tclHzDvC6vF2fk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lyaWR/dJMcab47PiP/5qbkRZf4tclHzDvC6vF2fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlyaWR%2FdJMcab47PiP%2F5qbkRZf4tclHzDvC6vF2fk%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;05-quote-1.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06-quote-2.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beTC9m/dJMcaiXrgXx/5OBzeSassLAvYbY0sZKkCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beTC9m/dJMcaiXrgXx/5OBzeSassLAvYbY0sZKkCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beTC9m/dJMcaiXrgXx/5OBzeSassLAvYbY0sZKkCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeTC9m%2FdJMcaiXrgXx%2F5OBzeSassLAvYbY0sZKkCK%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;06-quote-2.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07-safety.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvDDeU/dJMcaarDmvE/I4e2sGAAEvIbCn9btes7Xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvDDeU/dJMcaarDmvE/I4e2sGAAEvIbCn9btes7Xk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvDDeU/dJMcaarDmvE/I4e2sGAAEvIbCn9btes7Xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdvDDeU%2FdJMcaarDmvE%2FI4e2sGAAEvIbCn9btes7Xk%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;07-safety.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08-alignment.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqLnP7/dJMcaarDmvF/99qFxzEfnD2pnzukbrKW71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqLnP7/dJMcaarDmvF/99qFxzEfnD2pnzukbrKW71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqLnP7/dJMcaarDmvF/99qFxzEfnD2pnzukbrKW71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqLnP7%2FdJMcaarDmvF%2F99qFxzEfnD2pnzukbrKW71%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;08-alignment.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;09-migration.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjiCew/dJMcab47PiQ/SVN1NfvsDvqJegURzAmH9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjiCew/dJMcab47PiQ/SVN1NfvsDvqJegURzAmH9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjiCew/dJMcab47PiQ/SVN1NfvsDvqJegURzAmH9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjiCew%2FdJMcab47PiQ%2FSVN1NfvsDvqJegURzAmH9K%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;09-migration.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;10-cta.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5ZXFb/dJMb99TLOg9/dkAAGZLzWn9lcYuGGX9hm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5ZXFb/dJMb99TLOg9/dkAAGZLzWn9lcYuGGX9hm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5ZXFb/dJMb99TLOg9/dkAAGZLzWn9lcYuGGX9hm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5ZXFb%2FdJMb99TLOg9%2FdkAAGZLzWn9lcYuGGX9hm0%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;10-cta.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rich.legend.ai&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;richlegendai&lt;/p&gt;</description>
      <category>AI AX</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/751</guid>
      <comments>https://series.tistory.com/entry/AI-%EB%8F%84%EC%9E%85%ED%95%B4%EC%95%BC-%ED%95%9C%EB%8B%A4%EB%8A%94-%EA%B1%B4-%EC%95%84%EB%8A%94%EB%8D%B0-%EC%82%AC%EB%82%B4%EC%97%90%EC%84%9C-%EC%96%B4%EB%94%94%EB%B6%80%ED%84%B0-%EC%8B%9C%EC%9E%91%ED%95%B4%EC%95%BC-%ED%95%A0%EC%A7%80-%EB%AA%A8%EB%A5%B4%EC%8B%9C%EB%8A%94-%EB%B6%84-%EC%9E%88%EC%9C%BC%EC%84%B8%EC%9A%94#entry751comment</comments>
      <pubDate>Sat, 2 May 2026 15:46:52 +0900</pubDate>
    </item>
    <item>
      <title>AX 채용 시장을 직접 들여다보니 &amp;mdash; 경력직 중심, 재설계 역량, 그리고 진짜 AX 인재의 조건</title>
      <link>https://series.tistory.com/entry/AX-%EC%B1%84%EC%9A%A9-%EC%8B%9C%EC%9E%A5%EC%9D%84-%EC%A7%81%EC%A0%91-%EB%93%A4%EC%97%AC%EB%8B%A4%EB%B3%B4%EB%8B%88-%E2%80%94-%EA%B2%BD%EB%A0%A5%EC%A7%81-%EC%A4%91%EC%8B%AC-%EC%9E%AC%EC%84%A4%EA%B3%84-%EC%97%AD%EB%9F%89-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%A7%84%EC%A7%9C-AX-%EC%9D%B8%EC%9E%AC%EC%9D%98-%EC%A1%B0%EA%B1%B4</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01-cover.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5leZc/dJMcaa6ejY8/jOFKHsxyC5MBe0MfUjFBu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5leZc/dJMcaa6ejY8/jOFKHsxyC5MBe0MfUjFBu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5leZc/dJMcaa6ejY8/jOFKHsxyC5MBe0MfUjFBu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5leZc%2FdJMcaa6ejY8%2FjOFKHsxyC5MBe0MfUjFBu0%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;01-cover.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;AX 채용 시장을 직접 들여다보니 &amp;mdash; 경력직 중심, 재설계 역량, 그리고 진짜 AX 인재의 조건&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 AX(AI Transformation) 채용 공고를 꽤 오래 살펴볼 기회가 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포지션별 요건, 선호 경력, 도메인 분포까지 훑어보고 나니 하나의 흐름이 선명하게 보였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AX는 지금, 신입 시장이 아닙니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AX는 경력직 시장입니다 &amp;mdash; 평균 4.3년, 중앙값 3년&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공고에서 확인한 요구 경력의 평균은 약 4.3년이었고, 중앙값은 3년 정도였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신입 포지션이 아예 없는 건 아니었지만, 대부분은 인턴 또는 주니어에 가까운 수준이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 숫자가 의미하는 건 단순하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기업들이 AI를 다룰 줄 아는 사람이 아니라, &lt;b&gt;현업의 일을 이해하고 그 구조를 바꿀 수 있는 사람&lt;/b&gt;을 찾고 있다는 뜻입니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;가장 많이 본 역량 키워드 &amp;mdash; As-Is에서 To-Be로&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공고에서 가장 자주 등장한 흐름은 &lt;b&gt;As-Is 분석 &amp;rarr; To-Be 설계 &amp;rarr; 운영 안착&lt;/b&gt;이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 업무가 어떻게 굴러가는지 파악하고, 어디에 병목이 있는지 찾고, AI가 들어갈 수 있는 구조로 다시 설계하는 능력입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 중요한 포인트가 하나 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PoC(개념 검증)에서 끝나는 게 아니라, &lt;b&gt;실제 운영까지 끌고 가는 경험&lt;/b&gt;을 요구한다는 점입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실험에서 멈추는 게 아니라, 조직에 정착시키는 과정까지 책임져본 사람이어야 한다는 것이죠.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AX는 ChatGPT 계정 배포가 아닙니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔직히 말하면, 그동안 'AI 도입'이라는 이름 아래 ChatGPT 계정을 나눠주고 몇 번 교육하는 걸 AX라고 부르는 경우도 많았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 채용 시장에서 보이는 AX는 그 레벨이 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;일하는 방식 자체가 바뀌어야 AX입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순 툴 도입이 아닌, 프로세스 재설계, 구조 변화, 조직 문화의 전환까지 포함합니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;도메인별 수요 지도 &amp;mdash; 제조 / 금융 / 공공&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AX 수요가 어느 산업에 몰려 있는지도 꽤 선명하게 보였습니다.&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;: 공정, 설계, 품질, 생산관리 영역에 AI를 연결하려는 수요&lt;/li&gt;
&lt;li&gt;&lt;b&gt;금융&lt;/b&gt;: 보안과 컴플라이언스 규제 안에서 AI를 적용하려는 수요&lt;/li&gt;
&lt;li&gt;&lt;b&gt;공공&lt;/b&gt;: B2G, R&amp;amp;D, 행정 자동화 중심의 수요&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 산업 특성에 맞는 도메인 이해 없이는 AX 역할을 제대로 수행하기 어렵다는 뜻이기도 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뜬구름 잡듯 'AI 잘함'으로 통하던 시대가 지나고, 이제 각 산업의 실제 업무 안으로 AI가 들어가기 시작한 것입니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론 &amp;mdash; AX 인재의 진짜 조건&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AX 인재는 AI 뉴스를 많이 아는 사람이 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;툴 이름을 많이 외운 사람도 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진짜 중요한 건 이것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 속한 조직의 일이 어떻게 흘러가는지 알고,&lt;br /&gt;그 일을 AI가 들어갈 수 있는 구조로 다시 바꿀 수 있는 사람.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일을 직접 해본 경험, 시스템 안에서 굴러가는 업무를 이해해본 경험, 그리고 다른 사람의 문제를 해결 가능한 구조로 바꿔줄 수 있는 감각.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI를 잘 아는 것도 중요하지만, 그보다 먼저 &lt;b&gt;일이 어떻게 돌아가는지 알아야&lt;/b&gt; 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래야 어디에 AI를 넣어야 하는지, 무엇을 자동화해야 하는지, 어떤 부분은 사람이 판단해야 하는지가 비로소 보이기 때문입니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AX는 SI가 아닙니다. 일하는 방식을 재설계하는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03-essence.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XDirC/dJMcagZDBo6/CrOaw0Z1v9ulHoLFCd7v50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XDirC/dJMcagZDBo6/CrOaw0Z1v9ulHoLFCd7v50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XDirC/dJMcagZDBo6/CrOaw0Z1v9ulHoLFCd7v50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXDirC%2FdJMcagZDBo6%2FCrOaw0Z1v9ulHoLFCd7v50%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;03-essence.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04-skill.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqf6IV/dJMcadPlrTL/PU5V3c9POjDdkQHjxwFxL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqf6IV/dJMcadPlrTL/PU5V3c9POjDdkQHjxwFxL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqf6IV/dJMcadPlrTL/PU5V3c9POjDdkQHjxwFxL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbqf6IV%2FdJMcadPlrTL%2FPU5V3c9POjDdkQHjxwFxL0%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;04-skill.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05-poc.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djV0oV/dJMcagZDBo7/kw3gpP6kOk3hvLX2sjICZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djV0oV/dJMcagZDBo7/kw3gpP6kOk3hvLX2sjICZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djV0oV/dJMcagZDBo7/kw3gpP6kOk3hvLX2sjICZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjV0oV%2FdJMcagZDBo7%2Fkw3gpP6kOk3hvLX2sjICZk%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;05-poc.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06-domain.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dLZJPC/dJMcadPlrTK/Pm2f2C8XRBLYh8vVhUUkC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dLZJPC/dJMcadPlrTK/Pm2f2C8XRBLYh8vVhUUkC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dLZJPC/dJMcadPlrTK/Pm2f2C8XRBLYh8vVhUUkC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdLZJPC%2FdJMcadPlrTK%2FPm2f2C8XRBLYh8vVhUUkC1%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;06-domain.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07-diff.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/epC9Bu/dJMcahK3g6q/El1SdBGf1ZGKKO7m1wqhiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/epC9Bu/dJMcahK3g6q/El1SdBGf1ZGKKO7m1wqhiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/epC9Bu/dJMcahK3g6q/El1SdBGf1ZGKKO7m1wqhiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FepC9Bu%2FdJMcahK3g6q%2FEl1SdBGf1ZGKKO7m1wqhiK%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;07-diff.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08-cta.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HYH0n/dJMcahK3g6r/l6P3sRx1wU0fXyc0aHBkk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HYH0n/dJMcahK3g6r/l6P3sRx1wU0fXyc0aHBkk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HYH0n/dJMcahK3g6r/l6P3sRx1wU0fXyc0aHBkk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHYH0n%2FdJMcahK3g6r%2Fl6P3sRx1wU0fXyc0aHBkk1%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;08-cta.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI AX</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/750</guid>
      <comments>https://series.tistory.com/entry/AX-%EC%B1%84%EC%9A%A9-%EC%8B%9C%EC%9E%A5%EC%9D%84-%EC%A7%81%EC%A0%91-%EB%93%A4%EC%97%AC%EB%8B%A4%EB%B3%B4%EB%8B%88-%E2%80%94-%EA%B2%BD%EB%A0%A5%EC%A7%81-%EC%A4%91%EC%8B%AC-%EC%9E%AC%EC%84%A4%EA%B3%84-%EC%97%AD%EB%9F%89-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%A7%84%EC%A7%9C-AX-%EC%9D%B8%EC%9E%AC%EC%9D%98-%EC%A1%B0%EA%B1%B4#entry750comment</comments>
      <pubDate>Fri, 1 May 2026 15:59:02 +0900</pubDate>
    </item>
    <item>
      <title>github에 오픈소스 SaaS 스타터킷을 배포했습니다.</title>
      <link>https://series.tistory.com/entry/github%EC%97%90-%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4-SaaS-%EC%8A%A4%ED%83%80%ED%84%B0%ED%82%B7%EC%9D%84-%EB%B0%B0%ED%8F%AC%ED%96%88%EC%8A%B5%EB%8B%88%EB%8B%A4</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;1904&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Bic7F/dJMcag6pVcw/exBRzk3V9K4ctGlFwM19iK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Bic7F/dJMcag6pVcw/exBRzk3V9K4ctGlFwM19iK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Bic7F/dJMcag6pVcw/exBRzk3V9K4ctGlFwM19iK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBic7F%2FdJMcag6pVcw%2FexBRzk3V9K4ctGlFwM19iK%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;1772&quot; height=&quot;1904&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;1904&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;SaaS&amp;nbsp;새로&amp;nbsp;만들&amp;nbsp;때마다&amp;nbsp;똑같은&amp;nbsp;데서&amp;nbsp;시간&amp;nbsp;다&amp;nbsp;까먹는&amp;nbsp;거,&amp;nbsp;저만&amp;nbsp;그런&amp;nbsp;거&amp;nbsp;아니죠.&lt;br /&gt;로그인&amp;nbsp;붙이는&amp;nbsp;데&amp;nbsp;하루,&amp;nbsp;결제&amp;nbsp;붙이는&amp;nbsp;데&amp;nbsp;또&amp;nbsp;하루,&amp;nbsp;DB&amp;nbsp;스키마&amp;nbsp;짜다&amp;nbsp;보면&amp;nbsp;정작&amp;nbsp;본&amp;nbsp;기능은&amp;nbsp;손도&amp;nbsp;못&amp;nbsp;댄&amp;nbsp;채&amp;nbsp;주말이&amp;nbsp;끝나더라고요.&amp;nbsp;매번&amp;nbsp;그러니까&amp;nbsp;어느&amp;nbsp;순간부터&amp;nbsp;새&amp;nbsp;SaaS&amp;nbsp;시작하는&amp;nbsp;게&amp;nbsp;좀&amp;nbsp;무서워졌어요.&lt;br /&gt;그래서&amp;nbsp;제가&amp;nbsp;매번&amp;nbsp;쓰던&amp;nbsp;조합을&amp;nbsp;한&amp;nbsp;번에&amp;nbsp;합쳐서&amp;nbsp;github에&amp;nbsp;오픈소스&amp;nbsp;SaaS&amp;nbsp;스타터킷으로&amp;nbsp;풀었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름은&amp;nbsp;RichLegend&amp;nbsp;AI&amp;nbsp;SaaS&amp;nbsp;Starter&amp;nbsp;Kit이고,&amp;nbsp;한국어가&amp;nbsp;기본인&amp;nbsp;SaaS&amp;nbsp;보일러플레이트&amp;nbsp;/&amp;nbsp;템플릿이라고&amp;nbsp;보시면&amp;nbsp;돼요.&lt;br /&gt;들어&amp;nbsp;있는&amp;nbsp;스택은&amp;nbsp;이렇게&amp;nbsp;돼요.&lt;br /&gt;Next.js&amp;nbsp;16&amp;nbsp;(App&amp;nbsp;Router&amp;nbsp;기반)&lt;br /&gt;Clerk&amp;nbsp;인증&lt;br /&gt;Polar.sh&amp;nbsp;결제&amp;nbsp;+&amp;nbsp;webhook&lt;br /&gt;Supabase&amp;nbsp;Postgres&amp;nbsp;+&amp;nbsp;Drizzle&amp;nbsp;ORM&lt;br /&gt;next-intl&amp;nbsp;다국어&amp;nbsp;(한국어/영어,&amp;nbsp;확장&amp;nbsp;가능)&lt;br /&gt;TailwindCSS&amp;nbsp;+&amp;nbsp;Base&amp;nbsp;UI&lt;br /&gt;SEO&amp;nbsp;/&amp;nbsp;JSON-LD&amp;nbsp;/&amp;nbsp;sitemap&amp;nbsp;/&amp;nbsp;hreflang&lt;br /&gt;공개&amp;nbsp;저장소용&amp;nbsp;secret-scan&lt;br /&gt;MIT라&amp;nbsp;그냥&amp;nbsp;가져다&amp;nbsp;쓰셔도&amp;nbsp;되고,&amp;nbsp;한국어가&amp;nbsp;기본이라&amp;nbsp;카피&amp;nbsp;다시&amp;nbsp;쓰는&amp;nbsp;일도&amp;nbsp;줄어요.&lt;br /&gt;pnpm&amp;nbsp;install&amp;nbsp;하고&amp;nbsp;.env.local&amp;nbsp;채운&amp;nbsp;다음&amp;nbsp;pnpm&amp;nbsp;dev&amp;nbsp;하면&amp;nbsp;바로&amp;nbsp;/ko&amp;nbsp;화면이&amp;nbsp;떠요.&amp;nbsp;똑같은&amp;nbsp;기반&amp;nbsp;작업&amp;nbsp;또&amp;nbsp;반복하기&amp;nbsp;싫으셨던&amp;nbsp;분들에게&amp;nbsp;도움이&amp;nbsp;됐으면&amp;nbsp;해요.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/richlegendai/richlegendai-saas-starter-kit-nextjs-v1&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/richlegendai/richlegendai-saas-starter-kit-nextjs-v1&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1777521891319&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - richlegendai/richlegendai-saas-starter-kit-nextjs-v1&quot; data-og-description=&quot;Contribute to richlegendai/richlegendai-saas-starter-kit-nextjs-v1 development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/richlegendai/richlegendai-saas-starter-kit-nextjs-v1&quot; data-og-url=&quot;https://github.com/richlegendai/richlegendai-saas-starter-kit-nextjs-v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/g6MWF/dJMb85WWEeT/7mIz2AaZB6RHO4OVWCLcR1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/caIPTE/dJMb87NZOZY/KNIdghGgt2FElbKQgViFe0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/richlegendai/richlegendai-saas-starter-kit-nextjs-v1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/richlegendai/richlegendai-saas-starter-kit-nextjs-v1&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/g6MWF/dJMb85WWEeT/7mIz2AaZB6RHO4OVWCLcR1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/caIPTE/dJMb87NZOZY/KNIdghGgt2FElbKQgViFe0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - richlegendai/richlegendai-saas-starter-kit-nextjs-v1&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to richlegendai/richlegendai-saas-starter-kit-nextjs-v1 development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1744&quot; data-origin-height=&quot;1202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bklVu2/dJMcadohPUv/8MCT2PuuKpsocP2nVci1v0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bklVu2/dJMcadohPUv/8MCT2PuuKpsocP2nVci1v0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bklVu2/dJMcadohPUv/8MCT2PuuKpsocP2nVci1v0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbklVu2%2FdJMcadohPUv%2F8MCT2PuuKpsocP2nVci1v0%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;1744&quot; height=&quot;1202&quot; data-origin-width=&quot;1744&quot; data-origin-height=&quot;1202&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1724&quot; data-origin-height=&quot;1920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZ4oaz/dJMcajaXJyf/CI5SbYEqlq1kWmZo6vuku1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZ4oaz/dJMcajaXJyf/CI5SbYEqlq1kWmZo6vuku1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZ4oaz/dJMcajaXJyf/CI5SbYEqlq1kWmZo6vuku1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZ4oaz%2FdJMcajaXJyf%2FCI5SbYEqlq1kWmZo6vuku1%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;1724&quot; height=&quot;1920&quot; data-origin-width=&quot;1724&quot; data-origin-height=&quot;1920&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dv9aiM/dJMcajaXJzE/aKmhcScYVKzgjjoM7tJnw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dv9aiM/dJMcajaXJzE/aKmhcScYVKzgjjoM7tJnw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dv9aiM/dJMcajaXJzE/aKmhcScYVKzgjjoM7tJnw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdv9aiM%2FdJMcajaXJzE%2FaKmhcScYVKzgjjoM7tJnw1%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;1150&quot; height=&quot;2048&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>AI AX</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/749</guid>
      <comments>https://series.tistory.com/entry/github%EC%97%90-%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4-SaaS-%EC%8A%A4%ED%83%80%ED%84%B0%ED%82%B7%EC%9D%84-%EB%B0%B0%ED%8F%AC%ED%96%88%EC%8A%B5%EB%8B%88%EB%8B%A4#entry749comment</comments>
      <pubDate>Thu, 30 Apr 2026 13:05:24 +0900</pubDate>
    </item>
    <item>
      <title>AI 전환 진단 프로그램 AX Doctor v1 을 리뉴얼했습니다.</title>
      <link>https://series.tistory.com/entry/AI-%EC%A0%84%ED%99%98-%EC%A7%84%EB%8B%A8-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-AX-Doctor-v1-%EC%9D%84-%EB%A6%AC%EB%89%B4%EC%96%BC%ED%96%88%EC%8A%B5%EB%8B%88%EB%8B%A4</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;631&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C2BeM/dJMcafGrjgc/9OWrSpWNK6XrjuHKIKkll0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C2BeM/dJMcafGrjgc/9OWrSpWNK6XrjuHKIKkll0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C2BeM/dJMcafGrjgc/9OWrSpWNK6XrjuHKIKkll0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC2BeM%2FdJMcafGrjgc%2F9OWrSpWNK6XrjuHKIKkll0%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;944&quot; height=&quot;631&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;631&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AI&amp;nbsp;전환&amp;nbsp;진단&amp;nbsp;프로그램&amp;nbsp;AX&amp;nbsp;Doctor&amp;nbsp;v1&amp;nbsp;by&amp;nbsp;axq.kr&lt;/b&gt;&lt;br /&gt;흩어져&amp;nbsp;있던&amp;nbsp;접점들을&amp;nbsp;단일&amp;nbsp;도메인으로&amp;nbsp;정리했고,&amp;nbsp;AI&amp;nbsp;전환&amp;nbsp;진단&amp;nbsp;프로그램&amp;nbsp;AX&amp;nbsp;Doctor&amp;nbsp;by&amp;nbsp;axq.kr&amp;nbsp;으로&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;AX&amp;nbsp;Doctor는&amp;nbsp;조직의&amp;nbsp;AI&amp;nbsp;전환&amp;nbsp;준비&amp;nbsp;수준을&amp;nbsp;30문항&amp;middot;5분으로&amp;nbsp;진단하는&amp;nbsp;프로그램입니다.&lt;br /&gt;Gartner&amp;middot;Cisco&amp;middot;Microsoft&amp;nbsp;프레임워크를&amp;nbsp;기반으로,&amp;nbsp;전략&amp;nbsp;정합성부터&amp;nbsp;문화&amp;middot;변화&amp;nbsp;관리까지&amp;nbsp;6개&amp;nbsp;차원을&amp;nbsp;측정합니다.&lt;br /&gt;익명이고,&amp;nbsp;로그인도&amp;nbsp;필요&amp;nbsp;없습니다.&amp;nbsp;결과는&amp;nbsp;즉시&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;&quot;우리 조직이 AI를 도입할 준비가 됐는가&quot;라는 질문에 데이터 기반의 답을 드립니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://www.axq.kr&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt; &lt;a href=&quot;http://www.axq.kr&quot;&gt;www.axq.kr&amp;nbsp;&lt;/a&gt;&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1777442384104&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;AXQ &amp;mdash; AI Transformation 진단&quot; data-og-description=&quot;01 산업 &amp;amp; 기본 정보 입력 회사명과 산업군을 선택하면 동종업계 평균과 비교가 가능합니다. 모두 익명 처리됩니다. 02 30문항 응답 (약 5분) 6개 핵심 Dimension에 걸쳐 5점 척도로 응답합니다. 각 질&quot; data-og-host=&quot;www.axq.kr&quot; data-og-source-url=&quot;http://www.axq.kr&quot; data-og-url=&quot;https://www.axq.kr/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;http://www.axq.kr&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.axq.kr&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;AXQ &amp;mdash; AI Transformation 진단&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;01 산업 &amp;amp; 기본 정보 입력 회사명과 산업군을 선택하면 동종업계 평균과 비교가 가능합니다. 모두 익명 처리됩니다. 02 30문항 응답 (약 5분) 6개 핵심 Dimension에 걸쳐 5점 척도로 응답합니다. 각 질&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.axq.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7zqTN/dJMcahYxgQ3/xUen3pE4CxrULKtek20P50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7zqTN/dJMcahYxgQ3/xUen3pE4CxrULKtek20P50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7zqTN/dJMcahYxgQ3/xUen3pE4CxrULKtek20P50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7zqTN%2FdJMcahYxgQ3%2FxUen3pE4CxrULKtek20P50%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;722&quot; height=&quot;628&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;628&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1207&quot; data-origin-height=&quot;526&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dM06nd/dJMcaa6cs9J/c3McbWOTzJi88RENjWK6kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dM06nd/dJMcaa6cs9J/c3McbWOTzJi88RENjWK6kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dM06nd/dJMcaa6cs9J/c3McbWOTzJi88RENjWK6kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdM06nd%2FdJMcaa6cs9J%2Fc3McbWOTzJi88RENjWK6kK%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;1207&quot; height=&quot;526&quot; data-origin-width=&quot;1207&quot; data-origin-height=&quot;526&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1209&quot; data-origin-height=&quot;586&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nY8RK/dJMcaaymMXk/ryaeBodPSfBpxz78kgNK1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nY8RK/dJMcaaymMXk/ryaeBodPSfBpxz78kgNK1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nY8RK/dJMcaaymMXk/ryaeBodPSfBpxz78kgNK1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnY8RK%2FdJMcaaymMXk%2FryaeBodPSfBpxz78kgNK1k%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;1209&quot; height=&quot;586&quot; data-origin-width=&quot;1209&quot; data-origin-height=&quot;586&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1165&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B1dqP/dJMcaaymMYH/jLJUbunU2YqPmrI7QB1Lv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B1dqP/dJMcaaymMYH/jLJUbunU2YqPmrI7QB1Lv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B1dqP/dJMcaaymMYH/jLJUbunU2YqPmrI7QB1Lv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB1dqP%2FdJMcaaymMYH%2FjLJUbunU2YqPmrI7QB1Lv1%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;1165&quot; height=&quot;571&quot; data-origin-width=&quot;1165&quot; data-origin-height=&quot;571&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>AI AX</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/748</guid>
      <comments>https://series.tistory.com/entry/AI-%EC%A0%84%ED%99%98-%EC%A7%84%EB%8B%A8-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-AX-Doctor-v1-%EC%9D%84-%EB%A6%AC%EB%89%B4%EC%96%BC%ED%96%88%EC%8A%B5%EB%8B%88%EB%8B%A4#entry748comment</comments>
      <pubDate>Wed, 29 Apr 2026 15:00:53 +0900</pubDate>
    </item>
    <item>
      <title>AX 전에 DX, 데이터가 흐르는 인프라가 먼저다</title>
      <link>https://series.tistory.com/entry/AX-%EC%A0%84%EC%97%90-DX-%EB%8D%B0%EC%9D%B4%ED%84%B0%EA%B0%80-%ED%9D%90%EB%A5%B4%EB%8A%94-%EC%9D%B8%ED%94%84%EB%9D%BC%EA%B0%80-%EB%A8%BC%EC%A0%80%EB%8B%A4</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01-cover.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nbgX4/dJMcadIyeM8/FUUwsStChIYkU4GXztkenk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nbgX4/dJMcadIyeM8/FUUwsStChIYkU4GXztkenk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nbgX4/dJMcadIyeM8/FUUwsStChIYkU4GXztkenk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnbgX4%2FdJMcadIyeM8%2FFUUwsStChIYkU4GXztkenk%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;1081&quot; height=&quot;1350&quot; data-filename=&quot;01-cover.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;ai를-쓰고-있다고-말하기-어려운-이유&quot; style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;18&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;AI를 쓰고 있다고 말하기 어려운 이유&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;20&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;우리 조직은 AI를 제대로 쓰고 있는가?&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;22&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에이전트, 자동화, AX 키워드가 쏟아지지만 이 질문에 자신 있게 답하는 리더는 많지 않다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;24&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터는 솔루션 안에 갇혀 있고, 꺼내려면 데이터 팀에 요청해야 하며, 보고서는 며칠 후에야 돌아온다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;26&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;최근 한 B2B SaaS 기업의 사업개발 리드가 이 문제를 '극단적 경영 가시성' &amp;mdash; 조직의 모든 부서와 계층에서 즉시&amp;middot;충분히 알 수 있는 상태 &amp;mdash; 이라는 개념으로 풀어냈다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;28&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;결론은 단순하다. 데이터가 흐르는 IT 인프라가 없으면 AI는 접근할 데이터 자체가 없다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;데이터-주권-3조건과-일의-정의&quot; style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;30&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;데이터 주권 3조건과 일의 정의&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;32&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AI 활용의 출발점은 데이터 주권이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;34&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자사가 데이터를 직접 보유할 것, 그 데이터로 어떤 의사결정을 내려야 하는지 알 것, 데이터 간 연결이 가능할 것.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;36&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 세 가지가 없으면 특정 솔루션에 종속된 의존성이 생기고 AI에게 넘길 일 자체를 정의하지 못한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;38&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;딸깍에 이르는 과정은 딸깍이 아니다.&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;40&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;어느 커머스 플랫폼 사업은 자사몰 자동화를 위해 900개 넘는 세부 태스크를 먼저 정의했다. 그 과정을 거친 뒤에야 AI가 대체할 항목을 분리할 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;데이터가-흐르는-인프라가-먼저다&quot; style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;43&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;데이터가 흐르는 인프라가 먼저다&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;45&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;한 CX 솔루션은 API가 없어 요청 후 2~3주 뒤에야 데이터가 돌아왔고 그마저도 깨진 상태였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;47&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이런 환경에서는 어떤 AI를 붙여도 읽을 데이터가 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;49&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;해결책은 툴 중심 사일로를 해체하고 단일 소스 오브 트루스를 구축하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;51&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;한 기업은 DW를 하나로 통합하고 각 필드에 의미&amp;middot;맥락 주석을 달았다. 그 결과 LLM이 직접 데이터를 읽게 됐고, 단순 쿼리를 데이터 팀에 의뢰하지 않아도 되는 환경이 만들어졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;54&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;진짜 중요한 것은 앱이 아니라 데이터 파이프라인.&quot;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;감지실행연결--ai-에이전트-역할-설계&quot; style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;56&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;감지&amp;middot;실행&amp;middot;연결 &amp;mdash; AI 에이전트 역할 설계&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;58&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AI 에이전트의 역할은 세 단계로 나눈다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;60&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;감지(Detect) &amp;mdash; 이상 데이터를 발견해 알려주는 수준. 여기까지만 돼도 의미 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;62&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실행(Execute) &amp;mdash; 위임된 범위 안에서 이메일 발송 등 특정 액션을 수행한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;64&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;연결(Connect) &amp;mdash; 문제 상황과 제안을 요약해 적절한 의사결정권자에게 넘긴다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;66&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CRUD 권한 설계도 함께 이루어져야 한다. 어디까지 읽고, 쓰고, 지울 수 있는지를 용도와 권한에 따라 나누는 것이 보안과 자율성을 동시에 확보하는 방법이다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;ax-전에-dx-사금이-금이-되려면&quot; style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;69&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;AX 전에 DX, 사금이 금이 되려면&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;71&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;한 기업은 Claude에 MCP 접근 권한을 부여해 테이블 구조를 자동 설계하고, 고객 미팅 후 음성으로 대화 내용을 전달하면 CRM 필드에 자동 입력되는 환경을 만들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;73&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;기획&amp;middot;가공 시간은 체감 30% 수준으로 줄었고, 남은 시간에 사람을 직접 만나는 일에 집중할 수 있게 됐다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;75&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;30년치 데이터도 그 자체로 가치를 갖지는 않는다. 사금을 캐고, 흔들고, 녹여야 금이 된다.&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;77&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AX 전에 DX부터. 우리 조직의 데이터는 지금 AI가 접근할 수 있는 상태인가?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #bbbebf; text-align: start;&quot; data-line=&quot;77&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01-cover.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VKBnP/dJMcaa6bEcN/vtOO4dLkYMnQIkVsySg6R0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VKBnP/dJMcaa6bEcN/vtOO4dLkYMnQIkVsySg6R0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VKBnP/dJMcaa6bEcN/vtOO4dLkYMnQIkVsySg6R0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVKBnP%2FdJMcaa6bEcN%2FvtOO4dLkYMnQIkVsySg6R0%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;1081&quot; height=&quot;1350&quot; data-filename=&quot;01-cover.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02-summary.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cn7Rpp/dJMcagrMfGr/maAC0KdfzMSXcIooTtJwEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cn7Rpp/dJMcagrMfGr/maAC0KdfzMSXcIooTtJwEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cn7Rpp/dJMcagrMfGr/maAC0KdfzMSXcIooTtJwEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcn7Rpp%2FdJMcagrMfGr%2FmaAC0KdfzMSXcIooTtJwEK%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;1081&quot; height=&quot;1350&quot; data-filename=&quot;02-summary.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03-quote-problem.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LBI5W/dJMcahEcFMd/TZR1XB3a8I5A54j1HGQDpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LBI5W/dJMcahEcFMd/TZR1XB3a8I5A54j1HGQDpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LBI5W/dJMcahEcFMd/TZR1XB3a8I5A54j1HGQDpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLBI5W%2FdJMcahEcFMd%2FTZR1XB3a8I5A54j1HGQDpK%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;1081&quot; height=&quot;1350&quot; data-filename=&quot;03-quote-problem.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04-list-data-sovereignty.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/drViGS/dJMcahEcFMe/kZINAV8Fen6BpxkBmpQwh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/drViGS/dJMcahEcFMe/kZINAV8Fen6BpxkBmpQwh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/drViGS/dJMcahEcFMe/kZINAV8Fen6BpxkBmpQwh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdrViGS%2FdJMcahEcFMe%2FkZINAV8Fen6BpxkBmpQwh0%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;1081&quot; height=&quot;1350&quot; data-filename=&quot;04-list-data-sovereignty.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05-flow-work-definition.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eG0egI/dJMcahEcFMc/Vk4M4WwcA3Dpz9t1lFEKN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eG0egI/dJMcahEcFMc/Vk4M4WwcA3Dpz9t1lFEKN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eG0egI/dJMcahEcFMc/Vk4M4WwcA3Dpz9t1lFEKN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeG0egI%2FdJMcahEcFMc%2FVk4M4WwcA3Dpz9t1lFEKN1%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;1081&quot; height=&quot;1350&quot; data-filename=&quot;05-flow-work-definition.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06-infra-pipeline.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bie6Zo/dJMcaa6bEcP/Mq0tJ6g13Rq2oOSlRolIGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bie6Zo/dJMcaa6bEcP/Mq0tJ6g13Rq2oOSlRolIGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bie6Zo/dJMcaa6bEcP/Mq0tJ6g13Rq2oOSlRolIGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbie6Zo%2FdJMcaa6bEcP%2FMq0tJ6g13Rq2oOSlRolIGK%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;1081&quot; height=&quot;1350&quot; data-filename=&quot;06-infra-pipeline.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07-agent-roles.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/t8zKu/dJMcagrMfGu/oE0xDrKZI9d0sXZlrfp751/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/t8zKu/dJMcagrMfGu/oE0xDrKZI9d0sXZlrfp751/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/t8zKu/dJMcagrMfGu/oE0xDrKZI9d0sXZlrfp751/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ft8zKu%2FdJMcagrMfGu%2FoE0xDrKZI9d0sXZlrfp751%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;1081&quot; height=&quot;1350&quot; data-filename=&quot;07-agent-roles.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08-case-enterprise.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BDRov/dJMcahEcFMf/SMGPtGmhpp5BBCO1JODKT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BDRov/dJMcahEcFMf/SMGPtGmhpp5BBCO1JODKT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BDRov/dJMcahEcFMf/SMGPtGmhpp5BBCO1JODKT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBDRov%2FdJMcahEcFMf%2FSMGPtGmhpp5BBCO1JODKT0%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;1081&quot; height=&quot;1350&quot; data-filename=&quot;08-case-enterprise.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;09-result-impact.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xkFoa/dJMcaa6bEcS/Gi9Qn8fJTz8UZuj92MSKk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xkFoa/dJMcaa6bEcS/Gi9Qn8fJTz8UZuj92MSKk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xkFoa/dJMcaa6bEcS/Gi9Qn8fJTz8UZuj92MSKk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxkFoa%2FdJMcaa6bEcS%2FGi9Qn8fJTz8UZuj92MSKk1%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;1081&quot; height=&quot;1350&quot; data-filename=&quot;09-result-impact.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;10-cta.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WeyFx/dJMcadIyeXN/p6kjhoPrQhedcaQ3HbFPD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WeyFx/dJMcadIyeXN/p6kjhoPrQhedcaQ3HbFPD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WeyFx/dJMcadIyeXN/p6kjhoPrQhedcaQ3HbFPD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWeyFx%2FdJMcadIyeXN%2Fp6kjhoPrQhedcaQ3HbFPD1%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;1081&quot; height=&quot;1350&quot; data-filename=&quot;10-cta.png&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;1350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>AI AX</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/747</guid>
      <comments>https://series.tistory.com/entry/AX-%EC%A0%84%EC%97%90-DX-%EB%8D%B0%EC%9D%B4%ED%84%B0%EA%B0%80-%ED%9D%90%EB%A5%B4%EB%8A%94-%EC%9D%B8%ED%94%84%EB%9D%BC%EA%B0%80-%EB%A8%BC%EC%A0%80%EB%8B%A4#entry747comment</comments>
      <pubDate>Tue, 28 Apr 2026 16:31:19 +0900</pubDate>
    </item>
    <item>
      <title>AX(AI Transformation) 진단 프로그램 v1을 만들었습니다.</title>
      <link>https://series.tistory.com/entry/AXAI-Transformation-%EC%A7%84%EB%8B%A8-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-v1%EC%9D%84-%EB%A7%8C%EB%93%A4%EC%97%88%EC%8A%B5%EB%8B%88%EB%8B%A4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;AX 상태를 진단할 수 있는 간단하지만 핵심적인 내용으로 구성했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 계속 업데이트할 예정입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ax-doctor.vercel.app/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ax-doctor.vercel.app/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1777252192024&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;AX Doctor &amp;mdash; AI Transformation 진단&quot; data-og-description=&quot;AX(AI Transformation) 성숙도를5분 만에 진단하세요 Gartner&amp;middot;Cisco&amp;middot;Microsoft AI Readiness 프레임워크 기반 30문항 설문으로 6개 핵심 Dimension의 현 수준과 우선 개선 방향을 즉시 확인합니다. 무료 진단 시작하&quot; data-og-host=&quot;ax-doctor.vercel.app&quot; data-og-source-url=&quot;https://ax-doctor.vercel.app/&quot; data-og-url=&quot;https://ax-doctor.vercel.app/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://ax-doctor.vercel.app/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ax-doctor.vercel.app/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;AX Doctor &amp;mdash; AI Transformation 진단&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;AX(AI Transformation) 성숙도를5분 만에 진단하세요 Gartner&amp;middot;Cisco&amp;middot;Microsoft AI Readiness 프레임워크 기반 30문항 설문으로 6개 핵심 Dimension의 현 수준과 우선 개선 방향을 즉시 확인합니다. 무료 진단 시작하&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ax-doctor.vercel.app&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;930&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KwprJ/dJMcafzDNp5/Ams2OxHjhcgvFF7421x9gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KwprJ/dJMcafzDNp5/Ams2OxHjhcgvFF7421x9gk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KwprJ/dJMcafzDNp5/Ams2OxHjhcgvFF7421x9gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKwprJ%2FdJMcafzDNp5%2FAms2OxHjhcgvFF7421x9gk%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;865&quot; height=&quot;930&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;930&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;752&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7qt6a/dJMcajopxkq/UC3sN9ww2fMARdbVECUgt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7qt6a/dJMcajopxkq/UC3sN9ww2fMARdbVECUgt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7qt6a/dJMcajopxkq/UC3sN9ww2fMARdbVECUgt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7qt6a%2FdJMcajopxkq%2FUC3sN9ww2fMARdbVECUgt0%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;752&quot; height=&quot;483&quot; data-origin-width=&quot;752&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;713&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btFEV2/dJMcafGpcyM/k5ilMltX4kriGPuK4gEau1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btFEV2/dJMcafGpcyM/k5ilMltX4kriGPuK4gEau1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btFEV2/dJMcafGpcyM/k5ilMltX4kriGPuK4gEau1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtFEV2%2FdJMcafGpcyM%2Fk5ilMltX4kriGPuK4gEau1%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;713&quot; height=&quot;432&quot; data-origin-width=&quot;713&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>AI AX</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/746</guid>
      <comments>https://series.tistory.com/entry/AXAI-Transformation-%EC%A7%84%EB%8B%A8-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-v1%EC%9D%84-%EB%A7%8C%EB%93%A4%EC%97%88%EC%8A%B5%EB%8B%88%EB%8B%A4#entry746comment</comments>
      <pubDate>Mon, 27 Apr 2026 10:10:57 +0900</pubDate>
    </item>
    <item>
      <title>AX의 성공은 기술이 아니라 '조직'이 결정한다</title>
      <link>https://series.tistory.com/entry/AX%EC%9D%98-%EC%84%B1%EA%B3%B5%EC%9D%80-%EA%B8%B0%EC%88%A0%EC%9D%B4-%EC%95%84%EB%8B%88%EB%9D%BC-%EC%A1%B0%EC%A7%81%EC%9D%B4-%EA%B2%B0%EC%A0%95%ED%95%9C%EB%8B%A4</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01-cover.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BfTgl/dJMcagrKZ71/1zB1bSiToKAgVWUAiFuVt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BfTgl/dJMcagrKZ71/1zB1bSiToKAgVWUAiFuVt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BfTgl/dJMcagrKZ71/1zB1bSiToKAgVWUAiFuVt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBfTgl%2FdJMcagrKZ71%2F1zB1bSiToKAgVWUAiFuVt1%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;01-cover.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&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;AI&amp;nbsp;접근성은&amp;nbsp;+50%&amp;nbsp;늘었지만,&amp;nbsp;정작&amp;nbsp;줄어든&amp;nbsp;것은&amp;nbsp;&quot;사람이&amp;nbsp;직접&amp;nbsp;숙고하는&amp;nbsp;시간&quot;이다.&amp;nbsp;AX의&amp;nbsp;성공은&amp;nbsp;더&amp;nbsp;좋은&amp;nbsp;모델이&amp;nbsp;아니라&amp;nbsp;책임&amp;nbsp;있는&amp;nbsp;의사결정&amp;nbsp;구조와&amp;nbsp;실습&amp;middot;공유&amp;nbsp;기반의&amp;nbsp;문화가&amp;nbsp;결정한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;왜&amp;nbsp;AI가&amp;nbsp;늘어도&amp;nbsp;AX는&amp;nbsp;어려운가&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국 딜로이트 그룹의 '기업의 AI 활용현황 2026 보고서'에 따르면 직원 AI 접근성은 50% 확대됐다. 회의록은 수 분 만에 요약되고, 보고서 초안도 즉시 나온다. 문제는 그 다음이다. 그럴듯한 결과물에 익숙해질수록 검증과 숙고가 뒤로 밀리고, 그렇게 굳어진 프로세스가 표준이 되어버리면 조직은 매일 틀린 줄도 모르는 답을 결재하게 된다.&lt;br /&gt;&lt;br /&gt;LLM의&amp;nbsp;한계도&amp;nbsp;같은&amp;nbsp;위험을&amp;nbsp;키운다.&amp;nbsp;연구논문&amp;nbsp;Artificial&amp;nbsp;Hivemind는&amp;nbsp;유사한&amp;nbsp;출력에&amp;nbsp;반복&amp;nbsp;노출될&amp;nbsp;경우&amp;nbsp;사고&amp;nbsp;자체가&amp;nbsp;동질화될&amp;nbsp;수&amp;nbsp;있다고&amp;nbsp;경고한다.&amp;nbsp;마이크로소프트&amp;nbsp;리서치(2025)도&amp;nbsp;자동화의&amp;nbsp;역설을&amp;nbsp;인용하며&amp;nbsp;&quot;책임&amp;nbsp;설계가&amp;nbsp;없으면&amp;nbsp;조직은&amp;nbsp;결국&amp;nbsp;통제&amp;nbsp;강화로&amp;nbsp;회귀한다&quot;고&amp;nbsp;짚었다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;처방 1. 책임 있는 의사결정 조직 재설계&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리더의&amp;nbsp;일은&amp;nbsp;AI&amp;nbsp;답변을&amp;nbsp;받아쓰는&amp;nbsp;게&amp;nbsp;아니라&amp;nbsp;더&amp;nbsp;잘&amp;nbsp;판단하기&amp;nbsp;위해&amp;nbsp;깊이&amp;nbsp;숙고하는&amp;nbsp;일이다.&amp;nbsp;정답이&amp;nbsp;없는&amp;nbsp;기획&amp;middot;전략에서는&amp;nbsp;&quot;결정을&amp;nbsp;검증하는&amp;nbsp;과정&quot;&amp;nbsp;자체가&amp;nbsp;경쟁력이다.&amp;nbsp;핵심은&amp;nbsp;'AI&amp;nbsp;네이티브화'&amp;nbsp;&amp;mdash;&amp;nbsp;AI를&amp;nbsp;전제로&amp;nbsp;업무를&amp;nbsp;설계하되,&amp;nbsp;그&amp;nbsp;안에서&amp;nbsp;사람이&amp;nbsp;해야&amp;nbsp;할&amp;nbsp;의사결정&amp;nbsp;영역을&amp;nbsp;분명히&amp;nbsp;구분하고&amp;nbsp;표준화된&amp;nbsp;검증&amp;middot;책임&amp;nbsp;구조를&amp;nbsp;함께&amp;nbsp;운영하는&amp;nbsp;것이다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;처방 2. 문화 확산 &amp;mdash; 퍼널 4단계&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AX의&amp;nbsp;본질은&amp;nbsp;기술이&amp;nbsp;아니라&amp;nbsp;문화다.&amp;nbsp;강의&amp;nbsp;한&amp;nbsp;번으로는&amp;nbsp;정착하지&amp;nbsp;않는다.&amp;nbsp;마케팅의&amp;nbsp;퍼널&amp;nbsp;효과를&amp;nbsp;그대로&amp;nbsp;적용할&amp;nbsp;수&amp;nbsp;있다.&lt;br /&gt;&lt;br /&gt;인지&amp;nbsp;&amp;mdash;&amp;nbsp;AI&amp;nbsp;사용&amp;nbsp;불안을&amp;nbsp;줄이고&amp;nbsp;&quot;이렇게&amp;nbsp;쓰면&amp;nbsp;된다&quot;는&amp;nbsp;예시를&amp;nbsp;공유한다.&lt;br /&gt;참여&amp;nbsp;&amp;mdash;&amp;nbsp;AI&amp;nbsp;CoE(Center&amp;nbsp;of&amp;nbsp;Excellence)가&amp;nbsp;실무&amp;nbsp;문서를&amp;nbsp;함께&amp;nbsp;다듬어&amp;nbsp;주는&amp;nbsp;마중물이&amp;nbsp;된다.&lt;br /&gt;적용&amp;nbsp;&amp;mdash;&amp;nbsp;개선된&amp;nbsp;표준&amp;nbsp;프롬프트&amp;middot;템플릿으로&amp;nbsp;전사&amp;nbsp;품질을&amp;nbsp;상향&amp;nbsp;표준화한다.&lt;br /&gt;공유&amp;nbsp;&amp;mdash;&amp;nbsp;레시피&amp;nbsp;공유전&amp;middot;챌린지로&amp;nbsp;성공&amp;nbsp;경험의&amp;nbsp;장을&amp;nbsp;주기적으로&amp;nbsp;마련한다.&lt;br /&gt;페인&amp;nbsp;포인트가&amp;nbsp;발견되고&amp;nbsp;작은&amp;nbsp;성과가&amp;nbsp;쌓이면&amp;nbsp;신뢰가&amp;nbsp;만들어지고,&amp;nbsp;그&amp;nbsp;신뢰가&amp;nbsp;다음&amp;nbsp;확산의&amp;nbsp;연료가&amp;nbsp;된다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정부도&amp;nbsp;같은&amp;nbsp;방향이다&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행정안전부는&amp;nbsp;'AI&amp;nbsp;거점리더&amp;middot;챔피언'&amp;nbsp;인재&amp;nbsp;양성으로&amp;nbsp;현장&amp;nbsp;거점을&amp;nbsp;세우고&amp;nbsp;있다.&amp;nbsp;재정경제부는&amp;nbsp;89개&amp;nbsp;공공기관이&amp;nbsp;참여하는&amp;nbsp;분과별&amp;nbsp;AI&amp;nbsp;활용&amp;nbsp;협의체를&amp;nbsp;가동했다.&amp;nbsp;인공지능전략위원회는&amp;nbsp;행동계획(26~28)을&amp;nbsp;통해&amp;nbsp;부처별&amp;nbsp;이행&amp;nbsp;과제를&amp;nbsp;제시했다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;마무리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AX는 더 비싼 모델을 쓰는 일이 아니다. 사람이 결정해야 할 자리를 지키고, 그 결정을 검증할 수 있는 구조와 문화를 만드는 일이다. 검증 없이 표준이 된 프로세스가 우리 회의실에도 한두 개쯤 있다면, 지금이 시작할 가장 좋은 때다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02-summary.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y5UP2/dJMcagrKZ8b/QbWrKHVuAluSLYCZ2z8An1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y5UP2/dJMcagrKZ8b/QbWrKHVuAluSLYCZ2z8An1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y5UP2/dJMcagrKZ8b/QbWrKHVuAluSLYCZ2z8An1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy5UP2%2FdJMcagrKZ8b%2FQbWrKHVuAluSLYCZ2z8An1%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;02-summary.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03-quote.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZCniJ/dJMcacXbB4B/UmwLIMcgBTuvRJV7afGbX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZCniJ/dJMcacXbB4B/UmwLIMcgBTuvRJV7afGbX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZCniJ/dJMcacXbB4B/UmwLIMcgBTuvRJV7afGbX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZCniJ%2FdJMcacXbB4B%2FUmwLIMcgBTuvRJV7afGbX0%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;03-quote.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04-hivemind.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7Srzj/dJMcacJG79X/FvxL03g2jhLKpEVLwvKGo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7Srzj/dJMcacJG79X/FvxL03g2jhLKpEVLwvKGo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7Srzj/dJMcacJG79X/FvxL03g2jhLKpEVLwvKGo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7Srzj%2FdJMcacJG79X%2FFvxL03g2jhLKpEVLwvKGo0%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;04-hivemind.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05-automation-paradox.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJX3To/dJMcacJG79Y/k8d7Mok96AV0U34SHBgie1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJX3To/dJMcacJG79Y/k8d7Mok96AV0U34SHBgie1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJX3To/dJMcacJG79Y/k8d7Mok96AV0U34SHBgie1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJX3To%2FdJMcacJG79Y%2Fk8d7Mok96AV0U34SHBgie1%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;05-automation-paradox.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06-redesign.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cS4CgN/dJMcagrKZ8c/k3kZu6sIxUToub2wX88Hb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cS4CgN/dJMcagrKZ8c/k3kZu6sIxUToub2wX88Hb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cS4CgN/dJMcagrKZ8c/k3kZu6sIxUToub2wX88Hb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcS4CgN%2FdJMcagrKZ8c%2Fk3kZu6sIxUToub2wX88Hb0%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;06-redesign.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07-culture.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eClNYY/dJMcacJG79Z/yuVzXdOTT1rFKLyV813hVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eClNYY/dJMcacJG79Z/yuVzXdOTT1rFKLyV813hVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eClNYY/dJMcacJG79Z/yuVzXdOTT1rFKLyV813hVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeClNYY%2FdJMcacJG79Z%2FyuVzXdOTT1rFKLyV813hVK%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;07-culture.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08-funnel.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IiGBg/dJMcacXbB4C/uqU7uVclMkiaX3qYEnI7OK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IiGBg/dJMcacXbB4C/uqU7uVclMkiaX3qYEnI7OK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IiGBg/dJMcacXbB4C/uqU7uVclMkiaX3qYEnI7OK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIiGBg%2FdJMcacXbB4C%2FuqU7uVclMkiaX3qYEnI7OK%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;08-funnel.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;09-government.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MJ4CM/dJMcagkYZMM/3qf4hl325TfexM6TekV3M1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MJ4CM/dJMcagkYZMM/3qf4hl325TfexM6TekV3M1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MJ4CM/dJMcagkYZMM/3qf4hl325TfexM6TekV3M1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMJ4CM%2FdJMcagkYZMM%2F3qf4hl325TfexM6TekV3M1%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;09-government.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;10-cta.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mkNke/dJMcagkYZMN/XsbPcMKvtTWn9RMmvpAZcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mkNke/dJMcagkYZMN/XsbPcMKvtTWn9RMmvpAZcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mkNke/dJMcagkYZMN/XsbPcMKvtTWn9RMmvpAZcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmkNke%2FdJMcagkYZMN%2FXsbPcMKvtTWn9RMmvpAZcK%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;2160&quot; height=&quot;2700&quot; data-filename=&quot;10-cta.png&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;2700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI AX</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/745</guid>
      <comments>https://series.tistory.com/entry/AX%EC%9D%98-%EC%84%B1%EA%B3%B5%EC%9D%80-%EA%B8%B0%EC%88%A0%EC%9D%B4-%EC%95%84%EB%8B%88%EB%9D%BC-%EC%A1%B0%EC%A7%81%EC%9D%B4-%EA%B2%B0%EC%A0%95%ED%95%9C%EB%8B%A4#entry745comment</comments>
      <pubDate>Mon, 27 Apr 2026 10:03:02 +0900</pubDate>
    </item>
    <item>
      <title>AI 전환(AX)보다 DX(Digital Transformation)이 먼저다.</title>
      <link>https://series.tistory.com/entry/AI-%EC%A0%84%ED%99%98AX%EB%B3%B4%EB%8B%A4-DXDigital-Transformation%EC%9D%B4-%EB%A8%BC%EC%A0%80%EB%8B%A4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;AI&amp;nbsp;전환(AX)을&amp;nbsp;서두르는&amp;nbsp;조직이&amp;nbsp;늘어나고&amp;nbsp;있다.&amp;nbsp;하지만&amp;nbsp;현장에서&amp;nbsp;보면,&amp;nbsp;많은&amp;nbsp;팀이&amp;nbsp;&amp;lsquo;AI를&amp;nbsp;도입하면&amp;nbsp;뭔가&amp;nbsp;달라질&amp;nbsp;것&amp;rsquo;이라는&amp;nbsp;기대만으로&amp;nbsp;움직이고&amp;nbsp;있다.&amp;nbsp;문제는&amp;nbsp;AX가&amp;nbsp;독립적인&amp;nbsp;변화가&amp;nbsp;아니라,&amp;nbsp;기존&amp;nbsp;디지털&amp;nbsp;전환(DX)의&amp;nbsp;연장선이라는&amp;nbsp;점이다.&amp;nbsp;기반&amp;nbsp;없이&amp;nbsp;얹힌&amp;nbsp;AI는&amp;nbsp;생산성을&amp;nbsp;높이기보다&amp;nbsp;오히려&amp;nbsp;혼란을&amp;nbsp;키운다.&lt;br /&gt;&lt;br /&gt;AX를&amp;nbsp;시작하기&amp;nbsp;전에&amp;nbsp;반드시&amp;nbsp;점검해야&amp;nbsp;할&amp;nbsp;첫&amp;nbsp;번째는&amp;nbsp;데이터&amp;nbsp;파이프라인이다.&amp;nbsp;많은&amp;nbsp;조직이&amp;nbsp;데이터를&amp;nbsp;가지고&amp;nbsp;있다고&amp;nbsp;말하지만,&amp;nbsp;실제로는&amp;nbsp;활용&amp;nbsp;가능한&amp;nbsp;상태로&amp;nbsp;흐르고&amp;nbsp;있지&amp;nbsp;않은&amp;nbsp;경우가&amp;nbsp;많다.&amp;nbsp;데이터가&amp;nbsp;수집되고&amp;nbsp;저장되는&amp;nbsp;것과,&amp;nbsp;그것이&amp;nbsp;분석되고&amp;nbsp;의사결정에&amp;nbsp;쓰이는&amp;nbsp;것은&amp;nbsp;완전히&amp;nbsp;다른&amp;nbsp;이야기다.&amp;nbsp;AI는&amp;nbsp;결국&amp;nbsp;데이터를&amp;nbsp;입력으로&amp;nbsp;삼기&amp;nbsp;때문에,&amp;nbsp;이&amp;nbsp;흐름이&amp;nbsp;정리되어&amp;nbsp;있지&amp;nbsp;않다면&amp;nbsp;결과&amp;nbsp;역시&amp;nbsp;불안정할&amp;nbsp;수밖에&amp;nbsp;없다.&lt;br /&gt;&lt;br /&gt;두&amp;nbsp;번째는&amp;nbsp;반복&amp;nbsp;업무의&amp;nbsp;자동화&amp;nbsp;수준이다.&amp;nbsp;AX는&amp;nbsp;자동화를&amp;nbsp;대체하는&amp;nbsp;개념이&amp;nbsp;아니라,&amp;nbsp;자동화를&amp;nbsp;기반으로&amp;nbsp;고도화하는&amp;nbsp;단계다.&amp;nbsp;여전히&amp;nbsp;사람이&amp;nbsp;엑셀을&amp;nbsp;정리하고,&amp;nbsp;수작업으로&amp;nbsp;데이터를&amp;nbsp;옮기고,&amp;nbsp;반복적인&amp;nbsp;보고서를&amp;nbsp;작성하고&amp;nbsp;있다면,&amp;nbsp;그&amp;nbsp;위에&amp;nbsp;AI를&amp;nbsp;얹는&amp;nbsp;것은&amp;nbsp;비효율을&amp;nbsp;확장하는&amp;nbsp;것에&amp;nbsp;가깝다.&amp;nbsp;먼저&amp;nbsp;RPA,&amp;nbsp;스크립트,&amp;nbsp;API&amp;nbsp;연동&amp;nbsp;등을&amp;nbsp;통해&amp;nbsp;기본적인&amp;nbsp;자동화를&amp;nbsp;확보해야&amp;nbsp;한다.&amp;nbsp;그&amp;nbsp;다음에야&amp;nbsp;AI가&amp;nbsp;의미&amp;nbsp;있는&amp;nbsp;개선을&amp;nbsp;만들어낸다.&lt;br /&gt;&lt;br /&gt;세&amp;nbsp;번째는&amp;nbsp;팀의&amp;nbsp;디지털&amp;nbsp;리터러시다.&amp;nbsp;AI&amp;nbsp;도구를&amp;nbsp;사용할&amp;nbsp;줄&amp;nbsp;아는&amp;nbsp;것만으로는&amp;nbsp;부족하다.&amp;nbsp;중요한&amp;nbsp;것은&amp;nbsp;문제를&amp;nbsp;구조화하고,&amp;nbsp;AI가&amp;nbsp;낸&amp;nbsp;결과를&amp;nbsp;비판적으로&amp;nbsp;검토하며,&amp;nbsp;워크플로우에&amp;nbsp;맞게&amp;nbsp;재구성할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;능력이다.&amp;nbsp;이&amp;nbsp;역량이&amp;nbsp;없다면&amp;nbsp;AI는&amp;nbsp;&amp;lsquo;마법&amp;nbsp;같은&amp;nbsp;도구&amp;rsquo;가&amp;nbsp;아니라&amp;nbsp;&amp;lsquo;예측&amp;nbsp;불가능한&amp;nbsp;변수&amp;rsquo;가&amp;nbsp;된다.&lt;br /&gt;&lt;br /&gt;결국&amp;nbsp;AX는&amp;nbsp;기술&amp;nbsp;도입의&amp;nbsp;문제가&amp;nbsp;아니라,&amp;nbsp;준비&amp;nbsp;상태의&amp;nbsp;문제다.&amp;nbsp;많은&amp;nbsp;실패&amp;nbsp;사례는&amp;nbsp;AI&amp;nbsp;성능&amp;nbsp;때문이&amp;nbsp;아니라,&amp;nbsp;적용&amp;nbsp;대상이&amp;nbsp;되는&amp;nbsp;프로세스가&amp;nbsp;정리되어&amp;nbsp;있지&amp;nbsp;않았기&amp;nbsp;때문에&amp;nbsp;발생한다.&amp;nbsp;정리되지&amp;nbsp;않은&amp;nbsp;워크플로우&amp;nbsp;위에&amp;nbsp;AI를&amp;nbsp;얹으면,&amp;nbsp;기존의&amp;nbsp;비효율과&amp;nbsp;혼란이&amp;nbsp;그대로&amp;nbsp;증폭된다.&lt;br /&gt;&lt;br /&gt;그래서&amp;nbsp;AX는&amp;nbsp;DX를&amp;nbsp;건너뛰는&amp;nbsp;전략이&amp;nbsp;될&amp;nbsp;수&amp;nbsp;없다.&amp;nbsp;오히려&amp;nbsp;DX가&amp;nbsp;잘&amp;nbsp;되어&amp;nbsp;있는&amp;nbsp;조직일수록&amp;nbsp;AX의&amp;nbsp;효과를&amp;nbsp;빠르게&amp;nbsp;체감한다.&amp;nbsp;데이터가&amp;nbsp;흐르고,&amp;nbsp;자동화가&amp;nbsp;자리&amp;nbsp;잡고,&amp;nbsp;팀이&amp;nbsp;디지털&amp;nbsp;방식으로&amp;nbsp;사고할&amp;nbsp;수&amp;nbsp;있을&amp;nbsp;때,&amp;nbsp;AI는&amp;nbsp;비로소&amp;nbsp;&amp;lsquo;레버리지&amp;rsquo;로&amp;nbsp;작동한다.&lt;br /&gt;&lt;br /&gt;정리하면,&amp;nbsp;AX의&amp;nbsp;본질은&amp;nbsp;&amp;lsquo;AI를&amp;nbsp;도입하는&amp;nbsp;것&amp;rsquo;이&amp;nbsp;아니라,&amp;nbsp;&amp;lsquo;AI가&amp;nbsp;제대로&amp;nbsp;작동할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;상태를&amp;nbsp;만드는&amp;nbsp;것&amp;rsquo;이다.&amp;nbsp;그리고&amp;nbsp;그&amp;nbsp;출발점은&amp;nbsp;언제나&amp;nbsp;DX다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>AI AX</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/744</guid>
      <comments>https://series.tistory.com/entry/AI-%EC%A0%84%ED%99%98AX%EB%B3%B4%EB%8B%A4-DXDigital-Transformation%EC%9D%B4-%EB%A8%BC%EC%A0%80%EB%8B%A4#entry744comment</comments>
      <pubDate>Thu, 23 Apr 2026 10:27:31 +0900</pubDate>
    </item>
    <item>
      <title>AX 실패의 역설: 왜 당신의 자동화 프로젝트는 '유령 시스템'이 되는가?</title>
      <link>https://series.tistory.com/entry/AX-%EC%8B%A4%ED%8C%A8%EC%9D%98-%EC%97%AD%EC%84%A4-%EC%99%9C-%EB%8B%B9%EC%8B%A0%EC%9D%98-%EC%9E%90%EB%8F%99%ED%99%94-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EB%8A%94-%EC%9C%A0%EB%A0%B9-%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%9D%B4-%EB%90%98%EB%8A%94%EA%B0%80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;AX가 실패하는 이유: 기술이 아니라 접근 방식이다.&lt;br /&gt;많은&amp;nbsp;기업이&amp;nbsp;AX(업무&amp;nbsp;자동화)를&amp;nbsp;도입할&amp;nbsp;때&amp;nbsp;비슷한&amp;nbsp;패턴을&amp;nbsp;밟는다.&lt;br /&gt;&amp;ldquo;우리&amp;nbsp;업무를&amp;nbsp;분석해서&amp;nbsp;자동화&amp;nbsp;설계해보자.&amp;rdquo;&lt;br /&gt;그리고&amp;nbsp;몇&amp;nbsp;달&amp;nbsp;뒤,&amp;nbsp;결과는&amp;nbsp;뻔하다.&amp;nbsp;시스템은&amp;nbsp;남지만&amp;nbsp;현업은&amp;nbsp;쓰지&amp;nbsp;않는다.&lt;br /&gt;&lt;br /&gt;왜&amp;nbsp;이런&amp;nbsp;일이&amp;nbsp;반복될까?&lt;br /&gt;핵심은&amp;nbsp;AX&amp;nbsp;대상&amp;nbsp;업무가&amp;nbsp;&amp;lsquo;고약한&amp;nbsp;문제&amp;rsquo;라는&amp;nbsp;데&amp;nbsp;있다.&lt;br /&gt;해보기&amp;nbsp;전까지는&amp;nbsp;진짜&amp;nbsp;병목이&amp;nbsp;어디인지&amp;nbsp;알&amp;nbsp;수&amp;nbsp;없다.&lt;br /&gt;사람의&amp;nbsp;습관,&amp;nbsp;예외&amp;nbsp;케이스,&amp;nbsp;책임&amp;nbsp;구조가&amp;nbsp;계속&amp;nbsp;튀어나오며&amp;nbsp;계획을&amp;nbsp;흔든다.&lt;br /&gt;&lt;br /&gt;그런데&amp;nbsp;많은&amp;nbsp;기업은&amp;nbsp;폭포수&amp;nbsp;방식으로&amp;nbsp;접근한다.&lt;br /&gt;즉,&amp;nbsp;&amp;ldquo;처음에&amp;nbsp;모든&amp;nbsp;걸&amp;nbsp;정의할&amp;nbsp;수&amp;nbsp;있다&amp;rdquo;는&amp;nbsp;가정&amp;nbsp;위에서&amp;nbsp;출발한다.&lt;br /&gt;이&amp;nbsp;방식은&amp;nbsp;완성도를&amp;nbsp;높이는&amp;nbsp;데는&amp;nbsp;적합하지만,&lt;br /&gt;예측&amp;nbsp;불가능성이&amp;nbsp;큰&amp;nbsp;AX에는&amp;nbsp;맞지&amp;nbsp;않는다.&lt;br /&gt;그래서&amp;nbsp;실패한다.&lt;br /&gt;&lt;br /&gt;AX의&amp;nbsp;올바른&amp;nbsp;접근:&amp;nbsp;작은&amp;nbsp;자동화에서&amp;nbsp;시작하기&lt;br /&gt;AX는&amp;nbsp;거대한&amp;nbsp;설계가&amp;nbsp;아니라&amp;nbsp;작은&amp;nbsp;시도에서&amp;nbsp;출발해야&amp;nbsp;한다.&lt;br /&gt;&lt;br /&gt;1. 작은 자동화를 실제 업무에 붙인다.&lt;br /&gt;2. 현업의 반응을 관찰한다.&lt;br /&gt;3. 문제를 다시 정의한다.&lt;br /&gt;4. 반복한다.&lt;br /&gt;&lt;br /&gt;이&amp;nbsp;과정을&amp;nbsp;통해&amp;nbsp;조직은&amp;nbsp;단순히&amp;nbsp;자동화를&amp;nbsp;구축하는&amp;nbsp;것이&amp;nbsp;아니라,&lt;br /&gt;문제를&amp;nbsp;정의하는&amp;nbsp;속도를&amp;nbsp;높인다.&lt;br /&gt;자동화는&amp;nbsp;결과물이&amp;nbsp;아니라&amp;nbsp;학습을&amp;nbsp;위한&amp;nbsp;도구가&amp;nbsp;된다.&lt;br /&gt;&lt;br /&gt;폭포수&amp;nbsp;vs&amp;nbsp;AX:&amp;nbsp;완성도&amp;nbsp;vs&amp;nbsp;학습&amp;nbsp;속도&lt;br /&gt;폭포수&amp;nbsp;방식은&amp;nbsp;완성도를&amp;nbsp;올리는&amp;nbsp;구조다.&lt;br /&gt;&lt;br /&gt;AX는&amp;nbsp;학습&amp;nbsp;속도를&amp;nbsp;올리는&amp;nbsp;게임이다.&lt;br /&gt;&lt;br /&gt;즉,&amp;nbsp;AX의&amp;nbsp;성공은&amp;nbsp;기술적&amp;nbsp;완성도가&amp;nbsp;아니라&lt;br /&gt;얼마나&amp;nbsp;빠르게&amp;nbsp;문제를&amp;nbsp;재정의하고&amp;nbsp;개선할&amp;nbsp;수&amp;nbsp;있는지에&amp;nbsp;달려&amp;nbsp;있다.&lt;br /&gt;&lt;br /&gt;결론&lt;br /&gt;AX는&amp;nbsp;단순히&amp;nbsp;&amp;ldquo;업무를&amp;nbsp;자동화한다&amp;rdquo;는&amp;nbsp;프로젝트가&amp;nbsp;아니다.&lt;br /&gt;조직이&amp;nbsp;문제를&amp;nbsp;정의하고&amp;nbsp;학습하는&amp;nbsp;능력을&amp;nbsp;키우는&amp;nbsp;과정이다.&lt;br /&gt;작은&amp;nbsp;자동화부터&amp;nbsp;시작해,&amp;nbsp;현업과&amp;nbsp;함께&amp;nbsp;배우고,&lt;br /&gt;반복하며&amp;nbsp;점차&amp;nbsp;확장하는&amp;nbsp;접근만이&amp;nbsp;AX를&amp;nbsp;성공으로&amp;nbsp;이끈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI AX</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/743</guid>
      <comments>https://series.tistory.com/entry/AX-%EC%8B%A4%ED%8C%A8%EC%9D%98-%EC%97%AD%EC%84%A4-%EC%99%9C-%EB%8B%B9%EC%8B%A0%EC%9D%98-%EC%9E%90%EB%8F%99%ED%99%94-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EB%8A%94-%EC%9C%A0%EB%A0%B9-%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%9D%B4-%EB%90%98%EB%8A%94%EA%B0%80#entry743comment</comments>
      <pubDate>Thu, 23 Apr 2026 09:58:05 +0900</pubDate>
    </item>
    <item>
      <title>AX(AI Transformation) - 기획서부터 백엔드, 프론트엔드, 배포까지, AI가 바꾼 개발 파이프라인 이야기</title>
      <link>https://series.tistory.com/entry/AXAI-Transformation-%EA%B8%B0%ED%9A%8D%EC%84%9C%EB%B6%80%ED%84%B0-%EB%B0%B1%EC%97%94%EB%93%9C-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%B0%B0%ED%8F%AC%EA%B9%8C%EC%A7%80-AI%EA%B0%80-%EB%B0%94%EA%BE%BC-%EA%B0%9C%EB%B0%9C-%ED%8C%8C%EC%9D%B4%ED%94%84%EB%9D%BC%EC%9D%B8-%EC%9D%B4%EC%95%BC%EA%B8%B0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;AX(AI&amp;nbsp;Transformation)&amp;nbsp;-&amp;nbsp;기획서부터&amp;nbsp;백엔드,&amp;nbsp;프론트엔드,&amp;nbsp;배포까지,&amp;nbsp;AI가&amp;nbsp;바꾼&amp;nbsp;개발&amp;nbsp;파이프라인&amp;nbsp;이야기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;얼마&amp;nbsp;전까지만&amp;nbsp;해도&amp;nbsp;&quot;AI&amp;nbsp;잘&amp;nbsp;쓰는&amp;nbsp;개발자&quot;의&amp;nbsp;기준은&amp;nbsp;코드&amp;nbsp;자동완성을&amp;nbsp;얼마나&amp;nbsp;잘&amp;nbsp;활용하느냐였습니다.&amp;nbsp;커서(Cursor)를&amp;nbsp;쓰냐,&amp;nbsp;Claude&amp;nbsp;Code를&amp;nbsp;쓰냐.&amp;nbsp;그게&amp;nbsp;전부인&amp;nbsp;줄&amp;nbsp;알았어요.&lt;br /&gt;&lt;br /&gt;그런데&amp;nbsp;어느&amp;nbsp;순간부터&amp;nbsp;그&amp;nbsp;질문이&amp;nbsp;달라지기&amp;nbsp;시작했습니다.&amp;nbsp;&quot;어떤&amp;nbsp;AI&amp;nbsp;에디터를&amp;nbsp;쓰냐&quot;가&amp;nbsp;아니라,&amp;nbsp;&quot;어떤&amp;nbsp;파이프라인으로&amp;nbsp;개발하느냐&quot;로.&amp;nbsp;그&amp;nbsp;변화를&amp;nbsp;직접&amp;nbsp;겪으면서,&amp;nbsp;저는&amp;nbsp;꽤&amp;nbsp;많은&amp;nbsp;것을&amp;nbsp;다시&amp;nbsp;생각하게&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;AI 에디터를 넘어 파이프라인으로: 파도의 방향이 바뀌었다.&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년에 DX(디지털 전환)가 있었다면, 2025년엔 AX(AI 전환)가 왔습니다. 이름만 바뀐 게 아닙니다. 결이 다릅니다.&lt;br /&gt;&lt;br /&gt;DX는&amp;nbsp;오프라인에&amp;nbsp;있던&amp;nbsp;것을&amp;nbsp;온라인으로&amp;nbsp;옮기는&amp;nbsp;작업이었습니다.&amp;nbsp;예약&amp;nbsp;시스템을&amp;nbsp;만들고,&amp;nbsp;재고&amp;nbsp;관리를&amp;nbsp;엑셀에서&amp;nbsp;SaaS로&amp;nbsp;이전하고.&amp;nbsp;비교적&amp;nbsp;명확한&amp;nbsp;목적지가&amp;nbsp;있었죠.&lt;br /&gt;&lt;br /&gt;AX는&amp;nbsp;좀&amp;nbsp;다릅니다.&amp;nbsp;&quot;AI로&amp;nbsp;뭘&amp;nbsp;해야&amp;nbsp;하지?&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;PR&amp;nbsp;요약.&lt;br /&gt;&lt;br /&gt;나쁜&amp;nbsp;선택은&amp;nbsp;아닙니다.&amp;nbsp;그런데&amp;nbsp;거기서&amp;nbsp;멈추는&amp;nbsp;팀과,&amp;nbsp;그다음을&amp;nbsp;보는&amp;nbsp;팀&amp;nbsp;사이에&amp;nbsp;이미&amp;nbsp;격차가&amp;nbsp;생기고&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;1세대&amp;nbsp;AI&amp;nbsp;도입이&amp;nbsp;&quot;AI로&amp;nbsp;코드를&amp;nbsp;빠르게&amp;nbsp;짜는&amp;nbsp;것&quot;이었다면,&amp;nbsp;2세대는&amp;nbsp;다릅니다.&amp;nbsp;기획서부터&amp;nbsp;배포까지,&amp;nbsp;산출물&amp;nbsp;전&amp;nbsp;공정에&amp;nbsp;AI가&amp;nbsp;읽고&amp;nbsp;쓸&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;언어를&amp;nbsp;심는&amp;nbsp;것.&amp;nbsp;그게&amp;nbsp;지금&amp;nbsp;제가&amp;nbsp;생각하는&amp;nbsp;진짜&amp;nbsp;AX입니다.&lt;br /&gt;&lt;br /&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;직접&amp;nbsp;겪어본&amp;nbsp;이야기:&amp;nbsp;내가&amp;nbsp;파이프라인을&amp;nbsp;만들게&amp;nbsp;된&amp;nbsp;이유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;처음엔&amp;nbsp;솔직히&amp;nbsp;불편했습니다.&amp;nbsp;내가&amp;nbsp;짜야&amp;nbsp;할&amp;nbsp;코드를&amp;nbsp;AI가&amp;nbsp;대신&amp;nbsp;쓴다는&amp;nbsp;게&amp;nbsp;왠지&amp;nbsp;어색했거든요.&lt;br /&gt;&lt;br /&gt;그런데&amp;nbsp;방향을&amp;nbsp;바꾸니&amp;nbsp;달라졌습니다.&amp;nbsp;AI에게&amp;nbsp;코드를&amp;nbsp;맡기는&amp;nbsp;게&amp;nbsp;아니라,&amp;nbsp;AI가&amp;nbsp;일할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;환경을&amp;nbsp;설계하는&amp;nbsp;것이&amp;nbsp;제&amp;nbsp;일이&amp;nbsp;됐습니다.&lt;br /&gt;&lt;br /&gt;그&amp;nbsp;과정에서&amp;nbsp;겪은&amp;nbsp;일들이&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;첫&amp;nbsp;번째.&amp;nbsp;저는&amp;nbsp;Claude&amp;nbsp;Code&amp;nbsp;환경에&amp;nbsp;훅(hook),&amp;nbsp;스킬(skill),&amp;nbsp;에이전트&amp;nbsp;계층을&amp;nbsp;직접&amp;nbsp;만들어&amp;nbsp;쌓았습니다.&amp;nbsp;처음엔&amp;nbsp;&quot;이게&amp;nbsp;AI&amp;nbsp;생산성이랑&amp;nbsp;무슨&amp;nbsp;관계가&amp;nbsp;있나?&quot;&amp;nbsp;싶었어요.&amp;nbsp;그런데&amp;nbsp;써보니&amp;nbsp;알겠더라고요.&amp;nbsp;AI가&amp;nbsp;실수를&amp;nbsp;덜&amp;nbsp;하는&amp;nbsp;환경이&amp;nbsp;결국&amp;nbsp;생산성의&amp;nbsp;본체였습니다.&amp;nbsp;AI&amp;nbsp;자체보다&amp;nbsp;AI를&amp;nbsp;둘러싼&amp;nbsp;구조가&amp;nbsp;더&amp;nbsp;중요했습니다.&lt;br /&gt;&lt;br /&gt;두&amp;nbsp;번째.&amp;nbsp;Figma에서&amp;nbsp;컴포넌트를&amp;nbsp;코드로&amp;nbsp;자동&amp;nbsp;변환하는&amp;nbsp;걸&amp;nbsp;해봤습니다.&amp;nbsp;처음엔&amp;nbsp;기대가&amp;nbsp;컸습니다.&amp;nbsp;그런데&amp;nbsp;디자인&amp;nbsp;토큰이&amp;nbsp;정리&amp;nbsp;안&amp;nbsp;된&amp;nbsp;상태에서&amp;nbsp;돌리니&amp;nbsp;쓸&amp;nbsp;수&amp;nbsp;없는&amp;nbsp;코드가&amp;nbsp;나왔어요.&amp;nbsp;AI가&amp;nbsp;나쁜&amp;nbsp;게&amp;nbsp;아니었습니다.&amp;nbsp;제가&amp;nbsp;AI에게&amp;nbsp;줄&amp;nbsp;재료를&amp;nbsp;준비&amp;nbsp;안&amp;nbsp;한&amp;nbsp;거였습니다.&lt;br /&gt;&lt;br /&gt;세&amp;nbsp;번째.&amp;nbsp;Vercel에&amp;nbsp;환경변수를&amp;nbsp;설정하다가&amp;nbsp;런타임에서만&amp;nbsp;인증이&amp;nbsp;실패하는&amp;nbsp;이슈를&amp;nbsp;겪었습니다.&amp;nbsp;원인은&amp;nbsp;$&amp;nbsp;문자가&amp;nbsp;포함된&amp;nbsp;값을&amp;nbsp;대시보드에&amp;nbsp;넣을&amp;nbsp;때&amp;nbsp;\$로&amp;nbsp;이스케이프된&amp;nbsp;채&amp;nbsp;저장된&amp;nbsp;것이었습니다.&amp;nbsp;AI가&amp;nbsp;검토한&amp;nbsp;코드에는&amp;nbsp;문제가&amp;nbsp;없었습니다.&amp;nbsp;우리가&amp;nbsp;AI에게&amp;nbsp;준&amp;nbsp;컨텍스트에&amp;nbsp;구멍이&amp;nbsp;있었던&amp;nbsp;겁니다.&lt;br /&gt;&lt;br /&gt;세&amp;nbsp;가지&amp;nbsp;사례에서&amp;nbsp;공통점이&amp;nbsp;보였습니다.&amp;nbsp;문제는&amp;nbsp;항상&amp;nbsp;AI&amp;nbsp;이전&amp;nbsp;단계에&amp;nbsp;있었습니다.&amp;nbsp;AI에게&amp;nbsp;무엇을&amp;nbsp;어떻게&amp;nbsp;줄&amp;nbsp;것인가,&amp;nbsp;그&amp;nbsp;준비가&amp;nbsp;개발&amp;nbsp;생산성의&amp;nbsp;진짜&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;왜 PRD부터 시작해야 하는가: 스펙 없이 시작한 코드는 결국 다시 짠다.&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;AI&amp;nbsp;에이전트에게&amp;nbsp;&quot;API&amp;nbsp;만들어줘&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;mdash;&amp;nbsp;그&amp;nbsp;맥락이&amp;nbsp;없으면&amp;nbsp;AI는&amp;nbsp;그냥&amp;nbsp;그럴듯한&amp;nbsp;코드를&amp;nbsp;만들&amp;nbsp;뿐입니다.&lt;br /&gt;&lt;br /&gt;문제는&amp;nbsp;요청&amp;nbsp;방식이&amp;nbsp;아닙니다.&amp;nbsp;입력&amp;nbsp;자체입니다.&lt;br /&gt;&lt;br /&gt;현업에서&amp;nbsp;쓰는&amp;nbsp;PRD(Product&amp;nbsp;Requirements&amp;nbsp;Document,&amp;nbsp;제품&amp;nbsp;요구사항&amp;nbsp;문서)의&amp;nbsp;문제가&amp;nbsp;여기&amp;nbsp;있습니다.&amp;nbsp;대부분의&amp;nbsp;PRD는&amp;nbsp;사람이&amp;nbsp;읽기&amp;nbsp;위해&amp;nbsp;씁니다.&amp;nbsp;&quot;사용자가&amp;nbsp;로그인&amp;nbsp;버튼을&amp;nbsp;누르면&amp;nbsp;인증&amp;nbsp;프로세스가&amp;nbsp;시작된다.&quot;&amp;nbsp;이&amp;nbsp;문장은&amp;nbsp;사람에게는&amp;nbsp;자연스럽지만&amp;nbsp;AI에게는&amp;nbsp;모호합니다.&amp;nbsp;어떤&amp;nbsp;인증&amp;nbsp;방식인지,&amp;nbsp;실패&amp;nbsp;시&amp;nbsp;어떻게&amp;nbsp;처리하는지,&amp;nbsp;어떤&amp;nbsp;상태를&amp;nbsp;반환해야&amp;nbsp;하는지가&amp;nbsp;없습니다.&lt;br /&gt;&lt;br /&gt;그래서&amp;nbsp;PRD를&amp;nbsp;다시&amp;nbsp;써야&amp;nbsp;합니다.&amp;nbsp;명시적&amp;nbsp;제약,&amp;nbsp;수용&amp;nbsp;기준(acceptance&amp;nbsp;criteria),&amp;nbsp;데이터&amp;nbsp;계약이&amp;nbsp;담긴&amp;nbsp;AI가&amp;nbsp;읽을&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;문서로.&amp;nbsp;그게&amp;nbsp;파이프라인의&amp;nbsp;진짜&amp;nbsp;출발점입니다.&lt;br /&gt;&lt;br /&gt;요즘은&amp;nbsp;이걸&amp;nbsp;**컨텍스트&amp;nbsp;엔지니어링(Context&amp;nbsp;Engineering)**이라고&amp;nbsp;부릅니다.&amp;nbsp;AI에게&amp;nbsp;무엇을&amp;nbsp;어떤&amp;nbsp;형식으로&amp;nbsp;줄&amp;nbsp;것인가를&amp;nbsp;설계하는&amp;nbsp;일&amp;nbsp;자체가&amp;nbsp;하나의&amp;nbsp;전문&amp;nbsp;영역이&amp;nbsp;된&amp;nbsp;겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;1167&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cg4XHT/dJMcadhrAav/KJEy6QjMVD5UnGL0HKGZv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cg4XHT/dJMcadhrAav/KJEy6QjMVD5UnGL0HKGZv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cg4XHT/dJMcadhrAav/KJEy6QjMVD5UnGL0HKGZv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcg4XHT%2FdJMcadhrAav%2FKJEy6QjMVD5UnGL0HKGZv0%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;710&quot; height=&quot;1167&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;1167&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;파이프라인&amp;nbsp;5단계:&amp;nbsp;기획에서&amp;nbsp;배포까지&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;개발&amp;nbsp;파이프라인에는&amp;nbsp;순서가&amp;nbsp;있습니다.&amp;nbsp;상류가&amp;nbsp;제대로&amp;nbsp;정의되어야&amp;nbsp;하류가&amp;nbsp;흔들리지&amp;nbsp;않습니다.&amp;nbsp;AI를&amp;nbsp;쓸수록&amp;nbsp;이&amp;nbsp;원칙이&amp;nbsp;더&amp;nbsp;선명해집니다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1단계&amp;nbsp;&amp;mdash;&amp;nbsp;PRD&amp;nbsp;표준화&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;PRD를&amp;nbsp;AI가&amp;nbsp;읽을&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;형식으로&amp;nbsp;바꾸는&amp;nbsp;데서&amp;nbsp;시작합니다.&amp;nbsp;YAML&amp;nbsp;프론트매터에&amp;nbsp;기능&amp;nbsp;ID,&amp;nbsp;수용&amp;nbsp;기준,&amp;nbsp;의존성,&amp;nbsp;데이터&amp;nbsp;타입을&amp;nbsp;명시합니다.&amp;nbsp;&quot;사용자가&amp;nbsp;가입할&amp;nbsp;수&amp;nbsp;있다&quot;가&amp;nbsp;아니라,&amp;nbsp;&quot;이메일&amp;nbsp;+&amp;nbsp;비밀번호를&amp;nbsp;받아&amp;nbsp;users&amp;nbsp;테이블에&amp;nbsp;INSERT하고,&amp;nbsp;중복&amp;nbsp;시&amp;nbsp;409를&amp;nbsp;반환한다&quot;로&amp;nbsp;씁니다.&amp;nbsp;처음엔&amp;nbsp;귀찮습니다.&amp;nbsp;그런데&amp;nbsp;이게&amp;nbsp;이후&amp;nbsp;모든&amp;nbsp;단계의&amp;nbsp;재료가&amp;nbsp;됩니다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2단계&amp;nbsp;&amp;mdash;&amp;nbsp;디자인&amp;nbsp;시스템&amp;nbsp;토큰화&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Figma&amp;nbsp;Variables를&amp;nbsp;JSON&amp;nbsp;토큰으로&amp;nbsp;추출하고,&amp;nbsp;그것이&amp;nbsp;Tailwind&amp;nbsp;설정이나&amp;nbsp;CSS&amp;nbsp;변수로&amp;nbsp;자동&amp;nbsp;연동되게&amp;nbsp;합니다.&amp;nbsp;디자이너가&amp;nbsp;브랜드&amp;nbsp;컬러를&amp;nbsp;바꾸면&amp;nbsp;코드가&amp;nbsp;따라&amp;nbsp;움직이는&amp;nbsp;구조.&amp;nbsp;이게&amp;nbsp;되어&amp;nbsp;있지&amp;nbsp;않으면,&amp;nbsp;컴포넌트를&amp;nbsp;AI가&amp;nbsp;아무리&amp;nbsp;잘&amp;nbsp;만들어도&amp;nbsp;스타일&amp;nbsp;불일치가&amp;nbsp;수동으로&amp;nbsp;쌓입니다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3단계&amp;nbsp;&amp;mdash;&amp;nbsp;API&amp;nbsp;스펙&amp;nbsp;먼저&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;PRD에서&amp;nbsp;정의한&amp;nbsp;요구사항이&amp;nbsp;OpenAPI&amp;nbsp;스펙&amp;nbsp;또는&amp;nbsp;Zod&amp;nbsp;스키마로&amp;nbsp;정리됩니다.&amp;nbsp;코드를&amp;nbsp;먼저&amp;nbsp;짜는&amp;nbsp;게&amp;nbsp;아닙니다.&amp;nbsp;어떤&amp;nbsp;데이터를&amp;nbsp;주고받을지를&amp;nbsp;먼저&amp;nbsp;정합니다.&amp;nbsp;이&amp;nbsp;스펙이&amp;nbsp;명확하면&amp;nbsp;프론트엔드와&amp;nbsp;백엔드가&amp;nbsp;병렬로&amp;nbsp;개발해도&amp;nbsp;충돌이&amp;nbsp;없습니다.&amp;nbsp;AI도&amp;nbsp;스펙에서&amp;nbsp;시작하면&amp;nbsp;훨씬&amp;nbsp;정확한&amp;nbsp;코드를&amp;nbsp;만듭니다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4단계&amp;nbsp;&amp;mdash;&amp;nbsp;프론트엔드&amp;nbsp;조립&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;디자인&amp;nbsp;토큰,&amp;nbsp;API&amp;nbsp;스펙,&amp;nbsp;PRD&amp;nbsp;요구사항이&amp;nbsp;모두&amp;nbsp;AI가&amp;nbsp;읽을&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;형태로&amp;nbsp;갖춰져&amp;nbsp;있으면&amp;nbsp;프론트엔드&amp;nbsp;개발은&amp;nbsp;AI가&amp;nbsp;상당&amp;nbsp;부분&amp;nbsp;조립합니다.&amp;nbsp;컴포넌트&amp;nbsp;생성,&amp;nbsp;API&amp;nbsp;연동,&amp;nbsp;에러&amp;nbsp;핸들링.&amp;nbsp;사람은&amp;nbsp;설계를&amp;nbsp;검토하고&amp;nbsp;엣지&amp;nbsp;케이스를&amp;nbsp;판단합니다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;5단계&amp;nbsp;&amp;mdash;&amp;nbsp;하네스(검증&amp;nbsp;게이트)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;하네스(harness)란&amp;nbsp;AI가&amp;nbsp;만든&amp;nbsp;결과물을&amp;nbsp;자동으로&amp;nbsp;검증하는&amp;nbsp;장치입니다.&amp;nbsp;타입&amp;nbsp;체크,&amp;nbsp;빌드&amp;nbsp;검증,&amp;nbsp;런타임&amp;nbsp;테스트,&amp;nbsp;AI&amp;nbsp;코드&amp;nbsp;리뷰어.&amp;nbsp;이&amp;nbsp;게이트&amp;nbsp;없이&amp;nbsp;파이프라인을&amp;nbsp;돌리는&amp;nbsp;건&amp;nbsp;안전장치&amp;nbsp;없이&amp;nbsp;공장을&amp;nbsp;가동하는&amp;nbsp;것과&amp;nbsp;같습니다.&amp;nbsp;실수가&amp;nbsp;빠르게&amp;nbsp;누적됩니다.&lt;/p&gt;
&lt;p data-ke-size=&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;시작하는&amp;nbsp;팀을&amp;nbsp;위한&amp;nbsp;현실적인&amp;nbsp;조언&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&quot;그럼&amp;nbsp;당장&amp;nbsp;뭘&amp;nbsp;해야&amp;nbsp;하나요?&quot;라는&amp;nbsp;질문을&amp;nbsp;많이&amp;nbsp;받습니다.&lt;br /&gt;&lt;br /&gt;다짜고짜&amp;nbsp;에이전트부터&amp;nbsp;도입하지&amp;nbsp;마세요.&amp;nbsp;저도&amp;nbsp;그랬다가&amp;nbsp;돌아온&amp;nbsp;경험이&amp;nbsp;있습니다.&amp;nbsp;AI&amp;nbsp;에이전트는&amp;nbsp;좋은&amp;nbsp;재료가&amp;nbsp;있을&amp;nbsp;때&amp;nbsp;진짜&amp;nbsp;힘을&amp;nbsp;발휘합니다.&amp;nbsp;재료가&amp;nbsp;엉망이면&amp;nbsp;결과도&amp;nbsp;엉망입니다.&lt;br /&gt;&lt;br /&gt;첫&amp;nbsp;주에&amp;nbsp;할&amp;nbsp;일은&amp;nbsp;하나입니다.&amp;nbsp;PRD&amp;nbsp;하나를&amp;nbsp;골라서&amp;nbsp;AI가&amp;nbsp;이해할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;형식으로&amp;nbsp;다시&amp;nbsp;씁니다.&amp;nbsp;수용&amp;nbsp;기준을&amp;nbsp;명시적으로,&amp;nbsp;데이터&amp;nbsp;흐름을&amp;nbsp;타입과&amp;nbsp;함께.&amp;nbsp;그것만&amp;nbsp;해도&amp;nbsp;충분합니다.&lt;br /&gt;&lt;br /&gt;첫&amp;nbsp;달에&amp;nbsp;할&amp;nbsp;일은&amp;nbsp;두&amp;nbsp;가지입니다.&amp;nbsp;Figma&amp;nbsp;디자인&amp;nbsp;토큰&amp;nbsp;정리,&amp;nbsp;그리고&amp;nbsp;OpenAPI&amp;nbsp;스펙&amp;nbsp;기반으로&amp;nbsp;엔드포인트&amp;nbsp;하나를&amp;nbsp;파이프라인화합니다.&amp;nbsp;한&amp;nbsp;번&amp;nbsp;성공하면&amp;nbsp;팀&amp;nbsp;전체가&amp;nbsp;느낍니다.&amp;nbsp;뭔가&amp;nbsp;달라지고&amp;nbsp;있다는&amp;nbsp;걸.&lt;br /&gt;&lt;br /&gt;첫&amp;nbsp;분기에&amp;nbsp;할&amp;nbsp;일은&amp;nbsp;자동화와&amp;nbsp;회고입니다.&amp;nbsp;리뷰&amp;nbsp;게이트를&amp;nbsp;CI에&amp;nbsp;붙이고,&amp;nbsp;실패했던&amp;nbsp;것들을&amp;nbsp;회고합니다.&amp;nbsp;AI&amp;nbsp;실수의&amp;nbsp;패턴이&amp;nbsp;보이기&amp;nbsp;시작합니다.&amp;nbsp;그&amp;nbsp;패턴이&amp;nbsp;다음&amp;nbsp;하네스를&amp;nbsp;설계하는&amp;nbsp;재료가&amp;nbsp;됩니다.&lt;br /&gt;&lt;br /&gt;핵심은&amp;nbsp;이겁니다.&amp;nbsp;AI에게&amp;nbsp;일을&amp;nbsp;맡기는&amp;nbsp;게&amp;nbsp;아니라,&amp;nbsp;AI가&amp;nbsp;일할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;환경을&amp;nbsp;만드는&amp;nbsp;것이&amp;nbsp;AX입니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자는 완성된 화면을 봅니다. 버튼이 잘 눌리는지, 속도가 빠른지. 그게 전부처럼 보이죠.&lt;br /&gt;&lt;br /&gt;그런데&amp;nbsp;그&amp;nbsp;화면의&amp;nbsp;품질은&amp;nbsp;PRD가&amp;nbsp;얼마나&amp;nbsp;명확했는지,&amp;nbsp;디자인&amp;nbsp;토큰이&amp;nbsp;얼마나&amp;nbsp;잘&amp;nbsp;정의됐는지,&amp;nbsp;API&amp;nbsp;스펙이&amp;nbsp;얼마나&amp;nbsp;구체적이었는지에&amp;nbsp;달려&amp;nbsp;있습니다.&amp;nbsp;사용자&amp;nbsp;눈에&amp;nbsp;보이지&amp;nbsp;않는&amp;nbsp;곳에서&amp;nbsp;품질이&amp;nbsp;결정됩니다.&lt;br /&gt;&lt;br /&gt;AI가&amp;nbsp;바꾼&amp;nbsp;건&amp;nbsp;단순히&amp;nbsp;코드&amp;nbsp;작성&amp;nbsp;속도가&amp;nbsp;아닙니다.&amp;nbsp;상류&amp;nbsp;산출물의&amp;nbsp;품질이&amp;nbsp;하류&amp;nbsp;결과를&amp;nbsp;결정한다는&amp;nbsp;원리를&amp;nbsp;더&amp;nbsp;선명하게&amp;nbsp;드러낸&amp;nbsp;것입니다.&lt;br /&gt;&lt;br /&gt;그&amp;nbsp;파이프라인을&amp;nbsp;설계하는&amp;nbsp;사람이,&amp;nbsp;다음&amp;nbsp;시대의&amp;nbsp;개발자라고&amp;nbsp;생각합니다.&lt;/p&gt;</description>
      <category>AI AX</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/742</guid>
      <comments>https://series.tistory.com/entry/AXAI-Transformation-%EA%B8%B0%ED%9A%8D%EC%84%9C%EB%B6%80%ED%84%B0-%EB%B0%B1%EC%97%94%EB%93%9C-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%B0%B0%ED%8F%AC%EA%B9%8C%EC%A7%80-AI%EA%B0%80-%EB%B0%94%EA%BE%BC-%EA%B0%9C%EB%B0%9C-%ED%8C%8C%EC%9D%B4%ED%94%84%EB%9D%BC%EC%9D%B8-%EC%9D%B4%EC%95%BC%EA%B8%B0#entry742comment</comments>
      <pubDate>Wed, 22 Apr 2026 09:17:47 +0900</pubDate>
    </item>
    <item>
      <title>ChatGPT Canvas(캔버스) 완벽 활용법! 실무자가 알려주는 진짜 꿀팁 모음 (2024년 최신 가이드) by 일하지마닷컴AI 리치레전드</title>
      <link>https://series.tistory.com/entry/ChatGPT-Canvas%EC%BA%94%EB%B2%84%EC%8A%A4-%EC%99%84%EB%B2%BD-%ED%99%9C%EC%9A%A9%EB%B2%95-%EC%8B%A4%EB%AC%B4%EC%9E%90%EA%B0%80-%EC%95%8C%EB%A0%A4%EC%A3%BC%EB%8A%94-%EC%A7%84%EC%A7%9C-%EA%BF%80%ED%8C%81-%EB%AA%A8%EC%9D%8C-2024%EB%85%84-%EC%B5%9C%EC%8B%A0-%EA%B0%80%EC%9D%B4%EB%93%9C-by-%EC%9D%BC%ED%95%98%EC%A7%80%EB%A7%88%EB%8B%B7%EC%BB%B4AI-%EB%A6%AC%EC%B9%98%EB%A0%88%EC%A0%84%EB%93%9C</link>
      <description>&lt;h1&gt;ChatGPT&amp;nbsp;Canvas(캔버스)&amp;nbsp;완벽&amp;nbsp;활용법!&amp;nbsp;실무자가&amp;nbsp;알려주는&amp;nbsp;진짜&amp;nbsp;꿀팁&amp;nbsp;모음&amp;nbsp;(2024년&amp;nbsp;최신&amp;nbsp;가이드)&amp;nbsp;by&amp;nbsp;일하지마닷컴AI&amp;nbsp;리치레전드&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요, 일하지마닷컴AI - 디지털노마드 N잡러 개발자 리치레전드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 제가 AI 자동화 프로그램을 개발하면서 실제로 활용하고 있는 ChatGPT Canvas의 모든 노하우를 여러분과 공유하려고 해요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ChatGPT Canvas의 강력한 기능들을 200% 활용하는 방법, 함께 알아볼까요?&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;ChatGPT Canvas가 특별한 이유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 정말 다양한 AI 도구들이 쏟아져 나오고 있죠? 그중에서도 ChatGPT Canvas는 특별한 점이 있어요. 기존의 ChatGPT와는 차원이 다른 작업 환경을 제공한다는 거예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;bull; 다중 채팅 관리로 복잡한 프로젝트도 한눈에&lt;br /&gt;&amp;bull; 드래그 앤 드롭으로 작업물을 자유자재로 구성&lt;br /&gt;&amp;bull; 실시간으로 다른 팀원들과 협업 가능&lt;br /&gt;&amp;bull; 나만의 프롬프트 템플릿 만들기 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://images.unsplash.com/photo-1661961112951-f2bfd1f253ce?q=80&amp;amp;w=2072&amp;amp;auto=format&amp;amp;fit=crop&quot; alt=&quot;ChatGPT Canvas 메인 화면&quot; /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Canvas 시작 전 체크리스트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Canvas를 제대로 사용하기 위한 필수 준비사항들을 정리해봤어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;bull; OpenAI 계정 생성하기&lt;br /&gt;&amp;bull; GPT-4 모델 접근 권한 확보 (추천)&lt;br /&gt;&amp;bull; 안정적인 인터넷 환경 확인&lt;br /&gt;&amp;bull; 크롬 브라우저 최신 버전 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 기본적인 환경만 갖추면, 여러분도 바로 시작하실 수 있어요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실무자가 알려주는 Canvas 실전 활용법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 이제부터가 진짜 핵심이에요. 제가 일하지마닷컴AI 리치레전드로서 실제 업무에서 활용하고 있는 Canvas 꿀팁들을 낱낱이 공개할게요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;bull; 프롬프트 라이브러리 구축하기&lt;br /&gt;업무별로 자주 쓰는 프롬프트를 정리해두면 정말 편해요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;bull; 멀티 채팅 프로세스 활용하기&lt;br /&gt;복잡한 프로젝트를 주제별로 나누어 관리하면 효율이 확 올라가요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;bull; 캔버스 레이아웃 최적화하기&lt;br /&gt;자주 쓰는 기능은 드래그해서 쉽게 접근할 수 있게 배치하세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://images.unsplash.com/photo-1620712943543-bcc4688e7485?q=80&amp;amp;w=2065&amp;amp;auto=format&amp;amp;fit=crop&quot; alt=&quot;Canvas 활용 팁&quot; /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;프로그래머가 직접 겪은 Canvas 활용 사례&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 RPA 프로그램을 개발하면서 Canvas를 어떻게 활용했는지 실제 사례를 들어볼게요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;bull; 코드 최적화 작업&lt;br /&gt;여러 버전의 코드를 동시에 분석하고 개선할 수 있었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;bull; API 문서 자동화&lt;br /&gt;반복적인 문서 작업을 Canvas로 자동화했더니 시간이 반으로 줄었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;bull; 시스템 설계 브레인스토밍&lt;br /&gt;복잡한 시스템 구조도 Canvas에서 체계적으로 정리할 수 있었죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://images.unsplash.com/photo-1552664730-d307ca884978?q=80&amp;amp;w=2070&amp;amp;auto=format&amp;amp;fit=crop&quot; alt=&quot;실제 활용 예시&quot; /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;일하지마닷컴 AI의 특별한 자동화 서비스&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희 일하지마닷컴 AI는 ChatGPT Canvas의 강력한 기능을 활용한 맞춤형 자동화 서비스를 제공하고 있어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;bull; RPA 자동화 프로그램 개발&lt;br /&gt;&amp;bull; 엑셀 매크로 솔루션 구축&lt;br /&gt;&amp;bull; 맞춤형 웹 크롤링 시스템 구현&lt;br /&gt;&amp;bull; 데이터 스크래핑 자동화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모든 프로그램은 파이썬을 기반으로 개발되며, Canvas의 강력한 기능과 결합하여 더욱 똑똑하게 작동한답니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러분만의 맞춤형 자동화 프로그램이 필요하시다면 &lt;a href=&quot;http://ilhajima.com/&quot;&gt;ilhajima.com&lt;/a&gt;을 방문해주세요. 상담 신청서에 원하시는 기능을 자세히 적어주시면, 리치레전드가 최적의 솔루션을 제안해드릴게요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;마무리: AI로 진화하는 업무 환경&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 ChatGPT Canvas의 숨은 기능들과 실전 활용법을 자세히 알아보았는데요, Canvas를 제대로 활용하면 업무 효율이 정말 놀랍게 높아진답니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 자동화 도구와 결합했을 때 그 시너지가 엄청나요. 저희 일하지마닷컴AI와 함께라면 여러분의 업무 혁신이 한층 더 가까워질 거예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 자세한 내용이 궁금하시다면 언제든 일하지마닷컴AI 리치레전드를 찾아주세요. 여러분의 디지털 혁신을 항상 응원하겠습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인기 검색어 키워드: ChatGPT 캔버스 가이드 2024, Canvas 프롬프트 작성법, GPT4 실무 활용, 챗GPT 캔버스 업데이트, AI 업무 효율화, Canvas 비즈니스 적용, GPT Canvas 팁, 챗GPT 응용 활용, Canvas 실전 사례, AI 자동화 도구, ChatGPT Canvas 활용법, GPT 캔버스 사용법, AI 글쓰기 도구, 챗GPT 프롬프트, Canvas 초보 가이드, GPT 캔버스 강의, ChatGPT 최신기능, AI 업무 효율화, ChatGPT Canvas 팁, 캔버스 실전 활용&lt;/p&gt;</description>
      <category>AWS</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/741</guid>
      <comments>https://series.tistory.com/entry/ChatGPT-Canvas%EC%BA%94%EB%B2%84%EC%8A%A4-%EC%99%84%EB%B2%BD-%ED%99%9C%EC%9A%A9%EB%B2%95-%EC%8B%A4%EB%AC%B4%EC%9E%90%EA%B0%80-%EC%95%8C%EB%A0%A4%EC%A3%BC%EB%8A%94-%EC%A7%84%EC%A7%9C-%EA%BF%80%ED%8C%81-%EB%AA%A8%EC%9D%8C-2024%EB%85%84-%EC%B5%9C%EC%8B%A0-%EA%B0%80%EC%9D%B4%EB%93%9C-by-%EC%9D%BC%ED%95%98%EC%A7%80%EB%A7%88%EB%8B%B7%EC%BB%B4AI-%EB%A6%AC%EC%B9%98%EB%A0%88%EC%A0%84%EB%93%9C#entry741comment</comments>
      <pubDate>Thu, 7 Nov 2024 16:44:56 +0900</pubDate>
    </item>
    <item>
      <title>Claude AI 활용 가이드: 현직 개발자의 실전 경험담</title>
      <link>https://series.tistory.com/entry/Claude-AI-%ED%99%9C%EC%9A%A9-%EA%B0%80%EC%9D%B4%EB%93%9C-%ED%98%84%EC%A7%81-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%9D%98-%EC%8B%A4%EC%A0%84-%EA%B2%BD%ED%97%98%EB%8B%B4</link>
      <description>&lt;h1&gt;Claude AI 활용 가이드: 현직 개발자의 실전 경험담&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요! 일하지마닷컴AI에서 RPA 매크로 프로그램을 개발하고 있는 리치레전드입니다. 오늘은 제가 실제로 업무에서 활용하고 있는 Claude AI에 대해 제 경험을 공유해드리려고 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;처음 Claude를 만나다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작년에 처음 일하지마닷컴 AI를 개발하면서 Claude AI를 알게 되었을 때만 해도, 저 리치레전드는 그저 &quot;또 하나의 챗봇이겠지&quot;라고 생각했습니다. GPT-3.5 기반이라는 설명을 듣고 큰 기대 없이 시작했죠. 하지만 실제로 사용해보니, 제 생각이 완전히 틀렸다는 걸 깨달았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 개발자의 입장에서 보면, Claude는 단순한 챗봇이 아닌 든든한 동료 프로그래머 같은 존재입니다. 복잡한 알고리즘을 구현할 때나 버그를 찾아낼 때, 때로는 제가 미처 생각하지 못한 접근 방식을 제안해주기도 하죠.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실제 업무에서의 활용 사례&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 Claude를 가장 유용하게 활용한 경험을 하나 공유해드리겠습니다. 얼마 전 네이버 뉴스 데이터를 수집하는 크롤러를 만들어야 했는데요, Claude의 도움으로 작업 시간을 절반 이상 단축할 수 있었습니다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;# 이런 복잡한 크롤링 코드도 Claude와 함께라면 쉽게 작성할 수 있습니다
def crawl_naver_news(keyword, page_num=1):
    base_url = f&quot;https://search.naver.com/search.naver?where=news&amp;amp;query={keyword}&amp;amp;start={(page_num-1)*10+1}&quot;

    response = requests.get(base_url)
    soup = BeautifulSoup(response.text, 'html.parser')

    news_list = []
    articles = soup.select(&quot;.news_area&quot;)
    # ... (코드 상세 내용)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 Claude가 제안한 코드를 그대로 사용하지는 않았습니다. 제 프로젝트의 특성에 맞게 수정하고, 예외 처리도 추가했죠. 하지만 기본 뼈대를 빠르게 잡을 수 있었다는 점에서 정말 큰 도움이 되었습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;개발자가 느낀 장단점&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;실용적인 코드 제안&lt;/b&gt;: 단순히 동작하는 코드가 아닌, 실제 프로덕션에서 사용할 수 있는 수준의 코드를 제안받을 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;빠른 문제 해결&lt;/b&gt;: 에러 메시지를 붙여넣으면 대부분의 경우 명확한 해결책을 제시해줍니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자연스러운 소통&lt;/b&gt;: &quot;이 부분은 이렇게 하면 어떨까요?&quot;처럼 동료와 대화하듯 자연스러운 피드백을 주고받을 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;실시간 정보의 한계&lt;/b&gt;: 새로 출시된 라이브러리나 최신 버전의 API 변경사항은 모를 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;맥락 이해의 한계&lt;/b&gt;: 프로젝트의 전체적인 구조나 비즈니스 로직을 완벽히 이해시키기는 어렵습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;효과적인 활용을 위한 팁&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;구체적인 요청하기&lt;/b&gt;: &quot;이 코드 어떻게 고치면 돼?&quot;보다는 &quot;이 파이썬 코드에서 메모리 사용량을 줄이고 싶은데, 어떤 부분을 개선하면 좋을까요?&quot;처럼 구체적으로 물어보세요.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단계적 접근&lt;/b&gt;: 큰 기능을 한 번에 요청하기보다는, 작은 단위로 나누어 요청하세요. 코드 품질도 높아지고 디버깅도 쉬워집니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;검증하기&lt;/b&gt;: Claude가 제안한 코드는 반드시 테스트해보세요. 가끔 논리적 오류가 있을 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마치며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI는 분명 강력한 도구지만, 결국 그것을 어떻게 활용하느냐는 우리의 몫입니다. 일하지마닷컴AI를 개발하면서 Claude는 제게 없어서는 안 될 개발 파트너가 되었지만, 동시에 이는 제가 더 나은 개발자가 되기 위해 노력하게 만드는 자극제이기도 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러분도 Claude를 단순한 도구가 아닌, 함께 성장하는 파트너로 생각하고 접근해보세요. 분명 일하지마닷컴AI의 리치레전드와 같이 새로운 가능성을 발견하실 수 있을 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문이나 의견이 있으시다면 언제든 일하지마닷컴 AI 리치레전드를 통해 연락주세요. 여러분의 AI 활용 이야기도 궁금합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감사합니다!  &lt;/p&gt;</description>
      <category>AWS</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/734</guid>
      <comments>https://series.tistory.com/entry/Claude-AI-%ED%99%9C%EC%9A%A9-%EA%B0%80%EC%9D%B4%EB%93%9C-%ED%98%84%EC%A7%81-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%9D%98-%EC%8B%A4%EC%A0%84-%EA%B2%BD%ED%97%98%EB%8B%B4#entry734comment</comments>
      <pubDate>Wed, 23 Oct 2024 09:45:46 +0900</pubDate>
    </item>
    <item>
      <title>Selenium과 Playwright 비교</title>
      <link>https://series.tistory.com/entry/Selenium%EA%B3%BC-Playwright-%EB%B9%84%EA%B5%90</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Selenium과&amp;nbsp;Playwright&amp;nbsp;비교&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요,&amp;nbsp;일하지마닷컴AI&amp;nbsp;리치레전드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;오늘은&amp;nbsp;웹&amp;nbsp;자동화&amp;nbsp;테스트에서&amp;nbsp;많이&amp;nbsp;사용되는&amp;nbsp;두&amp;nbsp;가지&amp;nbsp;도구인&amp;nbsp;Selenium과&amp;nbsp;Playwright를&amp;nbsp;비교해&amp;nbsp;보려고&amp;nbsp;합니다.&amp;nbsp;특히&amp;nbsp;파이썬을&amp;nbsp;사용하여&amp;nbsp;두&amp;nbsp;도구가&amp;nbsp;어떻게&amp;nbsp;활용될&amp;nbsp;수&amp;nbsp;있는지&amp;nbsp;구체적으로&amp;nbsp;살펴볼&amp;nbsp;것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 도구 소개&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Selenium&lt;br /&gt;&lt;br /&gt;2004년에&amp;nbsp;출시된&amp;nbsp;오픈&amp;nbsp;소스&amp;nbsp;웹&amp;nbsp;자동화&amp;nbsp;도구로,&amp;nbsp;다양한&amp;nbsp;언어와&amp;nbsp;브라우저를&amp;nbsp;지원합니다.&lt;br /&gt;Python,&amp;nbsp;Java,&amp;nbsp;C#&amp;nbsp;등&amp;nbsp;여러&amp;nbsp;프로그래밍&amp;nbsp;언어와&amp;nbsp;통합할&amp;nbsp;수&amp;nbsp;있어&amp;nbsp;Python&amp;nbsp;개발자들&amp;nbsp;사이에서도&amp;nbsp;널리&amp;nbsp;쓰이고&amp;nbsp;있습니다.&lt;br /&gt;Playwright&lt;br /&gt;&lt;br /&gt;2020년&amp;nbsp;Microsoft에서&amp;nbsp;발표한&amp;nbsp;새로운&amp;nbsp;웹&amp;nbsp;자동화&amp;nbsp;도구입니다.&lt;br /&gt;Python,&amp;nbsp;JavaScript,&amp;nbsp;TypeScript&amp;nbsp;등&amp;nbsp;여러&amp;nbsp;언어를&amp;nbsp;지원하며,&amp;nbsp;강력한&amp;nbsp;기능을&amp;nbsp;제공합니다.&lt;br /&gt;현대적인&amp;nbsp;웹&amp;nbsp;테스트&amp;nbsp;환경을&amp;nbsp;위한&amp;nbsp;최신&amp;nbsp;도구로&amp;nbsp;자리&amp;nbsp;잡고&amp;nbsp;있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;2.&amp;nbsp;파이썬에서의&amp;nbsp;주요&amp;nbsp;특징&amp;nbsp;비교&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;특징 Selenium&amp;nbsp;with&amp;nbsp;Python Playwright&amp;nbsp;for&amp;nbsp;Python&lt;br /&gt;설치&amp;nbsp;방법 pip&amp;nbsp;install&amp;nbsp;selenium pip&amp;nbsp;install&amp;nbsp;playwright&lt;br /&gt;브라우저&amp;nbsp;지원 Chrome,&amp;nbsp;Firefox,&amp;nbsp;Safari,&amp;nbsp;Edge&amp;nbsp;등 Chromium,&amp;nbsp;Firefox,&amp;nbsp;WebKit&lt;br /&gt;Python&amp;nbsp;버전&amp;nbsp;지원 Python&amp;nbsp;2.7&amp;nbsp;및&amp;nbsp;3.x Python&amp;nbsp;3.7&amp;nbsp;이상&lt;br /&gt;비동기&amp;nbsp;지원 제한적 asyncio를&amp;nbsp;통한&amp;nbsp;강력한&amp;nbsp;비동기&amp;nbsp;지원&lt;br /&gt;자동&amp;nbsp;대기 명시적&amp;nbsp;대기&amp;nbsp;필요 자동&amp;nbsp;대기&amp;nbsp;기능&amp;nbsp;내장&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;3.&amp;nbsp;코드&amp;nbsp;예제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Selenium&amp;nbsp;예제&lt;br /&gt;python&lt;br /&gt;코드&amp;nbsp;복사&lt;br /&gt;from&amp;nbsp;selenium&amp;nbsp;import&amp;nbsp;webdriver&lt;br /&gt;from&amp;nbsp;seleniu&lt;a href=&quot;http://m.webdriver.common.by&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://m.webdriver.common.by&lt;/a&gt;&amp;nbsp;import&amp;nbsp;By&lt;br /&gt;&lt;br /&gt;driver&amp;nbsp;=&amp;nbsp;webdriver.Chrome()&lt;br /&gt;driver.get(&quot;&lt;a href=&quot;https://www.example.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.example.com&lt;/a&gt;&quot;)&lt;br /&gt;&lt;br /&gt;element&amp;nbsp;=&amp;nbsp;driver.find_element(By.ID,&amp;nbsp;&quot;example-id&quot;)&lt;br /&gt;element.click()&lt;br /&gt;&lt;br /&gt;driver.quit()&lt;br /&gt;Playwright&amp;nbsp;예제&lt;br /&gt;python&lt;br /&gt;코드&amp;nbsp;복사&lt;br /&gt;from&amp;nbsp;playwright.sync_api&amp;nbsp;import&amp;nbsp;sync_playwright&lt;br /&gt;&lt;br /&gt;with&amp;nbsp;sync_playwright()&amp;nbsp;as&amp;nbsp;p:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;browser&amp;nbsp;=&amp;nbsp;p.chromium.launch()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;page&amp;nbsp;=&amp;nbsp;browser.new_page()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;page.goto(&quot;&lt;a href=&quot;https://www.example.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.example.com&lt;/a&gt;&quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;element&amp;nbsp;=&amp;nbsp;page.locator(&quot;#example-id&quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;element.click()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;browser.close()&lt;br /&gt;4.&amp;nbsp;파이썬&amp;nbsp;개발자를&amp;nbsp;위한&amp;nbsp;장단점&amp;nbsp;분석&lt;br /&gt;Selenium&amp;nbsp;with&amp;nbsp;Python&lt;br /&gt;&lt;br /&gt;장점:&lt;br /&gt;&lt;br /&gt;오랜&amp;nbsp;역사와&amp;nbsp;넓은&amp;nbsp;사용자층&amp;nbsp;덕분에&amp;nbsp;참고할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;자료가&amp;nbsp;풍부합니다.&lt;br /&gt;다양한&amp;nbsp;Python&amp;nbsp;라이브러리와의&amp;nbsp;호환성이&amp;nbsp;좋습니다.&lt;br /&gt;여전히&amp;nbsp;Python&amp;nbsp;2.7&amp;nbsp;버전을&amp;nbsp;지원하여&amp;nbsp;레거시&amp;nbsp;시스템에서도&amp;nbsp;사용&amp;nbsp;가능합니다.&lt;br /&gt;단점:&lt;br /&gt;&lt;br /&gt;파이썬의&amp;nbsp;비동기&amp;nbsp;프로그래밍을&amp;nbsp;완전히&amp;nbsp;활용하기&amp;nbsp;어려워&amp;nbsp;일부&amp;nbsp;프로젝트에서는&amp;nbsp;성능상의&amp;nbsp;한계가&amp;nbsp;있습니다.&lt;br /&gt;초기&amp;nbsp;설정이&amp;nbsp;다소&amp;nbsp;복잡할&amp;nbsp;수&amp;nbsp;있어,&amp;nbsp;Python을&amp;nbsp;처음&amp;nbsp;접하는&amp;nbsp;개발자에게는&amp;nbsp;진입&amp;nbsp;장벽이&amp;nbsp;있을&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;Playwright&amp;nbsp;for&amp;nbsp;Python&lt;br /&gt;&lt;br /&gt;장점:&lt;br /&gt;&lt;br /&gt;Python의&amp;nbsp;최신&amp;nbsp;비동기&amp;nbsp;기능을&amp;nbsp;활용하여&amp;nbsp;더&amp;nbsp;빠르고&amp;nbsp;효율적인&amp;nbsp;테스트가&amp;nbsp;가능합니다.&lt;br /&gt;직관적이고&amp;nbsp;현대적인&amp;nbsp;API&amp;nbsp;설계로&amp;nbsp;사용하기&amp;nbsp;편리하며&amp;nbsp;코드의&amp;nbsp;가독성이&amp;nbsp;좋습니다.&lt;br /&gt;자동&amp;nbsp;대기&amp;nbsp;기능을&amp;nbsp;통해&amp;nbsp;복잡한&amp;nbsp;대기&amp;nbsp;설정&amp;nbsp;없이&amp;nbsp;안정적인&amp;nbsp;테스트가&amp;nbsp;가능합니다.&lt;br /&gt;단점:&lt;br /&gt;&lt;br /&gt;Python&amp;nbsp;3.7&amp;nbsp;이상의&amp;nbsp;버전만&amp;nbsp;지원하여&amp;nbsp;구형&amp;nbsp;시스템에서는&amp;nbsp;사용이&amp;nbsp;제한됩니다.&lt;br /&gt;Selenium에&amp;nbsp;비해&amp;nbsp;Python&amp;nbsp;커뮤니티의&amp;nbsp;참고&amp;nbsp;자료가&amp;nbsp;적어&amp;nbsp;학습&amp;nbsp;시&amp;nbsp;불편할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;5.&amp;nbsp;결론&lt;br /&gt;Python&amp;nbsp;개발자&amp;nbsp;입장에서&amp;nbsp;두&amp;nbsp;도구&amp;nbsp;모두&amp;nbsp;각자의&amp;nbsp;강점을&amp;nbsp;지니고&amp;nbsp;있습니다.&amp;nbsp;Selenium은&amp;nbsp;오랜&amp;nbsp;역사와&amp;nbsp;풍부한&amp;nbsp;커뮤니티&amp;nbsp;지원&amp;nbsp;덕분에&amp;nbsp;레거시&amp;nbsp;프로젝트나&amp;nbsp;여러&amp;nbsp;라이브러리와의&amp;nbsp;통합이&amp;nbsp;필요한&amp;nbsp;경우&amp;nbsp;유리합니다.&amp;nbsp;반면,&amp;nbsp;Playwright는&amp;nbsp;최신&amp;nbsp;Python&amp;nbsp;기능을&amp;nbsp;적극&amp;nbsp;활용할&amp;nbsp;수&amp;nbsp;있고&amp;nbsp;현대적인&amp;nbsp;웹&amp;nbsp;애플리케이션&amp;nbsp;테스트에&amp;nbsp;최적화되어&amp;nbsp;있어&amp;nbsp;더&amp;nbsp;빠르고&amp;nbsp;안정적인&amp;nbsp;테스트를&amp;nbsp;제공할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;프로젝트의&amp;nbsp;요구사항과&amp;nbsp;개발&amp;nbsp;환경에&amp;nbsp;따라&amp;nbsp;적절한&amp;nbsp;도구를&amp;nbsp;선택하는&amp;nbsp;것이&amp;nbsp;중요합니다.&amp;nbsp;두&amp;nbsp;도구&amp;nbsp;모두&amp;nbsp;Python&amp;nbsp;개발자가&amp;nbsp;충분히&amp;nbsp;활용할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;강력한&amp;nbsp;도구이므로,&amp;nbsp;실제&amp;nbsp;프로젝트에&amp;nbsp;적용해&amp;nbsp;보면서&amp;nbsp;각&amp;nbsp;도구의&amp;nbsp;장단점을&amp;nbsp;직접&amp;nbsp;체감해&amp;nbsp;보는&amp;nbsp;것도&amp;nbsp;좋은&amp;nbsp;방법입니다.&lt;/p&gt;</description>
      <category>AWS</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/733</guid>
      <comments>https://series.tistory.com/entry/Selenium%EA%B3%BC-Playwright-%EB%B9%84%EA%B5%90#entry733comment</comments>
      <pubDate>Mon, 21 Oct 2024 09:00:03 +0900</pubDate>
    </item>
    <item>
      <title>Claude 3.5 Sonnet의 혁신적인 기능인 Agentic Workflow</title>
      <link>https://series.tistory.com/entry/Claude-35-Sonnet%EC%9D%98-%ED%98%81%EC%8B%A0%EC%A0%81%EC%9D%B8-%EA%B8%B0%EB%8A%A5%EC%9D%B8-Agentic-Workflow</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;안녕하세요, 일하지마닷컴AI의 디지털 노마드이자 N잡러 개발자 리치레전드입니다.&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;오늘은&amp;nbsp;Claude&amp;nbsp;3.5&amp;nbsp;Sonnet의&amp;nbsp;혁신적인&amp;nbsp;기능인&amp;nbsp;Agentic&amp;nbsp;Workflow에&amp;nbsp;대해&amp;nbsp;이야기해보려고&amp;nbsp;합니다.&amp;nbsp;제가&amp;nbsp;RPA&amp;nbsp;매크로&amp;nbsp;프로그램을&amp;nbsp;개발하며&amp;nbsp;직접&amp;nbsp;체험한&amp;nbsp;경험을&amp;nbsp;토대로,&amp;nbsp;이&amp;nbsp;기능이&amp;nbsp;어떻게&amp;nbsp;업무&amp;nbsp;효율을&amp;nbsp;극대화할&amp;nbsp;수&amp;nbsp;있는지&amp;nbsp;자세히&amp;nbsp;설명드릴게요.&amp;nbsp;Agentic&amp;nbsp;Workflow를&amp;nbsp;제대로&amp;nbsp;활용하면&amp;nbsp;여러분의&amp;nbsp;생산성이&amp;nbsp;200%&amp;nbsp;이상&amp;nbsp;올라갈&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;이제&amp;nbsp;Claude&amp;nbsp;3.5&amp;nbsp;Sonnet과&amp;nbsp;함께&amp;nbsp;Agentic&amp;nbsp;Workflow의&amp;nbsp;세계로&amp;nbsp;들어가&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;Agentic Workflow란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agentic&amp;nbsp;Workflow는&amp;nbsp;Claude&amp;nbsp;3.5&amp;nbsp;Sonnet의&amp;nbsp;주요&amp;nbsp;기능&amp;nbsp;중&amp;nbsp;하나로,&amp;nbsp;단순한&amp;nbsp;AI&amp;nbsp;챗봇의&amp;nbsp;수준을&amp;nbsp;넘어&amp;nbsp;&amp;lsquo;에이전트&amp;rsquo;처럼&amp;nbsp;행동하며&amp;nbsp;복잡한&amp;nbsp;작업을&amp;nbsp;단계별로&amp;nbsp;수행합니다.&amp;nbsp;기존의&amp;nbsp;AI&amp;nbsp;도구가&amp;nbsp;질문에&amp;nbsp;답하는&amp;nbsp;역할에&amp;nbsp;머물렀다면,&amp;nbsp;Agentic&amp;nbsp;Workflow는&amp;nbsp;프로젝트를&amp;nbsp;전반적으로&amp;nbsp;관리하고&amp;nbsp;실행할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;기능을&amp;nbsp;갖추고&amp;nbsp;있죠.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;&amp;ldquo;웹사이트를&amp;nbsp;새로&amp;nbsp;만들고&amp;nbsp;싶어&amp;rdquo;라고&amp;nbsp;말하면&amp;nbsp;Claude&amp;nbsp;AI가&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;단계로&amp;nbsp;안내합니다:&lt;br /&gt;&lt;br /&gt;웹사이트의&amp;nbsp;목적과&amp;nbsp;타겟&amp;nbsp;고객&amp;nbsp;정의&lt;br /&gt;주요&amp;nbsp;페이지와&amp;nbsp;구조&amp;nbsp;설계&lt;br /&gt;디자인&amp;nbsp;컨셉&amp;nbsp;결정&lt;br /&gt;필요한&amp;nbsp;콘텐츠&amp;nbsp;목록&amp;nbsp;작성&lt;br /&gt;개발&amp;nbsp;방법&amp;nbsp;선택&amp;nbsp;(예:&amp;nbsp;WordPress,&amp;nbsp;React)&lt;br /&gt;개발&amp;nbsp;일정&amp;nbsp;수립&lt;br /&gt;테스트와&amp;nbsp;론칭&amp;nbsp;계획&amp;nbsp;수립&lt;br /&gt;이처럼&amp;nbsp;전체&amp;nbsp;프로젝트의&amp;nbsp;큰&amp;nbsp;그림을&amp;nbsp;그려주고,&amp;nbsp;각&amp;nbsp;단계에서&amp;nbsp;구체적인&amp;nbsp;지침과&amp;nbsp;필요한&amp;nbsp;리소스를&amp;nbsp;제시해줍니다.&amp;nbsp;마치&amp;nbsp;프로젝트&amp;nbsp;매니저,&amp;nbsp;기술&amp;nbsp;컨설턴트,&amp;nbsp;디자이너&amp;nbsp;역할을&amp;nbsp;동시에&amp;nbsp;수행하는&amp;nbsp;것&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;Agentic Workflow의 핵심 특징&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Agentic&amp;nbsp;Workflow의&amp;nbsp;주요&amp;nbsp;특징은&amp;nbsp;다음과&amp;nbsp;같습니다:&lt;br /&gt;&lt;br /&gt;목표&amp;nbsp;지향적&amp;nbsp;접근:&amp;nbsp;정보&amp;nbsp;제공을&amp;nbsp;넘어&amp;nbsp;최종&amp;nbsp;목표&amp;nbsp;달성을&amp;nbsp;위한&amp;nbsp;체계적인&amp;nbsp;접근을&amp;nbsp;제공합니다.&lt;br /&gt;맥락&amp;nbsp;이해&amp;nbsp;및&amp;nbsp;유지:&amp;nbsp;긴&amp;nbsp;대화에서도&amp;nbsp;목표와&amp;nbsp;맥락을&amp;nbsp;일관성&amp;nbsp;있게&amp;nbsp;유지하며&amp;nbsp;작업을&amp;nbsp;진행합니다.&lt;br /&gt;단계별&amp;nbsp;가이드:&amp;nbsp;복잡한&amp;nbsp;작업을&amp;nbsp;잘게&amp;nbsp;나누어&amp;nbsp;쉽게&amp;nbsp;따라할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;단계로&amp;nbsp;안내합니다.&lt;br /&gt;유연한&amp;nbsp;대응:&amp;nbsp;사용자의&amp;nbsp;피드백에&amp;nbsp;따라&amp;nbsp;계획을&amp;nbsp;조정하고&amp;nbsp;예상치&amp;nbsp;못한&amp;nbsp;상황에도&amp;nbsp;대처할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;다양한&amp;nbsp;역할&amp;nbsp;수행:&amp;nbsp;조언자,&amp;nbsp;코치,&amp;nbsp;프로그래머,&amp;nbsp;작가&amp;nbsp;등&amp;nbsp;여러&amp;nbsp;역할을&amp;nbsp;상황에&amp;nbsp;맞게&amp;nbsp;수행합니다.&lt;br /&gt;이러한&amp;nbsp;특징&amp;nbsp;덕분에&amp;nbsp;Agentic&amp;nbsp;Workflow는&amp;nbsp;단순한&amp;nbsp;AI&amp;nbsp;도우미를&amp;nbsp;넘어&amp;nbsp;다양한&amp;nbsp;업무에서&amp;nbsp;훌륭한&amp;nbsp;파트너로&amp;nbsp;자리잡을&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;Claude&amp;nbsp;3.5&amp;nbsp;Sonnet의&amp;nbsp;Agentic&amp;nbsp;Workflow&amp;nbsp;활용&amp;nbsp;방법&lt;br /&gt;Agentic&amp;nbsp;Workflow를&amp;nbsp;실제로&amp;nbsp;어떻게&amp;nbsp;활용할&amp;nbsp;수&amp;nbsp;있는지&amp;nbsp;구체적으로&amp;nbsp;알아볼까요?&lt;br /&gt;&lt;br /&gt;명확한&amp;nbsp;목표&amp;nbsp;설정:&amp;nbsp;프로젝트의&amp;nbsp;목표를&amp;nbsp;구체적으로&amp;nbsp;제시하세요.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;&quot;파이썬으로&amp;nbsp;네이버&amp;nbsp;뉴스에서&amp;nbsp;&amp;lsquo;인공지능&amp;rsquo;&amp;nbsp;키워드로&amp;nbsp;검색된&amp;nbsp;기사&amp;nbsp;제목과&amp;nbsp;링크를&amp;nbsp;크롤링하고&amp;nbsp;싶어&quot;라고&amp;nbsp;말하는&amp;nbsp;겁니다.&lt;br /&gt;작업&amp;nbsp;계획&amp;nbsp;수립&amp;nbsp;요청:&amp;nbsp;목표가&amp;nbsp;설정되면&amp;nbsp;Claude&amp;nbsp;AI에게&amp;nbsp;단계별&amp;nbsp;작업&amp;nbsp;계획을&amp;nbsp;요청하세요.&lt;br /&gt;상세&amp;nbsp;지침&amp;nbsp;요청:&amp;nbsp;각&amp;nbsp;단계에&amp;nbsp;대한&amp;nbsp;구체적인&amp;nbsp;설명을&amp;nbsp;요청해&amp;nbsp;필요할&amp;nbsp;때마다&amp;nbsp;지침을&amp;nbsp;받을&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;코드&amp;nbsp;생성&amp;nbsp;요청:&amp;nbsp;코드&amp;nbsp;작성&amp;nbsp;단계에서는&amp;nbsp;Claude&amp;nbsp;AI가&amp;nbsp;실제로&amp;nbsp;코드를&amp;nbsp;작성하고&amp;nbsp;설명까지&amp;nbsp;제공할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;오류&amp;nbsp;해결:&amp;nbsp;코드&amp;nbsp;실행&amp;nbsp;중&amp;nbsp;발생하는&amp;nbsp;오류에&amp;nbsp;대한&amp;nbsp;해결&amp;nbsp;방법도&amp;nbsp;Claude&amp;nbsp;AI에게&amp;nbsp;물어볼&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;결과&amp;nbsp;분석&amp;nbsp;및&amp;nbsp;추가&amp;nbsp;작업&amp;nbsp;제안:&amp;nbsp;작업&amp;nbsp;완료&amp;nbsp;후&amp;nbsp;Claude&amp;nbsp;AI에게&amp;nbsp;수집된&amp;nbsp;데이터의&amp;nbsp;활용&amp;nbsp;방안&amp;nbsp;등을&amp;nbsp;조언&amp;nbsp;받을&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;프로젝트&amp;nbsp;문서화:&amp;nbsp;프로젝트가&amp;nbsp;끝나면&amp;nbsp;전체&amp;nbsp;작업&amp;nbsp;과정을&amp;nbsp;README&amp;nbsp;파일&amp;nbsp;등으로&amp;nbsp;정리해달라고&amp;nbsp;요청할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;이렇게&amp;nbsp;체계적으로&amp;nbsp;활용하면,&amp;nbsp;복잡한&amp;nbsp;프로젝트도&amp;nbsp;처음부터&amp;nbsp;끝까지&amp;nbsp;일관성&amp;nbsp;있게&amp;nbsp;진행할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;Agentic&amp;nbsp;Workflow의&amp;nbsp;실제&amp;nbsp;사례&lt;br /&gt;최근&amp;nbsp;저는&amp;nbsp;일하지마닷컴&amp;nbsp;AI를&amp;nbsp;위해&amp;nbsp;복잡한&amp;nbsp;RPA&amp;nbsp;매크로&amp;nbsp;프로그램을&amp;nbsp;개발해야&amp;nbsp;했습니다.&amp;nbsp;여러&amp;nbsp;웹사이트에서&amp;nbsp;데이터를&amp;nbsp;자동으로&amp;nbsp;수집하고&amp;nbsp;분석하는&amp;nbsp;것이&amp;nbsp;목표였죠.&amp;nbsp;하지만&amp;nbsp;어디서부터&amp;nbsp;시작해야&amp;nbsp;할지&amp;nbsp;막막했을&amp;nbsp;때,&amp;nbsp;Claude&amp;nbsp;3.5&amp;nbsp;Sonnet의&amp;nbsp;Agentic&amp;nbsp;Workflow가&amp;nbsp;큰&amp;nbsp;도움이&amp;nbsp;되었습니다.&lt;br /&gt;&lt;br /&gt;프로젝트&amp;nbsp;정의:&amp;nbsp;프로젝트의&amp;nbsp;목적과&amp;nbsp;요구사항을&amp;nbsp;상세히&amp;nbsp;설명했습니다.&lt;br /&gt;아키텍처&amp;nbsp;설계:&amp;nbsp;Claude&amp;nbsp;AI가&amp;nbsp;프로그램&amp;nbsp;구조와&amp;nbsp;필요한&amp;nbsp;모듈을&amp;nbsp;제안해줬습니다.&lt;br /&gt;기술&amp;nbsp;스택&amp;nbsp;선택:&amp;nbsp;Claude&amp;nbsp;AI로부터&amp;nbsp;적합한&amp;nbsp;프로그래밍&amp;nbsp;언어와&amp;nbsp;라이브러리&amp;nbsp;추천을&amp;nbsp;받았습니다.&lt;br /&gt;코드&amp;nbsp;작성:&amp;nbsp;Claude&amp;nbsp;AI가&amp;nbsp;제안한&amp;nbsp;코드를&amp;nbsp;검토하고&amp;nbsp;수정하는&amp;nbsp;방식으로&amp;nbsp;진행했습니다.&lt;br /&gt;테스트&amp;nbsp;및&amp;nbsp;디버깅:&amp;nbsp;오류가&amp;nbsp;발생했을&amp;nbsp;때&amp;nbsp;Claude&amp;nbsp;AI의&amp;nbsp;조언을&amp;nbsp;받아&amp;nbsp;문제를&amp;nbsp;해결했습니다.&lt;br /&gt;최적화:&amp;nbsp;프로그램&amp;nbsp;성능&amp;nbsp;개선을&amp;nbsp;위한&amp;nbsp;다양한&amp;nbsp;제안도&amp;nbsp;받았습니다.&lt;br /&gt;문서화:&amp;nbsp;프로젝트&amp;nbsp;전&amp;nbsp;과정을&amp;nbsp;상세히&amp;nbsp;정리한&amp;nbsp;문서를&amp;nbsp;작성했습니다.&lt;br /&gt;결과적으로,&amp;nbsp;Agentic&amp;nbsp;Workflow&amp;nbsp;덕분에&amp;nbsp;혼자&amp;nbsp;개발했다면&amp;nbsp;한&amp;nbsp;달&amp;nbsp;이상&amp;nbsp;걸렸을&amp;nbsp;프로젝트를&amp;nbsp;단&amp;nbsp;2주&amp;nbsp;만에&amp;nbsp;끝낼&amp;nbsp;수&amp;nbsp;있었습니다.&lt;br /&gt;&lt;br /&gt;Agentic&amp;nbsp;Workflow와&amp;nbsp;다른&amp;nbsp;AI&amp;nbsp;도구들의&amp;nbsp;차이점&lt;br /&gt;다른&amp;nbsp;AI&amp;nbsp;도구들과&amp;nbsp;비교하면,&amp;nbsp;Agentic&amp;nbsp;Workflow는&amp;nbsp;더&amp;nbsp;폭넓고&amp;nbsp;체계적인&amp;nbsp;지원을&amp;nbsp;제공합니다.&lt;br /&gt;&lt;br /&gt;챗GPT와의&amp;nbsp;차이:&amp;nbsp;챗GPT는&amp;nbsp;주로&amp;nbsp;질의응답에&amp;nbsp;중점을&amp;nbsp;두지만,&amp;nbsp;Agentic&amp;nbsp;Workflow는&amp;nbsp;프로젝트&amp;nbsp;전체를&amp;nbsp;관리합니다.&lt;br /&gt;AI&amp;nbsp;코딩&amp;nbsp;도우미들과의&amp;nbsp;차이:&amp;nbsp;대부분의&amp;nbsp;AI&amp;nbsp;코딩&amp;nbsp;도우미는&amp;nbsp;코드&amp;nbsp;작성과&amp;nbsp;디버깅에만&amp;nbsp;집중하지만,&amp;nbsp;Agentic&amp;nbsp;Workflow는&amp;nbsp;프로젝트&amp;nbsp;기획,&amp;nbsp;설계,&amp;nbsp;테스트,&amp;nbsp;문서화까지&amp;nbsp;포괄합니다.&lt;br /&gt;프로젝트&amp;nbsp;관리&amp;nbsp;도구들과의&amp;nbsp;차이:&amp;nbsp;기존&amp;nbsp;도구들은&amp;nbsp;정해진&amp;nbsp;틀&amp;nbsp;안에서만&amp;nbsp;작업을&amp;nbsp;지원하지만,&amp;nbsp;Agentic&amp;nbsp;Workflow는&amp;nbsp;더&amp;nbsp;유연하고&amp;nbsp;창의적인&amp;nbsp;해결책을&amp;nbsp;제시할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;장점과&amp;nbsp;주의점&lt;br /&gt;장점:&lt;br /&gt;&lt;br /&gt;시간&amp;nbsp;절약&lt;br /&gt;프로젝트의&amp;nbsp;일관성&amp;nbsp;유지&lt;br /&gt;창의적&amp;nbsp;문제&amp;nbsp;해결&lt;br /&gt;새로운&amp;nbsp;기술&amp;nbsp;학습&lt;br /&gt;높은&amp;nbsp;품질의&amp;nbsp;결과물&lt;br /&gt;주의점:&lt;br /&gt;&lt;br /&gt;AI에&amp;nbsp;과도한&amp;nbsp;의존은&amp;nbsp;금물&lt;br /&gt;보안에&amp;nbsp;유의&lt;br /&gt;AI의&amp;nbsp;맥락&amp;nbsp;이해를&amp;nbsp;항상&amp;nbsp;검토&lt;br /&gt;기술적&amp;nbsp;한계&amp;nbsp;고려&lt;br /&gt;일하지마닷컴&amp;nbsp;AI의&amp;nbsp;Agentic&amp;nbsp;Workflow&amp;nbsp;활용&amp;nbsp;서비스&lt;br /&gt;일하지마닷컴&amp;nbsp;AI는&amp;nbsp;Claude&amp;nbsp;3.5&amp;nbsp;Sonnet의&amp;nbsp;Agentic&amp;nbsp;Workflow&amp;nbsp;기능을&amp;nbsp;활용해&amp;nbsp;업무&amp;nbsp;자동화&amp;nbsp;및&amp;nbsp;효율&amp;nbsp;향상&amp;nbsp;서비스를&amp;nbsp;제공합니다.&amp;nbsp;주요&amp;nbsp;서비스는&amp;nbsp;다음과&amp;nbsp;같습니다:&lt;br /&gt;&lt;br /&gt;RPA&amp;nbsp;매크로&amp;nbsp;프로그램:&amp;nbsp;복잡한&amp;nbsp;업무&amp;nbsp;프로세스를&amp;nbsp;자동화&lt;br /&gt;엑셀&amp;nbsp;매크로&amp;nbsp;프로그램:&amp;nbsp;대규모&amp;nbsp;데이터&amp;nbsp;처리와&amp;nbsp;분석&amp;nbsp;지원&lt;br /&gt;웹&amp;nbsp;크롤링&amp;nbsp;프로그램:&amp;nbsp;효율적인&amp;nbsp;웹&amp;nbsp;데이터&amp;nbsp;수집&lt;br /&gt;스크래핑&amp;nbsp;프로그램:&amp;nbsp;정확한&amp;nbsp;데이터&amp;nbsp;추출&lt;br /&gt;모든&amp;nbsp;프로그램은&amp;nbsp;파이썬을&amp;nbsp;기반으로&amp;nbsp;개발되며,&amp;nbsp;일하지마닷컴&amp;nbsp;AI&amp;nbsp;홈페이지를&amp;nbsp;방문해&amp;nbsp;상담을&amp;nbsp;신청할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;마무리&lt;br /&gt;Agentic&amp;nbsp;Workflow는&amp;nbsp;단순한&amp;nbsp;AI&amp;nbsp;도구를&amp;nbsp;넘어,&amp;nbsp;여러분의&amp;nbsp;든든한&amp;nbsp;협업&amp;nbsp;파트너가&amp;nbsp;될&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;복잡한&amp;nbsp;프로젝트도&amp;nbsp;일관성&amp;nbsp;있게&amp;nbsp;관리하고,&amp;nbsp;창의적인&amp;nbsp;해결책을&amp;nbsp;제시하며,&amp;nbsp;끊임없이&amp;nbsp;발전하는&amp;nbsp;AI와&amp;nbsp;함께&amp;nbsp;업무&amp;nbsp;효율을&amp;nbsp;극대화할&amp;nbsp;수&amp;nbsp;있죠.&amp;nbsp;일하지마닷컴&amp;nbsp;AI와&amp;nbsp;함께&amp;nbsp;스마트한&amp;nbsp;업무&amp;nbsp;환경을&amp;nbsp;만들어보세요.&amp;nbsp;여러분의&amp;nbsp;성공을&amp;nbsp;항상&amp;nbsp;응원합니다!&lt;/p&gt;</description>
      <category>AWS</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/732</guid>
      <comments>https://series.tistory.com/entry/Claude-35-Sonnet%EC%9D%98-%ED%98%81%EC%8B%A0%EC%A0%81%EC%9D%B8-%EA%B8%B0%EB%8A%A5%EC%9D%B8-Agentic-Workflow#entry732comment</comments>
      <pubDate>Mon, 21 Oct 2024 08:57:24 +0900</pubDate>
    </item>
    <item>
      <title>Selenium vs Playwright: 파이썬을 활용한 웹 자동화 도구 비교 분석</title>
      <link>https://series.tistory.com/entry/Selenium-vs-Playwright-%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9D%84-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9B%B9-%EC%9E%90%EB%8F%99%ED%99%94-%EB%8F%84%EA%B5%AC-%EB%B9%84%EA%B5%90-%EB%B6%84%EC%84%9D</link>
      <description>&lt;h1&gt;&lt;b&gt;Selenium vs Playwright: 파이썬을 활용한 웹 자동화 도구 비교 분석&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 자동화 테스팅 분야에서 주목받고 있는 두 가지 도구, Selenium과 Playwright에 대해 비교 분석해보려고 합니다. 특히 파이썬(Python) 언어를 사용하여 이 두 도구를 어떻게 활용할 수 있는지 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 소개&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Selenium&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;2004년에 처음 출시된 오픈 소스 웹 자동화 도구&lt;/li&gt;
&lt;li&gt;파이썬을 포함한 다양한 프로그래밍 언어와 브라우저를 지원&lt;/li&gt;
&lt;li&gt;Python 개발자들 사이에서 인기 있는 웹 테스트 자동화 도구&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;Playwright&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;Microsoft에서 2020년에 출시한 비교적 새로운 도구&lt;/li&gt;
&lt;li&gt;Python, JavaScript, TypeScript 등 다중 언어 지원&lt;/li&gt;
&lt;li&gt;파이썬 사용자를 위한 강력한 API와 기능 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 파이썬에서의 주요 특징 비교&lt;/b&gt;&lt;/h2&gt;
&lt;table data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;특징&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Selenium with Python&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Playwright for Python&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;설치 방법&lt;/td&gt;
&lt;td&gt;pip install selenium&lt;/td&gt;
&lt;td&gt;pip install playwright&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;브라우저 지원&lt;/td&gt;
&lt;td&gt;Chrome, Firefox, Safari, Edge 등&lt;/td&gt;
&lt;td&gt;Chromium, Firefox, WebKit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python 버전 지원&lt;/td&gt;
&lt;td&gt;Python 2.7 및 3.x&lt;/td&gt;
&lt;td&gt;Python 3.7 이상&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;비동기 지원&lt;/td&gt;
&lt;td&gt;제한적&lt;/td&gt;
&lt;td&gt;asyncio를 통한 강력한 비동기 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;자동 대기&lt;/td&gt;
&lt;td&gt;명시적 대기 필요&lt;/td&gt;
&lt;td&gt;자동 대기 기능 내장&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 파이썬 코드 예제&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Selenium with Python&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get(&quot;https://www.example.com&quot;)

element = driver.find_element(By.ID, &quot;example-id&quot;)
element.click()

driver.quit()&lt;/code&gt;&lt;/pre&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;b&gt;Playwright for Python&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.goto(&quot;https://www.example.com&quot;)

    element = page.locator(&quot;#example-id&quot;)
    element.click()

    browser.close()&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. Python 개발자를 위한 장단점 분석&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Selenium with Python&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장점:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파이썬 커뮤니티에서 오랫동안 사용되어 풍부한 참고 자료&lt;/li&gt;
&lt;li&gt;다양한 Python 라이브러리와의 호환성&lt;/li&gt;
&lt;li&gt;Python 2.7 버전 지원 (레거시 시스템)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파이썬의 비동기 특성을 완전히 활용하기 어려움&lt;/li&gt;
&lt;li&gt;설정이 복잡하고 Python 초보자에게는 학습 곡선이 가파를 수 있음&lt;/li&gt;
&lt;/ul&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;b&gt;Playwright for Python&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장점:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파이썬의 최신 기능 (asyncio 등)을 활용한 강력한 비동기 지원&lt;/li&gt;
&lt;li&gt;Python 개발자를 위한 직관적이고 현대적인 API 설계&lt;/li&gt;
&lt;li&gt;자동 대기 기능으로 파이썬 코드 작성 시 안정성 향상&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Python 3.7 이상 버전만 지원 (레거시 시스템에서는 사용 제한)&lt;/li&gt;
&lt;li&gt;Selenium에 비해 파이썬 커뮤니티의 자료가 상대적으로 적음&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 결론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬 개발자의 관점에서 볼 때, Selenium은 오랜 역사와 풍부한 참고 자료로 인해 여전히 강력한 선택지입니다. 특히 레거시 Python 프로젝트나 다양한 파이썬 라이브러리와의 통합이 필요한 경우에 유리할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 Playwright는 Python의 최신 기능을 적극 활용하고, 현대적인 웹 애플리케이션 테스팅에 최적화되어 있습니다. 파이썬의 asyncio를 활용한 비동기 프로그래밍이 필요하거나, 보다 안정적이고 빠른 테스트 실행이 필요한 프로젝트에 적합할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 파이썬 프로젝트의 요구사항, 팀의 기술 스택, 그리고 테스트 대상 애플리케이션의 특성을 고려하여 적합한 도구를 선택해야 합니다. Python 개발자라면 두 도구 모두 충분히 활용 가능하므로, 실제 프로젝트에 적용해보고 판단하는 것이 가장 좋은 방법일 것입니다.&lt;/p&gt;</description>
      <category>Python</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/731</guid>
      <comments>https://series.tistory.com/entry/Selenium-vs-Playwright-%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9D%84-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9B%B9-%EC%9E%90%EB%8F%99%ED%99%94-%EB%8F%84%EA%B5%AC-%EB%B9%84%EA%B5%90-%EB%B6%84%EC%84%9D#entry731comment</comments>
      <pubDate>Fri, 26 Jul 2024 21:10:55 +0900</pubDate>
    </item>
    <item>
      <title>Redis master-replicas sentinel 구성 시 docker-compose.yml 파일</title>
      <link>https://series.tistory.com/entry/Redis-master-replicas-sentinel-%EA%B5%AC%EC%84%B1-%EC%8B%9C-docker-composeyml-%ED%8C%8C%EC%9D%BC</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;docker-compose.yml 파일&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;bitnami/redis 이용&lt;/h3&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;services:
  my-redis-a:
    hostname: redis-master
    container_name: redis-master
    image: &quot;bitnami/redis&quot;
    environment:
      - REDIS_REPLICATION_MODE=master
      - ALLOW_EMPTY_PASSWORD=yes
    ports:
      - 5000:6379

  my-redis-b:
    hostname: redis-replicas-1
    container_name: redis-replicas-1
    image: &quot;bitnami/redis&quot;
    environment:
      - REDIS_REPLICATION_MODE=slave
      - REDIS_MASTER_HOST=redis-master
      - ALLOW_EMPTY_PASSWORD=yes
    ports:
      - 5001:6379
    depends_on:
      - my-redis-a

  my-redis-c:
    hostname: redis-replicas-2
    container_name: redis-replicas-2
    image: &quot;bitnami/redis&quot;
    environment:
      - REDIS_REPLICATION_MODE=slave
      - REDIS_MASTER_HOST=redis-master
      - ALLOW_EMPTY_PASSWORD=yes
    ports:
      - 5002:6379
    depends_on:
      - my-redis-a

  redis-sentinel-1:
    container_name: sentinel1
    image: 'bitnami/redis-sentinel:latest'
    environment:
      - REDIS_SENTINEL_DOWN_AFTER_MILLISECONDS=3000
      - REDIS_MASTER_HOST=redis-master
      - REDIS_MASTER_PORT_NUMBER=6379
      - REDIS_MASTER_SET=mymaster
      - REDIS_SENTINEL_QUORUM=2
    ports:
      - 26379:26379
    depends_on:
      - my-redis-a
      - my-redis-b
      - my-redis-c

  redis-sentinel-2:
    container_name: sentinel2
    image: 'bitnami/redis-sentinel:latest'
    environment:
      - REDIS_SENTINEL_DOWN_AFTER_MILLISECONDS=3000
      - REDIS_MASTER_HOST=redis-master
      - REDIS_MASTER_PORT_NUMBER=6379
      - REDIS_MASTER_SET=mymaster
      - REDIS_SENTINEL_QUORUM=2
    ports:
      - 26380:26379
    depends_on:
      - my-redis-a
      - my-redis-b
      - my-redis-c

  redis-sentinel-3:
    container_name: sentinel3
    image: 'bitnami/redis-sentinel:latest'
    environment:
      - REDIS_SENTINEL_DOWN_AFTER_MILLISECONDS=3000
      - REDIS_MASTER_HOST=redis-master
      - REDIS_MASTER_PORT_NUMBER=6379
      - REDIS_MASTER_SET=mymaster
      - REDIS_SENTINEL_QUORUM=2
    ports:
      - 26381:26379
    depends_on:
      - my-redis-a
      - my-redis-b
      - my-redis-c&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;redis-cli 로 어떤 pod가 master 역할을 하는지 확인하는 명령어&lt;/h2&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;redis-cli info | grep role&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Docker</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/688</guid>
      <comments>https://series.tistory.com/entry/Redis-master-replicas-sentinel-%EA%B5%AC%EC%84%B1-%EC%8B%9C-docker-composeyml-%ED%8C%8C%EC%9D%BC#entry688comment</comments>
      <pubDate>Sat, 27 Apr 2024 21:37:08 +0900</pubDate>
    </item>
    <item>
      <title>Amazon Linux 2023 에 Redis 설치하기</title>
      <link>https://series.tistory.com/entry/Amazon-Linux-2023-%EC%97%90-Redis-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Redis 설치&lt;/h2&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;sudo yum -y install openssl-devel gcc  
wget http://download.redis.io/redis-stable.tar.gz  
tar xvzf redis-stable.tar.gz  
cd redis-stable  
make distclean  
make redis-cli BUILD\_TLS=yes  
sudo install -m 755 src/redis-cli /usr/local/bin/&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실행&lt;/h2&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;./redis/src/redis-server&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설치한 레디스 파일 전역 디렉토리로 복사&lt;/h2&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;sudo cp src/redis-server src/redis-cli /usr/local/bin/&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;config 파일을 /etc/redis로 복사&lt;/h2&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;sudo mkdir /etc/redis
sudo cp src/redis.conf /etc/redis&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;config 설정 변경&lt;/h2&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;sudo vi /etc/redis/redis.conf&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이후 redis-server 명령어로 레디스 실행&lt;/h2&gt;</description>
      <category>AWS</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/687</guid>
      <comments>https://series.tistory.com/entry/Amazon-Linux-2023-%EC%97%90-Redis-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0#entry687comment</comments>
      <pubDate>Fri, 19 Apr 2024 00:02:53 +0900</pubDate>
    </item>
    <item>
      <title>Spock 테스트 시 java.lang.NullPointerException: Cannot invoke method save() on null object 오류</title>
      <link>https://series.tistory.com/entry/Spock-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%8B%9C-javalangNullPointerException-Cannot-invoke-method-save-on-null-object-%EC%98%A4%EB%A5%98</link>
      <description>&lt;h1&gt;문제점&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Spock 테스트 시 Repository를 주입받지 못하는 오류가 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;해결&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;build.gradle 에서 spring 3.2.4 버전을 기준으로 spock 버전을 재설정하여 해결&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;testImplementation 'org.spockframework:spock-core:2.4-M1-groovy-4.0'
testImplementation 'org.spockframework:spock-spring:2.4-M1-groovy-4.0'&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;mariadb testcontainers&lt;/h1&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;// testcontainers
testImplementation 'org.testcontainers:spock:1.19.7'
testImplementation 'org.testcontainers:mariadb:1.19.7'&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;build.gradle 전체&lt;/h1&gt;
&lt;pre class=&quot;puppet&quot;&gt;&lt;code&gt;plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.4'
    id 'io.spring.dependency-management' version '1.1.4'
    id 'groovy'
}

group = 'com.valletta'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = '21'
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

bootJar {
    archiveFileName = 'app.jar'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    testImplementation 'org.spockframework:spock-core:2.4-M1-groovy-4.0'
    testImplementation 'org.spockframework:spock-spring:2.4-M1-groovy-4.0'

    // testcontainers
    testImplementation 'org.testcontainers:spock:1.19.7'
    testImplementation 'org.testcontainers:mariadb:1.19.7'
}

tasks.named('test') {
    useJUnitPlatform()
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/686</guid>
      <comments>https://series.tistory.com/entry/Spock-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%8B%9C-javalangNullPointerException-Cannot-invoke-method-save-on-null-object-%EC%98%A4%EB%A5%98#entry686comment</comments>
      <pubDate>Sat, 30 Mar 2024 15:08:38 +0900</pubDate>
    </item>
    <item>
      <title>Docker - docker bind: an attempt was made to access a socket in a way forbidden by its access permissions. 오류 시</title>
      <link>https://series.tistory.com/entry/Docker-docker-bind-an-attempt-was-made-to-access-a-socket-in-a-way-forbidden-by-its-access-permissions-%EC%98%A4%EB%A5%98-%EC%8B%9C</link>
      <description>&lt;h1&gt;원인&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;사용하고자 하는 포트가 사용이 제한되었기 때문입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;해결 방법&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;powershell을 관리자 권한으로 열어서 아래 명령어를 입력하면 제한된 포트들 리스트들이 나옵니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;netsh interface ipv4 show excludedportrange protocol=tcp&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;아래 순서대로 해주면 원하는 포트로 도커를 실행시킬 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;net stop winnat netsh int ipv4 add excludedportrange protocol=tcp startport=6379

numberofports=1
또는
netsh int ipv4 add excludedportrange protocol=tcp startport=6379 numberofports=1

set start winnat&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;docker ps 명령어로 도커 컨테이너가 잘 생성되었는지 확인할 수 있습니다.&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;1044&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ca0fQX/btsGefWvtWR/o0UEuBpVxHuayzpVlQevt1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ca0fQX/btsGefWvtWR/o0UEuBpVxHuayzpVlQevt1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ca0fQX/btsGefWvtWR/o0UEuBpVxHuayzpVlQevt1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fca0fQX%2FbtsGefWvtWR%2Fo0UEuBpVxHuayzpVlQevt1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1044&quot; height=&quot;147&quot; data-origin-width=&quot;1044&quot; data-origin-height=&quot;147&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1234&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7x4kq/btsGd7qTtD0/VyJVNWM2IUIG37LP20ltVK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7x4kq/btsGd7qTtD0/VyJVNWM2IUIG37LP20ltVK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7x4kq/btsGd7qTtD0/VyJVNWM2IUIG37LP20ltVK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7x4kq%2FbtsGd7qTtD0%2FVyJVNWM2IUIG37LP20ltVK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1234&quot; height=&quot;62&quot; data-origin-width=&quot;1234&quot; data-origin-height=&quot;62&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Docker</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/685</guid>
      <comments>https://series.tistory.com/entry/Docker-docker-bind-an-attempt-was-made-to-access-a-socket-in-a-way-forbidden-by-its-access-permissions-%EC%98%A4%EB%A5%98-%EC%8B%9C#entry685comment</comments>
      <pubDate>Fri, 29 Mar 2024 20:50:20 +0900</pubDate>
    </item>
    <item>
      <title>Pycharm - Cannot connect to the Docker daemon at unix:///var/run/docker.sock 오류</title>
      <link>https://series.tistory.com/entry/Pycharm-Cannot-connect-to-the-Docker-daemon-at-unixvarrundockersock-%EC%98%A4%EB%A5%98</link>
      <description>&lt;h1&gt;해결 방법&lt;/h1&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;pre class=&quot;awk&quot;&gt;&lt;code&gt;# {name}에는 자신이 macOS에 설정한 값을 넣는다.
sudo ln -s /Users/{name}/.docker/run/docker.sock /var/run/&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;803&quot; data-origin-height=&quot;603&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tJh15/btsF6fowRv5/AJDEOvL9piDYsU0WMAhofK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tJh15/btsF6fowRv5/AJDEOvL9piDYsU0WMAhofK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tJh15/btsF6fowRv5/AJDEOvL9piDYsU0WMAhofK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtJh15%2FbtsF6fowRv5%2FAJDEOvL9piDYsU0WMAhofK%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;803&quot; height=&quot;603&quot; data-origin-width=&quot;803&quot; data-origin-height=&quot;603&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Python</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/684</guid>
      <comments>https://series.tistory.com/entry/Pycharm-Cannot-connect-to-the-Docker-daemon-at-unixvarrundockersock-%EC%98%A4%EB%A5%98#entry684comment</comments>
      <pubDate>Tue, 26 Mar 2024 13:27:14 +0900</pubDate>
    </item>
    <item>
      <title>AWS Cloudwatch - Log Insights 쿼리 예시 및 설명</title>
      <link>https://series.tistory.com/entry/AWS-Cloudwatch-Log-Insights-%EC%BF%BC%EB%A6%AC-%EC%98%88%EC%8B%9C-%EB%B0%8F-%EC%84%A4%EB%AA%85</link>
      <description>&lt;pre&gt;&lt;code&gt;
# fields @timestamp, @message, @logStream, @log
fields @timestamp
| parse @message &amp;quot;* * [*] * - [*] [*] : *&amp;quot; as springProfile, appName, instanceId, logLevel, traceId, classPath, errorMessage
| filter logLevel = &amp;quot;ERROR&amp;quot;
| filter appName = &amp;quot;goods-service&amp;quot;
| filter traceId = &amp;quot;aaaaabbbbcccc123123&amp;quot;
| sort @timestamp desc
| limit 1000
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;@timestamp 필드를 출력으로 선택합니다.&lt;/li&gt;
&lt;li&gt;@message 필드를 지정된 패턴에 따라 파싱하 springProfile, appName, instanceId, logLevel, traceId, classPath, errorMessage 필드로 분리합니다.&lt;/li&gt;
&lt;li&gt;logLevel 필드를 &amp;quot;ERROR&amp;quot;로 필터링하여 오류 로그만 선택합니다.&lt;/li&gt;
&lt;li&gt;appName 필드를 &amp;quot;goods-service&amp;quot;로 필터링하여 특정 어플리케이션 로그만 선택합니다.&lt;/li&gt;
&lt;li&gt;traceId 필드를 &amp;quot;65fa77ba7e360da8f0ca7ae7ca81d965&amp;quot;로 필터링하여 특정 추적 ID를 가진 로그만 선택합니다.&lt;/li&gt;
&lt;li&gt;@timestamp 필드를 내림차순으로 정렬합니다.&lt;/li&gt;
&lt;li&gt;최대 1000개의 결과만 반환합니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AWS</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/683</guid>
      <comments>https://series.tistory.com/entry/AWS-Cloudwatch-Log-Insights-%EC%BF%BC%EB%A6%AC-%EC%98%88%EC%8B%9C-%EB%B0%8F-%EC%84%A4%EB%AA%85#entry683comment</comments>
      <pubDate>Wed, 20 Mar 2024 16:36:45 +0900</pubDate>
    </item>
    <item>
      <title>Springdoc - use-fqn 설정으로 스웨거에서 Response 이름 충돌 문제 해결하기</title>
      <link>https://series.tistory.com/entry/Springdoc-use-fqn-%EC%84%A4%EC%A0%95%EC%9C%BC%EB%A1%9C-%EC%8A%A4%EC%9B%A8%EA%B1%B0%EC%97%90%EC%84%9C-Response-%EC%9D%B4%EB%A6%84-%EC%B6%A9%EB%8F%8C-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0</link>
      <description>&lt;p&gt;스웨거 문서에서 Response 모델 이름이 충돌하여 발생하는 문제가 있을 수 있습니다.&lt;br&gt;Springdoc를 사용하여 간단하게 해결할 수 있습니다.&lt;/p&gt;
&lt;p&gt;Springdoc는 스프링 부트 애플리케이션에서 OpenAPI 3.x 스펙을 지원하는 라이브러리입니다.&lt;br&gt;이를 사용하여 스웨거 문서를 생성하고 커스터마이징할 수 있습니다.&lt;br&gt;Springdoc를 사용하여 Response 이름 충돌 문제를 해결하는 방법에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;application.yml 설정하기: use-fqn 옵션을 true로 설정하여 Response 모델의 완전한 클래스 경로(Fully Qualified Name)를 사용하도록 설정합니다.&lt;br&gt;이를 통해 스웨거가 동일한 이름을 가진 모델을 구분할 수 있게 됩니다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;springdoc:
  use-fqn: true&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;위의 설정을 적용했을 때 Response 모델 이름이 충돌하지 않고 정확한 예시 값이 표시됩니다.&lt;/p&gt;
&lt;h3&gt;application.yml - springdoc 부분&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;springdoc:
  version: &amp;#39;1.6.13&amp;#39;
  api-docs:
    enabled: true
    path: /v3/api-docs
    groups:
      enabled: true
  swagger-ui:
    path: /swagger-ui.html
    tagsSorter: alpha
    use-root-path: true
    groups-order: desc
  cache:
    disabled: true
  use-fqn: true&lt;/code&gt;&lt;/pre&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/682</guid>
      <comments>https://series.tistory.com/entry/Springdoc-use-fqn-%EC%84%A4%EC%A0%95%EC%9C%BC%EB%A1%9C-%EC%8A%A4%EC%9B%A8%EA%B1%B0%EC%97%90%EC%84%9C-Response-%EC%9D%B4%EB%A6%84-%EC%B6%A9%EB%8F%8C-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0#entry682comment</comments>
      <pubDate>Tue, 19 Mar 2024 09:16:47 +0900</pubDate>
    </item>
    <item>
      <title>JPA에서 @IdClass를 사용한 복합 주키 매핑</title>
      <link>https://series.tistory.com/entry/JPA%EC%97%90%EC%84%9C-IdClass%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%9C-%EB%B3%B5%ED%95%A9-%EC%A3%BC%ED%82%A4-%EB%A7%A4%ED%95%91</link>
      <description>&lt;p&gt;JPA에서 @IdClass를 사용한 복합 주키 매핑&lt;br&gt;자바 영속성 API(JPA)에서는 @IdClass 주석을 사용하여 복합 주키를 지정합니다.&lt;br&gt;이를 통해 엔터티 클래스와 별도로 기본 키 클래스를 정의할 수 있습니다.&lt;br&gt;예제를 통해 @IdClass를 사용하여 복합 주키 매핑하는 방법을 살펴보겠습니다.&lt;/p&gt;
&lt;h1&gt;엔터티 클래스: UserGroupMappingEntity&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;java
Copy code
import javax.persistence.*;

@Getter
@Setter
@ToString
@Entity
@Table(name = &amp;quot;user_group_mapping&amp;quot;)
@IdClass(UserGroupMappingId.class)
public class UserGroupMappingEntity extends BaseEntity {

    @Id
    @Column(name = &amp;quot;user_group_id&amp;quot;)
    private String userGroupId;

    @Id
    @Column(name = &amp;quot;user_id&amp;quot;)
    private String userId;

    @Column(name = &amp;quot;user_group_name&amp;quot;)
    private String userGroupName;

    private String description;
}&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;기본 키 클래스: UserGroupMappingId&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;java
Copy code
import java.io.Serializable;

@Getter
@Setter
@ToString
public class UserGroupMappingId implements Serializable {

    private String userGroupId;

    private String userId;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이 예제에서는:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UserGroupMappingEntity 클래스는 &amp;quot;user_group_mapping&amp;quot; 테이블에 매핑된 엔터티를 나타냅니다.&lt;/li&gt;
&lt;li&gt;@IdClass(UserGroupMappingId.class)를 사용하여 UserGroupMappingId 클래스가 이 엔터티의 복합 기본 키를 포함한다는 것을 지정합니다.&lt;/li&gt;
&lt;li&gt;UserGroupMappingId 클래스는 복합 기본 키 필드 userGroupId와 userId를 정의합니다.&lt;/li&gt;
&lt;li&gt;UserGroupMappingEntity 클래스의 기본 키 필드는 @Id로 주석이 달려 있으며, 이는 이들이 복합 기본 키의 일부임을 나타냅니다.&lt;/li&gt;
&lt;li&gt;UserGroupMappingEntity 클래스의 다른 필드는 테이블의 열에 매핑됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 접근 방식을 사용하면 엔터티 모델에서 복합 기본 키를 깔끔하게 나타낼 수 있으며, 특히 기존 데이터베이스나 복합 기본 키가 있는 테이블과 작업할 때 유용합니다.&lt;/p&gt;</description>
      <category>JPA</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/681</guid>
      <comments>https://series.tistory.com/entry/JPA%EC%97%90%EC%84%9C-IdClass%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%9C-%EB%B3%B5%ED%95%A9-%EC%A3%BC%ED%82%A4-%EB%A7%A4%ED%95%91#entry681comment</comments>
      <pubDate>Fri, 15 Mar 2024 09:59:01 +0900</pubDate>
    </item>
    <item>
      <title>git flow 운영 정책</title>
      <link>https://series.tistory.com/entry/git-flow-%EC%9A%B4%EC%98%81-%EC%A0%95%EC%B1%85</link>
      <description>&lt;h2 id=&quot;서버&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;2&quot; data-ke-size=&quot;size26&quot;&gt;서버&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;dev : 개발 단계 확인&lt;/li&gt;
&lt;li&gt;stage : QA 검수등의 사용자 테스트&lt;/li&gt;
&lt;li&gt;prod : 운영&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;브랜치&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;68&quot; data-ke-size=&quot;size26&quot;&gt;브랜치&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;feature : 담당자 기능 브랜치&lt;/li&gt;
&lt;li&gt;develop : 개발 브랜치&lt;/li&gt;
&lt;li&gt;stage : QA 검수등 테스트 브랜치&lt;/li&gt;
&lt;li&gt;release : 배포 브랜치
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반적인 gitflow 에서는 develop 브랜치가 안정화 되었을때 생성하나, 배포시 브랜치 머지용도로 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;master : 운영 브랜치&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;상품-git-Flow&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;253&quot; data-ke-size=&quot;size26&quot;&gt;상품 git Flow&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;266&quot; data-ke-size=&quot;size16&quot;&gt;[1안]&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1134&quot; data-origin-height=&quot;848&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oROXP/btsFzbU9t3B/hYjynpYW3oTetjQrEXHmRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oROXP/btsFzbU9t3B/hYjynpYW3oTetjQrEXHmRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oROXP/btsFzbU9t3B/hYjynpYW3oTetjQrEXHmRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoROXP%2FbtsFzbU9t3B%2FhYjynpYW3oTetjQrEXHmRK%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;860&quot; height=&quot;643&quot; data-origin-width=&quot;1134&quot; data-origin-height=&quot;848&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;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본 프로세스&lt;/li&gt;
&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;feature &amp;rarr; 개발 &amp;rarr; PR &amp;rarr; develop , release 머지
&lt;ol style=&quot;list-style-type: decimal;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;develop 머지 후 개발자 테스트 수행 중 변경사항 발생 시 &lt;b&gt;위 프로세스(1번)와 동일 수행&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;release &amp;rarr; stage, develop 머지
&lt;ol style=&quot;list-style-type: decimal;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;만약, 개발자가 develop 머지 없이 release에만 머지를 수행할 경우를 대비하여 hook 설정
&lt;ol style=&quot;list-style-type: decimal;&quot; data-indent-level=&quot;3&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;hook 내용
&lt;ol style=&quot;list-style-type: decimal;&quot; data-indent-level=&quot;4&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;로컬&lt;/b&gt;에서 release upstream 반영 시 develop에 커밋해쉬정보가 존재하는지 검증합니다.&lt;/li&gt;
&lt;li&gt;위치 : 프로젝트/.git/hooks&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot;&gt;[2안]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1135&quot; data-origin-height=&quot;924&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UM0pm/btsFB5fdCM4/GLfK6dS5Ek1FikrwwIh6gK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UM0pm/btsFB5fdCM4/GLfK6dS5Ek1FikrwwIh6gK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UM0pm/btsFB5fdCM4/GLfK6dS5Ek1FikrwwIh6gK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUM0pm%2FbtsFB5fdCM4%2FGLfK6dS5Ek1FikrwwIh6gK%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;1135&quot; height=&quot;924&quot; data-origin-width=&quot;1135&quot; data-origin-height=&quot;924&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;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;release를 develop과 stage 에 반영&lt;/li&gt;
&lt;li&gt;릴리즈에 없는 내용이 develop이나 stage 에 반영 할 수 없음
&lt;ol style=&quot;list-style-type: decimal;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;feature를 release를 거치지 않고 올리거나, develop, stage 에서 직접 수정후 push 불가&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;develop 을 stage로 반영 할 수 없음&lt;/li&gt;
&lt;li&gt;v2에 개발된 소스가 배포일자 변경등으로 v1에 포함되어야 하는 경우
&lt;ol style=&quot;list-style-type: decimal;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;v2 전체가 v1으로 포함되어도 되는경우
&lt;ol style=&quot;list-style-type: decimal;&quot; data-indent-level=&quot;3&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;v2에 v1을 pull 받아 싱크 맞추고 머지&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;v2 일부가 v1으로 포함되어야 하는 경우
&lt;ol style=&quot;list-style-type: decimal;&quot; data-indent-level=&quot;3&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;feature에 pull 받아 싱크 맞추고 release v1에 머지&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;956&quot; data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 해당 머지과정에서 컨플릭트가 발생할 수 있음(base 브랜치가 다르므로), 발생 된 컨플릭트는 담당자가 해결 후 머지&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;v1에 올린 내용을 수정해야 할 경우 (스테이지 검수과정에서 변경 필요 시)
&lt;ol style=&quot;list-style-type: decimal;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;해당 release 기준으로 피처를 재생성 및 기존 feature에 해당 release를 pull 받아서, 싱크 맞추고 변경 개발 수행&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;지라-티켓-관련&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;1161&quot; data-ke-size=&quot;size23&quot;&gt;지라 티켓 관련&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소스 변경이 필요한 작업은 티켓을 생성&lt;/li&gt;
&lt;li&gt;QA 할 내용은 지라 release 에 티켓 추가&lt;/li&gt;
&lt;li&gt;hotfix의 경우 선배포 후 티켓추가 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;브랜치-생성-및-수행-기준&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;1259&quot; data-ke-size=&quot;size23&quot;&gt;브랜치 생성 및 수행 기준&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;feature는 develop 기준으로 생성 &lt;u data-renderer-mark=&quot;true&quot;&gt;(PR 수행)&lt;/u&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;stage&lt;/b&gt;는 release 머지
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스테이지 = master 싱크로 배포할 내용만 머지함.&lt;/li&gt;
&lt;li&gt;스테이지에는 release 한개의 브랜치만 머지함.
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;3&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ex) 11월 7일 배포건 &amp;rarr; release/v231107 &amp;rarr; stage&lt;/li&gt;
&lt;li&gt;ex) 11월 21일 배포건 &amp;rarr; release/v231121 &amp;rarr; stage&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;release&lt;/b&gt;는 stage 기준으로 생성
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;브랜치명 : release 티켓 명 (ex . v231026)&lt;/li&gt;
&lt;li&gt;생성시점 : 배포일자 확정 즉시&lt;/li&gt;
&lt;li&gt;&lt;b&gt;머지 : feature &amp;rarr; release &lt;/b&gt;&lt;/li&gt;
&lt;li&gt;release &amp;rarr; stage 시 release &amp;rarr; develop 동시 수행 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;hotfix &lt;/b&gt;는 master 기준으로 생성
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff;&quot; data-color=&quot;blue&quot; data-node-type=&quot;status&quot;&gt;&lt;span style=&quot;background-color: #000000;&quot;&gt;케이스&lt;/span&gt;&lt;/span&gt; 긴급하게 수정후 바로 머지해야 할 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;3&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;develop, master 머지
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;4&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;cf) gitFlow 사용 시 develop, master 동시 머지 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff;&quot; data-color=&quot;blue&quot; data-node-type=&quot;status&quot;&gt;&lt;span style=&quot;background-color: #000000;&quot;&gt;케이스&lt;/span&gt; &lt;/span&gt;당장 배포하지 않아도 되는 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;3&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PR 수행 후 develop, master 머지 ( PR 시 머지대상 브랜치는 master)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;GitFlow-설명&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;1866&quot; data-ke-size=&quot;size23&quot;&gt;GitFlow 설명&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 id=&quot;feature&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;1878&quot; data-ke-size=&quot;size20&quot;&gt;feature&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;설명
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;start feature : develop 기준으로 생성&lt;/li&gt;
&lt;li&gt;publish feature : upstream 반영&lt;/li&gt;
&lt;li&gt;finish feature : develop 머지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;사용 예
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;start feature &amp;rarr; 개발 &amp;rarr; publish feature &amp;rarr; PR(비트버켓) &amp;rarr; 머지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;release&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;2069&quot; data-ke-size=&quot;size20&quot;&gt;release&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;설명
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;start release : develop 기준으로 생성&lt;/li&gt;
&lt;li&gt;publish release : push(upStream 반영)&lt;/li&gt;
&lt;li&gt;finish release : develop , master 머지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;사용 예
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;master 브랜치 기준 release/{릴리즈티켓명} 생성 후 push(upStream 반영)&lt;/li&gt;
&lt;li&gt;release/{릴리즈티켓명} 에 배포 내용 머지&lt;/li&gt;
&lt;li&gt;finish release : develop , master 머지 &amp;rarr; 각 브랜치(develop , master) push &amp;rarr; 배포&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;hotfix&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-renderer-start-pos=&quot;2380&quot; data-ke-size=&quot;size20&quot;&gt;hotfix&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;설명
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;start hotfix : master 기준으로 생성&lt;/li&gt;
&lt;li&gt;publish hotfix : push(upStream 반영)&lt;/li&gt;
&lt;li&gt;finish hotfix : develop , master 머지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;사용 예
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;start hotfix &amp;rarr; publish hotfix &amp;rarr; PR &amp;rarr; finish hotfix &amp;rarr; 각 브랜치(develop , master) push &amp;rarr; 배포&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Git</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/680</guid>
      <comments>https://series.tistory.com/entry/git-flow-%EC%9A%B4%EC%98%81-%EC%A0%95%EC%B1%85#entry680comment</comments>
      <pubDate>Wed, 6 Mar 2024 14:34:17 +0900</pubDate>
    </item>
    <item>
      <title>ReflectionTestUtils를 사용하여 private 변수나 메소드(함수)를 테스트할 수 있습니다</title>
      <link>https://series.tistory.com/entry/ReflectionTestUtils%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-private-%EB%B3%80%EC%88%98%EB%82%98-%EB%A9%94%EC%86%8C%EB%93%9C%ED%95%A8%EC%88%98%EB%A5%BC-%ED%85%8C%EC%8A%A4%ED%8A%B8%ED%95%A0-%EC%88%98-%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4</link>
      <description>&lt;h2 id=&quot;reflectiontestutils&quot; style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;ReflectionTestUtils&lt;/h2&gt;
&lt;h3 id=&quot;대상-class&quot; style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;대상 Class&lt;/h3&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;
&lt;div style=&quot;background-color: #272822; color: #d0d0d0;&quot;&gt;
&lt;pre class=&quot;java&quot; style=&quot;background-color: #272822; color: #d0d0d0;&quot;&gt;&lt;code&gt;@Component
@Getter
public class ReflectionTestUtilsComponent {

    private int privateValue;

    private int privateMethod(int a, int b) {
        privateValue += a;
        privateValue += b;
        return privateValue;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;private-변수-테스트&quot; data-ke-size=&quot;size23&quot;&gt;private 변수 테스트&lt;/h3&gt;
&lt;h4 id=&quot;형태&quot; data-ke-size=&quot;size20&quot;&gt;형태&lt;/h4&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #272822; color: #d0d0d0;&quot;&gt;
&lt;pre class=&quot;delphi&quot; style=&quot;background-color: #272822; color: #d0d0d0;&quot;&gt;&lt;code&gt;static void	setField(Class&amp;lt;?&amp;gt; targetClass, String name, Object value)

static void	setField(Class&amp;lt;?&amp;gt; targetClass, String name, Object value, Class&amp;lt;?&amp;gt; type)

static void	setField(Object targetObject, Class&amp;lt;?&amp;gt; targetClass, String name, Object value, Class&amp;lt;?&amp;gt; type)

static void	setField(Object targetObject, String name, Object value)

static void	setField(Object targetObject, String name, Object value, Class&amp;lt;?&amp;gt; type)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 id=&quot;사용-예시&quot; data-ke-size=&quot;size20&quot;&gt;사용 예시&lt;/h4&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #272822; color: #d0d0d0;&quot;&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;background-color: #272822; color: #d0d0d0;&quot;&gt;&lt;code&gt;@Test
public void testPrivateValue() {
    ReflectionTestUtils.setField(reflectionTestUtilsComponent, &quot;privateValue&quot;, 100);
    // ReflectionTestUtils.setField(대상 객체, &quot;변수명&quot;, 원하는 값);

    Assertions.assertEquals(100, reflectionTestUtilsComponent.getPrivateValue());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;private-메소드함수-테스트&quot; data-ke-size=&quot;size23&quot;&gt;private 메소드(함수) 테스트&lt;/h3&gt;
&lt;h4 id=&quot;형태-1&quot; data-ke-size=&quot;size20&quot;&gt;형태&lt;/h4&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #272822; color: #d0d0d0;&quot;&gt;
&lt;pre class=&quot;delphi&quot; style=&quot;background-color: #272822; color: #d0d0d0;&quot;&gt;&lt;code&gt;static &amp;lt;T&amp;gt; T	invokeMethod(Class&amp;lt;?&amp;gt; targetClass, String name, Object... args)

static &amp;lt;T&amp;gt; T	invokeMethod(Object targetObject, Class&amp;lt;?&amp;gt; targetClass, String name, Object... args)

static &amp;lt;T&amp;gt; T	invokeMethod(Object target, String name, Object... args)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 id=&quot;사용-예시-1&quot; data-ke-size=&quot;size20&quot;&gt;사용 예시&lt;/h4&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #272822; color: #d0d0d0;&quot;&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;background-color: #272822; color: #d0d0d0;&quot;&gt;&lt;code&gt;@Test
public void testPrivateMethod() {
    ReflectionTestUtils.setField(reflectionTestUtilsComponent, &quot;privateValue&quot;, 100);
    // ReflectionTestUtils.setField(대상 객체, &quot;변수명&quot;, 원하는 값);

    Assertions.assertEquals(103, (Integer) ReflectionTestUtils.invokeMethod(reflectionTestUtilsComponent, &quot;privateMethod&quot;, 1, 2));
    // ReflectionTestUtils.invokeMethod(대상 객체, &quot;메소드(함수)명&quot;, 인자);

    Assertions.assertEquals(103, reflectionTestUtilsComponent.getPrivateValue());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/679</guid>
      <comments>https://series.tistory.com/entry/ReflectionTestUtils%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-private-%EB%B3%80%EC%88%98%EB%82%98-%EB%A9%94%EC%86%8C%EB%93%9C%ED%95%A8%EC%88%98%EB%A5%BC-%ED%85%8C%EC%8A%A4%ED%8A%B8%ED%95%A0-%EC%88%98-%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4#entry679comment</comments>
      <pubDate>Sun, 27 Aug 2023 12:40:57 +0900</pubDate>
    </item>
    <item>
      <title>Springboot 테스트 - p6spy 적용하는 방법</title>
      <link>https://series.tistory.com/entry/Springboot-%ED%85%8C%EC%8A%A4%ED%8A%B8-p6spy-%EC%A0%81%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
      <description>&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;@Slf4j
@DisplayName(&quot;JPA 연결 테스트&quot;)
@Import(JpaConfig.class)
@ImportAutoConfiguration({DataSourceDecoratorAutoConfiguration.class, P6SpySqlFormatter.class})
@ActiveProfiles(&quot;local&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@Configuration
public class P6SpySqlFormatter {

    @PostConstruct
    public void setLogMessageFormat() {
        P6SpyOptions.getActiveInstance().setLogMessageFormat(P6spySqlFormatConfiguration.class.getName());
    }

    static public class P6spySqlFormatConfiguration implements MessageFormattingStrategy {

        // 표기에 허용되는 filter
        private static final String ALLOW_FILTER = &quot;com.hanssem&quot;;

        @Override
        public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {

            sql = formatSql(category, sql);
            if (sql.trim().isEmpty()) { // sql 이 없다면 출력하지 않아도 됨
                return &quot;&quot;;
            }

            // stack 을 구성하는 Format을 만든다
            return sql + createStack(connectionId, elapsed);
//            return sql + &quot;\n\n&quot;;
        }

        private String formatSql(String category, String sql) {

            if (sql == null || sql.trim().isEmpty()) {
                return sql;
            }

            // Only format Statement, distinguish DDL And DML
            if (Category.STATEMENT.getName().equals(category)) {
                String tmpsql = sql.trim().toLowerCase(Locale.ROOT);
                if (tmpsql.startsWith(&quot;create&quot;) || tmpsql.startsWith(&quot;alter&quot;) || tmpsql.startsWith(&quot;comment&quot;)) {
                    sql = FormatStyle.DDL.getFormatter().format(sql);
                } else {
                    sql = FormatStyle.BASIC.getFormatter().format(sql);
                }

                sql = &quot;|\n--------------------------------------&quot; + sql;
            }

            return sql;
        }

        // stack 콘솔 표기
        private String createStack(int connectionId, long elapsed) {
            Stack&amp;lt;String&amp;gt; callStack = new Stack&amp;lt;&amp;gt;();
            StackTraceElement[] stackTrace = new Throwable().getStackTrace();

            for (StackTraceElement stackTraceElement : stackTrace) {
                String trace = stackTraceElement.toString();

                // trace 항목을 보고 내게 맞는 것만 필터
                if (trace.startsWith(ALLOW_FILTER)) {
                    callStack.push(trace);
                }
            }

            StringBuilder sb = new StringBuilder();
            int order = 1;
            while (!callStack.isEmpty()) {
                sb.append(&quot;\n\t\t&quot;).append(order++).append(&quot;.&quot;).append(callStack.pop());
            }

            return new StringBuffer().append(&quot;\n\tCall Stack:&quot;).append(sb)
                .append(&quot;\n--------------------------------------\n&quot;)
                .toString();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/678</guid>
      <comments>https://series.tistory.com/entry/Springboot-%ED%85%8C%EC%8A%A4%ED%8A%B8-p6spy-%EC%A0%81%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95#entry678comment</comments>
      <pubDate>Sat, 19 Aug 2023 10:51:11 +0900</pubDate>
    </item>
    <item>
      <title>springboot 3.0 이상 p6spy 설정 (로깅이 안될 경우)</title>
      <link>https://series.tistory.com/entry/springboot-30-%EC%9D%B4%EC%83%81-p6spy-%EC%84%A4%EC%A0%95-%EB%A1%9C%EA%B9%85%EC%9D%B4-%EC%95%88%EB%90%A0-%EA%B2%BD%EC%9A%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;springboot&amp;nbsp;3.0&amp;nbsp;이상&amp;nbsp;p6spy&amp;nbsp;설정&amp;nbsp;(로깅이&amp;nbsp;안될&amp;nbsp;경우)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;springboot가 업데이트되면서 p6spy의 쿼리 로깅이 잘 안되는 문제가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 추가 설정을 통해서 순서와 상관없이 진행을 하시면 해결이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 개발 환경에만 적용하기!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. build.gradle 의존성 추가&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.8.1'&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. [project]/src/main/resources/META-INF/spring 경로에 파일 추가&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 파일 경로 : /src/main/resources/META-INF/spring/&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 파일명 : org.springframework.boot.autoconfigure.AutoConfiguration.imports&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 파일 내용&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;com.github.gavlyukovskiy.boot.jdbc.decorator.DataSourceDecoratorAutoConfiguration&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. [project]/src/main/resources 경로에 파일 추가&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 파일 경로 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;/src/main/resources/&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;* 파일명 :&lt;span&gt; spy.properties&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;* 파일 내용&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;appender=com.p6spy.engine.spy.appender.Slf4JLogger&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. application.yml 에서 다른 쿼리 로그는 헷갈리지 않도록 안보이게 설정&lt;/b&gt;&lt;/h3&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. p6spy 로그를 줄바꿈 formatting하여 가독성 높이기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* config 패키지에 P6spyLogMessageFormatConfiguration.java 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일명은 상관없습니다. 파일 내용이 중요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@Configuration
public class P6spyLogMessageFormatConfiguration {

    @PostConstruct
    public void setLogMessageFormat() {
        P6SpyOptions.getActiveInstance().setLogMessageFormat(P6spySqlFormatConfiguration.class.getName());
    }

    static public class P6spySqlFormatConfiguration implements MessageFormattingStrategy {

        // 표기에 허용되는 filter
        private static final String ALLOW_FILTER = &quot;com.creed&quot;;

        @Override
        public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {

            sql = formatSql(category, sql);
            if (sql.trim().isEmpty()) { // sql 이 없다면 출력하지 않아도 됨
                return &quot;&quot;;
            }

            // stack 을 구성하는 Format을 만든다
            return sql + createStack(connectionId, elapsed);
        }

        private String formatSql(String category, String sql) {

            if (sql == null || sql.trim().equals(&quot;&quot;)) {
                return sql;
            }

            // Only format Statement, distinguish DDL And DML
            if (Category.STATEMENT.getName().equals(category)) {
                String tmpsql = sql.trim().toLowerCase(Locale.ROOT);
                if (tmpsql.startsWith(&quot;create&quot;) || tmpsql.startsWith(&quot;alter&quot;) || tmpsql.startsWith(&quot;comment&quot;)) {
                    sql = FormatStyle.DDL.getFormatter().format(sql);
                } else {
                    sql = FormatStyle.BASIC.getFormatter().format(sql);
                }
                sql = &quot;|\nFormatSql(P6Spy sql, Hibernate format):&quot; + sql;
            }

            return sql;
        }

        // stack 콘솔 표기
        private String createStack(int connectionId, long elapsed) {
            Stack&amp;lt;String&amp;gt; callStack = new Stack&amp;lt;&amp;gt;();
            StackTraceElement[] stackTrace = new Throwable().getStackTrace();

            for (StackTraceElement stackTraceElement : stackTrace) {
                String trace = stackTraceElement.toString();

                // trace 항목을 보고 내게 맞는 것만 필터
                if (trace.startsWith(ALLOW_FILTER)) {
                    callStack.push(trace);
                }
            }

            StringBuilder sb = new StringBuilder();
            int order = 1;
            while (callStack.size() != 0) {
                sb.append(&quot;\n\t\t&quot;).append(order++).append(&quot;.&quot;).append(callStack.pop());
            }

            return new StringBuffer().append(&quot;\n\n\tConnection ID: &quot;).append(connectionId)
                    .append(&quot;\n\tExcution Time: &quot;).append(elapsed).append(&quot;ms&quot;)
                    .append(&quot;\n\tCall Stack:&quot;).append(sb)
                    .append(&quot;\n--------------------------------------&quot;)
                    .toString();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/677</guid>
      <comments>https://series.tistory.com/entry/springboot-30-%EC%9D%B4%EC%83%81-p6spy-%EC%84%A4%EC%A0%95-%EB%A1%9C%EA%B9%85%EC%9D%B4-%EC%95%88%EB%90%A0-%EA%B2%BD%EC%9A%B0#entry677comment</comments>
      <pubDate>Wed, 16 Aug 2023 22:53:55 +0900</pubDate>
    </item>
    <item>
      <title>springboot - SQL Binding 로깅 안되는 문제</title>
      <link>https://series.tistory.com/entry/springboot-SQL-Binding-%EB%A1%9C%EA%B9%85-%EC%95%88%EB%90%98%EB%8A%94-%EB%AC%B8%EC%A0%9C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;application.yml&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;logging:
  level:    
    org.hibernate.orm.jdbc.bind: trace&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;org.hibernate.or&lt;a style=&quot;color: #ee2323;&quot; href=&quot;http://m.jdbc.bind:&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;m.jdbc.bind:&lt;/a&gt;&amp;nbsp;trace&lt;/b&gt;&lt;/span&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;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;스프링부트 버젼 3.0.0 부터는 하이버네이트가 6.1.5로 버전업이 되면서 하이버네이트가 로깅하는 방식을 변경했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;227&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4Ya3x/btsrqBGmfmX/Kkd2nuVbVHGDAhkLjqrpmk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4Ya3x/btsrqBGmfmX/Kkd2nuVbVHGDAhkLjqrpmk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4Ya3x/btsrqBGmfmX/Kkd2nuVbVHGDAhkLjqrpmk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4Ya3x%2FbtsrqBGmfmX%2FKkd2nuVbVHGDAhkLjqrpmk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;904&quot; height=&quot;227&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;227&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바인딩 잘 되는 것 확인!!&lt;/p&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/676</guid>
      <comments>https://series.tistory.com/entry/springboot-SQL-Binding-%EB%A1%9C%EA%B9%85-%EC%95%88%EB%90%98%EB%8A%94-%EB%AC%B8%EC%A0%9C#entry676comment</comments>
      <pubDate>Wed, 16 Aug 2023 22:27:06 +0900</pubDate>
    </item>
    <item>
      <title>querydsl - @QueryProjection</title>
      <link>https://series.tistory.com/entry/querydsl-QueryProjection</link>
      <description>&lt;pre class=&quot;arduino&quot; style=&quot;color: #000000; text-align: left;&quot;&gt;&lt;code&gt;public class MemberDto {
    private String name;
    private int age;

    @QueryProjection // 어노테이션 추가
    public MemberDto(String name, int age) {
        this.name = name;
        this.age = age;
    }
}


public void findDtoByQueryProjection() {
	queryFactory
		.select(new QMemberDto(member.name, member.age))
		.from(member)
		.fetch();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;QDto로 생성된 생성자를 사용하는 방법&lt;br /&gt;&lt;b&gt;런타임 에러와 컴파일 에러 모두 잡을 수 있다.&lt;/b&gt;&lt;br /&gt;하지만 DTO 특성상 전 계층(Service, Controller)에 데이터를 전달하기 위한 객체인데 모든 사용에서 Querydsl 의존성을 가지게 된다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@daoh98/Querydsl-QuerydslPredicateExecutor-%EC%99%80-Querydsl-%EC%98%AC%EB%B0%94%EB%A5%B8-%EC%82%AC%EC%9A%A9%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@daoh98/Querydsl-QuerydslPredicateExecutor-%EC%99%80-Querydsl-%EC%98%AC%EB%B0%94%EB%A5%B8-%EC%82%AC%EC%9A%A9%EB%B2%95&lt;/a&gt;&lt;/p&gt;</description>
      <category>JPA</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/675</guid>
      <comments>https://series.tistory.com/entry/querydsl-QueryProjection#entry675comment</comments>
      <pubDate>Wed, 16 Aug 2023 22:05:46 +0900</pubDate>
    </item>
    <item>
      <title>Springboot 3.0.0 이상 - Querydsl build.gradle 설정 및 NoClassDefFoundError 오류 대응 방법</title>
      <link>https://series.tistory.com/entry/Springboot-300-%EC%9D%B4%EC%83%81-Querydsl-buildgradle-%EC%84%A4%EC%A0%95-%EB%B0%8F-NoClassDefFoundError-%EC%98%A4%EB%A5%98-%EB%8C%80%EC%9D%91-%EB%B0%A9%EB%B2%95</link>
      <description>&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. build.gradle 에 의존성 추가 및 Q class 설정&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;// ************* 최상단
buildscript {
    ext {
        queryDslVersion = &quot;5.0.0&quot;
    }
}



// ************* 의존성 부분
// queryDSL 설정
    implementation &quot;com.querydsl:querydsl-jpa:${queryDslVersion}:jakarta&quot;
    implementation &quot;com.querydsl:querydsl-core&quot;
    implementation &quot;com.querydsl:querydsl-collections&quot;

    annotationProcessor &quot;com.querydsl:querydsl-apt:${queryDslVersion}:jakarta&quot; // querydsl JPAAnnotationProcessor 사용 지정
    annotationProcessor &quot;jakarta.annotation:jakarta.annotation-api&quot; // java.lang.NoClassDefFoundError (javax.annotation.Generated) 대응 코드
    annotationProcessor &quot;jakarta.persistence:jakarta.persistence-api&quot; // java.lang.NoClassDefFoundError (javax.annotation.Entity) 대응 코드



// ************* 하단
// Querydsl 설정부
def querydslDir = 'src/main/generated'

// querydsl QClass 파일 생성 위치를 지정
tasks.withType(JavaCompile) {
    options.getGeneratedSourceOutputDirectory().set(file(querydslDir))
}

// java source set 에 querydsl QClass 위치 추가
sourceSets {
    main.java.srcDirs += [querydslDir]
}

// gradle clean 시에 QClass 디렉토리 삭제
clean {
    delete file(querydslDir)
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. &quot;.gitignore&quot; 파일에 추가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fafafa; color: #383a42; text-align: start;&quot;&gt;/src/main/generated/&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;* 발생할 수 있는 오류들 해결&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;1. java.lang.NoClassDefFoundError&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;:javax/persistence/Entity&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;2. attempt to recreate a file for type qclass&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;3. could not find class file for querydsl&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;4. Unable to load class 'javax.persistence.Entity'.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JPA</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/674</guid>
      <comments>https://series.tistory.com/entry/Springboot-300-%EC%9D%B4%EC%83%81-Querydsl-buildgradle-%EC%84%A4%EC%A0%95-%EB%B0%8F-NoClassDefFoundError-%EC%98%A4%EB%A5%98-%EB%8C%80%EC%9D%91-%EB%B0%A9%EB%B2%95#entry674comment</comments>
      <pubDate>Wed, 16 Aug 2023 20:15:46 +0900</pubDate>
    </item>
    <item>
      <title>JUnit 테스트 시 &amp;quot;Sharing is only supported for boot loader classes because bootstrap classpath has been appended&amp;quot; 경고</title>
      <link>https://series.tistory.com/entry/JUnit-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%8B%9C-Sharing-is-only-supported-for-boot-loader-classes-because-bootstrap-classpath-has-been-appended-%EA%B2%BD%EA%B3%A0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;JUnit 테스트 시&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&quot;Sharing is only supported for boot loader classes because bootstrap classpath has been appended&quot; 경고&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램을 실행하는데 문제는 없지만 계속 경고가 떠서 신경이 쓰이는 문구였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글링을 해본 결과를 모두 적용해 봤지만 모두 실패ㅠㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;(실패)&lt;/span&gt;&lt;/b&gt; 인텔리제이 -&amp;gt; Settings - Build, Execution, Deployment -&amp;gt; Debugger -&amp;gt; Async Stack Traces&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 설정 - async 로 검색 -&amp;gt; Async Stack Traces 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Instrumenting agent (requires debugger restart) 체크박스 해제&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ae2D3/btsrgQxEP0P/wZgf6Ho6tUCIF8M7A5bf11/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ae2D3/btsrgQxEP0P/wZgf6Ho6tUCIF8M7A5bf11/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ae2D3/btsrgQxEP0P/wZgf6Ho6tUCIF8M7A5bf11/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAe2D3%2FbtsrgQxEP0P%2FwZgf6Ho6tUCIF8M7A5bf11%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;839&quot; height=&quot;342&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;&lt;span style=&quot;color: #ee2323; text-align: start;&quot;&gt;(실패) &lt;/span&gt;&lt;/b&gt;Run/Debug Configurations -&amp;gt; Modify options -&amp;gt; &quot;optimization&quot; 타이핑 검색&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Disable Launch optimization 체크&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1345&quot; data-origin-height=&quot;486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lxVQG/btsrrSm54R2/IM5bbe0vgkgneFfdPAT7WK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lxVQG/btsrrSm54R2/IM5bbe0vgkgneFfdPAT7WK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lxVQG/btsrrSm54R2/IM5bbe0vgkgneFfdPAT7WK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlxVQG%2FbtsrrSm54R2%2FIM5bbe0vgkgneFfdPAT7WK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1345&quot; height=&quot;486&quot; data-origin-width=&quot;1345&quot; data-origin-height=&quot;486&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;(성공!!) &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Run/Debug Configurations -&amp;gt; Edit configuration template -&amp;gt; JUnit -&amp;gt; VM options -&amp;gt; &quot;-Xshre:off&quot; 추가&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;963&quot; data-origin-height=&quot;752&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJuu3T/btsrkRpfEKT/kLxkvdkXqy8KspbU645mK0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJuu3T/btsrkRpfEKT/kLxkvdkXqy8KspbU645mK0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJuu3T/btsrkRpfEKT/kLxkvdkXqy8KspbU645mK0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJuu3T%2FbtsrkRpfEKT%2FkLxkvdkXqy8KspbU645mK0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;963&quot; height=&quot;752&quot; data-origin-width=&quot;963&quot; data-origin-height=&quot;752&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에 모든 테스트에서 경고 메시지가 사라졌습니다!!&lt;/p&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/673</guid>
      <comments>https://series.tistory.com/entry/JUnit-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%8B%9C-Sharing-is-only-supported-for-boot-loader-classes-because-bootstrap-classpath-has-been-appended-%EA%B2%BD%EA%B3%A0#entry673comment</comments>
      <pubDate>Wed, 16 Aug 2023 17:39:01 +0900</pubDate>
    </item>
    <item>
      <title>p6spy 쿼리 로그 - 멀티 라인으로</title>
      <link>https://series.tistory.com/entry/p6spy-%EC%BF%BC%EB%A6%AC-%EB%A1%9C%EA%B7%B8-%EB%A9%80%ED%8B%B0-%EB%9D%BC%EC%9D%B8%EC%9C%BC%EB%A1%9C</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;945&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PLRXB/btr6pFiSCcR/chQQVw6PiOTwS7Ubgn9nn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PLRXB/btr6pFiSCcR/chQQVw6PiOTwS7Ubgn9nn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PLRXB/btr6pFiSCcR/chQQVw6PiOTwS7Ubgn9nn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPLRXB%2Fbtr6pFiSCcR%2FchQQVw6PiOTwS7Ubgn9nn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;945&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;945&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;config에 2개의 파일 추가&lt;/h3&gt;
&lt;pre id=&quot;code_1679980542308&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.hanssem.remodeling.content.common.config;

import com.p6spy.engine.common.P6Util;
import com.p6spy.engine.logging.Category;
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
import org.hibernate.engine.jdbc.internal.FormatStyle;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Stack;

public class P6spySqlFormatConfiguration implements MessageFormattingStrategy {

    // 표기에 허용되지 않는 filter
    private List&amp;lt;String&amp;gt; DENIED_FILTER = Arrays.asList(&quot;Test1&quot;, this.getClass().getSimpleName());

    // 표기에 허용되는 filter
    private String ALLOW_FILTER = &quot;com.hanssem&quot;;

    @Override
    public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {

        sql = formatSql(category, sql);
        if (sql.trim().isEmpty()) { // sql 이 없다면 출력하지 않아도 됨
            return &quot;&quot;;
        }

        // stack 을 구성하는 Format을 만든다
        return sql + createStack(connectionId, elapsed);
    }

    private String formatSql(String category,String sql) {

        if (sql ==null || sql.trim().equals(&quot;&quot;)) return sql;

        // Only format Statement, distinguish DDL And DML
        if (Category.STATEMENT.getName().equals(category)) {
            String tmpsql = sql.trim().toLowerCase(Locale.ROOT);
            if (tmpsql.startsWith(&quot;create&quot;) || tmpsql.startsWith(&quot;alter&quot;) || tmpsql.startsWith(&quot;comment&quot;)) {
                sql = FormatStyle.DDL.getFormatter().format(sql);
            } else {
                sql = FormatStyle.BASIC.getFormatter().format(sql);
            }
            sql = &quot;|\nFormatSql(P6Spy sql, Hibernate format):&quot; + sql;
        }

        return sql;
    }

    // stack 콘솔 표기
    private String createStack(int connectionId, long elapsed) {
        Stack&amp;lt;String&amp;gt; callStack = new Stack&amp;lt;&amp;gt;();
        StackTraceElement[] stackTrace = new Throwable().getStackTrace();

        for (StackTraceElement stackTraceElement : stackTrace) {
            String trace = stackTraceElement.toString();

            // trace 항목을 보고 내게 맞는 것만 필터
            if (trace.startsWith(ALLOW_FILTER)) {
                callStack.push(trace);
            }
        }

        StringBuffer sb = new StringBuffer();
        int order = 1;
        while (callStack.size() != 0) {
            sb.append(&quot;\n\t\t&quot; + (order++) + &quot;.&quot; + callStack.pop());
        }

        return new StringBuffer().append(&quot;\n\n\tConnection ID:&quot;).append(connectionId)
                .append(&quot; | Excution Time:&quot;).append(elapsed).append(&quot; ms\n&quot;)
                .append(&quot;\n\tExcution Time:&quot;).append(elapsed).append(&quot; ms\n&quot;)
                .append(&quot;\n\tCall Stack :&quot;).append(sb).append(&quot;\n&quot;)
                .append(&quot;\n--------------------------------------&quot;)
                .toString();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P6spySqlFormatConfiguration.java&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1679980571704&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.hanssem.remodeling.content.common.config;

import com.p6spy.engine.spy.P6SpyOptions;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Configuration
public class P6spyLogMessageFormatConfiguration {

    @PostConstruct
    public void setLogMessageFormat() {
        P6SpyOptions.getActiveInstance().setLogMessageFormat(P6spySqlFormatConfiguration.class.getName());
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P6spyLogMessageFormatConfiguration.java&lt;/p&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/672</guid>
      <comments>https://series.tistory.com/entry/p6spy-%EC%BF%BC%EB%A6%AC-%EB%A1%9C%EA%B7%B8-%EB%A9%80%ED%8B%B0-%EB%9D%BC%EC%9D%B8%EC%9C%BC%EB%A1%9C#entry672comment</comments>
      <pubDate>Tue, 28 Mar 2023 14:16:24 +0900</pubDate>
    </item>
    <item>
      <title>IntelliJ 에서 JUnit 테스트 - andExpect jsonPath 오류 시</title>
      <link>https://series.tistory.com/entry/IntelliJ-%EC%97%90%EC%84%9C-JUnit-%ED%85%8C%EC%8A%A4%ED%8A%B8-andExpect-jsonPath-%EC%98%A4%EB%A5%98-%EC%8B%9C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;수동으로 import 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1679980178324&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1679980237413&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Test
    @DisplayName(&quot;카카오 블로그 테스트&quot;)
    void testKakaoBlog() throws Exception {

        String url = &quot;/api/v1/blog/search/kakao&quot;;

        BlogSearchRequest request = BlogSearchRequest.builder()
                .query(&quot;테스트&quot;)
                .sort(&quot;accuracy&quot;)
                .size(100)
                .page(1)
                .build();

        ResultActions resultActions = mockMvc.perform(
                get(url)
                        .param(&quot;page&quot;, &quot;1&quot;)
                        .param(&quot;size&quot;, &quot;20&quot;)
                        .param(&quot;query&quot;, &quot;테스트&quot;)
                        .param(&quot;sort&quot;, &quot;accuracy&quot;)
        );

        String expectByTitle = &quot;title&quot;;

        // Then
        resultActions
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON))
//                .andExpect((ResultMatcher) jsonPath(&quot;$[0]&quot;).exists())
//                .andExpect(jsonPath(expectByTitle, &quot;Kyeongho Yoo&quot;).exists())
//                .andExpect(jsonPath(&quot;$.length()&quot;, is(2)))
//                .andExpect(content().json(, &quot;&quot;))
//                .andExpect(jsonPath(&quot;$.data[0].content[0].blogName[0]&quot;, equalTo(&quot;엠오엠&quot;)))
//                .andExpect(jsonPath(&quot;$.nm&quot;, notNullValue())
//                .andExpect(jsonPath(&quot;$.nm&quot;, notNullValue())
//                .andExpect(jsonPath(&quot;$.title&quot;, is(aaa)))
//                .andExpect(jsonPath(new Matcher)))

                .andExpect(jsonPath(&quot;$.content[0].blogName&quot;, is(&quot;엠오엠&quot;)))
                .andExpect(jsonPath(&quot;$.content[1].blogName&quot;, is(&quot;지식센터&quot;)))
                .andExpect(jsonPath(&quot;$.content[1].blogName&quot;, notNullValue()))
                .andDo(print());
    }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/671</guid>
      <comments>https://series.tistory.com/entry/IntelliJ-%EC%97%90%EC%84%9C-JUnit-%ED%85%8C%EC%8A%A4%ED%8A%B8-andExpect-jsonPath-%EC%98%A4%EB%A5%98-%EC%8B%9C#entry671comment</comments>
      <pubDate>Tue, 28 Mar 2023 14:10:51 +0900</pubDate>
    </item>
    <item>
      <title>Webflux - Webclient - header 복수개 적용 방법</title>
      <link>https://series.tistory.com/entry/Webflux-Webclient-header-%EB%B3%B5%EC%88%98%EA%B0%9C-%EC%A0%81%EC%9A%A9-%EB%B0%A9%EB%B2%95</link>
      <description>&lt;pre id=&quot;code_1679980064323&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private HttpHeaders createHeaders() {
        HttpHeaders headers = new HttpHeaders();

        headers.add(&quot;X-Naver-Client-Id&quot;, clientId);
        headers.add(&quot;X-Naver-Client-Secret&quot;, clientSecret);

        return headers;
    }

    @Bean
    public WebClient kakaoWebClient() {

        return WebClient.builder()
                .baseUrl(baseurl)
                .defaultHeaders((headers -&amp;gt; {headers.addAll(createHeaders());}))
                .build();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/670</guid>
      <comments>https://series.tistory.com/entry/Webflux-Webclient-header-%EB%B3%B5%EC%88%98%EA%B0%9C-%EC%A0%81%EC%9A%A9-%EB%B0%A9%EB%B2%95#entry670comment</comments>
      <pubDate>Tue, 28 Mar 2023 14:07:56 +0900</pubDate>
    </item>
    <item>
      <title>Swagger - enum을 코드로 노출되도록 - @JsonValue 어노테이션</title>
      <link>https://series.tistory.com/entry/Swagger-enum%EC%9D%84-%EC%BD%94%EB%93%9C%EB%A1%9C-%EB%85%B8%EC%B6%9C%EB%90%98%EB%8F%84%EB%A1%9D-JsonValue-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98</link>
      <description>&lt;pre id=&quot;code_1679979786959&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Getter
@NoArgsConstructor
public enum ApiType {

    KAKAO(&quot;kakao&quot;, &quot;카카오&quot;),
    NAVER(&quot;naver&quot;, &quot;네이버&quot;);

    private String code;
    private String name;

    ApiType(String code, String name) {
        this.code = code;
        this.name = name;
    }

    @JsonValue
    public String getCode() {
        return code;
    }

    public String getName() {
        return name;
    }

    public static ApiType code(String code){
        switch (code){
            case &quot;kakao&quot; :
                return KAKAO;
            case &quot;naver&quot; :
                return NAVER;
            default:
                return KAKAO;
        }
    }

    @Override
    public String toString() {
        return code;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@JsonValue 어노테이션을 붙여줘야 Swagger에서 code로 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;596&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJDmzL/btr6srRXkWw/tpwN8e9xk09eqUEteVUoQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJDmzL/btr6srRXkWw/tpwN8e9xk09eqUEteVUoQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJDmzL/btr6srRXkWw/tpwN8e9xk09eqUEteVUoQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJDmzL%2Fbtr6srRXkWw%2FtpwN8e9xk09eqUEteVUoQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;728&quot; height=&quot;596&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;596&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/669</guid>
      <comments>https://series.tistory.com/entry/Swagger-enum%EC%9D%84-%EC%BD%94%EB%93%9C%EB%A1%9C-%EB%85%B8%EC%B6%9C%EB%90%98%EB%8F%84%EB%A1%9D-JsonValue-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98#entry669comment</comments>
      <pubDate>Tue, 28 Mar 2023 14:04:49 +0900</pubDate>
    </item>
    <item>
      <title>IntelliJ 실행 시 Address already in use: bind 오류가 날 때</title>
      <link>https://series.tistory.com/entry/IntelliJ-%EC%8B%A4%ED%96%89-%EC%8B%9C-Address-already-in-use-bind-%EC%98%A4%EB%A5%98%EA%B0%80-%EB%82%A0-%EB%95%8C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;cmd 관리자 모드 실행 후&lt;/p&gt;
&lt;pre id=&quot;code_1678339385546&quot; class=&quot;dos&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;net stop winnat
net start winnat&lt;/code&gt;&lt;/pre&gt;</description>
      <category>IntelliJ</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/668</guid>
      <comments>https://series.tistory.com/entry/IntelliJ-%EC%8B%A4%ED%96%89-%EC%8B%9C-Address-already-in-use-bind-%EC%98%A4%EB%A5%98%EA%B0%80-%EB%82%A0-%EB%95%8C#entry668comment</comments>
      <pubDate>Thu, 9 Mar 2023 14:23:21 +0900</pubDate>
    </item>
    <item>
      <title>remote 저장소 push할 때 reject 오류 조치방법</title>
      <link>https://series.tistory.com/entry/remote-%EC%A0%80%EC%9E%A5%EC%86%8C-push%ED%95%A0-%EB%95%8C-reject-%EC%98%A4%EB%A5%98-%EC%A1%B0%EC%B9%98%EB%B0%A9%EB%B2%95</link>
      <description>&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;1001&quot; data-origin-height=&quot;494&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gg2IX/btr2OrmRlEh/P06zgaaMTWxHIRq9fgGMn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gg2IX/btr2OrmRlEh/P06zgaaMTWxHIRq9fgGMn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gg2IX/btr2OrmRlEh/P06zgaaMTWxHIRq9fgGMn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGg2IX%2Fbtr2OrmRlEh%2FP06zgaaMTWxHIRq9fgGMn0%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;1001&quot; height=&quot;494&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;494&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id=&quot;push-to-originmaster-was-rejected&quot; data-ke-size=&quot;size23&quot;&gt;Push to origin/master was rejected&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitHub에서 Readme를 포함시켜 Repository를 생성한 후, 해당 Repository를 remote로 추가하여 push 하니 생긴 오류.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Repository에 Readme파일이 이미 존재하여 생기는 오류&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 동기화를 위해 pull&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;git pull --rebase origin main&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;&lt;b&gt;2. 강제로 push&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;git push origin +main&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pull 이전에 발생한 변경사항을 무시(삭제)하고 현재 작업 내용을 강제로 push해도 된다.&lt;br /&gt;이 경우 pull 되지 않은 변경사항은 소실되기 때문에 주의해야 함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 경우에는 README를 건드렸던게 중요하지 않았어서 강제로 push했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;(나의 경우는 동기화 pull후 다시 push했다.)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;깃허브에서 확인해보면 해당 README의 변경사항은 사라졌고, 그외 작업내용들은 정상적으로 업로드되었음을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/667</guid>
      <comments>https://series.tistory.com/entry/remote-%EC%A0%80%EC%9E%A5%EC%86%8C-push%ED%95%A0-%EB%95%8C-reject-%EC%98%A4%EB%A5%98-%EC%A1%B0%EC%B9%98%EB%B0%A9%EB%B2%95#entry667comment</comments>
      <pubDate>Wed, 8 Mar 2023 13:53:03 +0900</pubDate>
    </item>
    <item>
      <title>p6spy 멀티라인 Formatter 적용</title>
      <link>https://series.tistory.com/entry/p6spy-%EB%A9%80%ED%8B%B0%EB%9D%BC%EC%9D%B8-Formatter-%EC%A0%81%EC%9A%A9</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. config에 2개의 파일 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;P6spyLogMessageFormatConfiguration.java&lt;/li&gt;
&lt;li&gt;P6spySqlFormatConfiguration.java&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xjTAI/btr2sGUeNCS/PlAzKKcSvJKJy60oGq2nHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xjTAI/btr2sGUeNCS/PlAzKKcSvJKJy60oGq2nHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xjTAI/btr2sGUeNCS/PlAzKKcSvJKJy60oGq2nHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxjTAI%2Fbtr2sGUeNCS%2FPlAzKKcSvJKJy60oGq2nHk%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;402&quot; height=&quot;475&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;475&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;&lt;b&gt;2.&lt;/b&gt; &lt;/span&gt;&lt;b&gt;P6spySqlFormatConfiguration.java&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678173421604&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.hanssem.remodeling.content.common.config;

import com.p6spy.engine.common.P6Util;
import com.p6spy.engine.logging.Category;
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
import org.hibernate.engine.jdbc.internal.FormatStyle;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Stack;

public class P6spySqlFormatConfiguration implements MessageFormattingStrategy {

    // 표기에 허용되지 않는 filter
    private List&amp;lt;String&amp;gt; DENIED_FILTER = Arrays.asList(&quot;Test1&quot;, this.getClass().getSimpleName());

    // 표기에 허용되는 filter
    private String ALLOW_FILTER = &quot;com.hanssem&quot;;

    @Override
    public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {

        sql = formatSql(category, sql);
        if (sql.trim().isEmpty()) { // sql 이 없다면 출력하지 않아도 됨
            return &quot;&quot;;
        }

        // stack 을 구성하는 Format을 만든다
        return sql + createStack(connectionId, elapsed);
    }

    private String formatSql(String category,String sql) {

        if (sql ==null || sql.trim().equals(&quot;&quot;)) return sql;

        // Only format Statement, distinguish DDL And DML
        if (Category.STATEMENT.getName().equals(category)) {
            String tmpsql = sql.trim().toLowerCase(Locale.ROOT);
            if (tmpsql.startsWith(&quot;create&quot;) || tmpsql.startsWith(&quot;alter&quot;) || tmpsql.startsWith(&quot;comment&quot;)) {
                sql = FormatStyle.DDL.getFormatter().format(sql);
            } else {
                sql = FormatStyle.BASIC.getFormatter().format(sql);
            }
            sql = &quot;|\nFormatSql(P6Spy sql, Hibernate format):&quot; + sql;
        }

        return sql;
    }

    // stack 콘솔 표기
    private String createStack(int connectionId, long elapsed) {
        Stack&amp;lt;String&amp;gt; callStack = new Stack&amp;lt;&amp;gt;();
        StackTraceElement[] stackTrace = new Throwable().getStackTrace();

        for (StackTraceElement stackTraceElement : stackTrace) {
            String trace = stackTraceElement.toString();

            // trace 항목을 보고 내게 맞는 것만 필터
            if (trace.startsWith(ALLOW_FILTER)) {
                callStack.push(trace);
            }
        }

        StringBuffer sb = new StringBuffer();
        int order = 1;
        while (callStack.size() != 0) {
            sb.append(&quot;\n\t\t&quot; + (order++) + &quot;.&quot; + callStack.pop());
        }

        return new StringBuffer().append(&quot;\n\n\tConnection ID:&quot;).append(connectionId)
                .append(&quot; | Excution Time:&quot;).append(elapsed).append(&quot; ms\n&quot;)
                .append(&quot;\n\tExcution Time:&quot;).append(elapsed).append(&quot; ms\n&quot;)
                .append(&quot;\n\tCall Stack :&quot;).append(sb).append(&quot;\n&quot;)
                .append(&quot;\n--------------------------------------&quot;)
                .toString();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;3. &lt;/span&gt;&lt;b&gt;P6spyLogMessageFormatConfiguration.java&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678173434201&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.hanssem.remodeling.content.common.config;

import com.p6spy.engine.spy.P6SpyOptions;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Configuration
public class P6spyLogMessageFormatConfiguration {

    @PostConstruct
    public void setLogMessageFormat() {
        P6SpyOptions.getActiveInstance().setLogMessageFormat(P6spySqlFormatConfiguration.class.getName());
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/666</guid>
      <comments>https://series.tistory.com/entry/p6spy-%EB%A9%80%ED%8B%B0%EB%9D%BC%EC%9D%B8-Formatter-%EC%A0%81%EC%9A%A9#entry666comment</comments>
      <pubDate>Tue, 7 Mar 2023 16:17:22 +0900</pubDate>
    </item>
    <item>
      <title>build.gradle</title>
      <link>https://series.tistory.com/entry/buildgradle</link>
      <description>&lt;h1 id=&quot;[Gradle]&quot; data-renderer-start-pos=&quot;1&quot;&gt;[Gradle]&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Gradle은 일종의 빌드 도구
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여기서 말하는 빌드란 개발한 소프트웨어가 제품으로 만들어지는 일련의 과정&lt;/li&gt;
&lt;li&gt;컴파일, 테스트, 배포, 문서화 등의 작업을 포함하는 절차&lt;/li&gt;
&lt;li&gt;이 때 빌드의 모든 과정을 자동으로 처리할 수 있도록 도와주는 것을 빌드 도구라고 함&lt;/li&gt;
&lt;li&gt;최근 대세는 Gradle&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Groovy, DSL(Domain-Specific Languages, 도메인 특화 언어)
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Gradle은 groovy라는 JVM 기반의 동적 타이핑 언어를 통해 기술된다.&lt;/li&gt;
&lt;li&gt;Gradle은 groovy 문법 자체를 그대로 이용하지는 않고, 그루비 기반의 DSL을 사용&lt;/li&gt;
&lt;li&gt;DSL = 도메인 고유 언어 (기반이 되는 언어에서 파생되어 특정한 용도에 한정되어 각색한 언어)&lt;/li&gt;
&lt;li&gt;Gradle에 사용되는 언어는 그루비를 기반으로 작성된 Gradle DSL&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 id=&quot;[build.gradle]&quot; data-renderer-start-pos=&quot;446&quot;&gt;[build.gradle]&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;build.gradle은 gradle에서 빌드 작업에 필요한 기본 설정, 동작 등을 정의하는 파일&lt;/li&gt;
&lt;li&gt;build.gradle 파일 자체가 Project 클래스로, Project 인터페이스를 구현하는 구현체&lt;/li&gt;
&lt;li&gt;build.gradle에 작성하는 코드들은 모두 Project 오브젝트의 프로퍼티와 메서드가 되며 Project 오브젝트는 프로젝트 이름, 변수, 메서드를 모두 포함하는 객체가 된다.&lt;/li&gt;
&lt;li&gt;Project 오브젝트는 내부에 수많은 메서드(Methods)와 속성(Properties)을 가지고 있다. 메서드 중에 대표적인 것은 모든 java application용 build.gradle이 가진 plugins, repositories, dependencies, application 메서드이다. 우리가 Gradle Task를 이용해 java application을 빌드하게 되면 build task는 이 메서드들을 수행시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;plugins&quot; data-renderer-start-pos=&quot;935&quot;&gt;plugins&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로젝트 컴파일이나 jar 파일의 생성 작업들을 해주는 플러그인 지정&lt;/li&gt;
&lt;li&gt;플러그인에는 빌드에 필요한 과정들을 task로 포함&lt;/li&gt;
&lt;li&gt;빌드 시 필요한 모든 과정을 플러그인의 내부 task가 진행해줌&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;dependencies&quot; data-renderer-start-pos=&quot;1059&quot;&gt;dependencies&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;의존성에 관한 설정을 관리하는 프로퍼티&lt;/li&gt;
&lt;li&gt;프로젝트에서 필요한 라이브러리를 등록&lt;/li&gt;
&lt;li&gt;여기에 필요한 라이브러리 등의 정보를 기술하면 그 라이브러리를 참조할 수 있음&lt;/li&gt;
&lt;li&gt;라이브러리 지정 시 &amp;ldquo;그룹:이름:버전&amp;rdquo; 형태 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MsaWI/btr2vTSCw2U/KAzHxfV0o1IN59kKnHWK3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MsaWI/btr2vTSCw2U/KAzHxfV0o1IN59kKnHWK3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MsaWI/btr2vTSCw2U/KAzHxfV0o1IN59kKnHWK3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMsaWI%2Fbtr2vTSCw2U%2FKAzHxfV0o1IN59kKnHWK3K%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;756&quot; height=&quot;326&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;326&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;h1 id=&quot;ext&quot; data-renderer-start-pos=&quot;1205&quot;&gt;ext&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 블록은 gradle의 모든 task에서 사용할 수 있는 일종의 전역 변수를 선언하는 블록&lt;/li&gt;
&lt;li&gt;gradle 에서 지원하는 변수&lt;/li&gt;
&lt;li&gt;이 변수를 이용하여 추가 속성을 정의할 수 있다.&lt;/li&gt;
&lt;li&gt;추가 속성은 모든 모듈에 공유가 가능하다.&lt;/li&gt;
&lt;li&gt;변수선언을 진행한 다음 진행해야 한다.&lt;/li&gt;
&lt;li&gt;프로젝트 전체와 서브 프로젝트에서도 접근 가능하다.&lt;/li&gt;
&lt;li&gt;ext 메소드는 그 인자를 buildScript 에서 전역변수로 사용하기 위해 사용되는 메소드이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1678173306016&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ext.javaVersion = '1.7' // 한개씩 선언
ext {
    // 여러개 한꺼번에 선언
    springVersion = '3.1.0.RELEASE'
    emailNotification = 'build@master.org'
}
 
// 가변 Key, 가변 값 형태로 코드를 통해 프라퍼티를 추가할 때는 아래 방식을 사용한다.
project.ext['keyname'] = 'value'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;def&quot; data-renderer-start-pos=&quot;1692&quot;&gt;def&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변수에 형을 생략할 때 사용&lt;/li&gt;
&lt;li&gt;형 지정을 생략할 때 def 키워드 이용&lt;/li&gt;
&lt;li&gt;def를 지정하는 것은 자바에서 Object 형을 지정한 것과 같음&lt;/li&gt;
&lt;li&gt;gradle 에서 지원하는 지역변수&lt;/li&gt;
&lt;li&gt;해당 스크립트에서만 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1678173319496&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;* 형 생략
String message = 'hi'
def message = 'hi'
Groovy는 def라는 키워드를 이용하여 모든 타입의 변수를 선언할 수 있습니다.
반대로 형을 지정하여 생성하는 방법도 가능합니다. 위 두줄의 코드는 같은 결과를 발생시킵니다.&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;h1 id=&quot;buildscript&quot; data-renderer-start-pos=&quot;1982&quot;&gt;buildscript&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;빌드하는 동안 필요한 처리들을 모아놓는 곳&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;sourceSets&quot; data-renderer-start-pos=&quot;2024&quot;&gt;sourceSets&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Gradle에서는 하나의 Source 디렉토리만 지원을 해줌 (src/main/java)&lt;/li&gt;
&lt;li&gt;sourceSets는 이러한 제약사항을 지원하기 위해 사용&lt;/li&gt;
&lt;li&gt;Java 소스와 리소스 파일의 논리적인 그룹&lt;/li&gt;
&lt;li&gt;하나 이상의 Source 디렉토리를 Gradle에서 처리를 하기 위해 sourceSets 에 Source 디렉토리를 등록해주면 된다.&lt;/li&gt;
&lt;li&gt;기본 프로젝트 레이아웃&lt;/li&gt;
&lt;li&gt;통합 테스트를 위한 별도의 소스 디렉토리를 만들 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KPPbA/btr2r5zLwz8/XDmQqdiHcGAmsb1SGbQQFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KPPbA/btr2r5zLwz8/XDmQqdiHcGAmsb1SGbQQFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KPPbA/btr2r5zLwz8/XDmQqdiHcGAmsb1SGbQQFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKPPbA%2Fbtr2r5zLwz8%2FXDmQqdiHcGAmsb1SGbQQFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;231&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;231&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;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위의 경우 sourceSets 셋팅 (폴더가 새 소스세트의 이름과 일치하면 따로 명시할 필요 없음)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;131&quot; data-origin-height=&quot;132&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbStOB/btr2sG0UDy3/JuWhaVAUBkzWxEYlvknYrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbStOB/btr2sG0UDy3/JuWhaVAUBkzWxEYlvknYrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbStOB/btr2sG0UDy3/JuWhaVAUBkzWxEYlvknYrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbStOB%2Fbtr2sG0UDy3%2FJuWhaVAUBkzWxEYlvknYrK%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;131&quot; height=&quot;132&quot; data-origin-width=&quot;131&quot; data-origin-height=&quot;132&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;따로 명시할 경우 아래와 같음&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;283&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z9KL0/btr2xUcCrjE/VL44RZRj5CUgKXbsk0Q8oK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z9KL0/btr2xUcCrjE/VL44RZRj5CUgKXbsk0Q8oK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z9KL0/btr2xUcCrjE/VL44RZRj5CUgKXbsk0Q8oK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz9KL0%2Fbtr2xUcCrjE%2FVL44RZRj5CUgKXbsk0Q8oK%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;283&quot; height=&quot;147&quot; data-origin-width=&quot;283&quot; data-origin-height=&quot;147&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;pre id=&quot;code_1678173364624&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;**// 1. queryDsl version 정보 추가**
buildscript { **// 빌드 시**
    ext {
        **queryDslVersion = &quot;5.0.0&quot; // 빌드 시 전역변수 설정**
    }
}

plugins {
    id 'org.springframework.boot' version '2.6.3'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    **// 2. querydsl plugins 추가
    id &quot;com.ewerk.gradle.plugins.querydsl&quot; version &quot;1.0.10&quot;**
    id 'java'
}

//...

dependencies { **// 멀티모듈에서 공통으로 사용될 의존성 추가**
    **// 3. querydsl library dependencies 추가
    implementation &quot;com.querydsl:querydsl-jpa:${queryDslVersion}&quot;
    implementation &quot;com.querydsl:querydsl-apt:${queryDslVersion}&quot;**
    //...
}

test {
    useJUnitPlatform()
}

**/*
 * queryDSL 설정 추가
 */
// querydsl에서 사용할 경로 설정
def querydslDir = &quot;$buildDir/generated/querydsl&quot;

// JPA 사용 여부와 사용할 경로를 설정
querydsl {
    jpa = true
    querydslSourcesDir = querydslDir
}

// build 시 사용할 sourceSet 추가
// IDE의 소스 폴더에 자동으로 넣어준다.
// 개발 환경에서 생성된 Q파일들을 사용할 수 있도록 generated 디렉토리를 sourceSet에 추가해주면 개발 코드에서 생성된 Q파일에 접근할 수 있습니다.
sourceSets {
    main.java.srcDir querydslDir
}

// querydsl 컴파일시 사용할 옵션 설정
// Q파일을 생성해준다.
compileQuerydsl{
    options.annotationProcessorPath = configurations.querydsl
}

// querydsl 이 compileClassPath 를 상속하도록 설정
// 컴파일이 될때 같이 수행
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
    querydsl.extendsFrom compileClasspath
}**&lt;/code&gt;&lt;/pre&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/665</guid>
      <comments>https://series.tistory.com/entry/buildgradle#entry665comment</comments>
      <pubDate>Tue, 7 Mar 2023 16:16:14 +0900</pubDate>
    </item>
    <item>
      <title>JPA (Java Persistence API)</title>
      <link>https://series.tistory.com/entry/JPA-Java-Persistence-API-1</link>
      <description>&lt;h1 id=&quot;JPA-(Java-Persistence-API)&quot; data-renderer-start-pos=&quot;1&quot;&gt;JPA (Java Persistence API)&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;h1 id=&quot;ORM&quot; data-renderer-start-pos=&quot;29&quot;&gt;ORM&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ORM (Object-Relational Mapping)&lt;/li&gt;
&lt;li&gt;애플리케이션 Class와 RDB(Relational DataBase)의 테이블을&amp;nbsp;매핑 (연결)&lt;/li&gt;
&lt;li&gt;어플리케이션의 객체를 RDB 테이블에 자동으로 영속화&lt;/li&gt;
&lt;li&gt;객체는 객체대로 설계하고, 관계형 데이터베이스는 관계형 데이터베이스대로 설계한다.&lt;/li&gt;
&lt;li&gt;ORM 프레임워크가 중간에서 매핑해 준다.&lt;/li&gt;
&lt;li&gt;대중적인 언어에는 대부분 ORM 기술이 존재한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;ORM-장점&quot; data-renderer-start-pos=&quot;267&quot;&gt;ORM 장점&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SQL문이 아닌 Method를 통해 DB를 조작할 수 있어, 개발자는 객체 모델을 이용하여 비즈니스 로직을 구성하는데만 집중할 수 있음
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내부적으로는 쿼리를 생성하여 DB를 조작함&lt;/li&gt;
&lt;li&gt;하지만 개발자가 이를 신경 쓰지 않아도 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Query와 같이 필요한 선언문, 할당 등의 부수적인 코드가 줄어들어 각종 객체에 대한 코드를 별도로 작성하여 코드의 가독성을 높임&lt;/li&gt;
&lt;li&gt;객체지향적인 코드 작성이 가능함. 오직 객체지향적 접근만 고려하면 되기때문에 생산성 증가&lt;/li&gt;
&lt;li&gt;매핑하는 정보가 Class로 명시 되었기 때문에 ERD를 보는 의존도를 낮출 수 있고 유지보수 및 리팩토링에 유리&lt;/li&gt;
&lt;li&gt;기존 방식에서 MySQL 데이터베이스를 사용하다가 ORACLE로 변환한다고 가정해보면, 새로 쿼리를 짜야하는 경우가 생김. 이런 경우에 ORM을 사용한다면 쿼리를 수정할 필요가 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;ORM-단점&quot; data-renderer-start-pos=&quot;714&quot;&gt;ORM 단점&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로젝트의 규모가 크고 복잡하여 설계가 잘못된 경우, 속도 저하 및 일관성을 무너뜨리는 문제점이 생길 수 있음&lt;/li&gt;
&lt;li&gt;복잡하고 무거운 Query는 속도를 위해 별도의 튜닝이 필요하기 때문에 결국 SQL문을 써야할 수도 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;ORM과-SQL-Mapper와의-차이점&quot; data-renderer-start-pos=&quot;851&quot;&gt;ORM과 &lt;b&gt;SQL Mapper와의 차이점&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;h2 id=&quot;1.-SQL-Mapper&quot; data-renderer-start-pos=&quot;874&quot; data-ke-size=&quot;size26&quot;&gt;1. SQL Mapper&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;myBatis, jdbcTemplate&lt;/li&gt;
&lt;li&gt;SQL을 명시하여 직접 DB 조작&lt;/li&gt;
&lt;li&gt;필드를 매핑시키는 것이 목적&lt;/li&gt;
&lt;li&gt;자바 클래스와 sql을 매핑&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;2.-ORM&quot; data-renderer-start-pos=&quot;976&quot; data-ke-size=&quot;size26&quot;&gt;2. ORM&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JPA, Hibernate&lt;/li&gt;
&lt;li&gt;자바 클래스와 DB 테이블을 매핑&lt;/li&gt;
&lt;li&gt;객체간의 관계를 바탕으로 SQL 자동 생성&lt;/li&gt;
&lt;li&gt;RDB의 관계를 Object 에 반영하는 것이 목적&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;JPA&quot; data-renderer-start-pos=&quot;1085&quot;&gt;JPA&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JPA(Java Persistence API)&lt;/li&gt;
&lt;li&gt;JPA는 자바 진영에서 ORM(Object-Relational Mapping) 기술 표준으로 사용되는 인터페이스의 모음&lt;/li&gt;
&lt;li&gt;JPA를 구현한 대표적인 오픈소스로는 Hibernate가 있음&lt;/li&gt;
&lt;li&gt;자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스&lt;/li&gt;
&lt;li&gt;JPA는 API의 규격 인터페이스일 뿐 (라이브러리나 프레임워크가 아님)&lt;/li&gt;
&lt;li&gt;JPA 2.1 표준 명세를 구현한 구현체 : Hibernate, EclipseLink, DataNucleus, OpenJPA, TopLink Essentials 등이 있다. (ORM 프레임워크)&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;490&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beGd3B/btr2D97O0e9/O7bnANNkX7bMosLBkb0Kw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beGd3B/btr2D97O0e9/O7bnANNkX7bMosLBkb0Kw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beGd3B/btr2D97O0e9/O7bnANNkX7bMosLBkb0Kw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeGd3B%2Fbtr2D97O0e9%2FO7bnANNkX7bMosLBkb0Kw0%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;490&quot; height=&quot;252&quot; data-origin-width=&quot;490&quot; data-origin-height=&quot;252&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;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JPA 는 애플리케이션과 JDBC 사이에서 동작하여 개발자가 JPA 를 사용하면, JPA 내부에서 JDBC API 를 사용하여 SQL 을 호출, DB 와 통신한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;449&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZiuCP/btr2sYAoBvI/eRg3UYDx5cQeB4nSugcLW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZiuCP/btr2sYAoBvI/eRg3UYDx5cQeB4nSugcLW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZiuCP/btr2sYAoBvI/eRg3UYDx5cQeB4nSugcLW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZiuCP%2Fbtr2sYAoBvI%2FeRg3UYDx5cQeB4nSugcLW1%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;954&quot; height=&quot;449&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;449&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;h1 id=&quot;왜-JPA를-사용해야-할까?&quot; data-renderer-start-pos=&quot;1538&quot;&gt;&lt;b&gt;왜 JPA를 사용해야 할까?&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;h3 id=&quot;1.-생산성&quot; data-renderer-start-pos=&quot;1555&quot; data-ke-size=&quot;size23&quot;&gt;1. 생산성&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JPA를 사용하면 자바 컬렉션에 저장하듯이 JPA에게 저장할 객체를 전달하면 된다.&lt;/li&gt;
&lt;li&gt;지루하고 반복적인 코드를 개발자가 직접 작성하지 않아도 되며, DDL문도 자동으로 생성해주기 때문에 데이터베이스 설계 중심을 객체 설계 중심으로 변경할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2.-유지보수&quot; data-renderer-start-pos=&quot;1709&quot; data-ke-size=&quot;size23&quot;&gt;2. 유지보수&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필드를 하나만 추가해도 관련된 SQL과 JDBC 코드를 전부 수행해야 했지만 JPA는 이를 대신 처리해주기 때문에 개발자가 유지보수해야하는 코드가 줄어든다.&lt;/li&gt;
&lt;li&gt;SQL을 직접 작성하는 것이 아닌, 객체를 사용하여 동작 -&amp;gt; 재사용성 up&lt;/li&gt;
&lt;li&gt;기존 SQL 방식 : 테이블 필드 변경시 모든 SQL을 수정해야 한다.&lt;/li&gt;
&lt;li&gt;JPA 방식 : Entity 객체에 필드만 추가하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3.-패러다임의-불일치-해결&quot; data-renderer-start-pos=&quot;1936&quot; data-ke-size=&quot;size23&quot;&gt;3. 패러다임의 불일치 해결&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JPA는 연관된 객체를 사용하는 시점에 SQL을 전달할 수 있고, 같은 트랜잭션 내에서 조회할 때 동일성도 보장하기 때문에 다양한 패러다임의 불일치를 해결한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;4.-성능&quot; data-renderer-start-pos=&quot;2048&quot; data-ke-size=&quot;size23&quot;&gt;4. 성능&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;애플리케이션과 데이터베이스 사이에서 성능 최적화 기회를 제공한다.&lt;/li&gt;
&lt;li&gt;같은 트랜잭션안에서는 같은 엔티티를 반환하기 때문에 데이터 베이스와의 통신 횟수를 줄일 수 있다.&lt;/li&gt;
&lt;li&gt;트랜잭션을 commit하기 전까지 메모리에 쌓고 한번에 SQL을 전송한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;5.-데이터-접근-추상화와-벤더-독립성&quot; data-renderer-start-pos=&quot;2200&quot; data-ke-size=&quot;size23&quot;&gt;5. 데이터 접근 추상화와 벤더 독립성&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RDB는 같은 기능이라도 벤더마다 사용법이 다르기 때문에 처음 선택한 데이터베이스에 종속되고 변경이 어렵다. JPA는 애플리케이션과 데이터베이스 사이에서 추상화된 데이터 접근을 제공하기 때문에 종속이 되지 않도록한다.&lt;/li&gt;
&lt;li&gt;만약 DB가 변경되더라도 JPA에게 알려주면 간단하게 변경이 가능하다.&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;716&quot; data-origin-height=&quot;486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/enIXRW/btr2DDg3qnq/KcXZ29lzoU5n19n0obAKv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/enIXRW/btr2DDg3qnq/KcXZ29lzoU5n19n0obAKv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/enIXRW/btr2DDg3qnq/KcXZ29lzoU5n19n0obAKv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FenIXRW%2Fbtr2DDg3qnq%2FKcXZ29lzoU5n19n0obAKv0%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;716&quot; height=&quot;486&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;486&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;h1 id=&quot;JPA와-객체-그래프-탐색&quot; data-renderer-start-pos=&quot;2398&quot;&gt;JPA와 객체 그래프 탐색&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;2414&quot; data-ke-size=&quot;size16&quot;&gt;신뢰할 수 있는 엔티티, 계층&lt;/p&gt;
&lt;pre id=&quot;code_1678172991677&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class MemberService {
	...
    public void process(){
    	// 기존 방식처럼 직접 구현한 DAO에서 객체를 가져온 경우
    	Member member1 = memberDAO.find(memberId);
        member1.getTeam(); // 엔티티를 신뢰할 수 없음
        member1.getOrder().getDelivery();
        
        // JPA를 통해서 객체를 가져온 경우
        Member member2 = jpa.find(Member.class, memberId);
        member2.getTeam(); // 자유로운 객체 그래프 탐색
        member2.getOrder().getDelivery();    
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;내가 아닌 다른 개발자가 직접 구현한 DAO에서 가져오는 경우&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DAO에서 직접 어떤 쿼리를 날렸는지 확인하지 않는 이상, 그래프 형태의 관련된 객체들을 모두 잘 가져왔는지 알 수 가 없다.&lt;/li&gt;
&lt;li&gt;즉, 반환한 엔티티를 신뢰하고 사용할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;JPA를 통해서 가져오는 경우&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체 그래프를 완전히 자유롭게 탐색할 수 있게 된다.&lt;/li&gt;
&lt;li&gt;동일한 트랜잭션에서 조회한 엔티티는 같음을 보장한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;JPA의-성능-최적화-기능&quot; data-renderer-start-pos=&quot;3094&quot;&gt;&lt;b&gt;JPA의 성능 최적화 기능&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;h2 id=&quot;1.-1차-캐시와-동일성(identity)-보장---캐싱-기능&quot; data-renderer-start-pos=&quot;3110&quot; data-ke-size=&quot;size26&quot;&gt;1. &lt;b&gt;1차 캐시와 동일성(identity) 보장 - 캐싱 기능&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;같은 트랜잭션 안에서는 같은 엔티티를 반환 - 조회 성능 향상&lt;/li&gt;
&lt;li&gt;동일 조건인 경우 쿼리를 2번 실행하지 않고, 캐시에서 읽어들임&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1678173010032&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String memberId = &quot;100&quot;;
Member member1 = jpa.find(Member.class, memberId);  // DB에서 가져옴
Member member2 = jpa.find(Member.class, memberId);  // 1차 캐시에서 가져옴
member1 == member2;  // 같다&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;2.-트랜잭션을-지원하는-쓰기-지연-(transactional-write-behind)---버퍼링-기능&quot; data-renderer-start-pos=&quot;3410&quot; data-ke-size=&quot;size26&quot;&gt;2. &lt;b&gt;트랜잭션을 지원하는 쓰기 지연 (transactional write-behind) - 버퍼링 기능&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-renderer-start-pos=&quot;3469&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(1) INSERT&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678173021815&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 1. 트랜잭션을 커밋할 때까지 INSERT 쿼리를 수행하지 않음
transaction.begin();	// 트랜잭션 시작
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);

// 2. 커밋하는 순간 데이터베이스에 INSERT 쿼리를 일괄 처리한다.
// JDBC BATCH SQL 기능을 사용해서 한번에 SQL 전송
transaction.commit();	// 트랜잭션 커밋&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;(2) UPDATE&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678173032815&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 1. UPDATE, DELETE로 인한 로우 락(ROW LOCK) 시간 최소화
transaction.begin();	// 트랜잭션 시작
changeMember(memberA);
deleteMember(memberB);

비즈니스_로직_수행();	// 비즈니스 로직 수행하는 동안 DB 로우 락이 걸리지 않는다.

// 커밋하는 순간 데이터베이스에 UPDATE, DELETE 쿼리를 보내고 바로 커밋
transaction.commit();	// 트랜잭션 커밋&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;3.-지연-로딩(Lazy-Loading)&quot; data-renderer-start-pos=&quot;4004&quot; data-ke-size=&quot;size26&quot;&gt;3. &lt;b&gt;지연 로딩(Lazy Loading)&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-renderer-start-pos=&quot;4028&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(a) 지연 로딩&lt;/b&gt;&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;4039&quot; data-ke-size=&quot;size16&quot;&gt;객체가 실제로 사용될 때 로딩하는 전략&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;4039&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;4062&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(b) 즉시 로딩&lt;/b&gt;&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;4073&quot; data-ke-size=&quot;size16&quot;&gt;JOIN 쿼리로 한번에 연관된 객체까지 미리 조회하는 전략&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;4107&quot; data-ke-size=&quot;size16&quot;&gt;어플리케이션 개발시 기본적으로 지연 로딩을 설정한 후 필요한 경우에 즉시 로딩으로 옵션을 변경하는 것을 추천한다.&lt;/p&gt;
&lt;h1 id=&quot;상속-관계&quot; data-renderer-start-pos=&quot;4172&quot;&gt;상속 관계&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JAVA에서는&amp;nbsp;부모클래스와&amp;nbsp;자식클래스의 관계 즉,&amp;nbsp;상속관계가 존재하는데 데이터베이스에서는 이러한 객체의 상속관계를 지원하지 않는다. 이런 상속관계를 JPA는 아래와 같은 방식으로 해결하였다.&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;1381&quot; data-origin-height=&quot;489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYj32M/btr2FeVllBC/eodkWsJE33AA3QJuF3ymlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYj32M/btr2FeVllBC/eodkWsJE33AA3QJuF3ymlK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYj32M/btr2FeVllBC/eodkWsJE33AA3QJuF3ymlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYj32M%2Fbtr2FeVllBC%2FeodkWsJE33AA3QJuF3ymlK%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;1381&quot; height=&quot;489&quot; data-origin-width=&quot;1381&quot; data-origin-height=&quot;489&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;위의 구조에서 만약 Album 클래스를 저장한다고 가정해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678173062403&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Album 객체저장
jpa.persist(album);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;그러면 JPA는 위의 코드를 아래의 쿼리로 변환해서 실행한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678173072189&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;INSERT INTO ITEM (ID, NAME, PRICE) .....
INSERT INTO ALBUM (ARTIST) .....&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위처럼 저장하면 당연히 조회할때도 두 테이블을 엮어서 가져올 것이다. 조회하는 JAVA코드와 변환되는 쿼리를 보도록하자.&lt;/p&gt;
&lt;pre id=&quot;code_1678173083427&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// JAVA 코드
String albumId = &quot;id100&quot;;
Album album = jpa.find(Album.class, albumId);

// 변환된 쿼리
SELECT I.*, A.*
  FROM ITEM I
  JOIN ALBUM A ON I.ITEM_ID = A.ITEM_ID&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;연관-관계&quot; data-renderer-start-pos=&quot;4723&quot;&gt;연관 관계&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위와 같이 상속관계에 대한 접근도 제공해주는데 객체지향에는&amp;nbsp;연관관계라는 것도 있다.&lt;/li&gt;
&lt;li&gt;코드로 따지면&amp;nbsp;Class에서 또 다른 Class Type을 필드 변수로 가지고 있는것이다.&lt;/li&gt;
&lt;li&gt;객체관계와 이를 테이블 구조로 나타낸 아래의 그림을 보도록하자.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;440&quot; data-origin-height=&quot;261&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wOUeT/btr2FhkelRi/smcSU3iNKTqvh0jS9AwXV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wOUeT/btr2FhkelRi/smcSU3iNKTqvh0jS9AwXV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wOUeT/btr2FhkelRi/smcSU3iNKTqvh0jS9AwXV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwOUeT%2Fbtr2FhkelRi%2FsmcSU3iNKTqvh0jS9AwXV1%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;440&quot; height=&quot;261&quot; data-origin-width=&quot;440&quot; data-origin-height=&quot;261&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;위의 그림은 Member 클래스가 Team 타입의 team 필드 변수를 가지고 있는 형태인데, 코드로 나타내면 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678173112984&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Member {
 String id;
 Team team;
 String username;
}

class Team {
 Long id;
 String name;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;그렇다면 Team 객체를 참조하는 필드를 가지고 있는 Member 객체는 어떻게 저장할까?&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678173123877&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Member member = new Member();
member.setId(&quot;100&quot;);
member.setUsername(&quot;dbjh&quot;);

Team team = new Team();
team.setName(&quot;dev_team&quot;);

member.setTeam(team);
jpa.persist(member);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;위처럼 Member 객체의 team 필드에 Team 객체를 set하고 Member 객체를 DB에 저장하게 되면 JPA는 아래와 같은 코드를 데이터베이스에게 실행하라고 할것이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678173135247&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;INSERT INTO MEMBER (ID, TEAM_ID, USERNAME) ....
INSERT INTO TEAM (ID, NAME) ....&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;이렇게 저장 후 Member 객체만 조회하면, Team 객체 정보도 가져와서 Member 객체의 team필드에 주입해주기 때문에 아래와 같이 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678173148140&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// JAVA 코드
Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam();

// 변환된 쿼리
SELECT M.*, T.*
 FROM MEMBER M
 JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 구조들이 더 복잡해진다고 해도 JPA는 이를 모두 지원해주기 때문에 문제없이 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;JPA의-저장-및-조회는-아래와-같은-구조로-실행&quot; data-renderer-start-pos=&quot;5798&quot;&gt;JPA의 저장 및 조회는 아래와 같은 구조로 실행&lt;/h1&gt;
&lt;pre id=&quot;code_1678173172562&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;**저장** : jpa.persist(member)

**조회** : Member member = jpa.find(memberId)

**수정** : member.setName(&quot;홍길동&quot;)

**삭제** : jpa.remove(member)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;[저장]&quot; data-renderer-start-pos=&quot;5964&quot; data-ke-size=&quot;size26&quot;&gt;[저장]&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-renderer-start-pos=&quot;5970&quot; data-ke-size=&quot;size16&quot;&gt;MemberDAO에서 객체를 저장하고 싶을 때 개발자는 JPA에 Member 객체를 넘기면 JPA는 아래와 같이 동작한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Member 엔티티를 분석한다.&lt;/li&gt;
&lt;li&gt;INSERT SQL을 생성한다.&lt;/li&gt;
&lt;li&gt;JDBC API를 사용하여 SQL을 DB 에 날린다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1187&quot; data-origin-height=&quot;605&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZThSv/btr2DCWI7wz/ut0Nxdq8ULyZLbQoZGVMJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZThSv/btr2DCWI7wz/ut0Nxdq8ULyZLbQoZGVMJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZThSv/btr2DCWI7wz/ut0Nxdq8ULyZLbQoZGVMJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZThSv%2Fbtr2DCWI7wz%2Fut0Nxdq8ULyZLbQoZGVMJK%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;1187&quot; height=&quot;605&quot; data-origin-width=&quot;1187&quot; data-origin-height=&quot;605&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;[조회]&quot; data-renderer-start-pos=&quot;6122&quot; data-ke-size=&quot;size26&quot;&gt;[조회]&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-renderer-start-pos=&quot;6128&quot; data-ke-size=&quot;size16&quot;&gt;Member 객체를 조회하고 싶을 때 개발자는 member의 pk 값을 JPA에 넘긴다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;엔티티의 매핑 정보를 바탕으로 적절한 SELECT SQL을 생성한다.&lt;/li&gt;
&lt;li&gt;JDBC API를 사용하여 SQL을 DB에 날린다.&lt;/li&gt;
&lt;li&gt;DB로 부터 결과를 받아온다.&lt;/li&gt;
&lt;li&gt;결과(ResultSet)를 객체에 매핑한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-renderer-start-pos=&quot;6303&quot; data-ke-size=&quot;size16&quot;&gt;쿼리를 JPA가 만들어 주기 때문에 Object와 RDB간의 패러다임 불일치를 해결 할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1181&quot; data-origin-height=&quot;590&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kR4uL/btr2tCRk5Zx/663aBJ6fY2d6MshCfNtm81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kR4uL/btr2tCRk5Zx/663aBJ6fY2d6MshCfNtm81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kR4uL/btr2tCRk5Zx/663aBJ6fY2d6MshCfNtm81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkR4uL%2Fbtr2tCRk5Zx%2F663aBJ6fY2d6MshCfNtm81%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;1181&quot; height=&quot;590&quot; data-origin-width=&quot;1181&quot; data-origin-height=&quot;590&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;[수정]&quot; data-renderer-start-pos=&quot;6364&quot; data-ke-size=&quot;size26&quot;&gt;[수정]&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JPA는 데이터 수정시, 매핑된 객체(테이블 데이터)를 조회해서 값을 변경 후 커밋하면 DB 서버에 UPDATE 문을 전송하여 UPDATE를 실행&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>JPA</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/664</guid>
      <comments>https://series.tistory.com/entry/JPA-Java-Persistence-API-1#entry664comment</comments>
      <pubDate>Tue, 7 Mar 2023 16:13:32 +0900</pubDate>
    </item>
    <item>
      <title>Querydsl 스터디</title>
      <link>https://series.tistory.com/entry/Querydsl-%EC%8A%A4%ED%84%B0%EB%94%94</link>
      <description>&lt;h1 id=&quot;1.-참고-페이지&quot; data-renderer-start-pos=&quot;1&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot; data-renderer-mark=&quot;true&quot; data-text-custom-color=&quot;#6554c0&quot;&gt;1. 참고 페이지&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;h1 id=&quot;Querydsl-공식-사이트&quot; data-renderer-start-pos=&quot;12&quot;&gt;&lt;b&gt;Querydsl 공식 사이트&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;29&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span data-inline-card=&quot;true&quot; data-card-url=&quot;http://querydsl.com/&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span data-testid=&quot;hover-card-trigger-wrapper&quot;&gt;&lt;a href=&quot;http://querydsl.com/&quot; data-testid=&quot;inline-card-resolved-view&quot;&gt;&lt;span data-testid=&quot;inline-card-icon-and-title&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span data-testid=&quot;inline-card-icon-and-title-default&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Querydsl - Unified Queries for Java&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;Querydsl-Reference-Guide&quot; data-renderer-start-pos=&quot;33&quot;&gt;&lt;b&gt;Querydsl Reference Guide&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;59&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span data-inline-card=&quot;true&quot; data-card-url=&quot;http://querydsl.com/static/querydsl/5.0.0/reference/html_single/&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span data-testid=&quot;hover-card-trigger-wrapper&quot;&gt;&lt;a href=&quot;http://querydsl.com/static/querydsl/5.0.0/reference/html_single/&quot; data-testid=&quot;inline-card-resolved-view&quot;&gt;&lt;span data-testid=&quot;inline-card-icon-and-title&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span data-testid=&quot;inline-card-icon-and-title-default&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Querydsl Reference Guide&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;Querydsl-5.0.0-API&quot; data-renderer-start-pos=&quot;63&quot;&gt;&lt;b&gt;Querydsl 5.0.0 API&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;83&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span data-inline-card=&quot;true&quot; data-card-url=&quot;http://querydsl.com/static/querydsl/5.0.0/apidocs/&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span data-testid=&quot;hover-card-trigger-wrapper&quot;&gt;&lt;a href=&quot;http://querydsl.com/static/querydsl/5.0.0/apidocs/&quot; data-testid=&quot;inline-card-resolved-view&quot;&gt;&lt;span data-testid=&quot;inline-card-icon-and-title&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span data-testid=&quot;inline-card-icon-and-title-default&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Querydsl 5.0.0 API&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;Querydsl-관련-소스&quot; data-renderer-start-pos=&quot;87&quot;&gt;&lt;b&gt;Querydsl 관련 소스&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;103&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span data-inline-card=&quot;true&quot; data-card-url=&quot;https://github.com/lcalmsky/querydsl&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span data-testid=&quot;hover-card-trigger-wrapper&quot;&gt;&lt;a href=&quot;https://github.com/lcalmsky/querydsl&quot; data-testid=&quot;inline-card-resolved-view&quot;&gt;&lt;span data-testid=&quot;inline-card-icon-and-title&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;GitHub - lcalmsky/querydsl&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;103&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;103&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;2.-Querydsl-특징&quot; data-renderer-start-pos=&quot;111&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot; data-renderer-mark=&quot;true&quot; data-text-custom-color=&quot;#6554c0&quot;&gt;2. Querydsl 특징&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;h1 id=&quot;(1)-Querydsl의-특징&quot; data-renderer-start-pos=&quot;127&quot;&gt;&lt;b&gt;(1) Querydsl의 특징&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;145&quot; data-ke-size=&quot;size16&quot;&gt;Spring Data JPA가 기본적으로 제공해주는 CRUD 메서드 및 쿼리 메서드 기능을 사용하더라도, 원하는 조건의 데이터를 수집하기 위해서는 필연적으로 JPQL을 작성하게 됩니다. 간단한 로직을 작성하는데 큰 문제는 없으나, 복잡한 로직의 경우 개행이 포함된 쿼리 문자열이 상당히 길어집니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;313&quot; data-ke-size=&quot;size16&quot;&gt;JPQL 문자열에 오타 혹은 문법적인 오류가 존재하는 경우, 정적 쿼리라면 어플리케이션 로딩 시점에 이를 발견할 수 있으나 그 외는 런타임 시점에서 에러가 발생합니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;408&quot; data-ke-size=&quot;size16&quot;&gt;이러한 문제를 어느 정도 해소하는데 기여하는 프레임워크가 바로&amp;nbsp;&lt;b&gt;QueryDSL&lt;/b&gt;입니다. QueryDSL은 정적 타입을 이용해서 SQL 등의 쿼리를 생성해주는 오픈소스 프레임워크입니다.&lt;/p&gt;
&lt;h1 id=&quot;(2)-QueryDSL의-장점&quot; data-renderer-start-pos=&quot;511&quot;&gt;&lt;b&gt;(2) QueryDSL의 장점&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문자가 아닌 코드로 쿼리를 작성함으로써, 컴파일 시점에 문법 오류를 쉽게 확인할 수 있다.&lt;/li&gt;
&lt;li&gt;자동 완성 등 IDE의 도움을 받을 수 있다.&lt;/li&gt;
&lt;li&gt;동적인 쿼리 작성이 편리하다.
&lt;ol style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;물론 한계가 있어서 통계성 쿼리 등은 natvie 쿼리 등으로 해결해야한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;쿼리 작성 시 제약 조건 등을 메서드 추출을 통해 재사용할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&quot;(3)-Querydsl-작동-방식&quot; data-renderer-start-pos=&quot;724&quot;&gt;&lt;b&gt;(3) Querydsl 작동 방식&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본적으로 QueryDSL은 프로젝트 내의 @Entity 어노테이션을 선언한 클래스를 탐색하고, JPAAnnotationProcessor를 사용해 Q 클래스를 생성합니다.&lt;/li&gt;
&lt;li&gt;querydsl-apt가 @Entity 및 @Id 등의 애너테이션을 알 수 있도록,&amp;nbsp;javax.persistence과&amp;nbsp;javax.annotation을 annotationProcessor에 함께 추가합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;annotationProcessor는 Java 컴파일러 플러그인으로서, 컴파일 단계에서 어노테이션을 분석 및 처리함으로써 추가적인 파일을 생성할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;build 폴더는 gradle에 의해 gitignore 처리된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Qfile 등은 시스템이 자동으로 만들어주는 형태이고, 버전마다 조금씩 달라질 수 있기 때문에 git으로 형상관리를 하지는 않는다.&lt;/li&gt;
&lt;li&gt;혹시나 src/main/generated에 들어가게 된다면, 해당 파일들은 gitignore 해줘야함도 기억하자&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;(4)-Querydsl-관련-라이브러리&quot; data-renderer-start-pos=&quot;1243&quot;&gt;&lt;b&gt;(4) Querydsl 관련 라이브러리&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;div data-layout=&quot;align-start&quot; data-node-type=&quot;mediaSingle&quot;&gt;
&lt;div&gt;
&lt;div data-context-id=&quot;9962121&quot; data-type=&quot;file&quot; data-node-type=&quot;media&quot; data-width=&quot;350&quot; data-height=&quot;92&quot; data-id=&quot;d18201a2-9d61-45d1-8430-dc1f057b501e&quot; data-collection=&quot;contentId-9962121&quot; data-file-name=&quot;image-20220928-053408.png&quot; data-file-size=&quot;16504&quot; data-file-mime-type=&quot;image/png&quot; data-alt=&quot;&quot;&gt;
&lt;div id=&quot;newFileExperienceWrapper&quot; data-testid=&quot;media-card-view&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;350&quot; data-origin-height=&quot;92&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4jpJB/btr2C7QdkUF/yqLoOAAGKaLmq5MEKKGkT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4jpJB/btr2C7QdkUF/yqLoOAAGKaLmq5MEKKGkT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4jpJB/btr2C7QdkUF/yqLoOAAGKaLmq5MEKKGkT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4jpJB%2Fbtr2C7QdkUF%2FyqLoOAAGKaLmq5MEKKGkT1%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;350&quot; height=&quot;92&quot; data-origin-width=&quot;350&quot; data-origin-height=&quot;92&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;apt&lt;/b&gt; 라는 부분이 코드 생성과 관련된 라이브러리라고 한다.&lt;/li&gt;
&lt;li&gt;QHello 등의 객체를 만들어주는 역할을 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;core, jpa&lt;/b&gt; 부분은 실제 querydsl의 코드를 작동하게 해주는 selectFrom.fetchOne 등의 작동을 담당하는 라이브러리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;(5)-기타&quot; data-renderer-start-pos=&quot;1420&quot;&gt;&lt;b&gt;(5) 기타&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Querydsl fetchResults(), fetchCount() Deprecated(향후 미지원)
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Querydsl은 향후 fetchCount() , fetchResult() 를 지원하지 않기로 결정했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;3.-Querydsl-설정-방법&quot; data-renderer-start-pos=&quot;1558&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot; data-renderer-mark=&quot;true&quot; data-text-custom-color=&quot;#6554c0&quot;&gt;3. Querydsl 설정 방법&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;1577&quot; data-ke-size=&quot;size16&quot;&gt;공식 문서에는 Gradle에 대한 내용이 누락되어 있으며, 실제로 QueryDSL 설정 방법은 Gradle 및 IntelliJ 버전에 따라 상이&lt;/p&gt;
&lt;h2 id=&quot;(1)-gradle.build&quot; data-renderer-start-pos=&quot;1659&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;(1) gradle.build&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1678172637891&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;**// 1. queryDsl version 정보 추가**
buildscript {
    ext {
        **queryDslVersion = &quot;5.0.0&quot;**
    }
}

plugins {
    id 'org.springframework.boot' version '2.6.3'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    **// 2. querydsl plugins 추가
    id &quot;com.ewerk.gradle.plugins.querydsl&quot; version &quot;1.0.10&quot;**
    id 'java'
}

//...

dependencies {
    **// 3. querydsl library dependencies 추가
    implementation &quot;com.querydsl:querydsl-jpa:${queryDslVersion}&quot;
    implementation &quot;com.querydsl:querydsl-apt:${queryDslVersion}&quot;**
    //...
}

test {
    useJUnitPlatform()
}

**/*
 * queryDSL 설정 추가
 */
// querydsl에서 사용할 경로 설정
def querydslDir = &quot;$buildDir/generated/querydsl&quot;

// JPA 사용 여부와 사용할 경로를 설정
querydsl {
    jpa = true
    querydslSourcesDir = querydslDir
}

// build 시 사용할 sourceSet 추가
// IDE의 소스 폴더에 자동으로 넣어준다.
// 개발 환경에서 생성된 Q파일들을 사용할 수 있도록 generated 디렉토리를 sourceSet에 추가해주면 개발 코드에서 생성된 Q파일에 접근할 수 있습니다.
sourceSets {
    main.java.srcDir querydslDir
}

// querydsl 컴파일시 사용할 옵션 설정
// Q파일을 생성해준다.
compileQuerydsl{
    options.annotationProcessorPath = configurations.querydsl
}

// querydsl 이 compileClassPath 를 상속하도록 설정
// 컴파일이 될때 같이 수행
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
    querydsl.extendsFrom compileClasspath
}**&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;(2)-compileQuerydsl-실행&quot; data-renderer-start-pos=&quot;2965&quot;&gt;&lt;b&gt;(2) compileQuerydsl 실행&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;2989&quot; data-ke-size=&quot;size16&quot;&gt;Gradle Tasks -&amp;gt; compileQuerydsl 을 실행&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;441&quot; data-origin-height=&quot;610&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpjQYB/btr2ufPnBZY/IUhKrDwqNV1bUXyyn36F91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpjQYB/btr2ufPnBZY/IUhKrDwqNV1bUXyyn36F91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpjQYB/btr2ufPnBZY/IUhKrDwqNV1bUXyyn36F91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpjQYB%2Fbtr2ufPnBZY%2FIUhKrDwqNV1bUXyyn36F91%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;610&quot; data-origin-width=&quot;441&quot; data-origin-height=&quot;610&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;또는 명령어를 이용하여 Querydsl query type 생성&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;3069&quot; data-ke-size=&quot;size16&quot;&gt;./gradlew clean compileQuerydsl&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;3069&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;3069&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;(3)-Querydsl-Build-결과-확인&quot; data-renderer-start-pos=&quot;3102&quot;&gt;&lt;b&gt;(3) Querydsl Build 결과 확인&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;div data-layout=&quot;align-start&quot; data-width=&quot;75&quot; data-node-type=&quot;mediaSingle&quot;&gt;
&lt;div&gt;
&lt;div data-context-id=&quot;9962121&quot; data-type=&quot;file&quot; data-node-type=&quot;media&quot; data-width=&quot;664&quot; data-height=&quot;493&quot; data-id=&quot;f25ce2d2-9bf3-45d6-aa61-0d325493b52c&quot; data-collection=&quot;contentId-9962121&quot; data-file-name=&quot;image-20220928-053641.png&quot; data-file-size=&quot;77533&quot; data-file-mime-type=&quot;image/png&quot; data-alt=&quot;&quot;&gt;
&lt;div id=&quot;newFileExperienceWrapper&quot; data-testid=&quot;media-card-view&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;493&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkD65q/btr2D4yFXCW/y0h71c0FKVscL05BoCw5g1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkD65q/btr2D4yFXCW/y0h71c0FKVscL05BoCw5g1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkD65q/btr2D4yFXCW/y0h71c0FKVscL05BoCw5g1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkD65q%2Fbtr2D4yFXCW%2Fy0h71c0FKVscL05BoCw5g1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;664&quot; height=&quot;493&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;493&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&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-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;BUILD SUCCESSFUL 을 확인하였다면 build/generated/querydsl 경로에 Project Entity 들의 QClass 가 생성된 것을 확인할 수 있다.&lt;/li&gt;
&lt;li&gt;프로젝트 하위 디렉토리 중&amp;nbsp;build/generated/querydsl 여기 진입하면 아까 생성한&amp;nbsp;Item Entity 가&amp;nbsp;QItem 으로 변해있는 것을 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;$projectDir/build/generated&amp;nbsp;디렉토리 하위에 Entity로 등록한 클래스들이 Q라는 접두사가 붙은 형태로 생성되었습니다.&lt;/li&gt;
&lt;li&gt;이러한 클래스들을 Q 클래스 혹은 Q(쿼리) 타입이라고 합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;QueryDSL로 쿼리를 작성할 때, Q 클래스를 사용함으로써 쿼리를 Type-Safe하게 작성할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;git으로 소스 코드를 관리할 땐 반드시 해당 경로를 무시하도록 처리해주셔야 합니다.&lt;/li&gt;
&lt;li&gt;QItem.java 파일을 열어보면&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1678172683821&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package io.lcalmsky.querydsl.domain;

import static com.querydsl.core.types.PathMetadataFactory.*;

import com.querydsl.core.types.dsl.*;

import com.querydsl.core.types.PathMetadata;
import javax.annotation.Generated;
import com.querydsl.core.types.Path;

@Generated(&quot;com.querydsl.codegen.EntitySerializer&quot;)
public class QItem extends EntityPathBase&amp;lt;Item&amp;gt; {

    private static final long serialVersionUID = 1540314452L;

    public static final QItem item = new QItem(&quot;item&quot;);

    public final NumberPath&amp;lt;Long&amp;gt; id = createNumber(&quot;id&quot;, Long.class);

    public QItem(String variable) {
        super(Item.class, forVariable(variable));
    }

    public QItem(Path&amp;lt;? extends Item&amp;gt; path) {
        super(path.getType(), path.getMetadata());
    }

    public QItem(PathMetadata metadata) {
        super(Item.class, metadata);
    }
}&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;h1 id=&quot;(4)-Querydsl-정상-동작-테스트&quot; data-renderer-start-pos=&quot;4438&quot;&gt;&lt;b&gt;(4) Querydsl 정상 동작 테스트&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;4462&quot; data-ke-size=&quot;size16&quot;&gt;그럼&amp;nbsp;Querydsl 을 이용해 정상적으로 쿼리를 수행하는지 확인해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1678172699346&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package io.lcalmsky.querydsl.domain;

import com.querydsl.jpa.impl.JPAQueryFactory;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.persistence.EntityManager;
import org.springframework.transaction.annotation.Transactional;;

import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest
@Transactional
class ItemTest {
    @Autowired
    EntityManager entityManager;

    @Test
    void test() {
        // given
        Item item = new Item();
        entityManager.persist(item);

        // when
        JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager); // (1)
        QItem qItem = new QItem(&quot;i&quot;); // (2)
        Item found = queryFactory.selectFrom(qItem).fetchOne(); // (3)

        // then
        assertEquals(found, item); // (4)
    }
}

(1) JPAQueryFactory를 생성합니다. 이 때 생성자로 EntityManager를 주입해줍니다.
(2) QItem 객체를 생성합니다. 생성자에는 Entity의 alias로 사용할 변수명을 입력합니다.
(3) JPQL을 작성하듯이 자바 코드로 쿼리를 작성합니다.
(4) DB에 저장된 데이터와 다시 조회해 온 데이터가 동일한지 확인합니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 동작했는지 확인하기 위해 아래 설정을 추가해줍니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;5643&quot; data-ke-size=&quot;size16&quot;&gt;H2 데이터베이스 가 실행되며 테이블을 직접 생성하고 포매팅된&amp;nbsp;SQL&amp;nbsp;로그를 확인할 수 있기 위함입니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;5643&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678172710889&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring:
  jpa:
    hibernate:
      ddl-auto: create
    properties:
      hibernate:
        format_sql: true
logging:
  level:
    org.hibernate.SQL: debug&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트를 실행시킨 결과는 다음과 같습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1678172725714&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;2021-07-15 19:53:33.992 DEBUG 4334 --- [           main] org.hibernate.SQL                        : 

    create table item (
       id bigint not null,
        primary key (id)
    )
// 생략
2021-07-15 19:53:35.898 DEBUG 4334 --- [           main] org.hibernate.SQL                        : 
    insert 
    into
        item
        (id) 
    values
        (?)
2021-07-15 19:53:35.906 DEBUG 4334 --- [           main] org.hibernate.SQL                        : 
    select
        item0_.id as id1_0_ 
    from
        item item0_&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;(5)-또-다른-예&quot; data-renderer-start-pos=&quot;6663&quot;&gt;&lt;b&gt;(5) 또 다른 예&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;6675&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ Java 파일 구조 ]&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;530&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVlwJd/btr2wurGmrD/J5ay3OVAW3VkmeyFoApF61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVlwJd/btr2wurGmrD/J5ay3OVAW3VkmeyFoApF61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVlwJd/btr2wurGmrD/J5ay3OVAW3VkmeyFoApF61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVlwJd%2Fbtr2wurGmrD%2FJ5ay3OVAW3VkmeyFoApF61%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;603&quot; height=&quot;530&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;530&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ 생성된 Q클래스 구조 ]&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;511&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EKmSF/btr2r48A0cR/NEJu2WQEvYZruGs4fr5VC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EKmSF/btr2r48A0cR/NEJu2WQEvYZruGs4fr5VC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EKmSF/btr2r48A0cR/NEJu2WQEvYZruGs4fr5VC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEKmSF%2Fbtr2r48A0cR%2FNEJu2WQEvYZruGs4fr5VC1%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;621&quot; height=&quot;511&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;511&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;(6)-p6spy-추가&quot; data-renderer-start-pos=&quot;6718&quot;&gt;&lt;b&gt;(6) p6spy 추가&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;6732&quot; data-ke-size=&quot;size16&quot;&gt;sql문의 파라미터 출력 및 기타 기능들을 위해서 p6spy 라이브러리를 추가한다.&lt;/p&gt;
&lt;pre id=&quot;code_1678172755973&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.8'&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;h1 data-renderer-start-pos=&quot;6860&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot; data-renderer-mark=&quot;true&quot; data-text-custom-color=&quot;#6554c0&quot;&gt;4. Querydsl 예제&lt;/span&gt;&lt;/b&gt;&lt;/h1&gt;
&lt;pre id=&quot;code_1678172767417&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@DisplayName(&quot;hi 내용을 포함하며 댓글이 1개 이상인 Post를 ID 내림차순으로 조회한다.&quot;)
@Test
void queryDsl_findPostsByMyCriteria_Three() {
    EntityManager entityManager = testEntityManager.getEntityManager();

    JPAQuery&amp;lt;Post&amp;gt; query = new JPAQuery&amp;lt;&amp;gt;(entityManager);
    QPost qPost = new QPost(&quot;p&quot;);

    List&amp;lt;Post&amp;gt; posts = query.from(qPost)
        .where(qPost.content.contains(&quot;hi&quot;)
            .and(qPost.comments.size().gt(0))
        ).orderBy(qPost.id.desc())
        .fetch();

    assertThat(posts).hasSize(3);
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;QueryDSL은 각종 풍부한 체이닝 메서드와 유틸리티 메서드 및 정적 타입(Q 클래스)을 기반으로 직관적으로 쿼리를 작성&lt;/li&gt;
&lt;li&gt;JPQL을 사용해본 독자님이라면 코드가 상당히 직관적임&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;5.-Check-List&quot; data-renderer-start-pos=&quot;7490&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot; data-renderer-mark=&quot;true&quot; data-text-custom-color=&quot;#6554c0&quot;&gt;5. Check List&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;h1 id=&quot;(1)-기본-Q-Type-활용&quot; data-renderer-start-pos=&quot;7505&quot;&gt;&lt;b&gt;(1) 기본 Q-Type 활용&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;7523&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ Q클래스 인스턴스를 사용하는 2가지 방법 ]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678172786715&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;QMember qMember = new QMember(&quot;m&quot;); // 별칭 직접 지정
QMember qMember = QMember.member; // 기본 인스턴스 사용&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;하지만 기본 인스턴스를 static import와 함께 사용하는 것을 권장한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;(2)-결과-조회&quot; data-renderer-start-pos=&quot;7695&quot;&gt;&lt;b&gt;(2) 결과 조회&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;fetch&amp;nbsp;: 리스트 조회, 데이터 없으면 빈 리스트 반환&lt;/li&gt;
&lt;li&gt;fetchOne&amp;nbsp;: 단 건 조회
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결과가 없으면 : null&lt;/li&gt;
&lt;li&gt;결과가 둘 이상이면 :&amp;nbsp;com.querydsl.core.NonUniqueResultException&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;fetchFirst&amp;nbsp;: limit(1).fetchOne()&lt;/li&gt;
&lt;li&gt;fetchResults&amp;nbsp;: &lt;span data-renderer-mark=&quot;true&quot;&gt;페이징 정보 포함, total count 쿼리 추가 실행&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;group by having 카운팅에서 해당 메소드가 명확하게 동작하지 않는 이슈가 발생하여 deprecated 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;fetchCount&amp;nbsp;: &lt;span data-renderer-mark=&quot;true&quot;&gt;count 쿼리로 변경해서 count 수 조회&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;group by having 카운팅에서 해당 메소드가 명확하게 동작하지 않는 이슈가 발생하여 deprecated 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;(3)-페이징&quot; data-renderer-start-pos=&quot;8114&quot;&gt;&lt;b&gt;(3) 페이징&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실무에서 페이징 쿼리를 작성할 때, 데이터를 조회하는 쿼리는 여러 테이블을 조인해야 하지만, count 쿼리는 조인이 필요 없는 경우도 있다.&lt;/li&gt;
&lt;li&gt;그런데 이렇게 자동화된 count 쿼리는 원본 쿼리와 같이 모두 조인을 해버리기 때문에 성능이 안나올 수 있다.&lt;/li&gt;
&lt;li&gt;count 쿼리에 조인이 필요없는 성능 최적화가 필요하다면, count 전용 쿼리를 별도로 작성해야 한다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>JPA</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/663</guid>
      <comments>https://series.tistory.com/entry/Querydsl-%EC%8A%A4%ED%84%B0%EB%94%94#entry663comment</comments>
      <pubDate>Tue, 7 Mar 2023 16:06:46 +0900</pubDate>
    </item>
    <item>
      <title>OpenSearch Service 설정</title>
      <link>https://series.tistory.com/entry/OpenSearch-Service-%EC%84%A4%EC%A0%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;Cloudwatch Log 구독필터 &amp;rarr; lambda Function &amp;rarr; AWS OpenSearch 로그 수집을 위해서는 OpenSearch에 아래와 같은 설정이 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1742&quot; data-origin-height=&quot;1108&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SuDjs/btr2C9gbbSG/GkTgUNreofa8khiUGifH01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SuDjs/btr2C9gbbSG/GkTgUNreofa8khiUGifH01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SuDjs/btr2C9gbbSG/GkTgUNreofa8khiUGifH01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSuDjs%2Fbtr2C9gbbSG%2FGkTgUNreofa8khiUGifH01%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;1742&quot; height=&quot;1108&quot; data-origin-width=&quot;1742&quot; data-origin-height=&quot;1108&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;Backend role의 ARN은 lambda 함수의 IAM 역할 ARN이다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;오래된-인덱스-자동-삭제-하기&quot; data-renderer-start-pos=&quot;1394&quot; data-ke-size=&quot;size26&quot;&gt;오래된 인덱스 자동 삭제 하기&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-renderer-start-pos=&quot;1412&quot; data-ke-size=&quot;size16&quot;&gt;Index Management &amp;rarr; State Management policies 에서 새로운 policy를 추가해 준다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-renderer-start-pos=&quot;1482&quot; data-ke-size=&quot;size16&quot;&gt;policy를 생성하고 특정 index pattern을 검색하여 자동으로 해당 policy를 적용해 준다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;1544&quot; data-ke-size=&quot;size16&quot;&gt;index의 상태(state)를 변경해 주고, 상태(state)에따라 명령을 실행하는 방식&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;최근-7일치-index만-보관할-경우&quot; data-renderer-start-pos=&quot;1597&quot; data-ke-size=&quot;size23&quot;&gt;최근 7일치 index만 보관할 경우&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-renderer-start-pos=&quot;1619&quot; data-ke-size=&quot;size16&quot;&gt;index는 날짜별로 생성된다고 가정한다(cwl-YYYY.mm.dd 형식).&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;1663&quot; data-ke-size=&quot;size16&quot;&gt;아래의 경우 정책(policy)의 이름은 &amp;ldquo;delete_old_indices_7d&amp;rdquo;이다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;1663&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678172394395&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    &quot;policy&quot;: {
        &quot;policy_id&quot;: &quot;delete_old_indices_7d&quot;,
        &quot;description&quot;: &quot;A policy that delete old 7 days.&quot;,
        &quot;last_updated_time&quot;: 1668408892087,
        &quot;schema_version&quot;: 14,
        &quot;error_notification&quot;: null,
        &quot;default_state&quot;: &quot;hot_state&quot;,
        &quot;states&quot;: [
            {
                &quot;name&quot;: &quot;hot_state&quot;,
                &quot;actions&quot;: [],
                &quot;transitions&quot;: [
                    {
                        &quot;state_name&quot;: &quot;delete&quot;,
                        &quot;conditions&quot;: {
                            &quot;min_index_age&quot;: &quot;7d&quot;
                        }
                    }
                ]
            },
            {
                &quot;name&quot;: &quot;delete&quot;,
                &quot;actions&quot;: [
                    {
                        &quot;retry&quot;: {
                            &quot;count&quot;: 3,
                            &quot;backoff&quot;: &quot;exponential&quot;,
                            &quot;delay&quot;: &quot;1m&quot;
                        },
                        &quot;delete&quot;: {}
                    }
                ],
                &quot;transitions&quot;: []
            }
        ],
        &quot;ism_template&quot;: [
            {
                &quot;index_patterns&quot;: [
                    &quot;cwl-*&quot;
                ],
                &quot;priority&quot;: 100,
                &quot;last_updated_time&quot;: 1639009244056
            }
        ]
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>AWS</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/662</guid>
      <comments>https://series.tistory.com/entry/OpenSearch-Service-%EC%84%A4%EC%A0%95#entry662comment</comments>
      <pubDate>Tue, 7 Mar 2023 16:00:06 +0900</pubDate>
    </item>
    <item>
      <title>EKS 배포 롤백 방법</title>
      <link>https://series.tistory.com/entry/EKS-%EB%B0%B0%ED%8F%AC-%EB%A1%A4%EB%B0%B1-%EB%B0%A9%EB%B2%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;이미 배포된 pod에 오류가 발생하여 롤백하여야 할 경우가 있을텐데, EKS는 배포 history기능을 통해 특정 revision으로 롤백할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;배포-히스토리-보기&quot; data-renderer-start-pos=&quot;90&quot;&gt;배포 히스토리 보기&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;102&quot; data-ke-size=&quot;size16&quot;&gt;배포 히스토리는 deployment 단위로 볼 수 있다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;102&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678172064678&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;]$ kubectl -n backend rollout history deploy backend-api-template-deployment
deployment.apps/backend-api-template-deployment
REVISION  CHANGE-CAUSE
15        [2022-12-26 11:12:18] backend-api-template:dev-73
16        [2022-12-26 11:25:59] backend-api-template:dev-74
17        [2022-12-26 11:37:21] backend-api-template:dev-75
18        [2022-12-28 19:02:14] backend-api-template:dev-76
19        [2023-01-03 07:49:41] backend-api-template:dev-77
20        [2023-01-03 08:45:55] backend-api-template:dev-78
21        [2023-01-04 10:55:50] backend-api-template:dev-79
22        [2023-01-04 11:13:08] backend-api-template:dev-80
23        [2023-01-05 15:33:44] backend-api-template:dev-81
24        [2023-01-06 11:47:46] backend-api-template:dev-82
25        [2023-01-06 14:40:16] backend-api-template:dev-83

]$&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;명령어는 &lt;/span&gt;kubectl -n {namespace 이름} rollout history deploy {deployment 이름}&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt; 의 형식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;kubectl -n remodeling-backend는 kb로 alias 되어 있습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;배포-히스토리의-내용&quot; data-renderer-start-pos=&quot;1092&quot;&gt;배포 히스토리의 내용&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;1105&quot; data-ke-size=&quot;size16&quot;&gt;위의 배포 히스토리의 내용 형식은 kubernetes 가 자동으로 만들어 주는것이 아닙니다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;1158&quot; data-ke-size=&quot;size16&quot;&gt;히스토리 내용은 아래의 명령어로 배포시에 적재가 가능합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1678172151222&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;]$ kubectl --namespace=$NAMESPACE annotate deployment $IMAGE_REPO_NAME-deployment kubernetes.io/change-cause=&quot;[$DATE] $IMAGE_REPO_NAME:$SPRING_PROFILES_ACTIVE-$CODEBUILD_BUILD_NUMBER&quot; --overwrite=true&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;위 내용은 AWS CodeBuild 할때 참조하여 실행하는 &lt;/span&gt;buildspec.yml&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;의 맨 마지막 줄에 적용되어 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;배포-롤백&quot; data-renderer-start-pos=&quot;1464&quot;&gt;배포 롤백&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;1471&quot; data-ke-size=&quot;size16&quot;&gt;롤백시에는 위 히스토리 보기 기능을 이용하여 REVISION을 확인 후 원하는 REVISION 번호로 롤백 하면 됩니다.&lt;br /&gt;롤백 명령어는 아래와 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1678172172374&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;]$ kubectl -n backend rollout undo deploy backend-api-deployment --to-revision=24&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;명령어는 &lt;/span&gt;kubectl -n {namespace 이름} rolloute undo deploy {deployment 이름} --to-revision={revision 번호}&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;의 형식 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;현재-적용된-리비전-확인&quot; data-renderer-start-pos=&quot;1779&quot;&gt;현재 적용된 리비전 확인&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;1794&quot; data-ke-size=&quot;size16&quot;&gt;배포 상세 정보와 배포 히스토리를 비교하여, 현재 적용된 버전을 확인할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1678172191073&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;]$ kubectl -n backend describe deployment.apps backend-api-template-deployment&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1678172197324&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[ec2-user@ip-10-204-*** ~]$ kubectl -n backend describe deployment.apps backend-api-template-deployment | grep -A 2 Environment
    Environment:
      DATE:        2023-02-24 16:46:05
      DOCKER_TAG:  dev-101&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;기타&quot; data-renderer-start-pos=&quot;2161&quot;&gt;기타&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;h3 id=&quot;ArgoCD와-같은-WebUI-툴을-사용하지-않는-이유는-무엇입니까?&quot; data-renderer-start-pos=&quot;2165&quot; data-ke-size=&quot;size23&quot;&gt;ArgoCD와 같은 WebUI 툴을 사용하지 않는 이유는 무엇입니까?&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-renderer-start-pos=&quot;2205&quot; data-ke-size=&quot;size16&quot;&gt;관리상의 이슈 입니다. 현재 리모델링 프로젝트는 AWS의 리소스를 사용하고 있고, 가능한 AWS에서 제공하는 자원만으로 운영하고 있습니다. ArgoCD는 개별적으로 설치해서 써야 해서 아직 적용하고 있지 않습니다.&lt;/p&gt;</description>
      <category>AWS</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/661</guid>
      <comments>https://series.tistory.com/entry/EKS-%EB%B0%B0%ED%8F%AC-%EB%A1%A4%EB%B0%B1-%EB%B0%A9%EB%B2%95#entry661comment</comments>
      <pubDate>Tue, 7 Mar 2023 15:56:51 +0900</pubDate>
    </item>
    <item>
      <title>JWT Postman 가이드</title>
      <link>https://series.tistory.com/entry/JWT-Postman-%EA%B0%80%EC%9D%B4%EB%93%9C-1</link>
      <description>&lt;h1 data-renderer-start-pos=&quot;2&quot;&gt;인증서 이슈&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;10&quot; data-ke-size=&quot;size16&quot;&gt;EKS API의 경우, API콜 할때 인증서를 셋팅해야 한다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;46&quot; data-ke-size=&quot;size16&quot;&gt;아래와 같은 인증서 관련 에러 발생시&lt;/p&gt;
&lt;div data-layout=&quot;center&quot; data-node-type=&quot;mediaSingle&quot;&gt;
&lt;div&gt;
&lt;div data-type=&quot;file&quot; data-node-type=&quot;media&quot; data-width=&quot;454&quot; data-height=&quot;294&quot; data-id=&quot;e926f437-1699-4e2f-a2d5-0f08e4d81793&quot; data-collection=&quot;contentId-156403273&quot; data-file-name=&quot;스크린샷 2023-03-06 오전 11.47.49.png&quot; data-file-size=&quot;57284&quot; data-file-mime-type=&quot;image/png&quot; data-alt=&quot;&quot; data-context-id=&quot;156403273&quot;&gt;
&lt;div id=&quot;newFileExperienceWrapper&quot; data-testid=&quot;media-card-view&quot;&gt;
&lt;div data-testid=&quot;media-file-card-view&quot; data-test-status=&quot;complete&quot; data-test-media-name=&quot;스크린샷 2023-03-06 오전 11.47.49.png&quot; data-test-progress=&quot;1&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eqLtxf/btr2CuYUTLd/JzfdpJssWpk21Zb4yD2jsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eqLtxf/btr2CuYUTLd/JzfdpJssWpk21Zb4yD2jsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eqLtxf/btr2CuYUTLd/JzfdpJssWpk21Zb4yD2jsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeqLtxf%2Fbtr2CuYUTLd%2FJzfdpJssWpk21Zb4yD2jsK%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;908&quot; height=&quot;588&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;588&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;방안1] 단순히 ssl 기능 disable&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2479&quot; data-origin-height=&quot;471&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQkESu/btr2tCRiuyj/cfhB0n6KkKI9MYJrIZLKbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQkESu/btr2tCRiuyj/cfhB0n6KkKI9MYJrIZLKbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQkESu/btr2tCRiuyj/cfhB0n6KkKI9MYJrIZLKbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQkESu%2Fbtr2tCRiuyj%2FcfhB0n6KkKI9MYJrIZLKbK%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;2479&quot; height=&quot;471&quot; data-origin-width=&quot;2479&quot; data-origin-height=&quot;471&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;방안2] 인증서 등록&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1438&quot; data-origin-height=&quot;438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTLL8s/btr2sWJkcBb/6Ma5W1ukpGXNHF2URjgMhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTLL8s/btr2sWJkcBb/6Ma5W1ukpGXNHF2URjgMhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTLL8s/btr2sWJkcBb/6Ma5W1ukpGXNHF2URjgMhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTLL8s%2Fbtr2sWJkcBb%2F6Ma5W1ukpGXNHF2URjgMhk%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;1438&quot; height=&quot;438&quot; data-origin-width=&quot;1438&quot; data-origin-height=&quot;438&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;h1 id=&quot;JWT-토큰-셋팅&quot; data-renderer-start-pos=&quot;122&quot;&gt;JWT 토큰 셋팅&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p data-renderer-start-pos=&quot;133&quot; data-ke-size=&quot;size16&quot;&gt;방법1] Authorization 설정&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2479&quot; data-origin-height=&quot;461&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bilOti/btr2tDQcbdH/7zelB2pQBIxmmkDTvdvLk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bilOti/btr2tDQcbdH/7zelB2pQBIxmmkDTvdvLk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bilOti/btr2tDQcbdH/7zelB2pQBIxmmkDTvdvLk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbilOti%2Fbtr2tDQcbdH%2F7zelB2pQBIxmmkDTvdvLk0%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;2479&quot; height=&quot;461&quot; data-origin-width=&quot;2479&quot; data-origin-height=&quot;461&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;방법2] 헤더 직접 셋팅&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;Authorization 필드에 &amp;ldquo;Bearer {TOKEN}&amp;rdquo; 으로 셋팅&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2479&quot; data-origin-height=&quot;712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SLDHs/btr2xS6SYhk/gk9wfhX7gD1AjCxrtrA5rK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SLDHs/btr2xS6SYhk/gk9wfhX7gD1AjCxrtrA5rK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SLDHs/btr2xS6SYhk/gk9wfhX7gD1AjCxrtrA5rK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSLDHs%2Fbtr2xS6SYhk%2Fgk9wfhX7gD1AjCxrtrA5rK%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;2479&quot; height=&quot;712&quot; data-origin-width=&quot;2479&quot; data-origin-height=&quot;712&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/660</guid>
      <comments>https://series.tistory.com/entry/JWT-Postman-%EA%B0%80%EC%9D%B4%EB%93%9C-1#entry660comment</comments>
      <pubDate>Tue, 7 Mar 2023 15:48:21 +0900</pubDate>
    </item>
    <item>
      <title>AWS command 정리 (kubectl)</title>
      <link>https://series.tistory.com/entry/AWS-command-%EC%A0%95%EB%A6%AC-kubectl</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kubernetes.io/docs/reference/kubectl/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kubernetes.io/docs/reference/kubectl/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678171342391&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Command line tool (kubectl)&quot; data-og-description=&quot;Production-Grade Container Orchestration&quot; data-og-host=&quot;kubernetes.io&quot; data-og-source-url=&quot;https://kubernetes.io/docs/reference/kubectl/&quot; data-og-url=&quot;https://kubernetes.io/docs/reference/kubectl/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bXJXKa/hyRRP5Pbf7/d7XJgkx2ItZclMTdFrCa90/img.png?width=1727&amp;amp;height=373&amp;amp;face=0_0_1727_373,https://scrap.kakaocdn.net/dn/bKZSZ2/hyRQp1ZYTe/YpvQ5SMzNT23HHPWOFonX1/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://kubernetes.io/docs/reference/kubectl/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kubernetes.io/docs/reference/kubectl/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bXJXKa/hyRRP5Pbf7/d7XJgkx2ItZclMTdFrCa90/img.png?width=1727&amp;amp;height=373&amp;amp;face=0_0_1727_373,https://scrap.kakaocdn.net/dn/bKZSZ2/hyRQp1ZYTe/YpvQ5SMzNT23HHPWOFonX1/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Command line tool (kubectl)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Production-Grade Container Orchestration&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kubernetes.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;기본&quot; data-renderer-start-pos=&quot;18&quot;&gt;기본&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;pre id=&quot;code_1678173913818&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl -n {NAME_SPACE} {COMMAND} {TYPE} {NAME}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-renderer-start-pos=&quot;75&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;목록-조회&quot; data-renderer-start-pos=&quot;77&quot;&gt;목록 조회&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;kubectl -n backend get {TYPE}
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DEV namespace 정보 모두 조회(pod, deployment, service, cluster 등.
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;3&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;kubctl -n backend get all&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DEV POD 조회.
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;3&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;kubctl -n backend get pod&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DEV deployment 조회.
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;3&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;kubctl -n backend get delpoy&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;상세-조회&quot; data-renderer-start-pos=&quot;361&quot;&gt;상세 조회&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;목록에서 조회된 항목의 상세 조회
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;kubectl -n backend describe {TYPE} {NAME}&lt;/li&gt;
&lt;li&gt;DEV namepsace의 특정 pod 조회
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;3&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;kubectl -n backend describe pod backend-api-common-deployment-67647bc77f-hncw6&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DEV namespace의 특정 deployment 조회
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;3&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;kubectl -n backend describe deploy backend-api-common-deployment&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-renderer-start-pos=&quot;689&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;EKS-API-서버-주소-조회&quot; data-renderer-start-pos=&quot;691&quot;&gt;EKS API 서버 주소 조회&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;kubectl cluster-info&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-renderer-start-pos=&quot;735&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;EKS-인증서-조회&quot; data-renderer-start-pos=&quot;737&quot;&gt;EKS 인증서 조회&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;kubectl config view --minify --raw --output 'jsonpath={..cluster.certificate-authority-data}' | base64 -d&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-renderer-start-pos=&quot;860&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;EKS-JWT-토큰-조회&quot; data-renderer-start-pos=&quot;862&quot;&gt;EKS JWT 토큰 조회&lt;/h1&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;pre id=&quot;code_1678171464725&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl get serviceaccount&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JWT 토큰 조회&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1678171494942&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl get secret $(kubectl get sa {서비스계정} \
    -ojsonpath=&quot;{.secrets[0].name}&quot;) \
    -ojsonpath=&quot;{.data.token}&quot; | base64 -d&lt;/code&gt;&lt;/pre&gt;</description>
      <category>AWS</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/658</guid>
      <comments>https://series.tistory.com/entry/AWS-command-%EC%A0%95%EB%A6%AC-kubectl#entry658comment</comments>
      <pubDate>Tue, 7 Mar 2023 15:45:09 +0900</pubDate>
    </item>
    <item>
      <title>AWS EKS K8S Cronjob 임시 중단하기</title>
      <link>https://series.tistory.com/entry/AWS-EKS-K8S-Cronjob-%EC%9E%84%EC%8B%9C-%EC%A4%91%EB%8B%A8%ED%95%98%EA%B8%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;# 임시 중단&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1678167923467&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;]$ kubectl -n {namespace_이름} patch cronjob {job_이름} -p '{&quot;spec&quot; : {&quot;suspend&quot; : true }}'&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;pre id=&quot;code_1678167964973&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;]$ kubectl -n {namespace_이름} get cronjob
NAME                               SCHEDULE                       SUSPEND   ACTIVE   LAST SCHEDULE   AGE
backend-batch-dump-goods-cronjob   CRON_TZ=Asia/Seoul 0 1 * * *   True      0        13h             34d&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SUSPEND 항목 True 확인&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AWS</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/657</guid>
      <comments>https://series.tistory.com/entry/AWS-EKS-K8S-Cronjob-%EC%9E%84%EC%8B%9C-%EC%A4%91%EB%8B%A8%ED%95%98%EA%B8%B0#entry657comment</comments>
      <pubDate>Tue, 7 Mar 2023 14:46:28 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] JPA Data Delete</title>
      <link>https://series.tistory.com/entry/JPA-JPA-Data-Delete</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;JPA 연관관계가 존재할 때 Entity 삭제하기&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JPA 프로젝트를 진행하던 중, 회원 탈퇴를 진행할 때 User와 그에 연관된 Entity에서 @ManyToOne 관계에서 영속성 관리에서 문제가 발생되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 User Data를 delete하려고하면 다음과 같은 Error가 발생한다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;Cannot delete or update a parent row: a foreign key constraint fail&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조된 객체를 지워주지 않았기 때문에 발생하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 id=&quot;-onetomany-cascade&quot; data-ke-size=&quot;size23&quot;&gt;OneToMany Cascade&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는&lt;span&gt;&amp;nbsp;&lt;/span&gt;@ManyToOne&lt;span&gt;&amp;nbsp;&lt;/span&gt;어노테이션에&lt;span&gt;&amp;nbsp;&lt;/span&gt;cascade&lt;span&gt;&amp;nbsp;&lt;/span&gt;option을 부여해서 영속성을 부여 해 보았다.&lt;br /&gt;그러나 User를 Delete할 때 위와 같은 오류가 계속해서 발생했다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결론적으로 찾은 이유는 내가 단방향으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;child에게&lt;span&gt;&amp;nbsp;&lt;/span&gt;parent만을 Mapping했기 때문이다.&lt;/b&gt;&lt;br /&gt;parent는&lt;span&gt;&amp;nbsp;&lt;/span&gt;child를 매핑하지 않았기 때문에 계단식으로 데이터가 삭제되는데 실패했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 둘을 양방향으로 연결 해 주는 것을 우선적으로 해야했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@OneToMany&lt;span&gt;&amp;nbsp;&lt;/span&gt;어노테이션으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;parent&lt;span&gt;&amp;nbsp;&lt;/span&gt;Entity에 List나 Set 형식으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;child를 Mapping 해 주었다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 때 @OneToMany의 mappedBy 옵션에는 실제 내가 child 셋팅한 변수명과 똑같이 설정 해주어야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 이 부분 때문에 계속&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러가 발생했었는데 변수명을 일치시키지 않아서 생긴 문제였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 id=&quot;-entity-구현&quot; data-ke-size=&quot;size23&quot;&gt;Entity 구현&lt;/h3&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;
@Entity
@Getter
@Setter
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    ...


    @OneToMany(mappedBy = &quot;userId&quot;, cascade = {CascadeType.ALL}, orphanRemoval=true)
    private List&amp;lt;UserConference&amp;gt; userConferences;

    ....
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;@Entity
@Getter
@Setter
public class UserConference {

  ...

  @ManyToOne
  @JoinColumn(name=&quot;User_ID&quot;, referencedColumnName = &quot;ID&quot;)
  private User userId;



}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 mappedBy는 child의 변수명과 일치시켜야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 관계에 대해서 양방향 설정을 마치고,&lt;br /&gt;cascade 옵션을 ALL로 주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 마친 후 유저 삭제가 계단식으로 잘 처리 되는 것을 확인하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 id=&quot;-cascade-type&quot; data-ke-size=&quot;size23&quot;&gt;+ Cascade Type&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CascadeType.PERSIST&lt;br /&gt;엔티티를 영속화 할 때이 필드에 보유 된 엔티티도 유지합니다. EntityManager가 flush 중에 새로운 엔티티를 참조하는 필드를 찾고이 필드가 CascadeType.PERSIST를 사용하지 않으면 오류이므로이 Cascade 규칙의 자유로운 적용을 제안합니다.&lt;/li&gt;
&lt;li&gt;CascadeType.MERGE&lt;br /&gt;엔티티 상태를 병합 할 때, 이 필드에 보유 된 엔티티도 병합하십시오.&lt;/li&gt;
&lt;li&gt;CascadeType.REFRESH&lt;br /&gt;엔티티를 새로 고칠 때, 이 필드에 보유 된 엔티티도 새로 고칩니다.&lt;/li&gt;
&lt;li&gt;CascadeType.REMOVE&lt;br /&gt;엔티티를 삭제할 때, 이 필드에 보유 된 엔티티도 삭제하십시오.&lt;/li&gt;
&lt;li&gt;CascadeType.DETACH&lt;br /&gt;부모 엔티티가 detach()를 수행하게 되면, 연관된 엔티티도 detach() 상태가 되어 변경사항이 반영되지 않는다.&lt;/li&gt;
&lt;li&gt;CascadeType.ALL&lt;br /&gt;모든 Cascade 적용&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>JPA</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/656</guid>
      <comments>https://series.tistory.com/entry/JPA-JPA-Data-Delete#entry656comment</comments>
      <pubDate>Mon, 27 Feb 2023 18:14:58 +0900</pubDate>
    </item>
    <item>
      <title>JPA 영속성 컨텍스트란?</title>
      <link>https://series.tistory.com/entry/JPA-%EC%98%81%EC%86%8D%EC%84%B1-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%9E%80</link>
      <description>&lt;h3 id=&quot;영속성-컨텍스트란&quot; data-ke-size=&quot;size23&quot;&gt;영속성 컨텍스트란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영속성 컨텐스트란&lt;span&gt;&amp;nbsp;&lt;/span&gt;엔티티를 영구 저장하는 환경이라는 뜻이다. 애플리케이션과 데이터베이스 사이에서 객체를 보관하는 가상의 데이터베이스 같은 역할을 한다. 엔티티 매니저를 통해 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;em.persist(member);&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;엔티티 매니저를 사용해 회원 엔티티를 영속성 컨텍스트에 저장한다는 의미!&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영속성 컨텍스트의 특징&lt;/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;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 id=&quot;엔티티의-생명주기&quot; 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;비영속(new/transient): 영속성 컨텍스트와 전혀 관계가 없는 상태&lt;/li&gt;
&lt;li&gt;영속(managed): 영속성 컨텍스트에 저장된 상태&lt;/li&gt;
&lt;li&gt;준영속(detached): 영속성 컨텍스트에 저장되었다가 분리된 상태&lt;/li&gt;
&lt;li&gt;삭제(removed): 삭제된 상태&lt;br /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;379&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpoMCK/btr0RPEg66Z/SoLJGltIiwwYjWCAnPONRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpoMCK/btr0RPEg66Z/SoLJGltIiwwYjWCAnPONRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpoMCK/btr0RPEg66Z/SoLJGltIiwwYjWCAnPONRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpoMCK%2Fbtr0RPEg66Z%2FSoLJGltIiwwYjWCAnPONRk%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;504&quot; height=&quot;379&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;379&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;비영속&quot; data-ke-size=&quot;size20&quot;&gt;비영속&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔티티 객체를 생성했지만 아직 영속성 컨텍스트에 저장하지 않은 상태를 비영속(new/transient)라 한다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;Member member = new Member();&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;영속&quot; data-ke-size=&quot;size20&quot;&gt;영속&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔티티 매니저를 통해서 엔티티를 영속성 컨텍스트에 저장한 상태를 말하며 영속성 컨텍스트에 의해 관리된다는 뜻이다.&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;em.persist(member);&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;준영속&quot; data-ke-size=&quot;size20&quot;&gt;준영속&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영속성 컨텍스트가 관리하던 영속 상태의 엔티티 더이상 관리하지 않으면 준영속 상태가 된다. 특정 엔티티를 준영속 상태로 만드려면&lt;span&gt;&amp;nbsp;&lt;/span&gt;em.datach()를 호출하면 된다.&lt;/p&gt;
&lt;pre class=&quot;gcode&quot;&gt;&lt;code&gt;// 엔티티를 영속성 컨텍스트에서 분리해 준영속 상태로 만든다.
em.detach(member);
// 영속성 콘텍스트를 비워도 관리되던 엔티티는 준영속 상태가 된다.
em.claer();
// 영속성 콘텍스트를 종료해도 관리되던 엔티티는 준영속 상태가 된다.
em.close();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;준영속 상태의 특징&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1차 캐시, 쓰기 지연, 변경 감지, 지연 로딩을 포함한 영속성 컨텍스트가 제공하는 어떠한 기능도 동작하지 않는다.&lt;/li&gt;
&lt;li&gt;식별자 값을 가지고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;삭제&quot; data-ke-size=&quot;size20&quot;&gt;삭제&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제한다.&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;em.remove(member);&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 id=&quot;영속성-컨텍스트의-특징&quot; data-ke-size=&quot;size23&quot;&gt;영속성 컨텍스트의 특징&lt;/h3&gt;
&lt;h4 id=&quot;영속성-컨텍스트의-식별자-값&quot; data-ke-size=&quot;size20&quot;&gt;영속성 컨텍스트의 식별자 값&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영속성 컨텍스트는 엔티티를 식별자 값으로 구분한다. 따라서 영속 상태는 식별자 값이 반드시 있어야 한다.&lt;/p&gt;
&lt;h4 id=&quot;영속성-컨텍스트와-데이터베이스-저장&quot; data-ke-size=&quot;size20&quot;&gt;영속성 컨텍스트와 데이터베이스 저장&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JPA는 보통 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 데이터 베이스에 반영하는데 이를&lt;span&gt;&amp;nbsp;&lt;/span&gt;flush라 한다.&lt;/p&gt;
&lt;h4 id=&quot;영속성-컨텍스트가-엔티티를-관리하면-다음과-같은-장점이-있다&quot; data-ke-size=&quot;size20&quot;&gt;영속성 컨텍스트가 엔티티를 관리하면 다음과 같은 장점이 있다.&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1차 캐시&lt;/li&gt;
&lt;li&gt;동일성 보장&lt;/li&gt;
&lt;li&gt;트랙잭션을 지원하는 쓰기 지연&lt;/li&gt;
&lt;li&gt;변경 감지&lt;/li&gt;
&lt;li&gt;지연 로딩&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;1차-캐시&quot; data-ke-size=&quot;size20&quot;&gt;1차 캐시&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영속성 컨텍스트 내부에는 캐시가 있는데 이를 1차 캐시라고 한다. 영속 상태의 엔티티를 이곳에 저장한다. 1차 캐시의 키는 식별자 값(데이터베이스의 기본 키)이고 값은 엔티티 인스턴스이다. 조회하는 방법은 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;// em.find(엔티티 클래스 타입, 식별자 값);
Member member = em.find(Member.class, &quot;member1&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조회의 흐름&lt;br /&gt;1. 1차 캐시에서 엔티티를 찾는다&lt;br /&gt;2. 있으면 메모리에 있는 1차 캐시에서 엔티티를 조회한다.&lt;br /&gt;3. 없으면 데이터베이스에서 조회한다.&lt;br /&gt;4. 조회한 데이터로 엔티티를 생성해 1차 캐시에 저장한다. (엔티티를 영속상태로 만든다)&lt;br /&gt;5. 조회한 엔티티를 반환한다.&lt;/p&gt;
&lt;h4 id=&quot;영속-엔티티의-동일성-보장&quot; data-ke-size=&quot;size20&quot;&gt;영속 엔티티의 동일성 보장&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영속성 컨텍스트는 엔티티의 동일성을 보장한다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;Member a = em.find(Member.class, &quot;member1&quot;);
Member b = em.find(Member.class, &quot;member1&quot;);
System.out.print(a==b) // true&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동일성 비교 : 실제 인스턴스가 같다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;==을 사용해 비교한다.&lt;br /&gt;동등성 비교 : 실제 인스턴스는 다를 수 있지만 인스턴스가 가지고 있는 값이 같다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;equals()메소드를 구현해서 비교한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;트랜잭션을-지원하는-쓰기-지연transactional-write-behind&quot; data-ke-size=&quot;size20&quot;&gt;트랜잭션을 지원하는 쓰기 지연(transactional write-behind)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;em.find(member)를 사용해 member를 저장해도 바로 INSERT SQL이 DB에 보내지는 것이 아니다. 엔티티 매니저는 트랜잭션을 커밋하기 직전까지 내부 쿼리 저장소에 INSERT SQL을 모아둔다. 그리고 트랜잭션을 커밋할 때 모아둔 쿼리를 DB에 보낸다. 이것을 트랜잭션을 지원하는 쓰기 지연이라 한다.&lt;/p&gt;
&lt;h4 id=&quot;변경-감지&quot; data-ke-size=&quot;size20&quot;&gt;변경 감지&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JPA로 엔티티를 수정할 때는 단순히 엔티티를 조회해서 데이터를 변경하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경감지의 흐름&lt;br /&gt;1. 트랙잭션을 커밋하면 엔티티 매니저 내부에서 먼저 플러시가 호출된다.&lt;br /&gt;2. 엔티티와 스냅샷을 비교하여 변경된 엔티티를 찾는다.&lt;br /&gt;3. 변경된 엔티티가 있으면 수정 쿼리를 생성해서 쓰기 지연 SQL 저장소에 저장한다.&lt;br /&gt;4. 쓰기 지연 저장소의 SQL을 플러시한다.&lt;br /&gt;5. 데이터베이스 트랜잭션을 커밋한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경 감지는 영속성 컨텍스트가 관리하는 영속 상태의 엔티티만 적용된다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();

Member member = em.find(Member.class, &quot;member1&quot;);
member.setName(&quot;노영삼&quot;);

transaction.commit();&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 id=&quot;플러시&quot; data-ke-size=&quot;size23&quot;&gt;플러시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러시는 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영한다. 영속성 컨텍스트의 엔티티를 지우는게 아니라 변경 내용을 데이터베이스에 동기화하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러시의 흐름&lt;br /&gt;1. 변경 감지가 동작해서 스냅샷과 비교해서 수정된 엔티티를 찾는다.&lt;br /&gt;2. 수정된 엔티티에 대해서 수정 쿼리를 만들거 SQL 저장소에 등록한다.&lt;br /&gt;3. 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러시하는 방법&lt;br /&gt;1.&lt;span&gt;&amp;nbsp;&lt;/span&gt;em.flush()&lt;br /&gt;2. 트랙잭션 커밋시 자동 호출&lt;br /&gt;3. JPQL 쿼리 실행시 자동 호출&lt;/p&gt;</description>
      <category>JPA</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/655</guid>
      <comments>https://series.tistory.com/entry/JPA-%EC%98%81%EC%86%8D%EC%84%B1-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%9E%80#entry655comment</comments>
      <pubDate>Mon, 27 Feb 2023 18:12:40 +0900</pubDate>
    </item>
    <item>
      <title>[Intellij] Build, Run, Test 좀 더 빠르게 실행하기</title>
      <link>https://series.tistory.com/entry/Intellij-Build-Run-Test-%EC%A2%80-%EB%8D%94-%EB%B9%A0%EB%A5%B4%EA%B2%8C-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0</link>
      <description>&lt;h3 id=&quot;test-worker&quot; data-ke-size=&quot;size23&quot;&gt;Test worker&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인텔리제이에서 Gradle + Springboot로 프로젝트를 생성 후 @SpringBootTest를 돌리게되면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;229&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dwrwtL/btr01VjEDT9/EXnkLeKgHbutADSGQHwLGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dwrwtL/btr01VjEDT9/EXnkLeKgHbutADSGQHwLGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dwrwtL/btr01VjEDT9/EXnkLeKgHbutADSGQHwLGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdwrwtL%2Fbtr01VjEDT9%2FEXnkLeKgHbutADSGQHwLGk%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;1280&quot; height=&quot;229&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;229&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오랜 시간 뒤에, Test worker 라는 처음보는 녀석이 뜨면서 아주 천천히 테스트가 실행된다.&lt;br /&gt;최신버전의 Intellij에서는 IDE에서 바로 테스트를 돌리는게 아닌, Gradle 빌드를 한 뒤에 테스트를 하게된다. (개발할 시간 1분 1초가 아까운데 시간을 은근히 잡아먹는다.)&lt;/p&gt;
&lt;h3 id=&quot;intellij-설정-변경&quot; data-ke-size=&quot;size23&quot;&gt;Intellij 설정 변경&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Preference(단축키 command + ',')를 열고&lt;br /&gt;Build, Execution, Deployment -&amp;gt; Build Tools -&amp;gt; Gradle 메뉴를 열어&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEB6zw/btr07y2GCuK/WvgANguViBdAOlcEp8BsV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEB6zw/btr07y2GCuK/WvgANguViBdAOlcEp8BsV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEB6zw/btr07y2GCuK/WvgANguViBdAOlcEp8BsV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEB6zw%2Fbtr07y2GCuK%2FWvgANguViBdAOlcEp8BsV0%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;985&quot; height=&quot;710&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Build and run using, Run test using 부분을 사진과 같이 Gradle -&amp;gt; Intellij IDEA로 바꿔준다.&lt;/p&gt;
&lt;h3 id=&quot;lombok-사용시-추가-설정&quot; data-ke-size=&quot;size23&quot;&gt;Lombok 사용시 추가 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Preference(단축키 command + ',')를 열고&lt;br /&gt;Build, Execution, Deployment -&amp;gt; Compiler -&amp;gt; Accotation Processors 메뉴를 열어&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;988&quot; data-origin-height=&quot;714&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XUr9t/btr0RKC0ea0/saxfOvqagwmtIHDvtl2AvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XUr9t/btr0RKC0ea0/saxfOvqagwmtIHDvtl2AvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XUr9t/btr0RKC0ea0/saxfOvqagwmtIHDvtl2AvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXUr9t%2Fbtr0RKC0ea0%2FsaxfOvqagwmtIHDvtl2AvK%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;988&quot; height=&quot;714&quot; data-origin-width=&quot;988&quot; data-origin-height=&quot;714&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Enable annotation processing 부분을 체크 해준다.&lt;/p&gt;
&lt;h3 id=&quot;적용-확인&quot; data-ke-size=&quot;size23&quot;&gt;적용 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 두 단계를 거친 뒤 다시 테스트를 돌려주면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yWL73/btr0OaWg6KD/DK8ikU8Fir49USyjnCx4x0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yWL73/btr0OaWg6KD/DK8ikU8Fir49USyjnCx4x0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yWL73/btr0OaWg6KD/DK8ikU8Fir49USyjnCx4x0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyWL73%2Fbtr0OaWg6KD%2FDK8ikU8Fir49USyjnCx4x0%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;1280&quot; height=&quot;246&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Test worker -&amp;gt; main 으로 바뀌어 있는 모습을 볼 수 있다.&lt;br /&gt;빌드 속도도 무척 빨라졌다.&lt;/p&gt;</description>
      <category>IntelliJ</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/654</guid>
      <comments>https://series.tistory.com/entry/Intellij-Build-Run-Test-%EC%A2%80-%EB%8D%94-%EB%B9%A0%EB%A5%B4%EA%B2%8C-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0#entry654comment</comments>
      <pubDate>Mon, 27 Feb 2023 17:57:40 +0900</pubDate>
    </item>
    <item>
      <title>spring.jpa.open-in-view is enabled by default</title>
      <link>https://series.tistory.com/entry/springjpaopen-in-view-is-enabled-by-default</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 문제상황 : 왜 로그에 warn이 뜨지?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 부트 app을 시작하면 로그가 나오는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 보면 아래와 같이 warning 메세지가 뜬다&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 문제 이유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring Boot에서는&amp;nbsp;spring.jpa.open-in-view를 true로 설정하고 있는데, 이는&amp;nbsp;&lt;b&gt;OSIV 측면에서 매우 부적절&lt;/b&gt;하다고 함. 즉&amp;nbsp;&lt;b&gt;성능이나&lt;/b&gt;&amp;nbsp;scalability,, 즉&amp;nbsp;&lt;b&gt;확장성 측면&lt;/b&gt;에서 볼 때 false로 해야 하는데 true로 하고 있어 warning 경고 사인이 뜨는 거라고.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/30549489/what-is-this-spring-jpa-open-in-view-true-property-in-spring-boot&quot;&gt;참고 사이트-스택오버플로우-로 바로가기&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 해결방안&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색결과 spring.jpa.open-in-view 설정을 true 에서&amp;nbsp;&lt;b&gt;false로 바꿔주면 해결&lt;/b&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바꿔주는 방법은 크게 두 가지 방법이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;application.properties&lt;/b&gt;에서 설정하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;spring.jpa.open-in-view=false&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;application.yml&lt;/b&gt;으로 설정 설정&lt;/li&gt;
&lt;li&gt;yaml으로 설정하는 방법은&amp;nbsp;여기&amp;nbsp;에서 잘 설명하고 있다.관련&amp;nbsp;스프링 부트 doc 사이트&amp;nbsp;로 가기&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SpringBoot</category>
      <author>크리드보이</author>
      <guid isPermaLink="true">https://series.tistory.com/652</guid>
      <comments>https://series.tistory.com/entry/springjpaopen-in-view-is-enabled-by-default#entry652comment</comments>
      <pubDate>Mon, 27 Feb 2023 17:54:26 +0900</pubDate>
    </item>
  </channel>
</rss>