<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발자겨려</title>
    <link>https://programmerjkr.tistory.com/</link>
    <description>개인 공부 블로그</description>
    <language>ko</language>
    <pubDate>Wed, 26 Aug 2026 22:30:32 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>개발자겨려</managingEditor>
    <image>
      <title>개발자겨려</title>
      <url>https://tistory1.daumcdn.net/tistory/4731792/attach/01ea146ded7048878215b318e945b704</url>
      <link>https://programmerjkr.tistory.com</link>
    </image>
    <item>
      <title>AWS EC2 접속 (git bash)</title>
      <link>https://programmerjkr.tistory.com/68</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;AWS에서 빌린 컴퓨터에 접속하는 방법은 다운로드 받은 키 페어 (pem key)를 활용해 접속하는 방법과 AWS 콘솔로 접속하는 방식이있다&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;방법1) 키페어 활용&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;pre id=&quot;code_1750233300708&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;chmod 400 &quot;경로\키페어명.pem&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;ssh -i 옵션을 사용하여 SSH 클라이언트가 인증에 사용할 특정 개인 키 파일을 지정.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ssh -i &quot;경로&quot; ec2-user@퍼블릭 IPv4 주소&amp;nbsp; 입력&lt;/p&gt;
&lt;pre id=&quot;code_1747915117827&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ ssh -i &quot;/c/Users/notyu/Documents/AWS_keypair/studying-developer.pem&quot; ec2-user@43.203.200.144&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결완료&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;253&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dDpSg4/btsOFXOL0d7/1KZJ5VpxCuAECPs4QXk5ZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dDpSg4/btsOFXOL0d7/1KZJ5VpxCuAECPs4QXk5ZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dDpSg4/btsOFXOL0d7/1KZJ5VpxCuAECPs4QXk5ZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDpSg4%2FbtsOFXOL0d7%2F1KZJ5VpxCuAECPs4QXk5ZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;666&quot; height=&quot;253&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;253&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 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;방법2) AWS 콘솔 활용&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;1178&quot; data-origin-height=&quot;335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceicfM/btsOGWnOub7/FzyDo6vz3pzpzscgt7sswk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceicfM/btsOGWnOub7/FzyDo6vz3pzpzscgt7sswk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceicfM/btsOGWnOub7/FzyDo6vz3pzpzscgt7sswk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceicfM%2FbtsOGWnOub7%2FFzyDo6vz3pzpzscgt7sswk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;1178&quot; height=&quot;335&quot; data-origin-width=&quot;1178&quot; data-origin-height=&quot;335&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1234&quot; data-origin-height=&quot;624&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/31Kmt/btsOFFU7rfd/FLqbhoe7P3wiecfOPWwLVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/31Kmt/btsOFFU7rfd/FLqbhoe7P3wiecfOPWwLVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/31Kmt/btsOFFU7rfd/FLqbhoe7P3wiecfOPWwLVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F31Kmt%2FbtsOFFU7rfd%2FFLqbhoe7P3wiecfOPWwLVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;624&quot; data-origin-width=&quot;1234&quot; data-origin-height=&quot;624&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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qchDB/btsOGNqXktl/wXRtdooEhqMzqHfavt1kLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qchDB/btsOGNqXktl/wXRtdooEhqMzqHfavt1kLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qchDB/btsOGNqXktl/wXRtdooEhqMzqHfavt1kLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqchDB%2FbtsOGNqXktl%2FwXRtdooEhqMzqHfavt1kLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;729&quot; height=&quot;375&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Project/library</category>
      <author>개발자겨려</author>
      <guid isPermaLink="true">https://programmerjkr.tistory.com/68</guid>
      <comments>https://programmerjkr.tistory.com/68#entry68comment</comments>
      <pubDate>Wed, 18 Jun 2025 17:55:52 +0900</pubDate>
    </item>
    <item>
      <title>[LeetCode] Second Highest Salary</title>
      <link>https://programmerjkr.tistory.com/60</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;문제 : &lt;a href=&quot;https://leetcode.com/problems/second-highest-salary/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://leetcode.com/problems/second-highest-salary/description/&lt;/a&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;풀이1. 서브쿼리&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1746781863673&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
	MAX(salary) AS SecondHighestSalary 
