<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Programming</title>
    <link>https://eatingmouse.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 14 Jun 2026 21:34:47 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>eatingmouse</managingEditor>
    <image>
      <title>Programming</title>
      <url>https://tistory1.daumcdn.net/tistory/5499527/attach/43c14ac6c08041779007c001735e6db1</url>
      <link>https://eatingmouse.tistory.com</link>
    </image>
    <item>
      <title>Mybatis와 JPA가 무엇인가?</title>
      <link>https://eatingmouse.tistory.com/72</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;필자가 한참 취준생으로 바빴던 시절, 취업공고로 자주 걸려있던 문구가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필수 기술: &lt;b&gt;Mybatis&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 당시에 JPA만 사용해봤던 나였기에 머리위로 물음표가 떠올랐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mybatis가 뭔데?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금이야 Mybatis를 다루는 회사를 다니고 있기도 하고 여러번 만져봤기에 익숙해지긴 했지만 그 당시에는 미숙했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JPA에 대한 감각이 무뎌지고 있기도하고 과거의 무지함에 대한 반성에 대한 의미로 Mybatis와 JPA의 개념에 대해 다시한번 확고히 짚고 넘어가려고한다.&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;Mybatis, JPA가 무엇이냐!&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 베이스 접근 계층을 구축해주는 프레임워크다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 자바 프로그램과 데이터베이스 사이를 이어주는 다리 역할을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mybatis와 JPA의 본질적인 기능은 완전히 동일하지만, 데이터를 어떻게 바라보는지에 대해 차이점이 분명히 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mybatis는 mapper를 통해 직접적인 쿼리를 짜고, DAO를 통해 연결하며 IF와 IMPL을 통해 서비스를 구축한다.&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;그에 비해 JPA는 Entity라는 자바객체를 통해 껍데기를 만들고, Repository를 통해 만들어낸 Entity를 데이터베이스에 연결한다.&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;즉, 개발자가 쿼리에 얼마나 관여를 하냐가 JPA와 Mybatis를 가르는 큰 차이점이라고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자동으로 생성되는 JPA가 현대식이고, 쿼리를 개발자가 전부 신경써줘야하는 Mybatis는 너무 구시대적이지 않냐고 생각할수도 있는데, 전혀 그렇지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대규모의 쿼리를 다루거나, 성능 최적화에 대해 신경쓰는 등 개발자가 직접적으로 데이터베이스에 영향을 끼칠 필요가 있는 시스템에는 Mybatis가 어울리고, 데이터구조가 빠르게 바뀌거나 기능을 빠르게 만들어내는 등 속도가 중요한곳에서는 JPA가 훨씬 유리하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘 다 나쁘지 않는 프레임워크지만, 사용하는 방법이 다르고 상황에 맞게 어울리는 프레임워크를 사용해야한다.&lt;/p&gt;</description>
      <category>자바 스프링</category>
      <author>eatingmouse</author>
      <guid isPermaLink="true">https://eatingmouse.tistory.com/72</guid>
      <comments>https://eatingmouse.tistory.com/72#entry72comment</comments>
      <pubDate>Wed, 4 Mar 2026 11:58:01 +0900</pubDate>
    </item>
    <item>
      <title>자바스크립트를 수정해도 캐시데이터를 삭제하지 않으면 적용되지 않는 문제..</title>
      <link>https://eatingmouse.tistory.com/71</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자바 스프링과 JSP를 사용하는 환경에서 기존에 사용되던 자바스크립트를 수정하던 중, 문제가 발생했다.&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;p data-ke-size=&quot;size16&quot;&gt;브라우저는 매번 서버에서 용량이 큰 JS, CSS파일 등을 받아오면 속도가 느려지기 때문에, 한 번 받은 파일은 컴퓨 로컬 저장소에 저장하고 사용한다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에, 파일명이 동일할경우 과거버전과 수정 후 버전을 브라우저에서 인식하지 못하는 문제가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결방법은 생각보다도 간단하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트를 호출할때, 자동으로 바뀔 수 있도록 인자값을 넣어주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시)&lt;/p&gt;