FROM (
    SELECT salary,
           DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
    FROM Employee
) ranked
WHERE rnk = 2;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DataBase /LeetCode 문제 풀이</category>
      <author>개발자겨려</author>
      <guid isPermaLink="true">https://programmerjkr.tistory.com/60</guid>
      <comments>https://programmerjkr.tistory.com/60#entry60comment</comments>
      <pubDate>Fri, 9 May 2025 18:11:14 +0900</pubDate>
    </item>
    <item>
      <title>JPA, Hibernate, spring Data JPA</title>
      <link>https://programmerjkr.tistory.com/59</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt; JPA는 표준 인터페이스를 제공&lt;/b&gt;하고, &lt;b&gt;Hibernate는 JPA를 구현&lt;/b&gt;하며, &lt;b&gt;Spring Data JPA는 JPA 사용을 간편하게&lt;/b&gt; 만들어주기 때문에 이 세 가지를 함께 사용합니다. Spring Data JPA는 Repository 인터페이스를 통해 데이터 액세스 코드를 줄이고, Hibernate는 JPA 표준을 준수하며 실제 데이터베이스와의 통신을 담당합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;h1 id=&quot;h1-0fd008eedf84d1c84d54e1ecf1690ceccfd3aa576fc90f6eb2064d3baa25694b&quot; data-title=&quot;1. JPA (Java Persistence API)&quot; data-depth=&quot;1&quot; data-heading=&quot;&quot;&gt;1. JPA (Java Persistence API)&lt;/h1&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JPA는 Java 애플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의하는 &lt;b&gt;표준 명세&lt;/b&gt;이다. JPA는 인터페이스의 집합이며, 실제 구현은 제공하지 않는다. JPA는 객체-관계 매핑(ORM)을 위한 인터페이스와 어노테이션을 제공하며, EntityManager와 같은 핵심 인터페이스를 정의함.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;주요 역할&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ORM 기술 사용을 위한 표준 정의&lt;/li&gt;
&lt;li&gt;EntityManager, EntityTransaction 등의 인터페이스 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;특징&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 기능을 수행하는 라이브러리가 아닌 인터페이스&lt;/li&gt;
&lt;li&gt;구현체가 없으므로 JPA만으로는 데이터베이스 연동 X&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;div&gt;
&lt;h1 id=&quot;h1-8880dc55b9414e5d9ae05a59adbae18402be3e0d21ba0848cc6a115bac0408f6&quot; data-title=&quot;2. Hibernate&quot; data-depth=&quot;1&quot; data-heading=&quot;&quot;&gt;2. Hibernate&lt;/h1&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Hibernate는 JPA 인터페이스를 구현하는 &lt;b&gt;ORM 프레임워크&lt;/b&gt;이다. Hibernate는 JPA의 구현체로서, 데이터베이스와 Java 객체 간의 매핑을 자동으로 처리하고 SQL 쿼리 작성 없이 데이터베이스 작업을 수행할 수 있도록 지원합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;주요 역할&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JPA 인터페이스 구현&lt;/li&gt;
&lt;li&gt;객체와 관계형 데이터베이스 간의 매핑 자동 처리&lt;/li&gt;
&lt;li&gt;SQL 쿼리 대신 객체 중심으로 데이터베이스 조작 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;특징&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JPA의 모든 기능을 지원하며 JPA 구현체로서 작동&lt;/li&gt;
&lt;li&gt;다양한 데이터베이스 벤더 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;h1 id=&quot;h1-2109b73a799f2e70a413c28fc48ff7c30f539cc8fb0b0d37eb32139b3eb34f0c&quot; data-title=&quot;3. Spring Data JPA&quot; data-depth=&quot;1&quot; data-heading=&quot;&quot;&gt;3. Spring Data JPA&lt;/h1&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring Data JPA는 Spring 프레임워크에서 JPA를 더욱 쉽고 편리하게 사용할 수 있도록 지원하는 &lt;b&gt;모듈&lt;/b&gt;입니다. Spring Data JPA는 JPA를 추상화한 Repository 인터페이스를 제공하여, CRUD (Create, Read, Update, Delete) 작업에 필요한 상용구 코드를 줄여줍니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;주요 역할&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JPA 기반 데이터 액세스 계층 구현 단순화&lt;/li&gt;
&lt;li&gt;Repository 인터페이스를 통해 JPA 사용 편의성 향상&lt;/li&gt;
&lt;li&gt;메서드 이름 규칙을 기반으로 쿼리 자동 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;특징&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Spring 프레임워크의 일부로, JPA를 추상화하여 더 쉽게 사용 가능&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;h1 id=&quot;h1-7a7bd1332b718525b43fda388f7bc751d913e37a21589b64733e80e419dd15cf&quot; data-title=&quot;동작 방식 요약&quot; data-depth=&quot;1&quot; data-heading=&quot;&quot;&gt;동작 방식 요약&lt;/h1&gt;
&lt;/div&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;JPA&lt;/b&gt;: 자바 객체와 관계형 데이터베이스 간의&amp;nbsp; 연동(ORM)을 위한 표준 인터페이스 정의의 집합.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Hibernate&lt;/b&gt;: JPA 인터페이스를 구현하여 실제 데이터베이스와 통신하고 객체-관계 매핑(ORM) 수행.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Spring Data JPA&lt;/b&gt;: Repository 인터페이스를 통해 데이터 액세스 로직을 추상화하고, JPA 사용을 간소화.&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>General/JPA</category>
      <author>개발자겨려</author>
      <guid isPermaLink="true">https://programmerjkr.tistory.com/59</guid>
      <comments>https://programmerjkr.tistory.com/59#entry59comment</comments>
      <pubDate>Fri, 9 May 2025 15:49:18 +0900</pubDate>
    </item>
    <item>
      <title>H2 DB를 local profile에 적용하기</title>
      <link>https://programmerjkr.tistory.com/58</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;H2 DB 는 경량 Database 로 개발 단계에서 많이 사용하고 있으며 , Disk 가 아닌 Memory 에 데이터를 저장할 수 있다 . &lt;br /&gt;데이터가 휘발된다는 단점을 코드에만 집중하는 데 사용하는 것이다&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;28&quot; data-end=&quot;44&quot; data-ke-size=&quot;size23&quot;&gt;✅&lt;b&gt;application.yml 설정&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746753844842&quot; class=&quot;javascript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;spring:
  config:
    activate:
      on-profile: local		//profile 선택: local
  datasource:
    url: &quot;jdbc:h2:mem:library;MODE=MYSQL;NON_KEYWORDS=USER&quot;
    username: &quot;sa&quot;
    password: &quot;&quot;
    driver-class-name: org.h2.Driver
  jpa:
    hibernate:
      ddl-auto: create
    properties:
      hibernate:
        format_sql: true
        show_sql: true
        dialect: org.hibernate.dialect.H2Dialect
    open-in-view: false
  h2:
    console:
      enabled: true
      settings:
        web-allow-others: true
      path: /h2-console&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;jpa.hibernate.ddl-auto: create
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;H2 DB를 in-Memory로 설정했기 때문에 서버가 시작될 때마다 테이블을 제거하고 만들어주는것이 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  주의할점:&amp;nbsp; local 외에 다른 설정(예:dev)이 있다면 다른 설정 쪽에도 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;on-profile : dev&lt;span&gt; &lt;/span&gt;&lt;/span&gt;해줘야된다.&amp;nbsp; 안하면 on-profile 설정 없는쪽이 기본 프로파일로 항상 적용됨&lt;/p&gt;
&lt;p data-ke-size=&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 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;28&quot; data-end=&quot;44&quot; data-ke-size=&quot;size23&quot;&gt;✅ &lt;b&gt;profile 변경&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;1-intellij-ultimate-유료&quot; style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. IntelliJ Ultimate (유료) 버전 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Edit Configurations 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;137&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beOThO/btsNOg2TfFE/w3sfGCxDafvr0laYQogMp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beOThO/btsNOg2TfFE/w3sfGCxDafvr0laYQogMp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beOThO/btsNOg2TfFE/w3sfGCxDafvr0laYQogMp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeOThO%2FbtsNOg2TfFE%2Fw3sfGCxDafvr0laYQogMp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;420&quot; height=&quot;137&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;137&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;Active profiles에 local 입력&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MsO7a/btsNQ1bM6Ak/7yEhvGhRhgCSSc6Q9mKddk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MsO7a/btsNQ1bM6Ak/7yEhvGhRhgCSSc6Q9mKddk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MsO7a/btsNQ1bM6Ak/7yEhvGhRhgCSSc6Q9mKddk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMsO7a%2FbtsNQ1bM6Ak%2F7yEhvGhRhgCSSc6Q9mKddk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;594&quot; height=&quot;308&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;308&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 id=&quot;2-intellij-community-무료&quot; style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. IntelliJ Community (무료) 버전 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Modify options 클릭 -&amp;gt; Add VM options 클릭 -&amp;gt; Dspring.profiles.active=local 입력&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1099&quot; data-origin-height=&quot;470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj0Z9j/btsNQPCJiDY/ruKKThiXadJquut8SdnHR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj0Z9j/btsNQPCJiDY/ruKKThiXadJquut8SdnHR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj0Z9j/btsNQPCJiDY/ruKKThiXadJquut8SdnHR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj0Z9j%2FbtsNQPCJiDY%2FruKKThiXadJquut8SdnHR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;1099&quot; height=&quot;470&quot; data-origin-width=&quot;1099&quot; data-origin-height=&quot;470&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 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;28&quot; data-end=&quot;44&quot; 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;실행 시 아래와 같이 지정된 profile로 실행되는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;24&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjzW3v/btsNP83NMcg/oDRwIibQB1kQ4IufnNmzqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjzW3v/btsNP83NMcg/oDRwIibQB1kQ4IufnNmzqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjzW3v/btsNP83NMcg/oDRwIibQB1kQ4IufnNmzqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjzW3v%2FbtsNP83NMcg%2FoDRwIibQB1kQ4IufnNmzqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;657&quot; height=&quot;24&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;24&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-end=&quot;44&quot; data-start=&quot;28&quot;&gt;✅ http://localhost:8080/h2-console 에 접속&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.yml에 설정해두었던 URL 과 Name 및 Password 입력&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;368&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkoHTS/btsNOm26h2X/V9xk20ePPsXkprvW00xzqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkoHTS/btsNOm26h2X/V9xk20ePPsXkprvW00xzqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkoHTS/btsNOm26h2X/V9xk20ePPsXkprvW00xzqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkoHTS%2FbtsNOm26h2X%2FV9xk20ePPsXkprvW00xzqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;485&quot; height=&quot;368&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;368&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 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;28&quot; data-end=&quot;44&quot; data-ke-size=&quot;size23&quot;&gt;✅테이블 확인&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLKJ59/btsNRJa41rD/rZK6kLMBus2tUXe4YfB1z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLKJ59/btsNRJa41rD/rZK6kLMBus2tUXe4YfB1z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLKJ59/btsNRJa41rD/rZK6kLMBus2tUXe4YfB1z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLKJ59%2FbtsNRJa41rD%2FrZK6kLMBus2tUXe4YfB1z0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;684&quot; height=&quot;302&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;302&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>DataBase /H2</category>
      <author>개발자겨려</author>
      <guid isPermaLink="true">https://programmerjkr.tistory.com/58</guid>
      <comments>https://programmerjkr.tistory.com/58#entry58comment</comments>
      <pubDate>Fri, 9 May 2025 11:03:03 +0900</pubDate>
    </item>
    <item>
      <title>[LeetCode] Combine Two Tables</title>
      <link>https://programmerjkr.tistory.com/55</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;문제 : &lt;a href=&quot;https://leetcode.com/problems/combine-two-tables/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://leetcode.com/problems/combine-two-tables/description/&lt;/a&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풀이:&lt;/p&gt;