&lt;pre id=&quot;code_1769493941981&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;script src=&quot;&amp;lt;c:url value='/js/test.js' /&amp;gt;?v=${now}&quot;&amp;gt;&amp;lt;/script&amp;gt;      /* 날짜를 통해 버전명을 동적으로 부여하는 방법 */
&amp;lt;script src=&quot;&amp;lt;c:url value='/js/a1b2c3.test.js'&quot;/&amp;gt;&amp;lt;/script&amp;gt;         /*  빌드 도구(Webpack, Vite, Jenkins 등)를 사용하여 파일 이름에 해시코드를 섞는방법 */&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;</description>
      <category>JSP</category>
      <author>eatingmouse</author>
      <guid isPermaLink="true">https://eatingmouse.tistory.com/71</guid>
      <comments>https://eatingmouse.tistory.com/71#entry71comment</comments>
      <pubDate>Tue, 27 Jan 2026 15:07:52 +0900</pubDate>
    </item>
    <item>
      <title>개발자로서 해선 안될 버릇들..(닌자 코드)</title>
      <link>https://eatingmouse.tistory.com/70</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;웹서핑을 하던 중 재밌는글을 발견했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.javascript.info/ninja-code&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ko.javascript.info/ninja-code&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1767327992010&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;닌자 코드&quot; data-og-description=&quot;&quot; data-og-host=&quot;ko.javascript.info&quot; data-og-source-url=&quot;https://ko.javascript.info/ninja-code&quot; data-og-url=&quot;https://ko.javascript.info/ninja-code&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eFXqG/hyZQMNhCSU/HXVQI7bCweEU7Cc7kWqSgK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/PHkPp/hyZQG7nQ68/ckrHprkRtUrhiAGqjok4AK/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://ko.javascript.info/ninja-code&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ko.javascript.info/ninja-code&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eFXqG/hyZQMNhCSU/HXVQI7bCweEU7Cc7kWqSgK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/PHkPp/hyZQG7nQ68/ckrHprkRtUrhiAGqjok4AK/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;닌자 코드&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ko.javascript.info&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사이트에서는 '닌자'(고위 개발자)가 되는 방법이 적혀있는 사이트인데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자가 가져서 안될 버릇들을 반어법을 사용해 재미있게 풀어놓았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유머성이 짙은 글이지만, 실무에서도 도움이 될 만한 내용이 가득하니, 한번쯤 들어가서 읽어보면 좋을 듯 하다.&lt;/p&gt;</description>
      <category>기타</category>
      <author>eatingmouse</author>
      <guid isPermaLink="true">https://eatingmouse.tistory.com/70</guid>
      <comments>https://eatingmouse.tistory.com/70#entry70comment</comments>
      <pubDate>Fri, 2 Jan 2026 13:29:05 +0900</pubDate>
    </item>
    <item>
      <title>의존성주입 구현</title>
      <link>https://eatingmouse.tistory.com/69</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Spring에서 의존성을 구현할때에는 크게 3가지 방법으로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp; 필드 주입&lt;/p&gt;
&lt;pre id=&quot;code_1764723559634&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Controller
public class AutoTestingController extends CommonController {
	@Autowired 
	private PsyItemVerIF psyItemVerIF; 
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 필드에 있는 변수에 @Autowired를 붙여 리플렉션을 통해 의존성을 주입하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; Spring은 컨테이너에서 @Autowire가 붙은 서비스타입의 빈을 찾아 의존성주입을 시킨다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 짧고 간단하게 의존성주입을 할 수 있지만 final을 붙일 수 없어 불변성을 보장할 수 없고, private를 통해 직접적으로 접근할 수 있&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 어 객체지향의 캡슐화 원칙을 위반한다.(유지보수 및 보안성 위험)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 대부분의 프로그래머들이 권장하는 방법은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 생성자 주입&lt;/p&gt;
&lt;pre id=&quot;code_1764723585065&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;

@Controller
@RequiredArgsConstructor
public class AutoTestingController extends CommonController {

	private final PsyItemVerIF psyItemVerIF; 
    
}&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;&amp;nbsp; &amp;nbsp;lombok 라이브러리를 통해 사용하면 짧은 코드로 구현이 가능하며, final를 통해 불변성의 보장이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;3. Setter 주입&lt;/p&gt;
&lt;pre id=&quot;code_1764723620449&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Controller
public class MyController {
    
    private MyService myService;