&lt;pre id=&quot;code_1746631531879&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 방법1. LEFT JOIN (가장 일반적인 방법)
SELECT 
	p.firstName, p.lastName, a.city, a.state
FROM 
	person p
LEFT JOIN 
	address a
ON 
	p.personId = a.personId;


# 방법2. COALESCE (lEFT JOIN 과 효율성 동일 단지 결과 가공용)
SELECT 
    p.firstName, 
    p.lastName,
    COALESCE(a.city, NULL ) AS city, 
    COALESCE(a.state, NULL ) AS state
FROM 
    Person p
LEFT JOIN 
    Address a
ON 
    p.personId = a.personId;



# 방법3. NATURAL JOIN (실무에서 사용 못함) 
# ON p.personId = a.personId 같은 명시적인 조건 없음
SELECT 
	p.firstName, p.lastName, a.city, a.state
FROM 
	person p
NATURAL JOIN 
	address a;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DataBase /LeetCode 문제 풀이</category>
      <author>개발자겨려</author>
      <guid isPermaLink="true">https://programmerjkr.tistory.com/55</guid>
      <comments>https://programmerjkr.tistory.com/55#entry55comment</comments>
      <pubDate>Thu, 8 May 2025 00:26:06 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] orphanRemoval vs CascadeType.REMOVE 정리</title>
      <link>https://programmerjkr.tistory.com/54</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;orphanRemoval&lt;/b&gt;&amp;nbsp;과&amp;nbsp;&lt;b&gt;CascadeType.REMOVE&lt;/b&gt; 는 JPA(Java Persistence API)에서 엔티티 간의 관계를 관리하고, 둘다&amp;nbsp;&lt;b&gt;부모 엔티티와 자식 엔티티 간의 관계에서 자식 엔티티를 삭제하는 데 사용된다는 점에선 같지만&lt;/b&gt;, 삭제 트리거(Trigger)가 다르다.&lt;/blockquote&gt;
&lt;div&gt;&amp;nbsp;&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;✅ 요약비교: CascadeType.REMOVE vs orphanRemoval = true&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.3798%;&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;width: 39.2635%;&quot;&gt;CascadeType.REMOVE&lt;/td&gt;
&lt;td style=&quot;width: 41.3566%;&quot;&gt;orphanRemoval = true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.3798%;&quot;&gt;삭제 trigger&lt;/td&gt;
&lt;td style=&quot;width: 39.2635%;&quot;&gt;부모 엔티티 자체가 삭제될 때&lt;/td&gt;
&lt;td style=&quot;width: 41.3566%;&quot;&gt;연관관계에서 자식이 제거될때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.3798%;&quot;&gt;실행 시점&lt;/td&gt;
&lt;td style=&quot;width: 39.2635%;&quot;&gt;entityManager.remove(parent)&lt;/td&gt;
&lt;td style=&quot;width: 41.3566%;&quot;&gt;parent.getChildren().remove(child) 등&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.3798%;&quot;&gt;자식 삭제 방식&lt;/td&gt;
&lt;td style=&quot;width: 39.2635%;&quot;&gt;부모와 함께 삭제&lt;/td&gt;
&lt;td style=&quot;width: 41.3566%;&quot;&gt;부모와의 관계가 끊어지면 삭제&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.3798%;&quot;&gt;삭제 대상&lt;/td&gt;
&lt;td style=&quot;width: 39.2635%;&quot;&gt;모든 자식 엔티티&lt;/td&gt;
&lt;td style=&quot;width: 41.3566%;&quot;&gt;관계에서 제거된 자식만&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.3798%;&quot;&gt;주요 목적&lt;/td&gt;
&lt;td style=&quot;width: 39.2635%;&quot;&gt;부모 삭제 시 자식 자동 삭제&lt;/td&gt;
&lt;td style=&quot;width: 41.3566%;&quot;&gt;연관관계 해제 시 자식 삭제 (고아 제거)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; 예시&lt;/p&gt;
&lt;pre id=&quot;code_1746608957262&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Entity
public class Parent {
    @Id @GeneratedValue
    private Long id;

    @OneToMany(mappedBy = &quot;parent&quot;, 
               cascade = CascadeType.ALL, 
               orphanRemoval = true)
    private List&amp;lt;Child&amp;gt; children = new ArrayList&amp;lt;&amp;gt;();
}

@Entity
public class Child {
    @Id @GeneratedValue
    private Long id;

    @ManyToOne
    private Parent parent;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1068&quot; data-start=&quot;1033&quot; data-ke-size=&quot;size23&quot;&gt;▶ CascadeType.REMOVE만 사용하는 경우&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1746609010316&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 1. 부모 삭제
Parent parent = entityManager.find(Parent.class, 1L);
entityManager.remove(parent); // 이때 자식도 같이 삭제됨&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote data-end=&quot;1202&quot; data-start=&quot;1174&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1202&quot; data-start=&quot;1176&quot; data-ke-size=&quot;size16&quot;&gt;자식은 부모와 연결돼 있기 때문에 부모 삭제 시 자식도 같이 삭제됨.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1246&quot; data-start=&quot;1209&quot; data-ke-size=&quot;size23&quot;&gt;▶ orphanRemoval = true만 사용하는 경우&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1746609025538&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 2. 자식만 제거
Parent parent = entityManager.find(Parent.class, 1L);
Child child = parent.getChildren().get(0);

parent.getChildren().remove(child); // 자식은 DB에서 DELETE됨&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote data-end=&quot;1479&quot; data-start=&quot;1417&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1479&quot; data-start=&quot;1419&quot; data-ke-size=&quot;size16&quot;&gt;부모는 그대로 살아 있고, 연결만 끊었는데도 자식이 삭제됨. 이것이 orphanRemoval의 핵심.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;1497&quot; data-start=&quot;1486&quot; data-ke-size=&quot;size26&quot;&gt;  핵심 정리&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1642&quot; data-start=&quot;1499&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1543&quot; data-start=&quot;1499&quot;&gt;CascadeType.REMOVE: &lt;b&gt;부모가 삭제될 때 자식도 삭제&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1595&quot; data-start=&quot;1544&quot;&gt;orphanRemoval = true: &lt;b&gt;부모는 살려두고 자식만 제거해도 삭제됨&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1642&quot; data-start=&quot;1596&quot;&gt;둘 다 설정하면: 부모 삭제 시 전부 삭제되고, 관계 끊으면 해당 자식만 삭제됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1714&quot; data-start=&quot;1649&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1714&quot; data-start=&quot;1649&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1714&quot; data-start=&quot;1649&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1714&quot; data-start=&quot;1649&quot; data-ke-size=&quot;size16&quot;&gt;둘을 같이 쓰는 경우가 많긴 하지만, &lt;b&gt;삭제의 의도와 트리거 시점이 다르기 때문에 목적에 따라 선택&lt;/b&gt;해야한다고한다..&lt;/p&gt;</description>
      <category>General/JPA</category>
      <author>개발자겨려</author>
      <guid isPermaLink="true">https://programmerjkr.tistory.com/54</guid>
      <comments>https://programmerjkr.tistory.com/54#entry54comment</comments>
      <pubDate>Wed, 7 May 2025 18:18:26 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] 연관관계 주인이란?</title>
      <link>https://programmerjkr.tistory.com/53</link>
      <description>&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;28&quot; data-end=&quot;44&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; data-start=&quot;57&quot; data-end=&quot;158&quot;&gt;
&lt;li data-start=&quot;57&quot; data-end=&quot;111&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;연관관계의 주인&lt;span style=&quot;color: #000000;&quot;&gt;은&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;외래 키를 직접 가지므로,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;해당 테이블에 외래 키 컬럼이 존재함.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li data-start=&quot;112&quot; data-end=&quot;158&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;연관관계의 주인이 아닌 쪽은&lt;span&gt;&amp;nbsp;&lt;/span&gt;외래 키 컬럼이 테이블에 존재하지 않는다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1746605477277&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Entity
public class Member {
    @Id @GeneratedValue
    private Long id;