    @Autowired 
    public void setMyService(MyService myService) { 
        this.myService = myService;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 공개적인 Setter를 통해 함수를 구현하고 필드에 의존성을 주입하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 필드 주입과 동일하게 final를 사용하지 못해 불변성이 보장이 안되지만, 선택적 의존성과 객체 변경이 가능하다는 점에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 의의를 둘 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 필수적이지 않은 의존성을 다루거나 런타임 변경 가능성이 있는 등 특수한 경우에 사용되는걸 보통 권장한다.&lt;/p&gt;</description>
      <category>자바 스프링</category>
      <author>eatingmouse</author>
      <guid isPermaLink="true">https://eatingmouse.tistory.com/69</guid>
      <comments>https://eatingmouse.tistory.com/69#entry69comment</comments>
      <pubDate>Wed, 3 Dec 2025 10:26:42 +0900</pubDate>
    </item>
    <item>
      <title>자바스프링 프로젝트 컨테이너화 및 배포하기 #3 배포하기</title>
      <link>https://eatingmouse.tistory.com/68</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이제, 태그지정까지 마쳤으니 지정된 컨테이너를 Gcloud에 Push시켜주어야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1744262533596&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker push gcr.io/YOUR_PROJECT_ID/spring-app:latest&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;성공적으로 push를 마쳤다면, 다음과 같은 명령어로 클라우드 배포를 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1744262774939&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gcloud run deploy 도커의 이미지명 --image 태그한 이미지명 --allow-unauthenticated --add-cloudsql-instances slq인스턴스명&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;Cloud가 정상적으로 실행됐다면 CloudRun의 로그를 통해 프로젝트가 보내오는 로그를 받아올 수 있다.&lt;/p&gt;</description>
      <category>클라우드</category>
      <author>eatingmouse</author>
      <guid isPermaLink="true">https://eatingmouse.tistory.com/68</guid>
      <comments>https://eatingmouse.tistory.com/68#entry68comment</comments>
      <pubDate>Thu, 10 Apr 2025 14:28:39 +0900</pubDate>
    </item>
    <item>
      <title>자바스프링 프로젝트 컨테이너화 및 배포하기 #2 Docker 설정</title>
      <link>https://eatingmouse.tistory.com/67</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이제, 클라우드의 설정을 마쳤으니 이번에는 프로젝트를 컨테이너화 시키기 위해 프로젝트의 Docker설정이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 자신이 원하는 경로에 맞춰 Docker 파일을 생성시켜주어야 하는데, 필자같은 경우에는 다음과 같은 경로로 설정했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Wgyqq/btsNgzzRsII/04781kJ0F9xA0SyfsmbGXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Wgyqq/btsNgzzRsII/04781kJ0F9xA0SyfsmbGXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Wgyqq/btsNgzzRsII/04781kJ0F9xA0SyfsmbGXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWgyqq%2FbtsNgzzRsII%2F04781kJ0F9xA0SyfsmbGXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;593&quot; height=&quot;220&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;220&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;그리고서는 Docker파일 및 sql설정을 위한 docker-compose.yml를 작성해주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dockerfile&lt;/p&gt;
&lt;pre id=&quot;code_1744261659458&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM ubuntu:latest
LABEL authors=&quot;autohrs&quot;

ENTRYPOINT [&quot;top&quot;, &quot;-b&quot;]

# OpenJDK 17을 기반으로 사용
FROM openjdk:17

# 작업 디렉터리 설정
WORKDIR /app

# 현재 프로젝트의 JAR 파일을 컨테이너로 복사
COPY build/libs/*.jar app.jar

# 8080 포트 노출
EXPOSE 8080

# 컨테이너에서 실행할 명령어
CMD [&quot;java&quot;, &quot;-jar&quot;, &quot;app.jar&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker-compose.yml&lt;/p&gt;
&lt;pre id=&quot;code_1744261773190&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;version: '3.8'

services:
  db:
    image: mysql:latest
    container_name: mysql_db
    restart: always
    environment:
      MYSQL_DATABASE: book_manage
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: rootpassword
    ports:
      - &quot;3307:3306&quot;
    networks:
      - app-network

  app:
    image: bookmanage-spring-app:latest
    build: .
    container_name: spring_app
    restart: always
    depends_on:
      - db
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://ip주소/인스턴스ID?useSSL=false&amp;amp;characterEncoding=UTF-8&amp;amp;serverTimezone=UTC
      SPRING_DATASOURCE_USERNAME: username
      SPRING_DATASOURCE_PASSWORD: password
    ports:
      - &quot;8080:8080&quot;
    networks:
      - app-network

networks:
  app-network:&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;username과 password같은 설정은 이전에 sqlcloud에서 설정한대로 가져오면되며, 포트번호같은경우에는 3306:3306으로 할시 중복되는 상황이 나와 3307:3306으로 해두었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring_datasource_url과 같은 경우에는 이전에 만들어두었던 sql인스턴스에서 가져와줘야한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;제목 없음.png&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBGpvv/btsNgq4mgKZ/lB25OFr6iMFjKa1TMEUwn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBGpvv/btsNgq4mgKZ/lB25OFr6iMFjKa1TMEUwn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBGpvv/btsNgq4mgKZ/lB25OFr6iMFjKa1TMEUwn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBGpvv%2FbtsNgq4mgKZ%2FlB25OFr6iMFjKa1TMEUwn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;1304&quot; height=&quot;165&quot; data-filename=&quot;제목 없음.png&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;165&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;제목 없음.png&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QLCGH/btsNf8iBXra/AhITWk7a7jY3EENP52rUjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QLCGH/btsNf8iBXra/AhITWk7a7jY3EENP52rUjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QLCGH/btsNf8iBXra/AhITWk7a7jY3EENP52rUjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQLCGH%2FbtsNf8iBXra%2FAhITWk7a7jY3EENP52rUjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;767&quot; height=&quot;190&quot; data-filename=&quot;제목 없음.png&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;190&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;후에는 application.properties에도 sqlcloud의 설정과 맞춰 변경시켜주자.&lt;/p&gt;
&lt;pre id=&quot;code_1744262101640&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring.datasource.url=jdbc:mysql://ip주소/인스턴스ID?useSSL=false&amp;amp;characterEncoding=UTF-8&amp;amp;serverTimezone=UTC
spring.datasource.username=username
spring.datasource.password=rootpassword&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;이제, 프로젝트를 컨테이너화할 차례인데 우선, 다음과 같은 명령어를 터미널에 입력하여 .jar파일을 만들어야한다.&lt;/p&gt;
&lt;pre id=&quot;code_1744262195039&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./gradlew build&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jar파일이 생성되면 다음과 같은 명령어를 통해 프로젝트를 컨테이너화 시켜주자.&lt;/p&gt;
&lt;pre id=&quot;code_1744262231364&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker-compose up --build -d&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;그리고, gcloud에 올릴 수 있도록 다음과 같은 명령어로 컨테이너에 태그를 지정하면 마무리다.&lt;/p&gt;
&lt;pre id=&quot;code_1744262301306&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker tag 컨테이너명 gcr.io/클라우드 인스턴스 ID/컨테이너명:latest&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*클라우드 sql연동 참조 블로그*&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@alstjsdlr0321/Spring-Boot-GCP-Cloud-SQL-DB-%EC%97%B0%EB%8F%99&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@alstjsdlr0321/Spring-Boot-GCP-Cloud-SQL-DB-%EC%97%B0%EB%8F%99&lt;/a&gt;&lt;/p&gt;</description>
      <category>클라우드</category>
      <author>eatingmouse</author>
      <guid isPermaLink="true">https://eatingmouse.tistory.com/67</guid>
      <comments>https://eatingmouse.tistory.com/67#entry67comment</comments>
      <pubDate>Thu, 10 Apr 2025 14:18:29 +0900</pubDate>
    </item>
    <item>
      <title>자바스프링 프로젝트 컨테이너화 및 배포하기 #1 클라우드 설정</title>
      <link>https://eatingmouse.tistory.com/66</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 저번에 만들었던 북길 프로젝트를 클라우드 배포하는 과정을 포스팃할 생각이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자의 경우에는 프로젝트를 컨테이너화 시킬때에는 Docker를 활용했으며, cloud run을 통해 프로젝트를 배포할 생각이다.&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://cloud.google.com/?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cloud.google.com/?hl=ko&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1744258732056&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;https://cloud.google.com/?hl=ko&quot; data-og-description=&quot;&quot; data-og-host=&quot;cloud.google.com&quot; data-og-source-url=&quot;https://cloud.google.com/?hl=ko&quot; data-og-url=&quot;https://cloud.google.com/?hl=ko&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://cloud.google.com/?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cloud.google.com/?hl=ko&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;https://cloud.google.com/?hl=ko&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cloud.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글 클라우드 사이트에 들어가고, 콘솔에 들어간뒤 새로운 프로젝트를 만들어줘야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트ID는 후에 자주사용되며, 프로젝트명이 프로젝트 ID의 생성에 영향을 끼치기 때문에 프로젝트명을 직관성있게 만들어주는게 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cloud run은 서버리스 컨테이너로, 다른 클라우드와 달리 콘솔을 통해 클라우드에 접속해 mysql을 설정하는 방법을 사용하기 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 구글 클라우드에서 제공하는 sql클라우드를 사용해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;697&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mPNfy/btsNfanS5pa/6pKrUTMeN1GNaAvjtrwKA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mPNfy/btsNfanS5pa/6pKrUTMeN1GNaAvjtrwKA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mPNfy/btsNfanS5pa/6pKrUTMeN1GNaAvjtrwKA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmPNfy%2FbtsNfanS5pa%2F6pKrUTMeN1GNaAvjtrwKA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;697&quot; height=&quot;651&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;651&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1356&quot; data-origin-height=&quot;391&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bM8KOp/btsNd4Pvj3a/buTFva5jtFaISKOzlENcoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bM8KOp/btsNd4Pvj3a/buTFva5jtFaISKOzlENcoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bM8KOp/btsNd4Pvj3a/buTFva5jtFaISKOzlENcoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbM8KOp%2FbtsNd4Pvj3a%2FbuTFva5jtFaISKOzlENcoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;1356&quot; height=&quot;391&quot; data-origin-width=&quot;1356&quot; data-origin-height=&quot;391&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;위의 이미지대로, 검색창을 통해 클라우드 sql에 접근한뒤, 인스턴스 만들기를 통해 인스턴스를 만들어준다.&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;1459&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzWli1/btsNePK8JIV/4CYxY5GZpA4pUyPaHNg7iK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzWli1/btsNePK8JIV/4CYxY5GZpA4pUyPaHNg7iK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzWli1/btsNePK8JIV/4CYxY5GZpA4pUyPaHNg7iK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzWli1%2FbtsNePK8JIV%2F4CYxY5GZpA4pUyPaHNg7iK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;1459&quot; height=&quot;256&quot; data-origin-width=&quot;1459&quot; data-origin-height=&quot;256&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;595&quot; data-origin-height=&quot;685&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXFCj3/btsNe9P4r3d/5zsrPP2xHi9OEtRpSZIQp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXFCj3/btsNe9P4r3d/5zsrPP2xHi9OEtRpSZIQp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXFCj3/btsNe9P4r3d/5zsrPP2xHi9OEtRpSZIQp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXFCj3%2FbtsNe9P4r3d%2F5zsrPP2xHi9OEtRpSZIQp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;595&quot; height=&quot;685&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;685&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후에는 무슨 데이터베이스를 사용할지 정하고 인스턴스 정보를 설정해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스 ID와 비밀번호는 후에 Root로 접속할때 사용하기에 꼼꼼하게 체크해야되며, 리전 영역은 가능한 거주하고 있는 국가와 일치하게 해주는게 좋다.&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;704&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TSoKk/btsNf65WbSQ/NYJNzIwNjFvbl5tmKxXHdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TSoKk/btsNf65WbSQ/NYJNzIwNjFvbl5tmKxXHdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TSoKk/btsNf65WbSQ/NYJNzIwNjFvbl5tmKxXHdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTSoKk%2FbtsNf65WbSQ%2FNYJNzIwNjFvbl5tmKxXHdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;704&quot; height=&quot;222&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;222&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;1424&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ApK36/btsNerX2ULY/g8sJBDrJaqWkMs9UTJy9Wk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ApK36/btsNerX2ULY/g8sJBDrJaqWkMs9UTJy9Wk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ApK36/btsNerX2ULY/g8sJBDrJaqWkMs9UTJy9Wk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FApK36%2FbtsNerX2ULY%2Fg8sJBDrJaqWkMs9UTJy9Wk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;1424&quot; height=&quot;768&quot; data-origin-width=&quot;1424&quot; data-origin-height=&quot;768&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;후에는 Iam에 들어가서, 필요에 따라 자신의 계정에 권한을 쥐어주자.&lt;/p&gt;
&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://cloud.google.com/sdk?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cloud.google.com/sdk?hl=ko&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1744260023283&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;https://cloud.google.com/sdk?hl=ko&quot; data-og-description=&quot;&quot; data-og-host=&quot;cloud.google.com&quot; data-og-source-url=&quot;https://cloud.google.com/sdk?hl=ko&quot; data-og-url=&quot;https://cloud.google.com/sdk?hl=ko&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://cloud.google.com/sdk?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cloud.google.com/sdk?hl=ko&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;https://cloud.google.com/sdk?hl=ko&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cloud.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 클라우드에서 명령어를 넣어주어주기 위해 위의 사이트에 들어가 CLI를 설치해주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CLI의 설치를 마쳤다면, GoogleCloudShell이 생겼을것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GoogleCloudShell를 통해 접속을 하고, gcloud auth login를 통해 로그인 및 하고자 하는 프로젝트를 연동시켜주자.&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;제목 없음.png&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1JVh0/btsNeBfbVh0/jc2mq84Zsty3SuDg3WiHQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1JVh0/btsNeBfbVh0/jc2mq84Zsty3SuDg3WiHQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1JVh0/btsNeBfbVh0/jc2mq84Zsty3SuDg3WiHQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1JVh0%2FbtsNeBfbVh0%2Fjc2mq84Zsty3SuDg3WiHQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;604&quot; height=&quot;218&quot; data-filename=&quot;제목 없음.png&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;218&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;프로젝트 연동을 위해서는 프로젝트의 ID값이 필요한데, 프로젝트 선택하는 창에서 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제, 성공적으로 로그인 및 클라우드 연동이 끝났다면, 이번에는 sql을 건드려줘야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 다음과 같은 명령어를 통해 sql에 접속해주자.&lt;/p&gt;
&lt;pre id=&quot;code_1744261334257&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gcloud sql connect [INSTANCE_ID] --user=root&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 프로젝트의 설정에 맞춰 프로젝트를 생성시켜주고, 생성후에는 다음과 같은 명령어로 유저생성 및 권한 부여를 해주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자생성:&lt;/p&gt;
&lt;pre id=&quot;code_1744261504980&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE USER '유저'@'%' IDENTIFIED BY '비밀번호';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;권한부여:&lt;/p&gt;
&lt;pre id=&quot;code_1744261523219&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GRANT ALL PRIVILEGES ON 데이터베이스명.* TO 'bookmanage_user'@'%';
FLUSH PRIVILEGES;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>클라우드</category>
      <author>eatingmouse</author>
      <guid isPermaLink="true">https://eatingmouse.tistory.com/66</guid>
      <comments>https://eatingmouse.tistory.com/66#entry66comment</comments>
      <pubDate>Thu, 10 Apr 2025 13:41:55 +0900</pubDate>
    </item>
    <item>
      <title>&amp;lt;button&amp;gt;을 통해 &amp;lt;script&amp;gt;영역으로 값을 전달</title>
      <link>https://eatingmouse.tistory.com/64</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 진행하던 도중 또 다른 문제가 발생했다.&lt;/p&gt;
&lt;pre id=&quot;code_1739505904738&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;button th:attr=&quot;onclick='bookmarkBook(\''
        + ${book.bookTitle} + '\', \''
        + ${book.bookAuth} + '\', \''
        + ${book.bookPub} + '\', \''
        + ${book.bookPubYear} + '\', \''
        + ${#strings.length(book.des) &amp;gt; 0 ? #strings.substring(book.des, 0, (book.des.length() &amp;gt; 400 ? 400 : book.des.length())) + (book.des.length() &amp;gt; 400 ? '...' : '') : ''} + '\', \''
        + ${book.discount} + '\', \''
        + ${book.ISBN} + '\', \''
        + ${book.img} + '\')'&quot;&amp;gt;북마크
&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드와 같이 button을 눌렀을 때 인자값을 &amp;lt;script&amp;gt;영역으로 넘겨주려다가 book.des에 ' '나 ()등 특수기호들이 들어가 스크립트가 정상적으로 작동되지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후에 인터넷 서핑 및 서적을 통해 찾아보니 위와 같이 버튼에 직접적으로 인자를 넘겨주는 행위가 보안면에서 좋은 방법은 아니라는걸 알게됐다(...)&lt;/p&gt;
&lt;pre id=&quot;code_1739505998952&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;button th:data-title=&quot;${book.bookTitle}&quot;
        th:data-auth=&quot;${book.bookAuth}&quot;
        th:data-pub=&quot;${book.bookPub}&quot;
        th:data-pubyear=&quot;${book.bookPubYear}&quot;
        th:data-des=&quot;${book.des != null and book.des.length() &amp;gt; 0 ? #strings.substring(book.des, 0, (book.des.length() &amp;gt; 100 ? 100 : book.des.length())) + (book.des.length() &amp;gt; 100 ? '...' : '') : ''}&quot;
        th:data-discount=&quot;${book.discount}&quot;
        th:data-isbn=&quot;${book.ISBN}&quot;
        th:data-img=&quot;${book.img}&quot;
        onclick=&quot;bookmarkBook(this)&quot;&amp;gt;북마크
&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 사이트를 참고해, 위의 코드와 같이 data속성을 저장하여 script로 전달해주는 방법으로 변경했다.&lt;/p&gt;</description>
      <category>기타</category>
      <author>eatingmouse</author>
      <guid isPermaLink="true">https://eatingmouse.tistory.com/64</guid>
      <comments>https://eatingmouse.tistory.com/64#entry64comment</comments>
      <pubDate>Fri, 14 Feb 2025 13:07:13 +0900</pubDate>
    </item>
    <item>
      <title>Lombok 생성자 생성안됨 문제</title>
      <link>https://eatingmouse.tistory.com/63</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 진행하던 도중 @Data어노테이션을 사용하는데 Setter가 정상적으로 작동하지 않는 문제가 발생했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@Data어노테이션은 Getter과 Setter와 생성자까지 전부 자동으로 생성해주기 때문에 무엇이 문제인지 헷갈려 하던도중&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자를 명시적으로 생성해주니 해결되었다.&lt;/p&gt;
&lt;pre id=&quot;code_1739348378471&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Data
public class BookResponseDto {
    private int totalResults;
    private List&amp;lt;BookDto&amp;gt; bookLists;

    public BookResponseDto(int totalResults, List&amp;lt;BookDto&amp;gt; bookLists) {
        this.totalResults = totalResults;
        this.bookLists = bookLists;
    }
}&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;아마 변수에 BookDto라는 복합적인 객체 타입을 인식하지 못하고 자동적으로 생성자를 생성하지 못해 생긴 문제라고 생각된다.&lt;/p&gt;</description>
      <category>자바 스프링</category>
      <author>eatingmouse</author>
      <guid isPermaLink="true">https://eatingmouse.tistory.com/63</guid>
      <comments>https://eatingmouse.tistory.com/63#entry63comment</comments>
      <pubDate>Wed, 12 Feb 2025 17:20:43 +0900</pubDate>
    </item>
    <item>
      <title>java.lang.IllegalArgumentException: The Unicode character at code point [49,548] cannot be encoded as it is outside the permitted range of 0 to 255</title>
      <link>https://eatingmouse.tistory.com/62</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 진행하던중 이번에는 한글이 담겨진 데이터를 타임리프로 만들어진 프론트로 보내주는 과정에서 오류가 발생했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오류를 해결하기 위해서는 다음의 코드를 application.properties에 등록하는것이 가장 보편적이지만&lt;/p&gt;
&lt;pre id=&quot;code_1739010468332&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 필자는 스프링에서 변환시켜주는것보다 데이터를 전달해줄 때 직접적으로 인코딩 방식을 지정을 해주는 방식을 채택했고 코드는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1739010537595&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;return &quot;redirect:/example?keyword=&quot; + URLEncoder.encode(keyword, StandardCharsets.UTF_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;위와 같이 인코드 방식을 UTF-8로 직접적으로 지정해주니 문제없이 작동됐다.&lt;/p&gt;</description>
      <category>자바 스프링</category>
      <author>eatingmouse</author>
      <guid isPermaLink="true">https://eatingmouse.tistory.com/62</guid>
      <comments>https://eatingmouse.tistory.com/62#entry62comment</comments>
      <pubDate>Sat, 8 Feb 2025 19:29:23 +0900</pubDate>
    </item>
  </channel>
</rss>