    @ManyToOne
    @JoinColumn(name = &quot;team_id&quot;) // 외래 키가 있는 쪽 &amp;rarr; 연관관계의 주인
    private Team team;
}

@Entity
public class Team {
    @Id @GeneratedValue
    private Long id;

    @OneToMany(mappedBy = &quot;team&quot;) // 주인이 아님 (읽기 전용)
    private List&amp;lt;Member&amp;gt; members = new ArrayList&amp;lt;&amp;gt;();
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-end=&quot;588&quot; data-start=&quot;567&quot; data-ke-size=&quot;size20&quot;&gt;  이 경우 DDL을 보면:&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;676&quot; data-start=&quot;590&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;636&quot; data-start=&quot;590&quot;&gt;member 테이블에는 team_id라는 외래 키 컬럼이 생성. ✅&lt;/li&gt;
&lt;li data-end=&quot;676&quot; data-start=&quot;637&quot;&gt;team 테이블에는 &lt;b&gt;아무런 외래 키 컬럼이 없다.&lt;/b&gt; ❌&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-start=&quot;154&quot; data-end=&quot;171&quot;&gt;✅ 연관관계 주인의 역할&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;172&quot; data-end=&quot;273&quot;&gt;
&lt;li data-start=&quot;172&quot; data-end=&quot;216&quot;&gt;&lt;b&gt;연관관계의 주인만이 외래 키 값을 변경(등록/수정/삭제)할 수 있다. ( 테이블에 존재하는 컬럼이니까 변경 가능 )&lt;/b&gt;&lt;/li&gt;
&lt;li data-start=&quot;217&quot; data-end=&quot;273&quot;&gt;&lt;b&gt;반대편(연관관계의 주인 X)&lt;/b&gt;, 외래 키에 영향을 주지 못하고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;읽기 전용&lt;/b&gt;이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;869&quot; data-start=&quot;836&quot; data-ke-size=&quot;size23&quot;&gt;  그래서 실제로 JPA에서 데이터 변경을 하려면?&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1029&quot; data-start=&quot;870&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1029&quot; data-start=&quot;870&quot;&gt;&lt;b&gt;연관관계의 주인 쪽에서만 수정/등록/삭제가 가능.&lt;/b&gt;&lt;br /&gt;예: member.setTeam(team) 으로 연관관계 설정해야 team_id가 DB에 반영됨.&lt;br /&gt;반대로 team.getMembers().add(member)만 하면 아무런 DB 반영이 안 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 게시물에서는 PA에서 연관관계와 관련된 중요한 옵션 중 하나인 orphanRemoval에 대해서 공부하기!&lt;/p&gt;</description>
      <category>General/JPA</category>
      <author>개발자겨려</author>
      <guid isPermaLink="true">https://programmerjkr.tistory.com/53</guid>
      <comments>https://programmerjkr.tistory.com/53#entry53comment</comments>
      <pubDate>Wed, 7 May 2025 17:21:44 +0900</pubDate>
    </item>
    <item>
      <title>NOT IN 과 NOT EXISTS 차이</title>
      <link>https://programmerjkr.tistory.com/52</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;SQL에서 &lt;b&gt;NOT IN&lt;/b&gt;과 &lt;b&gt;NOT EXISTS&lt;/b&gt;는 서브쿼리에서 특정 조건을 만족하지 않는 데이터를 필터링하는 데 사용되는 연산자이다. 두 연산자는 비슷한 결과를 낼 수 있지만, &lt;u&gt;동작 방식과 성능, NULL 값 처리에서 차이점을 보인다.&lt;/u&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span style=&quot;color: #222222; text-align: start;&quot;&gt; &lt;/span&gt; NOT IN&lt;/b&gt;&lt;b&gt; 연산자&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NOT IN 연산자는 서브쿼리 결과에 없는 값을 가진 행을 선택한다. 즉, 메인 쿼리의 특정 컬럼 값이 서브쿼리 결과 집합에 존재하지 않는 경우에 TRUE를 반환한다.&lt;/p&gt;
&lt;pre id=&quot;code_1746537552696&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT column1, column2, ...
FROM table_name
WHERE column_name NOT IN (subquery);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구문이 간단하고 직관적이다.&lt;/li&gt;
&lt;li&gt;비교적 작은 데이터 집합에서 사용하기에 적합하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단점:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;서브쿼리에 NULL 값이 포함될 경우, 전체 쿼리 결과가 NULL이 될 수 있다.&lt;/span&gt; 이는 NOT IN 연산자가 NULL 값을 처리하는 방식 때문이다. NOT IN은 내부적으로 AND 연산으로 처리되는데, NULL과의 비교는 항상 UNKNOWN을 반환하므로 결과적으로 어떠한 행도 반환하지 않게 된다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;큰 데이터 집합에서는 성능이 저하될 수 있다.&lt;/span&gt; &lt;u&gt;NOT IN은 서브쿼리의 결과를 모두 메모리에 로드하여 비교하기 때문에&lt;/u&gt;, 서브쿼리 결과가 클수록 비효율적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;NULL 값 문제 해결:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NOT IN 사용 시 NULL 값으로 인한 문제를 해결하기 위해 다음과 같은 방법을 사용할 수 있다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;WHERE절에 IS NOT NULL 조건을 추가하여 서브쿼리 결과에서 NULL 값을 제외한다.&lt;/li&gt;
&lt;li&gt;COALESCE 또는 IFNULL 함수를 사용하여 NULL 값을 다른 값으로 대체한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt; &lt;/span&gt;&lt;/b&gt; &lt;b&gt;NOT EXISTS 연산자&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NOT EXISTS 연산자는 서브쿼리가 결과를 반환하지 않는 경우에 TRUE를 반환한다. 즉, 메인 쿼리의 특정 행과 관련된 데이터가 서브쿼리에 존재하지 않는 경우에 해당 행을 선택한다.&lt;/p&gt;
&lt;pre id=&quot;code_1746537775023&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT column1, column2, ...
FROM table_name
WHERE NOT EXISTS (subquery);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;NULL 값을 안전하게 처리할 수 있다. &lt;b&gt;NOT EXISTS는 서브쿼리의 결과 존재 여부만 확인하므로 NULL 값에 영향을 받지 않는다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;큰 데이터 집합에서 NOT IN보다 성능이 우수할 수 있다. &lt;b&gt;NOT EXISTS는 서브쿼리에서 조건에 맞는 행을 찾으면 즉시 실행을 중단하므로, 불필요한 검색을 줄일 수 있다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단점:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;NOT IN보다 구문이 복잡하게 느껴질 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;h1 id=&quot;h1-0260995e83c8e0744d478598a4c49985c1a2642e80525bf6ee36cfe902c66cad&quot; data-title=&quot;성능 비교&quot; data-depth=&quot;1&quot; data-heading=&quot;&quot;&gt;성능 비교&lt;/h1&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 NOT EXISTS는 NOT IN보다 성능이 더 좋은 경향이 있다. 특히 서브쿼리의 결과 집합이 클 경우, NOT EXISTS는 더 효율적인 실행 계획을 생성할 수 있다. NOT EXISTS는 조건에 맞는 행을 찾는 즉시 서브쿼리 실행을 중단할 수 있지만, NOT IN은 서브쿼리 전체를 실행하여 결과를 메모리에 저장해야 하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;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;div&gt;
&lt;h1 id=&quot;h1-ce5da34183dc53ab86fed2e757c4056a6cb81424b0d228defde55c2099d7814b&quot; data-title=&quot;결론&quot; data-depth=&quot;1&quot; data-heading=&quot;&quot;&gt;결론&lt;/h1&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NOT IN과 NOT EXISTS는 모두 유용한 연산자이지만, 다음과 같은 점을 고려하여 상황에 맞게 선택하는 것이 좋다.&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;NULL 값&lt;/b&gt;: 서브쿼리 결과에 NULL 값이 포함될 가능성이 있다면 NOT EXISTS를 사용하는 것이 안전하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;성능&lt;/b&gt;: 큰 데이터 집합에서는 NOT EXISTS가 더 나은 성능을 제공할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;가독성&lt;/b&gt;: NOT IN이 더 직관적으로 느껴진다면, NULL 값 처리 문제를 해결하고 성능을 고려하여 사용 여부를 결정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최적의 성능을 위해서는 쿼리 실행 계획을 분석하고, 필요에 따라 인덱스를 추가하는 등의 튜닝을 수행하는 것이 중요하다.&lt;/p&gt;</description>
      <category>DataBase /query </category>
      <author>개발자겨려</author>
      <guid isPermaLink="true">https://programmerjkr.tistory.com/52</guid>
      <comments>https://programmerjkr.tistory.com/52#entry52comment</comments>
      <pubDate>Tue, 6 May 2025 22:28:11 +0900</pubDate>
    </item>
    <item>
      <title>CSS-in-JS</title>
      <link>https://programmerjkr.tistory.com/51</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;React는 크게 2가지 방식으로 컴포넌트의 스타일을 적용한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;CSS in CSS
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리액트 컴포넌트 별로 css 파일을 갖는 형식으로 스타일을 관리&lt;/li&gt;
&lt;li&gt;CSS Module&lt;/li&gt;
&lt;li&gt;별도의 자바스크립트 전환 필요 없음(속도가 빠름)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CSS in JS
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자바스크립트 내에서 css를 작성하는 방식&lt;/li&gt;
&lt;li&gt;대표적인 라이브러리로 styled-component, emotion 등이 있음&lt;/li&gt;
&lt;li&gt;현재 사용중인 스타일만 DOM에 포함시킬 수 있음&lt;/li&gt;
&lt;li&gt;별도 패키지를 설치하기 때운에 용량이 증가함(스크립트 전환이 필요하여 속도가 다소 느려짐)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt; &lt;/span&gt; CSS in JS 방식으로 하기위해 Emotion 적용하기&lt;/p&gt;
&lt;pre id=&quot;code_1746521216930&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;yarn add @emotion/react @emotion/styled
또는
npm install @emotion/react @emotion/styled&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;설치 완료되면 package.json에서 확인 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;236&quot; data-origin-height=&quot;166&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5sBwQ/btsNLcytClz/73PlHyQHeCk4hqvWsRyAyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5sBwQ/btsNLcytClz/73PlHyQHeCk4hqvWsRyAyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5sBwQ/btsNLcytClz/73PlHyQHeCk4hqvWsRyAyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5sBwQ%2FbtsNLcytClz%2F73PlHyQHeCk4hqvWsRyAyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;236&quot; height=&quot;166&quot; data-origin-width=&quot;236&quot; data-origin-height=&quot;166&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;App.jsx에 CSS-in-JS 방식 적용&lt;/p&gt;
&lt;pre id=&quot;code_1746521362746&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import logo from './logo.svg';
import './App.css';
import styled from '@emotion/styled';

const Container = styled.div`
  text-align: center;
`;

const Header = styled.header`
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
`;

const AppLogo = styled.img`
  height: 40vmin;
  pointer-events: none;

  @media (prefers-reduced-motion: no-preference) {
    {
      animation: App-logo-spin infinite 20s linear;
    }
  }

  @keyframes App-logo-spin {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(360deg);
    }
  }
`;

const AppLink = styled.a`
  color: #61dafb;
`;

function App() {
  return (
    &amp;lt;Container&amp;gt;
      &amp;lt;Header&amp;gt;
        &amp;lt;AppLogo src={logo} alt={'logo'} /&amp;gt;
        &amp;lt;p&amp;gt;
          Edit &amp;lt;code&amp;gt;src/App.tsx&amp;lt;/code&amp;gt; and save to reload.
        &amp;lt;/p&amp;gt;
        &amp;lt;AppLink
          href='https://reactjs.org'
          target='_blank'
          rel='noopener noreferrer'
        &amp;gt;
          Learn React
        &amp;lt;/AppLink&amp;gt;
      &amp;lt;/Header&amp;gt;
    &amp;lt;/Container&amp;gt;
  );
}

export default App;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>General/React⚛️</category>
      <author>개발자겨려</author>
      <guid isPermaLink="true">https://programmerjkr.tistory.com/51</guid>
      <comments>https://programmerjkr.tistory.com/51#entry51comment</comments>
      <pubDate>Tue, 6 May 2025 17:50:50 +0900</pubDate>
    </item>
    <item>
      <title>reportWebVitals.ts (오류 : Unknown options: extensions, resolvePluginsRelativeTo)</title>
      <link>https://programmerjkr.tistory.com/50</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;557&quot; data-origin-height=&quot;740&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dAC5qE/btsNKsIydHO/KDGX12lSfw5uZwUbgMkd31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dAC5qE/btsNKsIydHO/KDGX12lSfw5uZwUbgMkd31/img.png&quot; data-alt=&quot;can't find ReportCallback or ReportHandler type&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dAC5qE/btsNKsIydHO/KDGX12lSfw5uZwUbgMkd31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdAC5qE%2FbtsNKsIydHO%2FKDGX12lSfw5uZwUbgMkd31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;557&quot; height=&quot;740&quot; data-origin-width=&quot;557&quot; data-origin-height=&quot;740&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;can't find ReportCallback or ReportHandler type&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오류 해결 : 아래와 같이 수정 (참고 링크: &lt;a href=&quot;https://github.com/GoogleChrome/web-vitals/issues/482&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/GoogleChrome/web-vitals/issues/482&lt;/a&gt;)&lt;/p&gt;
&lt;pre id=&quot;code_1746513212456&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { MetricType } from &quot;web-vitals&quot;;

const reportWebVitals = (onPerfEntry?: (metric: MetricType) =&amp;gt; void) =&amp;gt; {
  if (onPerfEntry &amp;amp;&amp;amp; onPerfEntry instanceof Function) {
    import(&quot;web-vitals&quot;).then(({ onCLS, onINP, onFCP, onLCP, onTTFB }) =&amp;gt; {
      onCLS(onPerfEntry);
      onINP(onPerfEntry);
      onFCP(onPerfEntry);
      onLCP(onPerfEntry);
      onTTFB(onPerfEntry);
    });
  }
};

export default reportWebVitals;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Project/profile-service</category>
      <author>개발자겨려</author>
      <guid isPermaLink="true">https://programmerjkr.tistory.com/50</guid>
      <comments>https://programmerjkr.tistory.com/50#entry50comment</comments>
      <pubDate>Tue, 6 May 2025 15:36:47 +0900</pubDate>
    </item>
  </channel>
</rss>