<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>생각보다 실천을</title>
    <link>https://yjym33.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 17 Jul 2026 01:14:20 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>yjym33</managingEditor>
    <item>
      <title>김영한의 실전 자바 - 기본편 [생성자]</title>
      <link>https://yjym33.tistory.com/180</link>
      <description>&lt;p style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: center;&quot;&gt;출처 :&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&quot;&gt;https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&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-origin-width=&quot;1200&quot; data-origin-height=&quot;781&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vTZnY/btsNUKvGGkC/kT7GXbgiWUWDn51rRY10W1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vTZnY/btsNUKvGGkC/kT7GXbgiWUWDn51rRY10W1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vTZnY/btsNUKvGGkC/kT7GXbgiWUWDn51rRY10W1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvTZnY%2FbtsNUKvGGkC%2FkT7GXbgiWUWDn51rRY10W1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;543&quot; height=&quot;353&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;781&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;4. 생성자&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자는 객체 생성 직후 객체를 초기화 하기 위한 특별한 메서드로 생각할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4.1 생성자 - 필요한 이유&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체를 생성하는 시점에 어떤 작업을 하고 싶다면 생성자(Constructor)를 이용하면 된다. 어떠한 객체를 생성하고 나면 초기값을 설정해야 하는 경우가 있다. 객체 지향 프로그래밍에서는 속성과 기능을 한 곳에 두는 것이 더 나은 방법이다. 그러므로 객체 안에 객체의 초기값을 설정하는 생성자를 제공하는 것이 좋다.&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;4.2 this&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.2.1 this&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;this는 인스턴스 자신의 참조값을 가리킨다. 멤버 변수에 접근하려면 앞에&amp;nbsp;this.&amp;nbsp;붙여주면 된다.&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;4.2.2 this의 생략&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;this는 생략할 수 있다. 이 경우 변수를 찾을 때 가까운 지역변수(매개변수도 지역변수다)를 먼저 찾고 없으면 그 다음으로 멤버 변수를 찾는다. 멤버 변수도 없으면 오류가 발생한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4.3 생성자 - 도입&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자와 메서드의 차이점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생성자의 이름은 클래스 이름과 같아야 한다. 따라서 첫 글자도 대문자로 시작한다.&lt;/li&gt;
&lt;li&gt;생성자는 반환 타입이 없다. 비워두어야 한다.&lt;/li&gt;
&lt;li&gt;나머지는 메서드와 같다&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.3.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;생성자는 인스턴스를 생성하고 나서 즉시 호출된다. 생성자를 호출하는 방법은 다음 코드와 같이&amp;nbsp;new&amp;nbsp;명령어 다음에 생성자 이름과 매개변수에 맞추어 인수를 전달하면 된다.&lt;/p&gt;
&lt;pre class=&quot;haxe&quot;&gt;&lt;code&gt;new 생성자이름(생성자에 맞는 인수 목록)
new 클래스이름(생성자에 맞는 인수 목록)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로&amp;nbsp;new&amp;nbsp;키워드를 사용해서 객체를 생성할 때 마지막에 괄호&amp;nbsp;()&amp;nbsp;도 포함해야 하는 이유가 바로 생성자 때문이다. 객체를 생성하면서 동시에 생성자를 호출한다는 의미를 포함한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.3.2 생성자 장점&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자가 없던 시절에는 생성 직후에 어떤 작업을 수행하기 위해 메서드를 직접 한번 더 호출해야 했다. 생성자 덕분에 객체를 생성하면서 동시에 생성 직후에 필요한 작업을 한번에 처리할 수 있게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;제약 - 생성자 호출 필수&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체를 생성할 때 직접 정의한 생성자가 있다면&amp;nbsp;&lt;b&gt;직접 정의한 생성자를 반드시 호출&lt;/b&gt;해야 한다는 점이다. 참고로 생성자를 메서드 오버로딩처럼 여러개 정의할 수 있는데, 이 경우에는 하나만 호출하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;생성자를 사용하면 필수값 입력을 보장할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좋은 프로그램은 무한한 자유도가 주어지는 프로그램이 아니라 적절한 제약이 있는 프로그램이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4.4 기본 생성자&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.4.1 기본 생성자&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매개변수가 없는 생성자를 기본 생성자라 한다.&lt;/li&gt;
&lt;li&gt;클래스에 생성자가 하나도 없으면 자바 컴파일러는 매개변수가 없고, 작동하는 코드가 없는 기본 생성자를 자동으로 만들어준다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;생성자가 하나라도 있으면 자바는 기본 생성자를 만들지 않는다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&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;/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;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생성자는 반드시 호출되어야 한다.&lt;/li&gt;
&lt;li&gt;생성자가 없으면 기본 생성자가 제공된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;생성자가 하나라도 있으면 자바는 기본 생성자가 제공되지 않는다.&lt;/b&gt;&amp;nbsp;이 경우 개발자가 정의한 생성자를 직접 호출해야 한다.&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;4.5 생성자 - 오버로딩과 this()&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자도 메서드 오버로딩처럼 매개변수만 다르게 해서 여러 생성자를 제공할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public MemberConstruct(String name, int age) {
	this.name = name;
 	this.age = age;
 	this.grade = 50;
}
public MemberConstruct(String name, int age, int grade) {
   	this.name = name;
   	this.age = age;
   	this.grade = grade;
}
&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;4.5.1 this()&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;이때&amp;nbsp;this()&amp;nbsp;라는 기능을 사용하면 생성자 내부에서 자신의 생성자를 호출할 수 있다. 참고로&amp;nbsp;this&amp;nbsp;는 인스턴스 자신의 참조값을 가리킨다. 그래서 자신의 생성자를 호출한다고 생각하면 된다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;MemberConstruct(String name, int age) {
 	this(name, age, 50); //변경
}

MemberConstruct(String name, int age, int grade) {
 	System.out.println(&quot;생성자 호출 name=&quot; + name + &quot;,age=&quot; + age + &quot;,grade=&quot; + grade);
 	this.name = name;
 	this.age = age;
 	this.grade = grade;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;this() 규칙&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;this()&amp;nbsp;는 생성자 코드의 첫줄에만 작성할 수 있다.&lt;/p&gt;</description>
      <category>Development/Java</category>
      <author>yjym33</author>
      <guid isPermaLink="true">https://yjym33.tistory.com/180</guid>
      <comments>https://yjym33.tistory.com/180#entry180comment</comments>
      <pubDate>Tue, 13 May 2025 16:47:18 +0900</pubDate>
    </item>
    <item>
      <title>김영한의 실전 자바 기본편 - [객체 지향 프로그래밍]</title>
      <link>https://yjym33.tistory.com/179</link>
      <description>&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: center;&quot;&gt;출처 :&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&quot;&gt;https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&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-origin-width=&quot;1200&quot; data-origin-height=&quot;781&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w5xSv/btsNU8b42Kl/wUgSXvXzyUmFI8uegJZdak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w5xSv/btsNU8b42Kl/wUgSXvXzyUmFI8uegJZdak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w5xSv/btsNU8b42Kl/wUgSXvXzyUmFI8uegJZdak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw5xSv%2FbtsNU8b42Kl%2FwUgSXvXzyUmFI8uegJZdak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;458&quot; height=&quot;298&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;781&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;3. 객체 지향 프로그래밍&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.1 객체 지향 프로그래밍 vs 절차 지향 프로그래밍&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 지향 프로그래밍과 절차 지향 프로그래밍은 서로 대치되는 개념이 아니다. 객체 지향이라도 프로그램의 작동 순서는 중요하다. 다만 어디에 더 초점을 맞추는가에 둘의 차이가 있다. 객체 지향의 경우 객체의 설계와 관계를 중시한다. 반면 절차 지향의 경우 데이터와 기능이 분리되어 있고, 프로그램이 어떻게 작동하는지 그 순서에 초점을 맞춘다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;절차 지향 프로그래밍&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;절차 지향 프로그래밍은 이름 그대로 절차를 지향한다. 쉽게 이야기해서 실행 순서를 중요하게 생각하는 방식이다.&lt;/li&gt;
&lt;li&gt;절차 지향 프로그래밍은 프로그램의 흐름을 순차적으로 따르며 처리하는 방식이다. 즉,&amp;nbsp;어떻게&amp;nbsp;를 중심으로 프로그래밍 한다.&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;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체 지향 프로그래밍은 이름 그대로 객체를 지향한다. 쉽게 이야기해서 객체를 중요하게 생각하는 방식이다.&lt;/li&gt;
&lt;li&gt;객체 지향 프로그래밍은 실제 세계의 사물이나 사건을 객체로 보고, 이러한 객체들 간의 상호작용을 중심으로 프로그래밍하는 방식이다. 즉&amp;nbsp;무엇을&amp;nbsp;중심으로 프로그래밍 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;둘의 중요한 차이&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;절차 지향은 데이터와 해당 데이터에 대한 처리 방식이 분리되어 있다. 반면 객체 지향에서는 데이터와 그 데이터에 대한 행동(메서드)이 하나의&amp;nbsp;객체&amp;nbsp;안에 함께 포함되어 있다.&lt;span style=&quot;color: #000000; font-size: 1.62em; letter-spacing: -1px; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 1.62em; letter-spacing: -1px; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif;&quot;&gt;3.2 객체란?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세상의 모든 사물을 단순하게 추상화해보면 속성(데이터)과 기능 딱 2가지로 설명할 수 있다.&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;자동차&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;속성 : 차량 색상, 현재 속도&lt;/li&gt;
&lt;li&gt;기능 : 액셀, 브레이크, 문 열기, 문 닫기&lt;/li&gt;
&lt;/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;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;속성 : 색상, 키, 온도&lt;/li&gt;
&lt;li&gt;기능 : 먹는다, 걷는다&lt;/li&gt;
&lt;/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;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;속성 : 레벨, 경험치, 소유한 아이템들&lt;/li&gt;
&lt;li&gt;기능 : 이동, 공격, 아이템 획득&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 지향 프로그래밍은 모든 사물을 속성과 기능을 가진 객체로 생각하는 것이다. 객체에는 속성과 기능만 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 단순화하면 세상에 있는 객체들을 컴퓨터 프로그램으로 쉽게 설계할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 장점 덕분에 지금은 객체 지향 프로그래밍이 가장 많이 사용된다. 참고로 실세계와 객체가 항상 1:1로 매칭되는 것은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체의 각각의 기능을 메서드로 만들면 각각의 기능을&amp;nbsp;&lt;b&gt;모듈화&lt;/b&gt;하였다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 이야기해서 레고 블럭을 생각하면 된다. 필요한 블럭을 가져다 꼽아서 사용할 수 있다. 어떤 객체의 기능이 필요하면 해당 기능을 메서드 호출 만으로 손쉽게 사용할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.3 객체 지향 프로그래밍&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 지향 프로그래밍은 어떠한 개념을 객체로 온전히 만드는 것에 집중해야 한다. 그러기 위해서는 프로그램의 실행 순서보다는 객체로 표현하려는 클래스를 만드는 것 자체에 집중해야 한다. 객체로 표현하려는 개념이 어떤 속성(데이터)을 가지고 어떤 기능(메서드)을 제공하는지 이 부분에 초점을 맞추어야 한다. 쉽게 이야기 해서 어떠한 개념을 객체로 만들어서 제공하는 개발자와 그 객체를 사용하는 사용자가 분리되어 있다고 생각하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;public class MusicPlayer {
    int volume = 0;
    boolean isOn = false;
    void on() {
        isOn = true;
        System.out.println(&quot;음악 플레이어를 시작합니다&quot;);
    }
    void off() {
        isOn = false;
        System.out.println(&quot;음악 플레이어를 종료합니다&quot;);
    }
    void volumeUp() {
        volume++;
        System.out.println(&quot;음악 플레이어 볼륨:&quot; + volume);
    }
    void volumeDown() {
        volume--;
        System.out.println(&quot;음악 플레이어 볼륨:&quot; + volume);
    }
    void showStatus() {
        System.out.println(&quot;음악 플레이어 상태 확인&quot;);
        if (isOn) {
            System.out.println(&quot;음악 플레이어 ON, 볼륨:&quot; + volume);
        } else {
 			System.out.println(&quot;음악 플레이어 OFF&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;MusicPlayer&amp;nbsp;클래스에 음악 플레이어에 필요한 속성과 기능을 모두 정의했다. 이제 음악 플레이어가 필요한 곳에서 이 클래스만 있으면 온전한 음악 플레이어를 생성해서 사용할 수 있다. 음악 플레이어를 사용하는데 필요한 모든 속성과 기능이 하나의 클래스에 포함되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt; public class MusicPlayerMain4 {
     public static void main(String[] args) {
     	MusicPlayer player = new MusicPlayer();
        //음악 플레이어 켜기
        player.on();
        //볼륨 증가
        player.volumeUp();
        //볼륨 증가
        player.volumeUp();
        //볼륨 감소
        player.volumeDown();
        //음악 플레이어 상태
        player.showStatus();
        //음악 플레이어 끄기
        player.off();
    }
 }
&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;MusicPlayer&amp;nbsp;를 사용하는 코드를 보자.&amp;nbsp;MusicPlayer&amp;nbsp;객체를 생성하고 필요한 기능(메서드)을 호출하기만 하면 된다. 필요한 모든 것은&amp;nbsp;MusicPlayer&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;MusicPlayer&amp;nbsp;를 사용하는 입장에서는&amp;nbsp;MusicPlayer&amp;nbsp;의 데이터인&amp;nbsp;volume,&amp;nbsp;iOn&amp;nbsp;같은 데이터는 전혀 사용하지 않는다.&lt;/li&gt;
&lt;li&gt;MusicPlayer&amp;nbsp;를 사용하는 입장에서는 이제&amp;nbsp;MusicPlayer&amp;nbsp;내부에 어떤 속성(데이터)이 있는지 전혀 몰라도 된다.&amp;nbsp;MusicPlayer&amp;nbsp;를 사용하는 입장에서는 단순하게&amp;nbsp;MusicPlayer&amp;nbsp;가 제공하는 기능 중에 필요한 기능을 호출해서 사용하기만 하면 된다.&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MusicPlayer&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;MusicPlayer&amp;nbsp;내부 코드가 변하는 경우에 다른 코드는 변경하지 않아도 된다.&amp;nbsp;MusicPlayer&amp;nbsp;의&amp;nbsp;volume&amp;nbsp;이라는 필드 이름이 다른 이름으로 변한다고 할&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때&amp;nbsp;MusicPlayer&amp;nbsp;내부만 변경하면 된다. 또 음악 플레이어가 내부에서 출력하는 메시지를 변경할 때도&amp;nbsp;MusicPlayer&amp;nbsp;내부만 변경하면 된다. 이 경우&amp;nbsp;MusicPlayer&amp;nbsp;를 사용하는 사용자 입장에서는 코드를 전혀 변경하지 않아도 된다. 물론 외부에서 호출하는&amp;nbsp;MusicPlayer&amp;nbsp;의 메서드 이름을 변경한다면&amp;nbsp;MusicPlayer&amp;nbsp;를 사용하는 곳의 코드도 변경해야 한다.&lt;/p&gt;</description>
      <category>Development/Java</category>
      <author>yjym33</author>
      <guid isPermaLink="true">https://yjym33.tistory.com/179</guid>
      <comments>https://yjym33.tistory.com/179#entry179comment</comments>
      <pubDate>Tue, 13 May 2025 16:46:46 +0900</pubDate>
    </item>
    <item>
      <title>김영한의 실전 자바 - 기본편 [기본형과 참조형]</title>
      <link>https://yjym33.tistory.com/178</link>
      <description>&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: center;&quot;&gt;출처 :&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&quot;&gt;https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1747123154904&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;김영한의 실전 자바 - 기본편 강의 | 김영한 - 인프런&quot; data-og-description=&quot;김영한 | , 국내 개발 분야 누적 수강생 1위, 제대로 만든 김영한의 실전 자바[사진][임베딩 영상]단순히 자바 문법을 안다? 이걸로는 안됩니다!전 우아한형제들 기술이사, 누적 수강생 40만 명 돌&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/brX0cW/hyYU1xK1nK/3h6BkKywYIjAPD7KrfEG3k/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/4fCH6/hyYPsK2a0I/uApDT5IE9IGRAwZyi1fit1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/cDxWr8/hyYVew6aD0/FbqrsGHiK6ZfY4cX2Gdt50/img.jpg?width=1439&amp;amp;height=1441&amp;amp;face=171_677_281_798&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/brX0cW/hyYU1xK1nK/3h6BkKywYIjAPD7KrfEG3k/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/4fCH6/hyYPsK2a0I/uApDT5IE9IGRAwZyi1fit1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/cDxWr8/hyYVew6aD0/FbqrsGHiK6ZfY4cX2Gdt50/img.jpg?width=1439&amp;amp;height=1441&amp;amp;face=171_677_281_798');&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;김영한 | , 국내 개발 분야 누적 수강생 1위, 제대로 만든 김영한의 실전 자바[사진][임베딩 영상]단순히 자바 문법을 안다? 이걸로는 안됩니다!전 우아한형제들 기술이사, 누적 수강생 40만 명 돌&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.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;h1&gt;2. 기본형과 참조형&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2.1 기본형 vs 참조형&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;자바에서 참조형을 제대로 이해하는 것은 정말 중요하다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용하는 값을 변수에 직접 넣을 수 있는 기본형, 객체가 지정된 메모리의 위치를 가리키는 참조값을 넣을 수 있는 참조형으로 분류할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본형(Primitive Type) :&amp;nbsp;int, long, double, boolean&amp;nbsp;처럼 변수에 사용할 값을 직접 넣을 수 있는 데이터 타입을 기본형이라 한다.&lt;/li&gt;
&lt;li&gt;참조형(Reference Type) :&amp;nbsp;Student student,&amp;nbsp;int[] students&amp;nbsp;와 같이 데이터에 접근하기 위한 참조(주소)를 저장하는 데이터 타입을 참조형이라 한다. 참조형은 객체 또는 배열에 사용된다.&lt;/li&gt;
&lt;/ul&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;h3 data-ke-size=&quot;size23&quot;&gt;쉽게 이해하는 팁&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본형을 제외한 나머지는 모두 참조형이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본형은 소문자로 시작한다.&amp;nbsp;int, long, double, boolean&amp;nbsp;모두 소문자로 시작한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본형은 자바가 기본으로 제공하는 데이터 타입이다. 이러한 기본형은 개발자가 새로 정의할 수 없다. 개발자는 참조형인 클래스만 직접 정의할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;클래스는 대문자로 시작한다.&amp;nbsp;Student
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클래스는 모두 참조형이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 -&amp;nbsp;String&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서&amp;nbsp;String&amp;nbsp;은 특별하다.&amp;nbsp;String&amp;nbsp;은 사실은 클래스다. 따라서 참조형이다. 그런데 기본형처럼 문자 값을 바로 대입할 수 있다. 문자는 매우 자주 다루기 때문에 자바에서 특별하게 편의 기능을 제공한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;대원칙 : 자바는 항상 변수의 값을 복사해서 대입한다.&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서 변수에 값을 대입하는 것은 변수에 들어있는 값을 복사해서 대입하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본형, 참조형 모두 항상 변수에 있는 값을 복사해서 대입한다. 기본형이면 변수에 들어있는 실제 사용하는 값을 복사해서 대입하고, 참조형이면 변수에 들어있는 참조값을 복사해서 대입한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참조형의 경우 실제 사용하는 객체가 아니라 객체의 위치를 가리키는 참조값만 복사된다.&lt;/b&gt;&amp;nbsp;쉽게 이야기해서 실제 건물이 복사가 되는 것이 아니라 건물의 위치인 주소만 복사되는 것이다. 따라서 같은 건물을 찾아갈 수 있는 방법이 하나 늘어날 뿐이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2.2 참조형과 메서드 호출&lt;/h2&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;package ref;
public class Method2 {
 		public static void main(String[] args) {
 		Student student1 = createStudent(&quot;학생1&quot;, 15, 90);
 		Student student2 = createStudent(&quot;학생2&quot;, 16, 80);
 		printStudent(student1);
 		printStudent(student2);
 	}

 	static Student createStudent(String name, int age, int grade) {
 		Student student = new Student();
 		student.name = name;
 		student.age = age;
 		student.grade = grade;
 		return student;
 	}

 	static void printStudent(Student student1) {
 		System.out.println(&quot;이름:&quot; + student1.name + &quot; 나이:&quot; + student1.age + &quot; 성적:&quot; + student1.grade);
 	}
}
&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;student1&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1083&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p1zUR/btsNUJwLXMx/hVSO27ySw46wdgtyAPfmBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p1zUR/btsNUJwLXMx/hVSO27ySw46wdgtyAPfmBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p1zUR/btsNUJwLXMx/hVSO27ySw46wdgtyAPfmBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp1zUR%2FbtsNUJwLXMx%2FhVSO27ySw46wdgtyAPfmBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;1083&quot; height=&quot;593&quot; data-origin-width=&quot;1083&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2.3&amp;nbsp;null&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조형 변수에는 항상 객체가 있는 위치를 가리키는 참조값이 들어간다. 그런데 아직 가리키는 대상이 없거나, 가리키는 대상을 나중에 입력하고 싶다면 어떻게 해야할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조형 변수에는 아직 가리키는 대상이 없다면&amp;nbsp;null&amp;nbsp;이라는 특별한 값을 넣어둘 수 있다.&amp;nbsp;null은 값이 존재하지 않는, 없다는 뜻이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멤버 변수에서의 참조형의 값 초기화는 참조형 =&amp;nbsp;null&amp;nbsp;로 자동 초기화해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;GC - 아무도 참조하지 않는 인스턴스의 최후&lt;/h2&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;1057&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cR6jj5/btsNVA6XDqd/Or2wcZL1F4vUmmTmkD8So1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cR6jj5/btsNVA6XDqd/Or2wcZL1F4vUmmTmkD8So1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cR6jj5/btsNVA6XDqd/Or2wcZL1F4vUmmTmkD8So1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcR6jj5%2FbtsNVA6XDqd%2FOr2wcZL1F4vUmmTmkD8So1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;1057&quot; height=&quot;520&quot; data-origin-width=&quot;1057&quot; data-origin-height=&quot;520&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;data에&amp;nbsp;null을 할당했다. 따라서 앞서 생성한&amp;nbsp;x001&amp;nbsp;Data&amp;nbsp;인스턴스를 더는 아무도 참조하지 않는다. 이렇게 아무도 참조하지 않게 되면&amp;nbsp;x001이라는 참조값을 다시 구할 방법이 없다. 따라서 해당 인스턴스에 다시 접근할 방법이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 아무도 참조하지 않는 인스턴스는 사용되지 않고 메모리 용량만 차지할 뿐이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C와 같은 과거 프로그래밍 언어는 개발자가 직접 명령어를 사용해서 인스턴스를 메모리에서 제거해야 했다. 만약 실수로 인스턴스 삭제를 누락하면 메모리에 사용하지 않는 객체가 가득해져서 메모리 부족 오류가 발생하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바는 이런 과정을 자동으로 처리해준다. 아무도 참조하지 않는 인스턴스가 있으면&amp;nbsp;JVM&amp;nbsp;의&amp;nbsp;GC&amp;nbsp;(가비지 컬렉션)가 더 이상 사용하지 않는 인스턴스라 판단하고 해당 인스턴스를 자동으로 메모리에서 제거해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체는 해당 객체를 참조하는 곳이 있으면,&amp;nbsp;JVM&amp;nbsp;이 종료할 때 까지 계속 생존한다. 그런데 중간에 해당 객체를 참조하는 곳이 모두 사라지면 그때&amp;nbsp;JVM은 필요 없는 객체로 판단하고&amp;nbsp;GC를 사용해서 제거한다.&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;2.4 NullPointerException&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 참조값이 없이 객체를 찾아가면 어떤 문제가 발생할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우&amp;nbsp;NullPointerException&amp;nbsp;이라는 예외가 발생하는데, 개발자를 가장 많이 괴롭히는 예외이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NullPointerException은 이름 그래도&amp;nbsp;null&amp;nbsp;을 가리키나(Pointer)인데, 이때 발생하는 예외(Exception)다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;null은 없다는 뜻이므로 결국 주소가 없는 곳을 찾아갈 때 발생하는 예외이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체를 참조할떄는.(dot)을 사용한다. 이렇게 하면 참조값을 사용해서 해당 객체를 찾아갈 수 있다. 그런데 참조값이&amp;nbsp;null&amp;nbsp;이라면 값이 없다는 뜻이므로, 찾아갈 수 있는 객체(인스턴스)가 없다.&amp;nbsp;NullPointerException&amp;nbsp;은 이처럼&amp;nbsp;null에&amp;nbsp;.(dot)을 찍었을 때 발생한다.&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;NullPointerException이 발생하면&amp;nbsp;null&amp;nbsp;값에&amp;nbsp;.&amp;nbsp;(dot)을 찍었따고 생각하면 문제를 쉽게 찾을 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2.5 기본형과 참조형 정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;대원칙 : 자바는 항상 변수의 값을 복사해서 대입한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서 변수에 값을 대입하는 것은 변수에 들어있는 값을 복사해서 대입하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본형, 참조형 모두 항상 변수에 있는 값을 복사해서 대입한다. 기본형이면 변수에 들어있는 실제 사용하는 값을 복사해서 대입하고, 참조형이면 변수에 들어있는 참조값을 복사해서 대입한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본형이든 참조형이든 변수의 값을 대입하는 방식은 같다. 하지만 기본형과 참조형에 따라 동작하는 방식이 달라진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기본형 vs 참조형 - 기본&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자바의 데이터 타입을 가장 크게 보면 기본형과 참조형으로 나눌 수 있다.&lt;/li&gt;
&lt;li&gt;기본형을 제외한 나머지 변수는 모두 참조형이다. 클래스와 배열을 다루는 변수는, 참조형이다.&lt;/li&gt;
&lt;li&gt;기본형 변수는 값을 직접 저장하지만, 참조형 변수는 참조(주소)를 저장한다.&lt;/li&gt;
&lt;li&gt;기본형 변수는 산술 연산을 수행할 수 있지만, 참조형 변수는 산술 연산을 수행할 수 없다.&lt;/li&gt;
&lt;li&gt;기본형 변수는&amp;nbsp;null&amp;nbsp;을 할당할 수 없지만, 참조형 변수는&amp;nbsp;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;&lt;b&gt;기본형 vs 참조형 - 대입&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본형과 참조형 모두 대입시 변수 안에 있는 값을 읽고 복사해서 전달한다.&lt;/li&gt;
&lt;li&gt;기본형은 사용하는 값을 복사해서 전달하고,&amp;nbsp;&lt;b&gt;참조형은 참조값을 복사해서 전달한다! 이것이 중요하다. 실제 인스터스가 복사되는 것이 아니다. 인스턴스를 가리키는 참조값을 복사해서 전달하는 것이다! 따라서 하나의 인스턴스를 여러곳에서 참조할 수 있다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;헷갈리면 그냥 변수 안에 들어간 값을 떠올려보자. 기본형은 사용하는 값이, 참조형은 참조값이 들어있다! 변수에 어떤 값이 들어있든간에 그 값을 그대로 복사해서 전달한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기본형 vs 참조형 - 메서드 호출&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;</description>
      <category>Development/Java</category>
      <author>yjym33</author>
      <guid isPermaLink="true">https://yjym33.tistory.com/178</guid>
      <comments>https://yjym33.tistory.com/178#entry178comment</comments>
      <pubDate>Tue, 13 May 2025 16:46:13 +0900</pubDate>
    </item>
    <item>
      <title>김영한의 실전 자바 - 기본편 [클래스와 데이터]</title>
      <link>https://yjym33.tistory.com/177</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: center;&quot;&gt;&lt;br /&gt;출처 :&amp;nbsp; &lt;a href=&quot;https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&lt;/a&gt;&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;1200&quot; data-origin-height=&quot;781&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nErE7/btsNU5TUDGX/CiKxSTfBjKSTIB5adfm6Yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nErE7/btsNU5TUDGX/CiKxSTfBjKSTIB5adfm6Yk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nErE7/btsNU5TUDGX/CiKxSTfBjKSTIB5adfm6Yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnErE7%2FbtsNU5TUDGX%2FCiKxSTfBjKSTIB5adfm6Yk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;501&quot; height=&quot;326&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;781&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;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;1. 클래스와 데이터&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.1 클래스 도입&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사람이 관리하기 좋은 방식으로 어떠한 개념을 하나로 묶는 것이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예) Student 클래스&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;public class Student {
	String name;
    int age;
 	int grade;
}
&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;클래스에 정의된 변수들(name, age, grede)을 변수, 또는 필드라 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;멤버 변수(Member Variable) : 이 변수들은 특정 클래스에 소속된 멤버이기 때문에 이렇게 부른다.&lt;/li&gt;
&lt;li&gt;필드(Field) : 데이터 항목을 가리키는 전통적인 용어이다.&lt;/li&gt;
&lt;li&gt;자바에서 멤버 변수, 필드는 같은 뜻이다. 클래스에 소속된 변수를 뜻한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;클래스란 설계도&lt;/b&gt;이다.&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스를 사용하면&amp;nbsp;int, String&amp;nbsp;과 같은 타입을 직접 만들 수 있다.(Student)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 직접 정의하는 사용자 정의 타입을 만들려면 설계도가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;&lt;b&gt;설계도가 바로 클래스&lt;/b&gt;&amp;nbsp;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설계도인 클래스를 사용해서&amp;nbsp;&lt;b&gt;실제 메모리에 만들어진 실체를 객체 또는 인스턴스&lt;/b&gt;라 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.2 클래스 생성&lt;/h2&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;public class ClassStart3 {
	public static void main(String[] args) {
		Student student1;
      	student1 = new Student();
     	student1.name = &quot;학생1&quot;;
     	student1.age = 15;
     	student1.grade = 90;

     	Student student2 = new Student();
     	student2.name = &quot;학생2&quot;;
     	student2.age = 16;
     	student2.grade = 80;

     	System.out.println(&quot;이름:&quot; + student1.name + &quot; 나이:&quot; + student1.age + &quot; 성적:&quot; + student1.grade);
     	System.out.println(&quot;이름:&quot; + student2.name + &quot; 나이:&quot; + student2.age + &quot; 성적:&quot; + student2.grade);
    }
}
&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;1.2.1 변수 선언&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUJvcS/btsNUPpw78N/yvR7hoYbsEh0oc59t0X0X0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUJvcS/btsNUPpw78N/yvR7hoYbsEh0oc59t0X0X0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUJvcS/btsNUPpw78N/yvR7hoYbsEh0oc59t0X0X0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUJvcS%2FbtsNUPpw78N%2FyvR7hoYbsEh0oc59t0X0X0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;665&quot; height=&quot;220&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Student student1
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Student&amp;nbsp;타입을 받을 수 있는 변수를 선언한다.&lt;/li&gt;
&lt;li&gt;int는 정수를,&amp;nbsp;String은 문자를 담을 수 있듯이&amp;nbsp;Student는&amp;nbsp;Student&amp;nbsp;타입의 객체(인스턴스)를 받을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&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;1.2.2 객체 생성&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;855&quot; data-origin-height=&quot;235&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3IelC/btsNV5EVRgg/NW37e0vwS36TMKeIHTJeT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3IelC/btsNV5EVRgg/NW37e0vwS36TMKeIHTJeT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3IelC/btsNV5EVRgg/NW37e0vwS36TMKeIHTJeT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3IelC%2FbtsNV5EVRgg%2FNW37e0vwS36TMKeIHTJeT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;855&quot; height=&quot;235&quot; data-origin-width=&quot;855&quot; data-origin-height=&quot;235&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;student = new Student()
&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;new Student()&amp;nbsp;:&amp;nbsp;new&amp;nbsp;는 새로 생성한다는 뜻이다.&amp;nbsp;new Student()&amp;nbsp;는&amp;nbsp;Student&amp;nbsp;클래스 정보를 기반으로 새로운 객체를 생성하라는 뜻이다. 이렇게 하면 메모리에 실제&amp;nbsp;Student&amp;nbsp;객체(인스턴스)를 생성한다.&lt;/li&gt;
&lt;li&gt;객체를 생성할 때는&amp;nbsp;new 클래스명()&amp;nbsp;을 사용하면 된다. 마지막에&amp;nbsp;()&amp;nbsp;도 추가해야 한다.&lt;/li&gt;
&lt;li&gt;Sudent&amp;nbsp;클래스는&amp;nbsp;String name, int age, int grade&amp;nbsp;멤버 변수를 가지고 있다. 이 변수를 사용하는데 필요한 메모리 공간도 함께 확보한다.&lt;/li&gt;
&lt;/ul&gt;
&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;1.2.3&amp;nbsp;&lt;b&gt;참조값 보관&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;247&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cflI5o/btsNVVPVz5A/O01X6UkqBxvqcdNv2lRNJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cflI5o/btsNVVPVz5A/O01X6UkqBxvqcdNv2lRNJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cflI5o/btsNVVPVz5A/O01X6UkqBxvqcdNv2lRNJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcflI5o%2FbtsNVVPVz5A%2FO01X6UkqBxvqcdNv2lRNJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;868&quot; height=&quot;247&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;247&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체를 생성하면 자바는 메모리에 어딘가에 있는 이 객체에 접근할 수 있는&amp;nbsp;&lt;b&gt;참조값(주소)&lt;/b&gt;(x001)을 반환한다.&lt;/li&gt;
&lt;li&gt;new&amp;nbsp;키워드를 통해 객체를 생성되고 나면 참조값을 반환한다. 앞서 선언한 변수인&amp;nbsp;Student student1에 생성된 객체의 참조값(x001)을 보관한다.&lt;/li&gt;
&lt;li&gt;Student student1&amp;nbsp;변수는 이제 메모리에 존재하는 실제&amp;nbsp;Student&amp;nbsp;객체(인스턴스)의 참조값을 가지고 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;student1&amp;nbsp;변수는 방금 만든 객체에 접근할 수 있는 참조값을 가지고 있다. 따라서 이 변수를 통해 객체를 접근(참조)할 수 있다. 쉽게 이야기해서&amp;nbsp;student1&amp;nbsp;변수를 통해 메모리에 있는 실제 객체를 접근하고 사용할 수 있다.&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;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조값을 변수에 보관해야 하는 이유&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체를 생성하는&amp;nbsp;new Student()&amp;nbsp;코드 자체에는 아무런 이름이 없다. 이 코드는 단순히&amp;nbsp;Student&amp;nbsp;클래스(설계도)를 기반으로 메모리에 실제 객체를 만드는 것이다. 따라서 생성한 객체에 접근할 수 있는 방법이 필요하다. 이런 이유로 객체를 생성할 때 반환되는 참조값을 어딘가에 보관해두어야 한다. 앞서&amp;nbsp;Student student1&amp;nbsp;변수에 참조값(x001)을 저장해두었으므로&amp;nbsp;&lt;b&gt;저장한 참조값을 통해서 실제 메모리에 존재하는 객체에 접근할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.3 클래스, 객체, 인스턴스 정리&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.3.1 클래스 - Class&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스는 객체를 생성하기 위한&amp;nbsp;틀&amp;nbsp;또는&amp;nbsp;설계도&amp;nbsp;이다. 클래스는 객체가 가져야 할 속성(변수)과 기능(메서드)를 정의한다. 예를 들어 학생이라는 클래스는 속성으로&amp;nbsp;name, age, grade&amp;nbsp;를 가진다.&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;1.3.2 객체 - Object&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체는 클래스에서 정의한 속성과 기능을 가진 실체이다. 객체는 서로 독립적인 상태를 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 위 코드에서&amp;nbsp;student1&amp;nbsp;은 학생1의 속성을 가지는 객체이고,&amp;nbsp;student2&amp;nbsp;는 학생2의 속성을 가지는 객체이다.&amp;nbsp;student1&amp;nbsp;과&amp;nbsp;student2&amp;nbsp;는 같은 클래스에서 만들어졌지만, 서로 다른 객체이다.&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;1.3.3 인스턴스 - Instance&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스는 특정 클래스로부터 생성된 객체를 의미한다. 그래서 객체와 인스턴스라는 용어는 자주 혼용된다. 인스턴스는 주로 객체가 어떤 클래스에 속해 있는지 강조할 때 사용한다. 예를 들어서&amp;nbsp;student1&amp;nbsp;객체는&amp;nbsp;Student&amp;nbsp;클래스의 인스턴스다. 라고 표현한다.&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;객체 vs 인스턴스&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;student&amp;nbsp;은&amp;nbsp;Student&amp;nbsp;의 객체이다. 라고 말하는 대신&amp;nbsp;student&amp;nbsp;은&amp;nbsp;Student&amp;nbsp;의 인스턴스이다. 라고 특정 클래스와의 관계를 명확히 할 때 인스턴스라는 용어를 주로 사용한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.4&amp;nbsp;자바에서 대입은 항상 변수에 들어 있는 값을 복사해서 전달한다.&lt;/h2&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;students[0] = student1;
students[1] = student2;
//자바에서 대입은 항상 변수에 들어 있는 값을 복사한다.
students[0] = x001;
students[1] = x002;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서 변수의 대입(=)은 모두 변수에 들어있는 값을 복사해서 전달하는 것이다. 이 경우 오른쪽 변수인&amp;nbsp;student1, student2&amp;nbsp;에는 참조값이 들어있다. 그래서 이 값을 복사해서 왼쪽에 있는 배열에 전달한다. 따라서 기존&amp;nbsp;student1, student2&amp;nbsp;에 들어있던 참조값은 당연히 그대로 유지된다.&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수에는 인스턴스 자체가 들어있는 것이 아니다! 인스턴스의 위치를 가리키는 참조값이 들어있을 뿐이다! 따라서 대입(=)시에 인스턴스가 복사되는 것이 아니라 참조값만 복사된다.&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>Development/Java</category>
      <author>yjym33</author>
      <guid isPermaLink="true">https://yjym33.tistory.com/177</guid>
      <comments>https://yjym33.tistory.com/177#entry177comment</comments>
      <pubDate>Tue, 13 May 2025 13:25:58 +0900</pubDate>
    </item>
    <item>
      <title>커피/티 정기 구독 쇼핑몰 - ERD 설계</title>
      <link>https://yjym33.tistory.com/174</link>
      <description>&lt;h2 data-end=&quot;185&quot; data-start=&quot;148&quot; data-ke-size=&quot;size26&quot;&gt;  커피/티 정기 구독 쇼핑몰 ERD 설계 (표 기반 정리)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;209&quot; data-start=&quot;187&quot; data-ke-size=&quot;size23&quot;&gt; &amp;zwj;  users (회원)&lt;/h3&gt;
&lt;div&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; &amp;nbsp; 타입&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;593&quot; data-start=&quot;210&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;593&quot; data-start=&quot;305&quot;&gt;
&lt;tr data-end=&quot;351&quot; data-start=&quot;305&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;320&quot; data-start=&quot;305&quot;&gt;id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;334&quot; data-start=&quot;320&quot;&gt;PK&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;351&quot; data-start=&quot;334&quot;&gt;사용자 고유 ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;400&quot; data-start=&quot;352&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;367&quot; data-start=&quot;352&quot;&gt;email&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;381&quot; data-start=&quot;367&quot;&gt;VARCHAR&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;400&quot; data-start=&quot;381&quot;&gt;이메일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;446&quot; data-start=&quot;401&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;416&quot; data-start=&quot;401&quot;&gt;password&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;430&quot; data-start=&quot;416&quot;&gt;VARCHAR&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;446&quot; data-start=&quot;430&quot;&gt;비밀번호 해시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;496&quot; data-start=&quot;447&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;462&quot; data-start=&quot;447&quot;&gt;name&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;476&quot; data-start=&quot;462&quot;&gt;VARCHAR&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;496&quot; data-start=&quot;476&quot;&gt;이름&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;544&quot; data-start=&quot;497&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;512&quot; data-start=&quot;497&quot;&gt;address&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;526&quot; data-start=&quot;512&quot;&gt;TEXT&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;544&quot; data-start=&quot;526&quot;&gt;배송 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;593&quot; data-start=&quot;545&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;560&quot; data-start=&quot;545&quot;&gt;created_at&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;574&quot; data-start=&quot;560&quot;&gt;TIMESTAMP&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;593&quot; data-start=&quot;574&quot;&gt;가입일&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;598&quot; data-start=&quot;595&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;626&quot; data-start=&quot;600&quot; data-ke-size=&quot;size23&quot;&gt;☕ products (원두/티 상품)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&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; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &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;/div&gt;
&lt;div&gt;&lt;br /&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1259&quot; data-start=&quot;627&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1259&quot; data-start=&quot;742&quot;&gt;
&lt;tr data-end=&quot;800&quot; data-start=&quot;742&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;757&quot; data-start=&quot;742&quot;&gt;id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;771&quot; data-start=&quot;757&quot;&gt;PK&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;800&quot; data-start=&quot;771&quot;&gt;상품 ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;858&quot; data-start=&quot;801&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;816&quot; data-start=&quot;801&quot;&gt;name&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;830&quot; data-start=&quot;816&quot;&gt;VARCHAR&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;858&quot; data-start=&quot;830&quot;&gt;상품명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;914&quot; data-start=&quot;859&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;874&quot; data-start=&quot;859&quot;&gt;type&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;888&quot; data-start=&quot;874&quot;&gt;ENUM&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;914&quot; data-start=&quot;888&quot;&gt;커피 / 티 등 분류&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;972&quot; data-start=&quot;915&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;930&quot; data-start=&quot;915&quot;&gt;origin&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;944&quot; data-start=&quot;930&quot;&gt;VARCHAR&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;972&quot; data-start=&quot;944&quot;&gt;원산지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1026&quot; data-start=&quot;973&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;988&quot; data-start=&quot;973&quot;&gt;flavor_notes&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1002&quot; data-start=&quot;988&quot;&gt;TEXT&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1026&quot; data-start=&quot;1002&quot;&gt;향미 노트 (산미, 단맛 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1083&quot; data-start=&quot;1027&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1042&quot; data-start=&quot;1027&quot;&gt;caffeine&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1056&quot; data-start=&quot;1042&quot;&gt;BOOLEAN&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1083&quot; data-start=&quot;1056&quot;&gt;카페인 유무&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1143&quot; data-start=&quot;1084&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1099&quot; data-start=&quot;1084&quot;&gt;price&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1113&quot; data-start=&quot;1099&quot;&gt;INTEGER&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1143&quot; data-start=&quot;1113&quot;&gt;가격&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1201&quot; data-start=&quot;1144&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1159&quot; data-start=&quot;1144&quot;&gt;stock&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1173&quot; data-start=&quot;1159&quot;&gt;INTEGER&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1201&quot; data-start=&quot;1173&quot;&gt;재고 수량&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1259&quot; data-start=&quot;1202&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1217&quot; data-start=&quot;1202&quot;&gt;created_at&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1231&quot; data-start=&quot;1217&quot;&gt;TIMESTAMP&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1259&quot; data-start=&quot;1231&quot;&gt;등록일&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1264&quot; data-start=&quot;1261&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1296&quot; data-start=&quot;1266&quot; data-ke-size=&quot;size23&quot;&gt;  subscriptions (정기 구독)&lt;/h3&gt;
&lt;div&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; &amp;nbsp; &amp;nbsp; &amp;nbsp; 타입&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1848&quot; data-start=&quot;1297&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1848&quot; data-start=&quot;1420&quot;&gt;
&lt;tr data-end=&quot;1482&quot; data-start=&quot;1420&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1440&quot; data-start=&quot;1420&quot;&gt;id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1453&quot; data-start=&quot;1440&quot;&gt;PK&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1482&quot; data-start=&quot;1453&quot;&gt;구독 ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1544&quot; data-start=&quot;1483&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1503&quot; data-start=&quot;1483&quot;&gt;user_id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1516&quot; data-start=&quot;1503&quot;&gt;FK &amp;rarr; users&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1544&quot; data-start=&quot;1516&quot;&gt;구독자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1604&quot; data-start=&quot;1545&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1565&quot; data-start=&quot;1545&quot;&gt;product_id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1581&quot; data-start=&quot;1565&quot;&gt;FK &amp;rarr; products&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1604&quot; data-start=&quot;1581&quot;&gt;구독 상품&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1663&quot; data-start=&quot;1605&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1625&quot; data-start=&quot;1605&quot;&gt;interval&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1638&quot; data-start=&quot;1625&quot;&gt;VARCHAR&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1663&quot; data-start=&quot;1638&quot;&gt;주기 (1주, 2주, 4주 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1728&quot; data-start=&quot;1664&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1684&quot; data-start=&quot;1664&quot;&gt;status&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1697&quot; data-start=&quot;1684&quot;&gt;ENUM&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1728&quot; data-start=&quot;1697&quot;&gt;active, paused, cancelled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1786&quot; data-start=&quot;1729&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1749&quot; data-start=&quot;1729&quot;&gt;next_delivery_date&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1762&quot; data-start=&quot;1749&quot;&gt;DATE&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1786&quot; data-start=&quot;1762&quot;&gt;다음 배송 예정일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1848&quot; data-start=&quot;1787&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1807&quot; data-start=&quot;1787&quot;&gt;created_at&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1820&quot; data-start=&quot;1807&quot;&gt;TIMESTAMP&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1848&quot; data-start=&quot;1820&quot;&gt;생성일&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1853&quot; data-start=&quot;1850&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1875&quot; data-start=&quot;1855&quot; data-ke-size=&quot;size23&quot;&gt;  orders (주문)&lt;/h3&gt;
&lt;div&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; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &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;/div&gt;
&lt;div&gt;&lt;br /&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2386&quot; data-start=&quot;1876&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;2386&quot; data-start=&quot;2005&quot;&gt;
&lt;tr data-end=&quot;2070&quot; data-start=&quot;2005&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2024&quot; data-start=&quot;2005&quot;&gt;id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2039&quot; data-start=&quot;2024&quot;&gt;PK&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2070&quot; data-start=&quot;2039&quot;&gt;주문 ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2135&quot; data-start=&quot;2071&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2090&quot; data-start=&quot;2071&quot;&gt;user_id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2105&quot; data-start=&quot;2090&quot;&gt;FK &amp;rarr; users&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2135&quot; data-start=&quot;2105&quot;&gt;주문자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2194&quot; data-start=&quot;2136&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2155&quot; data-start=&quot;2136&quot;&gt;subscription_id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2176&quot; data-start=&quot;2155&quot;&gt;FK &amp;rarr; subscriptions&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2194&quot; data-start=&quot;2176&quot;&gt;어떤 구독에서 생성된 주문&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2257&quot; data-start=&quot;2195&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2214&quot; data-start=&quot;2195&quot;&gt;total_price&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2229&quot; data-start=&quot;2214&quot;&gt;INTEGER&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2257&quot; data-start=&quot;2229&quot;&gt;총 주문 금액&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2321&quot; data-start=&quot;2258&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2277&quot; data-start=&quot;2258&quot;&gt;status&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2292&quot; data-start=&quot;2277&quot;&gt;ENUM&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2321&quot; data-start=&quot;2292&quot;&gt;주문 상태 (created, shipped)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2386&quot; data-start=&quot;2322&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2341&quot; data-start=&quot;2322&quot;&gt;ordered_at&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2356&quot; data-start=&quot;2341&quot;&gt;TIMESTAMP&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2386&quot; data-start=&quot;2356&quot;&gt;주문일&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;2391&quot; data-start=&quot;2388&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2418&quot; data-start=&quot;2393&quot; data-ke-size=&quot;size23&quot;&gt;  payments (결제 정보)&lt;/h3&gt;
&lt;div&gt;&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&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; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;타입&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &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;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2882&quot; data-start=&quot;2419&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;2882&quot; data-start=&quot;2536&quot;&gt;
&lt;tr data-end=&quot;2595&quot; data-start=&quot;2536&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2552&quot; data-start=&quot;2536&quot;&gt;id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2567&quot; data-start=&quot;2552&quot;&gt;PK&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2595&quot; data-start=&quot;2567&quot;&gt;결제 ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2653&quot; data-start=&quot;2596&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2612&quot; data-start=&quot;2596&quot;&gt;order_id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2627&quot; data-start=&quot;2612&quot;&gt;FK &amp;rarr; orders&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2653&quot; data-start=&quot;2627&quot;&gt;해당 주문&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2711&quot; data-start=&quot;2654&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2670&quot; data-start=&quot;2654&quot;&gt;status&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2685&quot; data-start=&quot;2670&quot;&gt;ENUM&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2711&quot; data-start=&quot;2685&quot;&gt;성공/실패&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2766&quot; data-start=&quot;2712&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2728&quot; data-start=&quot;2712&quot;&gt;payment_method&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2743&quot; data-start=&quot;2728&quot;&gt;VARCHAR&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2766&quot; data-start=&quot;2743&quot;&gt;카드, 계좌이체 등&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2824&quot; data-start=&quot;2767&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2783&quot; data-start=&quot;2767&quot;&gt;payment_date&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2798&quot; data-start=&quot;2783&quot;&gt;TIMESTAMP&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2824&quot; data-start=&quot;2798&quot;&gt;결제 일시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2882&quot; data-start=&quot;2825&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2841&quot; data-start=&quot;2825&quot;&gt;amount&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2856&quot; data-start=&quot;2841&quot;&gt;INTEGER&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2882&quot; data-start=&quot;2856&quot;&gt;결제 금액&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;2887&quot; data-start=&quot;2884&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2919&quot; data-start=&quot;2889&quot; data-ke-size=&quot;size23&quot;&gt;  delivery_logs (배송 이력)&lt;/h3&gt;
&lt;div&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; &amp;nbsp; &amp;nbsp;타입&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &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;/div&gt;
&lt;div&gt;&lt;br /&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;3326&quot; data-start=&quot;2920&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;3326&quot; data-start=&quot;3041&quot;&gt;
&lt;tr data-end=&quot;3100&quot; data-start=&quot;3041&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3058&quot; data-start=&quot;3041&quot;&gt;id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3073&quot; data-start=&quot;3058&quot;&gt;PK&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3100&quot; data-start=&quot;3073&quot;&gt;배송 이력 ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3153&quot; data-start=&quot;3101&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3118&quot; data-start=&quot;3101&quot;&gt;order_id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3133&quot; data-start=&quot;3118&quot;&gt;FK &amp;rarr; orders&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3153&quot; data-start=&quot;3133&quot;&gt;어떤 주문에 대한 배송인지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3207&quot; data-start=&quot;3154&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3171&quot; data-start=&quot;3154&quot;&gt;status&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3186&quot; data-start=&quot;3171&quot;&gt;ENUM&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3207&quot; data-start=&quot;3186&quot;&gt;배송 상태 (준비중, 배송중 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3267&quot; data-start=&quot;3208&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3225&quot; data-start=&quot;3208&quot;&gt;tracking_number&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3240&quot; data-start=&quot;3225&quot;&gt;VARCHAR&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3267&quot; data-start=&quot;3240&quot;&gt;송장 번호&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3326&quot; data-start=&quot;3268&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3285&quot; data-start=&quot;3268&quot;&gt;delivery_date&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3300&quot; data-start=&quot;3285&quot;&gt;TIMESTAMP&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3326&quot; data-start=&quot;3300&quot;&gt;배송 완료일&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;3331&quot; data-start=&quot;3328&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3356&quot; data-start=&quot;3333&quot; data-ke-size=&quot;size23&quot;&gt;⭐ reviews (상품 후기)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&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; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &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;/div&gt;
&lt;div&gt;&lt;br /&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;3840&quot; data-start=&quot;3357&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;3840&quot; data-start=&quot;3478&quot;&gt;
&lt;tr data-end=&quot;3539&quot; data-start=&quot;3478&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3494&quot; data-start=&quot;3478&quot;&gt;id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3511&quot; data-start=&quot;3494&quot;&gt;PK&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3539&quot; data-start=&quot;3511&quot;&gt;리뷰 ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3600&quot; data-start=&quot;3540&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3556&quot; data-start=&quot;3540&quot;&gt;user_id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3573&quot; data-start=&quot;3556&quot;&gt;FK &amp;rarr; users&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3600&quot; data-start=&quot;3573&quot;&gt;작성자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3658&quot; data-start=&quot;3601&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3617&quot; data-start=&quot;3601&quot;&gt;product_id&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3634&quot; data-start=&quot;3617&quot;&gt;FK &amp;rarr; products&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3658&quot; data-start=&quot;3634&quot;&gt;후기 대상 상품&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3720&quot; data-start=&quot;3659&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3675&quot; data-start=&quot;3659&quot;&gt;rating&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3692&quot; data-start=&quot;3675&quot;&gt;INTEGER (1~5)&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3720&quot; data-start=&quot;3692&quot;&gt;별점&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3779&quot; data-start=&quot;3721&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3737&quot; data-start=&quot;3721&quot;&gt;comment&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3754&quot; data-start=&quot;3737&quot;&gt;TEXT&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3779&quot; data-start=&quot;3754&quot;&gt;텍스트 후기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3840&quot; data-start=&quot;3780&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3796&quot; data-start=&quot;3780&quot;&gt;created_at&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3813&quot; data-start=&quot;3796&quot;&gt;TIMESTAMP&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3840&quot; data-start=&quot;3813&quot;&gt;작성일&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;3845&quot; data-start=&quot;3842&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3858&quot; data-start=&quot;3847&quot; data-ke-size=&quot;size26&quot;&gt;  관계 요약&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4052&quot; data-start=&quot;3860&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3916&quot; data-start=&quot;3860&quot;&gt;users &amp;harr; subscriptions, orders, reviews 와 1:N&lt;/li&gt;
&lt;li data-end=&quot;3966&quot; data-start=&quot;3917&quot;&gt;products &amp;harr; subscriptions, reviews 와 1:N&lt;/li&gt;
&lt;li data-end=&quot;4003&quot; data-start=&quot;3967&quot;&gt;subscriptions &amp;harr; orders 와 1:N&lt;/li&gt;
&lt;li data-end=&quot;4052&quot; data-start=&quot;4004&quot;&gt;orders &amp;harr; payments, delivery_logs 와 1:1&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Development/Project</category>
      <author>yjym33</author>
      <guid isPermaLink="true">https://yjym33.tistory.com/174</guid>
      <comments>https://yjym33.tistory.com/174#entry174comment</comments>
      <pubDate>Sat, 10 May 2025 23:37:56 +0900</pubDate>
    </item>
    <item>
      <title>커피/티 원두 정기 구독 쇼핑몰 - 기획서</title>
      <link>https://yjym33.tistory.com/172</link>
      <description>&lt;h3 data-end=&quot;159&quot; data-start=&quot;145&quot; data-ke-size=&quot;size23&quot;&gt;1. 프로젝트 개요&lt;/h3&gt;
&lt;p data-end=&quot;231&quot; data-start=&quot;161&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;목표:&lt;/b&gt;&lt;br /&gt;사용자의 커피/티 취향 및 소비 패턴에 맞춰 개인화된 원두 구독 서비스를 제공하는 지능형 쇼핑몰 플랫폼 개발&lt;/p&gt;
&lt;p data-end=&quot;245&quot; data-start=&quot;233&quot; 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-end=&quot;418&quot; data-start=&quot;246&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;290&quot; data-start=&quot;246&quot;&gt;사용자 맞춤형 정기 구독 상품 추천 (맛, 향, 산미 기반 선호도 분석)&lt;/li&gt;
&lt;li data-end=&quot;314&quot; data-start=&quot;291&quot;&gt;배송 주기 설정 및 자동 결제 기능&lt;/li&gt;
&lt;li data-end=&quot;346&quot; data-start=&quot;315&quot;&gt;마이페이지 구독 관리 (일시 정지, 변경, 취소)&lt;/li&gt;
&lt;li data-end=&quot;367&quot; data-start=&quot;347&quot;&gt;후기 기반 상품 추천 알고리즘&lt;/li&gt;
&lt;li data-end=&quot;387&quot; data-start=&quot;368&quot;&gt;관리자 상품/구독 관리 기능&lt;/li&gt;
&lt;li data-end=&quot;418&quot; data-start=&quot;388&quot;&gt;향후 추천 알고리즘/기계학습 기반 최적화 기능 연동&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;423&quot; data-start=&quot;420&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;437&quot; data-start=&quot;425&quot; data-ke-size=&quot;size23&quot;&gt;2. 구축 전략&lt;/h3&gt;
&lt;h4 data-end=&quot;460&quot; data-start=&quot;439&quot; data-ke-size=&quot;size20&quot;&gt;2-1. 정기 구독 중심 설계&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;559&quot; data-start=&quot;461&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;510&quot; data-start=&quot;461&quot;&gt;구독은 단순 구매와 달리 &lt;b&gt;정기 반복성&lt;/b&gt;과 &lt;b&gt;사용자 커스터마이징&lt;/b&gt; 요소를 강조&lt;/li&gt;
&lt;li data-end=&quot;559&quot; data-start=&quot;511&quot;&gt;사용자 선호도 설문 기반으로 추천 초기화 후, 리뷰/구매 이력을 통한 지속적 개인화&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;580&quot; data-start=&quot;561&quot; data-ke-size=&quot;size20&quot;&gt;2-2. 개인화 추천 기능&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;662&quot; data-start=&quot;581&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;618&quot; data-start=&quot;581&quot;&gt;초기: 조건 기반 추천 (산미/바디감/카페인 유무 등 필터)&lt;/li&gt;
&lt;li data-end=&quot;662&quot; data-start=&quot;619&quot;&gt;확장: 유저 피드백 + 행동 데이터를 벡터로 변환해 유사 사용자 기반 추천&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;676&quot; data-start=&quot;664&quot; 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-end=&quot;760&quot; data-start=&quot;677&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;722&quot; data-start=&quot;677&quot;&gt;&amp;ldquo;산미 있는 원두 좋아함 + 오후에 마신다&amp;rdquo; &amp;rarr; 디카페인 과일향 원두 추천&lt;/li&gt;
&lt;li data-end=&quot;760&quot; data-start=&quot;723&quot;&gt;&amp;ldquo;블렌딩보단 싱글 오리진 선호&amp;rdquo; &amp;rarr; 상품 필터링 + 신상품 추천&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;790&quot; data-start=&quot;762&quot; data-ke-size=&quot;size20&quot;&gt;2-3. 정기 결제 자동화 및 유연한 관리&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;866&quot; data-start=&quot;791&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;818&quot; data-start=&quot;791&quot;&gt;결제는 주기(1/2/4주) 단위 자동 스케줄링&lt;/li&gt;
&lt;li data-end=&quot;866&quot; data-start=&quot;819&quot;&gt;마이페이지에서 사용자가 쉽게 &lt;b&gt;주문 일시정지 / 재개 / 변경 / 취소&lt;/b&gt; 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;871&quot; data-start=&quot;868&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;891&quot; data-start=&quot;873&quot; data-ke-size=&quot;size23&quot;&gt;3. 도메인별 데이터 구성&lt;/h3&gt;
&lt;h4 data-end=&quot;909&quot; data-start=&quot;893&quot; data-ke-size=&quot;size20&quot;&gt;3-1. 상품 도메인&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;973&quot; data-start=&quot;910&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;944&quot; data-start=&quot;910&quot;&gt;원두명, 로스팅일자, 향미 노트, 산지, 산미/바디감 지수&lt;/li&gt;
&lt;li data-end=&quot;973&quot; data-start=&quot;945&quot;&gt;카페인 유무, 적정 소비 시기, 이미지 및 설명&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;992&quot; data-start=&quot;975&quot; data-ke-size=&quot;size20&quot;&gt;3-2. 사용자 도메인&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1064&quot; data-start=&quot;993&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1023&quot; data-start=&quot;993&quot;&gt;취향 설문 데이터 (선호 향미/농도/마시는 시간대)&lt;/li&gt;
&lt;li data-end=&quot;1051&quot; data-start=&quot;1024&quot;&gt;구독 상태(활성/일시정지/취소), 배송지 정보&lt;/li&gt;
&lt;li data-end=&quot;1064&quot; data-start=&quot;1052&quot;&gt;리뷰 및 구매 이력&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;1085&quot; data-start=&quot;1066&quot; data-ke-size=&quot;size20&quot;&gt;3-3. 구독/결제 도메인&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1140&quot; data-start=&quot;1086&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1109&quot; data-start=&quot;1086&quot;&gt;구독 시작일, 주기 설정, 다음 결제일&lt;/li&gt;
&lt;li data-end=&quot;1140&quot; data-start=&quot;1110&quot;&gt;결제 실패 처리 로직, 자동 리트라이 시나리오 포함&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1145&quot; data-start=&quot;1142&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1164&quot; data-start=&quot;1147&quot; data-ke-size=&quot;size23&quot;&gt;4. 기술 스택 (예정)&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;범주기술 스택 예시
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1579&quot; data-start=&quot;1166&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1579&quot; data-start=&quot;1222&quot;&gt;
&lt;tr data-end=&quot;1266&quot; data-start=&quot;1222&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1235&quot; data-start=&quot;1222&quot;&gt;Frontend&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;1266&quot; data-start=&quot;1235&quot;&gt;Next.js, React, TailwindCSS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1321&quot; data-start=&quot;1267&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1280&quot; data-start=&quot;1267&quot;&gt;Backend&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;1321&quot; data-start=&quot;1280&quot;&gt;Spring Boot (추후 MSA 고려), 또는 초기 NestJS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1349&quot; data-start=&quot;1322&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1335&quot; data-start=&quot;1322&quot;&gt;DB&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;1349&quot; data-start=&quot;1335&quot;&gt;PostgreSQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1399&quot; data-start=&quot;1350&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1363&quot; data-start=&quot;1350&quot;&gt;ORM&lt;/td&gt;
&lt;td data-end=&quot;1399&quot; data-start=&quot;1363&quot; data-col-size=&quot;md&quot;&gt;JPA (Spring) or TypeORM (NestJS)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1425&quot; data-start=&quot;1400&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1411&quot; data-start=&quot;1400&quot;&gt;인증&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;1425&quot; data-start=&quot;1411&quot;&gt;JWT 기반 로그인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1470&quot; data-start=&quot;1426&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1435&quot; data-start=&quot;1426&quot;&gt;스케줄링&lt;/td&gt;
&lt;td data-end=&quot;1470&quot; data-start=&quot;1435&quot; data-col-size=&quot;md&quot;&gt;Spring Scheduler 또는 배치 기반 정기 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1531&quot; data-start=&quot;1471&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1480&quot; data-start=&quot;1471&quot;&gt;추천 기능&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;1531&quot; data-start=&quot;1480&quot;&gt;간단한 필터 기반 추천 &amp;rarr; 확장 시 FAISS or Qdrant + Embedding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1579&quot; data-start=&quot;1532&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1543&quot; data-start=&quot;1532&quot;&gt;배포&lt;/td&gt;
&lt;td data-end=&quot;1579&quot; data-start=&quot;1543&quot; data-col-size=&quot;md&quot;&gt;Docker, Nginx, AWS EC2 or Render&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1584&quot; data-start=&quot;1581&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1598&quot; data-start=&quot;1586&quot; data-ke-size=&quot;size23&quot;&gt;5. 기대 효과&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1763&quot; data-start=&quot;1600&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1633&quot; data-start=&quot;1600&quot;&gt;커피 취향 파악부터 배송까지 자동화된 구독 경험 제공&lt;/li&gt;
&lt;li data-end=&quot;1673&quot; data-start=&quot;1634&quot;&gt;커뮤니티 기반 추천이 아닌, &lt;b&gt;개인화된 상품 큐레이션&lt;/b&gt; 제공&lt;/li&gt;
&lt;li data-end=&quot;1716&quot; data-start=&quot;1674&quot;&gt;반복 주문의 편의성과 맞춤 추천으로 &lt;b&gt;구매 전환율과 충성도&lt;/b&gt; 향상&lt;/li&gt;
&lt;li data-end=&quot;1763&quot; data-start=&quot;1717&quot;&gt;스케줄링 처리와 추천 시스템 등 &lt;b&gt;기술적 완성도 높은 포트폴리오 구성 가능&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1768&quot; data-start=&quot;1765&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1782&quot; data-start=&quot;1770&quot; data-ke-size=&quot;size23&quot;&gt;6. 향후 계획&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2007&quot; data-start=&quot;1784&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1835&quot; data-start=&quot;1784&quot;&gt;MVP: 기본 CRUD + 정기 구독 관리 기능 구현 (Spring or Nest 기반)&lt;/li&gt;
&lt;li data-end=&quot;1856&quot; data-start=&quot;1836&quot;&gt;사용자 설문 기반 추천 기능 구현&lt;/li&gt;
&lt;li data-end=&quot;1893&quot; data-start=&quot;1857&quot;&gt;결제 시스템 API 연동 (가상 결제 or 모의 처리로 시작)&lt;/li&gt;
&lt;li data-end=&quot;1925&quot; data-start=&quot;1894&quot;&gt;유저 기반 구매/후기 데이터를 활용한 추천 기능 개선&lt;/li&gt;
&lt;li data-end=&quot;1964&quot; data-start=&quot;1926&quot;&gt;멀티 벡터 기반 추천 알고리즘 실험 (RAG-like 구조 가능)&lt;/li&gt;
&lt;li data-end=&quot;2007&quot; data-start=&quot;1965&quot;&gt;데이터/트래픽 증가 시 &lt;b&gt;마이크로서비스 아키텍처(MSA)&lt;/b&gt; 도입 고려&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2012&quot; data-start=&quot;2009&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2037&quot; data-start=&quot;2014&quot; data-ke-size=&quot;size23&quot;&gt;  선택 시나리오 기반 확장 예시&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;사용자 행동예상 기능 확장
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2234&quot; data-start=&quot;2039&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;2234&quot; data-start=&quot;2095&quot;&gt;
&lt;tr data-end=&quot;2130&quot; data-start=&quot;2095&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2110&quot; data-start=&quot;2095&quot;&gt;구독 취소/변경이 많음&lt;/td&gt;
&lt;td data-end=&quot;2130&quot; data-start=&quot;2110&quot; data-col-size=&quot;sm&quot;&gt;UX 개선 + 추천 품질 개선&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2166&quot; data-start=&quot;2131&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2145&quot; data-start=&quot;2131&quot;&gt;특정 원두 선호 높음&lt;/td&gt;
&lt;td data-end=&quot;2166&quot; data-start=&quot;2145&quot; data-col-size=&quot;sm&quot;&gt;인기 랭킹, 재입고 알림 시스템&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2202&quot; data-start=&quot;2167&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2179&quot; data-start=&quot;2167&quot;&gt;다양한 취향 요청&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2202&quot; data-start=&quot;2179&quot;&gt;상품 메타데이터 강화 + 추천 개선&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2234&quot; data-start=&quot;2203&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2217&quot; data-start=&quot;2203&quot;&gt;단일 상품 반복 구매&lt;/td&gt;
&lt;td data-end=&quot;2234&quot; data-start=&quot;2217&quot; data-col-size=&quot;sm&quot;&gt;단품 정기구매 기능 추가&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Development/Project</category>
      <author>yjym33</author>
      <guid isPermaLink="true">https://yjym33.tistory.com/172</guid>
      <comments>https://yjym33.tistory.com/172#entry172comment</comments>
      <pubDate>Sat, 10 May 2025 22:20:06 +0900</pubDate>
    </item>
    <item>
      <title>대화형 AI 구축 프로젝트 - 기획서</title>
      <link>https://yjym33.tistory.com/170</link>
      <description>&lt;p data-pm-slice=&quot;1 3 []&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;아래는 개인프로젝트로 사용할 프로젝트를 기획하기 위해 작성한 내용입니다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;189&quot; data-start=&quot;137&quot; data-ke-size=&quot;size26&quot;&gt;  기획서 ① &amp;ndash; 기억하는 AI 친구 (Persistent Memory Chatbot)&lt;/h2&gt;
&lt;h3 data-end=&quot;205&quot; data-start=&quot;191&quot; data-ke-size=&quot;size23&quot;&gt;1. 프로젝트 개요&lt;/h3&gt;
&lt;p data-end=&quot;285&quot; data-start=&quot;207&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;285&quot; data-start=&quot;207&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;목표&lt;/b&gt;&lt;br /&gt;사용자와 지속적인 관계를 형성하며, 이전 대화 내용을 기억하고 그에 맞는 응답을 제공하는 &lt;b&gt;지속형 감성 대화 AI&lt;/b&gt; 개발&lt;/p&gt;
&lt;p data-end=&quot;285&quot; data-start=&quot;207&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;296&quot; data-start=&quot;287&quot; 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-end=&quot;422&quot; data-start=&quot;297&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;334&quot; data-start=&quot;297&quot;&gt;사용자 정보, 감정 상태, 관심사 등을 기억하고 자연스럽게 반영&lt;/li&gt;
&lt;li data-end=&quot;354&quot; data-start=&quot;335&quot;&gt;자유로운 일상 대화와 감정 공감&lt;/li&gt;
&lt;li data-end=&quot;400&quot; data-start=&quot;355&quot;&gt;관계 기반의 대화 흐름 (예: &amp;ldquo;지난번에 피곤하다고 했었지? 좀 나아졌어?&amp;rdquo;)&lt;/li&gt;
&lt;li data-end=&quot;422&quot; data-start=&quot;401&quot;&gt;캐릭터 말투/성격 커스터마이징 기능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;441&quot; data-start=&quot;429&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;441&quot; data-start=&quot;429&quot; data-ke-size=&quot;size23&quot;&gt;2. 구축 전략&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;462&quot; data-start=&quot;443&quot; data-ke-size=&quot;size20&quot;&gt;2-1. LLM 기반 설계&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;579&quot; data-start=&quot;463&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;512&quot; data-start=&quot;463&quot;&gt;OpenAI GPT API 또는 오픈소스 LLM(Mistral, LLaMA 등) 활용&lt;/li&gt;
&lt;li data-end=&quot;549&quot; data-start=&quot;513&quot;&gt;사용자별 프롬프트 설정 또는 컨텍스트 리트리버 기반 기억 삽입&lt;/li&gt;
&lt;li data-end=&quot;579&quot; data-start=&quot;550&quot;&gt;감성 필터링을 통한 위로, 공감 중심의 응답 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;600&quot; data-start=&quot;581&quot; data-ke-size=&quot;size20&quot;&gt;2-2. 기억 시스템 구조&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;720&quot; data-start=&quot;601&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;658&quot; data-start=&quot;601&quot;&gt;Vector DB(Weaviate, FAISS, Qdrant 등)에 유저 발화 및 요약 임베딩 저장&lt;/li&gt;
&lt;li data-end=&quot;685&quot; data-start=&quot;659&quot;&gt;시간, 주제, 감정 중심으로 대화 요약/태깅&lt;/li&gt;
&lt;li data-end=&quot;720&quot; data-start=&quot;686&quot;&gt;현재 대화와 유의미한 기억만 유사도 기반으로 검색하여 삽입&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;741&quot; data-start=&quot;722&quot; data-ke-size=&quot;size20&quot;&gt;2-3. 대화 흐름 최적화&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;849&quot; data-start=&quot;742&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;769&quot; data-start=&quot;742&quot;&gt;LangChain 기반 메모리 체인 구조 적용&lt;/li&gt;
&lt;li data-end=&quot;812&quot; data-start=&quot;770&quot;&gt;유저 프로필 + 대화 이력을 기반으로 자동 성격 분석 or 프롬프트 조정&lt;/li&gt;
&lt;li data-end=&quot;849&quot; data-start=&quot;813&quot;&gt;&amp;lsquo;기억에 남는 일&amp;rsquo;이나 &amp;lsquo;중요한 대화&amp;rsquo;는 수동 저장 기능 고려&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;873&quot; data-start=&quot;856&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;873&quot; data-start=&quot;856&quot; data-ke-size=&quot;size23&quot;&gt;3. 기술 스택 (예정)&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;범주기술 스택
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1203&quot; data-start=&quot;875&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1203&quot; data-start=&quot;925&quot;&gt;
&lt;tr data-end=&quot;971&quot; data-start=&quot;925&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;939&quot; data-start=&quot;925&quot;&gt;LLM&lt;/td&gt;
&lt;td data-end=&quot;971&quot; data-start=&quot;939&quot; data-col-size=&quot;sm&quot;&gt;OpenAI GPT, Mistral, LLaMA 등&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1005&quot; data-start=&quot;972&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;986&quot; data-start=&quot;972&quot;&gt;Vector DB&lt;/td&gt;
&lt;td data-end=&quot;1005&quot; data-start=&quot;986&quot; data-col-size=&quot;sm&quot;&gt;FAISS, Weaviate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1051&quot; data-start=&quot;1006&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1020&quot; data-start=&quot;1006&quot;&gt;Embedding&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1051&quot; data-start=&quot;1020&quot;&gt;OpenAI Embedding, BGE, E5 등&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1090&quot; data-start=&quot;1052&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1066&quot; data-start=&quot;1052&quot;&gt;Agent&lt;/td&gt;
&lt;td data-end=&quot;1090&quot; data-start=&quot;1066&quot; data-col-size=&quot;sm&quot;&gt;LangChain, LangGraph&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1123&quot; data-start=&quot;1091&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1105&quot; data-start=&quot;1091&quot;&gt;Frontend&lt;/td&gt;
&lt;td data-end=&quot;1123&quot; data-start=&quot;1105&quot; data-col-size=&quot;sm&quot;&gt;React, Next.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1148&quot; data-start=&quot;1124&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1138&quot; data-start=&quot;1124&quot;&gt;Backend&lt;/td&gt;
&lt;td data-end=&quot;1148&quot; data-start=&quot;1138&quot; data-col-size=&quot;sm&quot;&gt;NestJS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1177&quot; data-start=&quot;1149&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1163&quot; data-start=&quot;1149&quot;&gt;Database&lt;/td&gt;
&lt;td data-end=&quot;1177&quot; data-start=&quot;1163&quot; data-col-size=&quot;sm&quot;&gt;PostgreSQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1203&quot; data-start=&quot;1178&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1192&quot; data-start=&quot;1178&quot;&gt;ORM&lt;/td&gt;
&lt;td data-end=&quot;1203&quot; data-start=&quot;1192&quot; data-col-size=&quot;sm&quot;&gt;TypeORM&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;1222&quot; data-start=&quot;1210&quot; data-ke-size=&quot;size23&quot;&gt;4. 기대 효과&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1339&quot; data-start=&quot;1224&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1249&quot; data-start=&quot;1224&quot;&gt;&amp;ldquo;인간처럼 기억하는 AI 친구&amp;rdquo; UX 실현&lt;/li&gt;
&lt;li data-end=&quot;1279&quot; data-start=&quot;1250&quot;&gt;단순 대화형 챗봇보다 깊이 있는 사용자 경험 제공&lt;/li&gt;
&lt;li data-end=&quot;1311&quot; data-start=&quot;1280&quot;&gt;개인화된 감정 AI 경험 &amp;rarr; 높은 사용자 재방문 유도&lt;/li&gt;
&lt;li data-end=&quot;1339&quot; data-start=&quot;1312&quot;&gt;개인화 기술/메모리 관리 기술 역량 어필 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1358&quot; data-start=&quot;1346&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;1358&quot; data-start=&quot;1346&quot; data-ke-size=&quot;size23&quot;&gt;5. 향후 계획&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1489&quot; data-start=&quot;1360&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1378&quot; data-start=&quot;1360&quot;&gt;텍스트 기반 챗봇 MVP 제작&lt;/li&gt;
&lt;li data-end=&quot;1401&quot; data-start=&quot;1379&quot;&gt;대화 요약/저장 최적화 알고리즘 개선&lt;/li&gt;
&lt;li data-end=&quot;1426&quot; data-start=&quot;1402&quot;&gt;유저 감정 분석 및 성격 분류 기능 추가&lt;/li&gt;
&lt;li data-end=&quot;1442&quot; data-start=&quot;1427&quot;&gt;말투/캐릭터 프리셋 도입&lt;/li&gt;
&lt;li data-end=&quot;1489&quot; data-start=&quot;1443&quot;&gt;장기 대화 흐름 시각화 및 리뷰 기능 (ex. &amp;ldquo;우리가 나눈 이야기들&amp;rdquo; 페이지)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1546&quot; data-start=&quot;1496&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;1546&quot; data-start=&quot;1496&quot; data-ke-size=&quot;size23&quot;&gt;6. 에이전트 기능 설계 &amp;ndash; 라이프 코치 에이전트 (Life Coach Agent)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1717&quot; data-start=&quot;1548&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;도입 배경&lt;/b&gt;&lt;br /&gt;기억 기반 챗봇이 단순히 대화에 응답하는 수준을 넘어서 &lt;b&gt;사용자의 삶에 개입하고 정서적으로 챙겨주는 조력자 역할&lt;/b&gt;을 수행하면, &amp;lsquo;AI 친구&amp;rsquo;의 몰입도가 훨씬 높아질수 있기 때문에 이를 위해 LangGraph를 활용한 상태기반 에이전트 구조로 &lt;b&gt;라이프 코치 에이전트&lt;/b&gt;를 설계합니다.&lt;/p&gt;
&lt;p data-end=&quot;1717&quot; data-start=&quot;1548&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;1737&quot; data-start=&quot;1724&quot; data-ke-size=&quot;size20&quot;&gt;  핵심 역할&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1824&quot; data-start=&quot;1738&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1768&quot; data-start=&quot;1738&quot;&gt;사용자의 목표/루틴/습관을 기억하고 주기적으로 점검&lt;/li&gt;
&lt;li data-end=&quot;1795&quot; data-start=&quot;1769&quot;&gt;감정 상태 변화에 따라 챙김/격려/위로 제공&lt;/li&gt;
&lt;li data-end=&quot;1824&quot; data-start=&quot;1796&quot;&gt;중요한 대화/목표에 대해 follow-up 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;1844&quot; data-start=&quot;1831&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;1844&quot; data-start=&quot;1831&quot; data-ke-size=&quot;size20&quot;&gt;  기능 구성&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;기능 범주설명
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2094&quot; data-start=&quot;1846&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;2094&quot; data-start=&quot;1892&quot;&gt;
&lt;tr data-end=&quot;1940&quot; data-start=&quot;1892&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1904&quot; data-start=&quot;1892&quot;&gt;목표 추적&lt;/td&gt;
&lt;td data-end=&quot;1940&quot; data-start=&quot;1904&quot; data-col-size=&quot;md&quot;&gt;&quot;다이어트 시작할 거야&quot; &amp;rarr; goal: 다이어트로 저장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1998&quot; data-start=&quot;1941&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1951&quot; data-start=&quot;1941&quot;&gt;감정 모니터링&lt;/td&gt;
&lt;td data-end=&quot;1998&quot; data-start=&quot;1951&quot; data-col-size=&quot;md&quot;&gt;&quot;요즘 너무 힘들어&quot; &amp;rarr; emotion: sad 저장 + follow-up&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2042&quot; data-start=&quot;1999&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2011&quot; data-start=&quot;1999&quot;&gt;챙김 응답&lt;/td&gt;
&lt;td data-end=&quot;2042&quot; data-start=&quot;2011&quot; data-col-size=&quot;md&quot;&gt;일정 시점 이후 자동 follow-up 대화 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2094&quot; data-start=&quot;2043&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2055&quot; data-start=&quot;2043&quot;&gt;관계 유지&lt;/td&gt;
&lt;td data-end=&quot;2094&quot; data-start=&quot;2055&quot; data-col-size=&quot;md&quot;&gt;&amp;ldquo;저번에 말한 시험 준비 잘 되고 있어?&amp;rdquo; 등 기억 기반 피드백&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;2099&quot; data-start=&quot;2096&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;2124&quot; data-start=&quot;2101&quot; data-ke-size=&quot;size20&quot;&gt;  LangGraph 흐름 구성&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;378&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWwPMk/btsOmNZkyqb/E1wzMcCRzxSavklcxCKko1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWwPMk/btsOmNZkyqb/E1wzMcCRzxSavklcxCKko1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWwPMk/btsOmNZkyqb/E1wzMcCRzxSavklcxCKko1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWwPMk%2FbtsOmNZkyqb%2FE1wzMcCRzxSavklcxCKko1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;732&quot; height=&quot;378&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;378&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote data-end=&quot;2518&quot; data-start=&quot;2454&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2518&quot; data-start=&quot;2456&quot; data-ke-size=&quot;size16&quot;&gt;각 노드는 LangGraph에서 상태 기계(State Machine) 노드로 정의되며, Intent에 따라 분기&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 data-end=&quot;2542&quot; data-start=&quot;2525&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;2542&quot; data-start=&quot;2525&quot; data-ke-size=&quot;size20&quot;&gt; ️ 예시 대화 흐름&lt;/h4&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;724&quot; data-origin-height=&quot;130&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DWfAj/btsOoneiJNl/pWdBBWPIaHvYkg599KI1MK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DWfAj/btsOoneiJNl/pWdBBWPIaHvYkg599KI1MK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DWfAj/btsOoneiJNl/pWdBBWPIaHvYkg599KI1MK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDWfAj%2FbtsOoneiJNl%2FpWdBBWPIaHvYkg599KI1MK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;724&quot; height=&quot;130&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;130&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-end=&quot;2737&quot; data-start=&quot;2721&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;2737&quot; data-start=&quot;2721&quot; data-ke-size=&quot;size20&quot;&gt;  기술 구성 요약&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;범주구성
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2968&quot; data-start=&quot;2739&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;2968&quot; data-start=&quot;2767&quot;&gt;
&lt;tr data-end=&quot;2791&quot; data-start=&quot;2767&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2773&quot; data-start=&quot;2767&quot;&gt;LLM&lt;/td&gt;
&lt;td data-end=&quot;2791&quot; data-start=&quot;2773&quot; data-col-size=&quot;sm&quot;&gt;GPT-4, Mistral&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2827&quot; data-start=&quot;2792&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2800&quot; data-start=&quot;2792&quot;&gt;Agent&lt;/td&gt;
&lt;td data-end=&quot;2827&quot; data-start=&quot;2800&quot; data-col-size=&quot;sm&quot;&gt;LangGraph (상태 분기 기반 처리)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2860&quot; data-start=&quot;2828&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2840&quot; data-start=&quot;2828&quot;&gt;Memory DB&lt;/td&gt;
&lt;td data-end=&quot;2860&quot; data-start=&quot;2840&quot; data-col-size=&quot;sm&quot;&gt;Weaviate, Qdrant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2900&quot; data-start=&quot;2861&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2873&quot; data-start=&quot;2861&quot;&gt;Embedding&lt;/td&gt;
&lt;td data-end=&quot;2900&quot; data-start=&quot;2873&quot; data-col-size=&quot;sm&quot;&gt;OpenAI Embedding or BGE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2930&quot; data-start=&quot;2901&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2908&quot; data-start=&quot;2901&quot;&gt;스케줄링&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2930&quot; data-start=&quot;2908&quot;&gt;내부 CRON / Temporal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2968&quot; data-start=&quot;2931&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2939&quot; data-start=&quot;2931&quot;&gt;대화 관리&lt;/td&gt;
&lt;td data-end=&quot;2968&quot; data-start=&quot;2939&quot; data-col-size=&quot;sm&quot;&gt;LangChain + NestJS API 연결&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-end=&quot;2988&quot; data-start=&quot;2975&quot; data-ke-size=&quot;size20&quot;&gt;  확장 방향&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3060&quot; data-start=&quot;2990&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3016&quot; data-start=&quot;2990&quot;&gt;사용자 루틴 진척도 시각화 (대시보드 형태)&lt;/li&gt;
&lt;li data-end=&quot;3035&quot; data-start=&quot;3017&quot;&gt;감정 변화 트래킹 그래프 생성&lt;/li&gt;
&lt;li data-end=&quot;3060&quot; data-start=&quot;3036&quot;&gt;장기 대화 히스토리 기반 추천/격려 기능&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Development/Project</category>
      <author>yjym33</author>
      <guid isPermaLink="true">https://yjym33.tistory.com/170</guid>
      <comments>https://yjym33.tistory.com/170#entry170comment</comments>
      <pubDate>Thu, 1 May 2025 22:55:44 +0900</pubDate>
    </item>
    <item>
      <title>패스트캠퍼스 (코드팩토리의 백엔드 아카데미 : 한 번에 끝내는 NestJS 패키지 - 기초부터 MSA까지) 수강후기</title>
      <link>https://yjym33.tistory.com/169</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20241202_223105211.jpg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mdrUn/btsK3tXTXwt/KDHVKkdaYKzeUqkkggvJMK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mdrUn/btsK3tXTXwt/KDHVKkdaYKzeUqkkggvJMK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mdrUn/btsK3tXTXwt/KDHVKkdaYKzeUqkkggvJMK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmdrUn%2FbtsK3tXTXwt%2FKDHVKkdaYKzeUqkkggvJMK%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;852&quot; height=&quot;639&quot; data-filename=&quot;KakaoTalk_20241202_223105211.jpg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20241202_223607984.jpg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xKH3F/btsK5O0cmm5/FSwtKtEwBeKkeaxqHKont1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xKH3F/btsK5O0cmm5/FSwtKtEwBeKkeaxqHKont1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xKH3F/btsK5O0cmm5/FSwtKtEwBeKkeaxqHKont1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxKH3F%2FbtsK5O0cmm5%2FFSwtKtEwBeKkeaxqHKont1%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;4032&quot; height=&quot;3024&quot; data-filename=&quot;KakaoTalk_20241202_223607984.jpg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&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;KakaoTalk_20241202_223720252.jpg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r5Bhy/btsK4zJT6vO/wuiPtwKwbwa3Zh2MI1hmtK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r5Bhy/btsK4zJT6vO/wuiPtwKwbwa3Zh2MI1hmtK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r5Bhy/btsK4zJT6vO/wuiPtwKwbwa3Zh2MI1hmtK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr5Bhy%2FbtsK4zJT6vO%2FwuiPtwKwbwa3Zh2MI1hmtK%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;4032&quot; height=&quot;3024&quot; data-filename=&quot;KakaoTalk_20241202_223720252.jpg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&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;현재까지 느낀점 + 앞으로의 목표 및 포부 &lt;br /&gt;&lt;br /&gt;현재 &quot;코드팩토리의 백엔드 아카데미: 한번에 끝내는 NestJS 패키지 - 기초부터 MSA까지&quot; 강의를 수강하며 NestJS의 기본 원리뿐만 아니라 다양한 기술 스택과 MSA 구조의 실무 적용 방식을 체계적으로 학습하고 있습니다. 특히, 실무에서 중요한 데브옵스까지도 다루며 CI/CD와 시스템 운영에 대한 이해를 넓힐 수 있어 매우 유익합니다. 앞으로 이 강의를 통해 MSA와 데브옵스를 완벽히 이해하고, 실제 프로젝트에서 고도화된 백엔드 시스템을 설계하며 전문성을 강화하고 싶습니다. 성장하는 개발자로 더 큰 가치를 창출하는 것이 목표입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 게시글은 패스트캠퍼스 후기 이벤트 참여를 위해 작성하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>yjym33</author>
      <guid isPermaLink="true">https://yjym33.tistory.com/169</guid>
      <comments>https://yjym33.tistory.com/169#entry169comment</comments>
      <pubDate>Mon, 2 Dec 2024 22:34:47 +0900</pubDate>
    </item>
    <item>
      <title>ReactQuery - useQuery</title>
      <link>https://yjym33.tistory.com/168</link>
      <description>&lt;h2 id=&quot;using-react-query&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Using React Query&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;install-react-query&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;install react-query&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 react-query를 설치하기 위해서 아래 명령어를 터미널에 입력해야 합니다.&lt;/p&gt;
&lt;pre class=&quot;css&quot; style=&quot;color: #212529; text-align: start;&quot;&gt;&lt;code&gt;npm install @tanstack/react-query&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;create-queryclient--queryclientprovider&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Create queryClient &amp;amp; QueryClientProvider&lt;/h3&gt;
&lt;p 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;QueryClient&lt;span&gt;&amp;nbsp;&lt;/span&gt;생성자로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;쿼리와 캐시를 관리&lt;/b&gt;하는 Query Client를 생성하고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;lt;QueryClientProvider&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;컴포넌트를 통해 생성한 Query Client를 하위 컴포넌트들이 접근할 수 있도록 최상위 컴포넌트로 감싸주어야 합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;모든 하위 컴포넌트들은 Query Client가 갖고 있는 캐시와 모든 기본 옵션을 사용할 수 있게 됩니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;참고로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;lt;QueryClientProvider&amp;gt;은 React의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Context API를 사용하여 생성된 queryClient를 제공&lt;/b&gt;합니다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;color: #212529; text-align: start;&quot;&gt;&lt;code&gt;import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

// 1. query client 생성
const queryClient = new QueryClient()

function App () {
  return (
    // 2. QueryClientProvider를 통해 하위 컴포넌트들에게 전달
    &amp;lt;QueryClientProvider client={queryClient}&amp;gt;
      ,,,
    &amp;lt;/QueryClientProvider&amp;gt;
  )
}

export default App;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;default-options&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Default Options&lt;/h3&gt;
&lt;p 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;QueryClient를 생성할 때 default option을 지정해 줄 수 있습니다. new 연산자와 함께 호출할 때 인수로 객체를 전달하고 객체의&lt;span&gt;&amp;nbsp;&lt;/span&gt;defaultOptions&lt;span&gt;&amp;nbsp;&lt;/span&gt;프로퍼티로&lt;span&gt;&amp;nbsp;&lt;/span&gt;queries&lt;span&gt;&amp;nbsp;&lt;/span&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;mutaions&lt;span&gt;&amp;nbsp;&lt;/span&gt;프로퍼티로 default option들을 설정할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;color: #212529; text-align: start;&quot;&gt;&lt;code&gt;import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      /*
      queries: number, // 쿼리 재시도 횟수를 설정, 기본값은 3으로 실패시 3번 재시도
      suspense: boolean, // React의 Suspense 모드 사용 여부를 설정, true 설정시 쿼리가 로딩중일 때 Suspense 모드 사용하여 처리 가능
      staleTime: number, // 쿼리 데이터의 &quot;stale&quot; 기간을 설정
      cacheTime: number, // 쿼리 데이터를 캐시에 저장하는 기간을 설정
      */
    },
    mutations: {
      /*
      onMutate: Function, // 뮤테이션을 시작하기 전에 실행되는 함수를 설정합니다.
      onSuccess: Function, // 뮤테이션 성공 시 실행되는 함수를 설정합니다.
      onError: Function, // 뮤테이션 실패 시 실행되는 함수를 설정합니다.
      */
    }
  }
})

function App () {
  return (
    // 2. QueryClientProvider를 통해 하위 컴포넌트들에게 전달
    &amp;lt;QueryClientProvider client={queryClient}&amp;gt;
        ,,,
    &amp;lt;/QueryClientProvider&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote style=&quot;color: #212529; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;queryClient&lt;span&gt;&amp;nbsp;&lt;/span&gt;에 설정한 옵션은 모든 쿼리에 전역적으로 설정되지만,&lt;span&gt;&amp;nbsp;&lt;/span&gt;useQuery나&lt;span&gt;&amp;nbsp;&lt;/span&gt;useMutation&lt;span&gt;&amp;nbsp;&lt;/span&gt;훅에 개별적으로 옵션을 설정한다면&lt;span&gt;&amp;nbsp;&lt;/span&gt;queryClient에 설정한 옵션들은 무시됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;usequeryclient&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;useQueryClient&lt;/h3&gt;
&lt;p 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;span&gt;&amp;nbsp;&lt;/span&gt;new&lt;span&gt;&amp;nbsp;&lt;/span&gt;연산자로 생성한 queryClient에 대해서 매번 재생성하여 사용하지 않습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;queryClient는 초기 한 번만 생성 후,&lt;span&gt;&amp;nbsp;&lt;/span&gt;QueryClientProvier의 client로 전달한 queryClient를 재사용해야 합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;만약 재사용하지 않고 필요할 때 재성성하게 된다면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;기존 쿼리에 대한 정보를 갖고 있는 queryClient를 버리고 쿼리에 대한 정보를 갖지 않는 빈 정보를 갖는 queryClient를 사용하는 것과 동일&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;생성된 queryClient에 접근하기 위한 훅으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;useQueryClient가 있으며, 호출시 초기 생성한 queryClient를 반환합니다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;color: #212529; text-align: start;&quot;&gt;&lt;code&gt;import { useQueryClient } from '@tanstack/react-query'

const Component = () =&amp;gt; {
  // 기존 QueryClient 반환
  const queryClient = useQueryClient()
  // ,,,
}

export default Component&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;setquerydata--setqueriesdata&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;setQueryData &amp;amp; setQueriesData&lt;/h3&gt;
&lt;p 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;queryClient가 제공하는 메서드 중&lt;span&gt;&amp;nbsp;&lt;/span&gt;setQueryData와&lt;span&gt;&amp;nbsp;&lt;/span&gt;setQueriesData를 통해 명시적으로 특정 쿼리에 대한 데이터를 설정할 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;첫 번째 인수로 queryKey, 두 번째 인수로는 해당 쿼리에 설정할 데이터를 전달합니다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;color: #212529; text-align: start;&quot;&gt;&lt;code&gt;import { useQueryClient } from '@tanstack/react-query'

const Component = () =&amp;gt; {
  cosnt queryClient = useQueryClient()
  
  // 특정 쿼리 데이터 설정
  queryClinet.setQueryData([queryKey, ...], TData)
  // ,,,
}

export default Component&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;setQueryData&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드를 호출하게 되면 React Query가 해당 쿼리를 구독하고 있는 컴포넌트들을 다시 호출(리렌더링)하게 됩니다.&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;removequery--removequeries&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;removeQuery &amp;amp; removeQueries&lt;/h3&gt;
&lt;p 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;queryClient가 제공하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;removeQuery와&lt;span&gt;&amp;nbsp;&lt;/span&gt;removeQueries&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드는 특정 쿼리를 명시적을 제거할 수 있습니다.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 id=&quot;using-usequery-hooks&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Using useQuery Hooks&lt;/h2&gt;
&lt;p 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;b&gt;useQuery&lt;span&gt;&amp;nbsp;&lt;/span&gt;훅은 서버 데이터를 GET 요청할 때 사용되는 훅&lt;/b&gt;입니다. 기본적으로 비동기 방식으로 동작합니다.&lt;/p&gt;
&lt;pre class=&quot;haskell&quot; style=&quot;color: #212529; text-align: start;&quot;&gt;&lt;code&gt;import { useQuery } from '@tanstack/react-query'

const { data, isLoading, error } = useQuery(['key', params...], callbackFn, Options)&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;즉,&lt;span&gt;&amp;nbsp;&lt;/span&gt;useQuery&lt;span&gt;&amp;nbsp;&lt;/span&gt;훅을 통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;GET 요청에 대한 쿼리와 요청에 대한 서버 데이터를 queryClient에 캐싱&lt;/b&gt;하기 위해서 사용합니다.&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;parameters&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Parameters&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;['key', ...deps]&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 첫 번째 인수로는 배열을 전달합니다. 배열의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;첫 요소는 쿼리를 식별할 수 있는 고유한 키 값을 문자열&lt;/b&gt;로 가져야 하며, 두 번째 요소 이후부터는 두 번째 인수로 전달될&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;콜백함수 내부에서 의존하고 있는 외부 식별자들을 작성&lt;/b&gt;합니다.&lt;br /&gt;이때&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;쿼리 키 값이 같더라도 의존하고 있는 식별자 값이 일치하지 않는 경우에는 다른 쿼리로 식별하여 별도의 쿼리로 캐싱되고 관리&lt;/b&gt;됩니다.&lt;/li&gt;
&lt;li&gt;CallbackFn:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;서버 데이터를 fetching하는 비동기 함수&lt;/b&gt;를 전달해야하며,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Promise 객체를 반환하는 함수&lt;/b&gt;를 전달합니다.&lt;/li&gt;
&lt;li&gt;Options&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 객체 타입으로 쿼리에 대한 옵션을 작성할 수 있습니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;staleTime: number&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;fresh 상태에서 stale 상태로 변경되기 까지의 시간&lt;/b&gt;을 설정하며 ms 단위의 숫자값을 작성합니다. 기본값은 0으로 설정되어 있습니다.즉, 모든 쿼리는 fetch된 직후 stale 상태가 됩니다.&lt;/li&gt;
&lt;li&gt;cacheTime: number&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;캐시 만료시간을 설정&lt;/b&gt;하는 옵션입니다. 캐시가 만료되면 가비지 컬렉션에 의해 수집되어 클라이언트는 해당 쿼리 데이터를 사용할 수 없게 됩니다. 기본값은 5분으로 설정되어 있습니다.&lt;br /&gt;이는 컴포넌트가 언마운트된 시점부터 cacheTime 시간 이후에 쿼리가 가바지 컬렉터에게 수집됩니다.&lt;/li&gt;
&lt;li&gt;refetchOnMount: boolean | 'always'&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;stale 상태를 갖는 컴포넌트가 마운트되면 새로운 데이터를 re-fetching&lt;/b&gt;합니다. 기본값은 true로 설정되어 있습니다.&lt;/li&gt;
&lt;li&gt;refetchOnWindowFocus: boolean | 'always'&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;쿼리가 stale 상태일 때 브라우저 창 포커스되면 새로운 데이터를 re-fetching&lt;/b&gt;합니다. 기본값은 true로 설정되어 있습니다.&lt;/li&gt;
&lt;li&gt;refetchInterval: number&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;쿼리가 stale 상태일 때 브라우저 창 포커스되어 있는 경우 지정한 시간 간격으로 새로운 데이터를 re-fetching&lt;/b&gt;합니다. 기본값은 0으로 설정되어 있습니다.&lt;/li&gt;
&lt;li&gt;refetchIntervalInBackground: boolean&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;쿼리가 stale 상태일 때 브라우저 창 포커스가 되어 있지 않더라도 지정한 시간 간경으로 새로운 데이터를 re-fetching&lt;/b&gt;합니다. 기본값은 false로 설정되어 있습니다.&lt;/li&gt;
&lt;li&gt;enabled: boolean&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;자동 fethcing 동작 유무&lt;/b&gt;를 설정합니다. 기본값으로 true로 설정되어 있으며, false로 설정한 경우 자동적으로 데이터를 fethcing하지 않습니다. 이때&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;useQuery&lt;span&gt;&amp;nbsp;&lt;/span&gt;훅이 반환하는 객체의&lt;span&gt;&amp;nbsp;&lt;/span&gt;refetch&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드를 통해 수동적으로 fethcing&lt;/b&gt;해야 합니다.&lt;/li&gt;
&lt;li&gt;KeepPreviousData: boolean&lt;span&gt;&amp;nbsp;&lt;/span&gt;: true로 설정한 경우 쿼리키가 변경되어 새로운 데이터를 요청(re-fethcing)하는 동안 이전 데이터를 표시합니다.&lt;/li&gt;
&lt;li&gt;onSuccess: Function&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 데이터&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;fethcing 성공시 실행될 콜백함수&lt;/b&gt;를 전달할 수 있습니다.&lt;br /&gt;콜백함수 인수로는&lt;span&gt;&amp;nbsp;&lt;/span&gt;useQuery&lt;span&gt;&amp;nbsp;&lt;/span&gt;훅의 두 번째 인수로 전달한 콜백함수의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;비동기 처리 결과&lt;/b&gt;가 전달됩니다.&lt;/li&gt;
&lt;li&gt;onError: Function&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 데이터&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;fethcing 실패시 실행될 콜백함수&lt;/b&gt;를 전달할 수 있습니다.&lt;br /&gt;인수로 두 번째 인수로 전달한 콜백함수에서 발생한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;에러 객체&lt;/b&gt;가 전달됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;returns&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Returns&lt;/h3&gt;
&lt;p 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;useQuery&lt;span&gt;&amp;nbsp;&lt;/span&gt;훅은 객체를 반환하며 객체의 프로퍼티들은 아래와 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;data&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 두 번째 인수로 전달한 콜백함수가 반환한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Promise 객체의 비동기 처리 결과&lt;/b&gt;가 바인딩됩니다. 콜백은 비동기로 동작하기 때문에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;fetch될 때까지&lt;span&gt;&amp;nbsp;&lt;/span&gt;undefined&lt;span&gt;&amp;nbsp;&lt;/span&gt;값&lt;/b&gt;을 갖고 있습니다.&lt;/li&gt;
&lt;li&gt;state&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 두 번째 인수로 전달한 콜백함수의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;비동기 처리 결과에 대한 상태&lt;/b&gt;를 문자열로 갖고 있습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;loading&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;success&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;error&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;세 가지 상태값을 갖고 있습니다.&lt;/li&gt;
&lt;li&gt;isLoading&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;캐싱된 데이터없는 상태에서 데이터를 fetching하고 있는 경우&lt;/b&gt;에&lt;span&gt;&amp;nbsp;&lt;/span&gt;true, 아니면&lt;span&gt;&amp;nbsp;&lt;/span&gt;false&lt;span&gt;&amp;nbsp;&lt;/span&gt;값을 갖습니다.&lt;/li&gt;
&lt;li&gt;isFetcing&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 캐싱 유무와 상관없이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;데이터를 fetching하고 있는 경우&lt;/b&gt;에&lt;span&gt;&amp;nbsp;&lt;/span&gt;true, 아니면&lt;span&gt;&amp;nbsp;&lt;/span&gt;false&lt;span&gt;&amp;nbsp;&lt;/span&gt;값을 갖습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;isLoading의 상위 집합이 됩니다.&lt;/li&gt;
&lt;li&gt;isError&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;에러가 발생했는지에 대한 여부&lt;/b&gt;를 나타 내는 불리언 값을 갖고 있습니다.&lt;br /&gt;기본적으로 React Query는 fetching을 세 번 시도하고 세 번 모두 실패한 경우&lt;span&gt;&amp;nbsp;&lt;/span&gt;isError&lt;span&gt;&amp;nbsp;&lt;/span&gt;프로퍼트 값을&lt;span&gt;&amp;nbsp;&lt;/span&gt;true로 설정합니다.&lt;/li&gt;
&lt;li&gt;error&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 에러가 발생한 경우&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;에러 객체&lt;/b&gt;가 바인딩되며, 에러가 발생하지 않은 경우&lt;span&gt;&amp;nbsp;&lt;/span&gt;undefined&lt;span&gt;&amp;nbsp;&lt;/span&gt;값을 갖습니다.&lt;/li&gt;
&lt;/ol&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;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;query-state&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Query State&lt;/h3&gt;
&lt;p 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;쿼리는 4가지 상태값을 갖습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&quot;fresh&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;새롭게 추가된 쿼리이며 만료되지 않은 쿼리&lt;/b&gt;입니다. 컴포넌트가 마운트되거나 리렌더링되더라도 기존 서버 데이터를 사용하며&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;re-fetching하지 않는 상태입니다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&quot;fetching&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;fetching 중인 쿼리&lt;/b&gt;를 나타냅니다.&lt;/li&gt;
&lt;li&gt;&quot;stale&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;만료된 쿼리&lt;/b&gt;이며 컴포넌트가 컴포넌트가 마운트되거나 리렌더링되는 경우 해당 쿼리를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;re-fetching&lt;/b&gt;합니다. 즉,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;stale 상태인 경우에만 데이터를 re-fetching&lt;/b&gt;합니다.&lt;br /&gt;staleTime를 통해 fresh에서 stale 상태로 변경되기 까지의 시간을 의미합니다.&lt;/li&gt;
&lt;li&gt;&quot;inactive&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;비활성화된 쿼리&lt;/b&gt;이며 캐시의 데이터 만료시간을 설정합니다. 이는&lt;span&gt;&amp;nbsp;&lt;/span&gt;cacheTime&lt;span&gt;&amp;nbsp;&lt;/span&gt;옵션을 통해 설정할 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;usequery-훅의-동작&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;useQuery 훅의 동작&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;처음&lt;span&gt;&amp;nbsp;&lt;/span&gt;useQuery&lt;span&gt;&amp;nbsp;&lt;/span&gt;훅이 호출되면 쿼리 상태가 fresh 상태가 되며, 첫 번째 인수로 전달한 키로 쿼리와 서버 데이터가 캐싱됩니다.&lt;/li&gt;
&lt;li&gt;이후&lt;span&gt;&amp;nbsp;&lt;/span&gt;staleTime으로 설정한 시간이 경과된 이후 해당 쿼리는 stale 상태가 됩니다. 쿼리가 stale 상태인 경우 re-fetching하고 기존 데이터를 새로운 서버 데이터로 교체합니다.&lt;/li&gt;
&lt;li&gt;컴포넌트가 언마운트된 시점부터 inactive 상태가 되고&lt;span&gt;&amp;nbsp;&lt;/span&gt;cacheTime으로 설정한 시간이 경과된 이후에는 캐싱된 쿼리가 메모리에서 제거되어 가비지 컬렉터로 수집됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;fresh 상태일 때는 re-fethcing을 하지 않고 캐싱된 쿼리 데이터를 사용하며, stale 상태인 경우에는 re-fetching하여 쿼리를 새로운 데이터로 교체합니다. re-fetching되는 동안에는 캐싱된 데이터를 보여주고 re-fetching이 완료되면 새로운 데이터로 교체됩니다.&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;select-option&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;select Option&lt;/h3&gt;
&lt;p 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;useQuery&lt;span&gt;&amp;nbsp;&lt;/span&gt;훅에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;select&lt;span&gt;&amp;nbsp;&lt;/span&gt;옵션을 통해 fetching된 데이터에 대해 가공(필터링)을 할 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;select&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수의 인수로는 fetchin된 데이터가 전달되고 반환값이 최종적으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;data에 바인딩됩니다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;color: #212529; text-align: start;&quot;&gt;&lt;code&gt;import { useQuery } from '@tanstack/react-query'

const Component = () =&amp;gt; {
  const { data } = useQuery([key, ...], queryFn, {
    select: (data) =&amp;gt; { ,,, }  // fetching한 데이터를 가공
    });
    // ,,,
}

export default Component&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;re-fetching-options&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Re-fetching Options&lt;/h3&gt;
&lt;p 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;useQuery&lt;span&gt;&amp;nbsp;&lt;/span&gt;훅을 호출하면 컴포넌트가 호출되어 실행되는 시점에 비동기 함수가 실행이 됩니다. 이후 캐싱된 데이터가 변경되는 경우 React Query가 자동적으로 re-fetching을 진행하며, 추가적으로 stale이 0인 쿼리 데이터에 대해서&lt;span&gt;&amp;nbsp;&lt;/span&gt;refetchOnMount,&lt;span&gt;&amp;nbsp;&lt;/span&gt;refetchOnWindowFocus와 같은 옵션을 통해서 특정 상황에 대해 re-fethcing을 실행하도록 설정할 수도 있습니다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;color: #212529; text-align: start;&quot;&gt;&lt;code&gt;import { useQuery } from '@tanstack/react-query'

const Component = () =&amp;gt; {
  const { data } = useQuery([key, ...], queryFn, {
    refetchOnMount: true,
    refetchOnWindowFocus: true,
    refetchOnReconnect: true,
    refetchInterval: number
  })
}

export default Component&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;intialdata-option&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;intialData Option&lt;/h3&gt;
&lt;p 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;useQuery&lt;span&gt;&amp;nbsp;&lt;/span&gt;훅에&lt;span&gt;&amp;nbsp;&lt;/span&gt;initialData라는 옵션을 통해 초기 쿼리 데이터를 캐싱할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;color: #212529; text-align: start;&quot;&gt;&lt;code&gt;import { useQuery } from '@tanstack/react-query'

const Component = () =&amp;gt; {
  const { data } = useQuery([key, ...], queryFn, {
    initialData: TData | () =&amp;gt; TData
  })
}

export default Component&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote style=&quot;color: #212529; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;placeholder&lt;span&gt;&amp;nbsp;&lt;/span&gt;옵션의 경우 쿼리 상태가 loading일 떄 표시될 데이터입니다. 실질적으로 캐싱되지 않는 데이터이며,&lt;span&gt;&amp;nbsp;&lt;/span&gt;initialData&lt;span&gt;&amp;nbsp;&lt;/span&gt;옵션이 설정되지 않은 경우에 동작하게 됩니다.&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>Development/React</category>
      <author>yjym33</author>
      <guid isPermaLink="true">https://yjym33.tistory.com/168</guid>
      <comments>https://yjym33.tistory.com/168#entry168comment</comments>
      <pubDate>Wed, 24 Jul 2024 12:40:16 +0900</pubDate>
    </item>
    <item>
      <title>ReactQuery - Client State vs Server State</title>
      <link>https://yjym33.tistory.com/167</link>
      <description>&lt;h2 id=&quot;client-state-vs-server-state&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Client State vs Server State&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Client State란 클라이언트가 자체적으로 생성한 상태&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;로 사용자의 input 값이나 UI 변경을 담당하는 부분으로 볼 수 있습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;예를 들어, 모달창을 열고 닫는 상태나 사용자가 입력한 값 같은 것들을 의미합니다.&lt;/span&gt;&lt;br /&gt;&lt;b&gt;즉, 서버에서 일어나는 일과는 아무 관련이 없는 상태&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;들을 의미합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;반면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;Server State란 클라이언트에 표시하는 데 필요한 서버 데이터&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;를 의미합니다. 예를 들어, DB에 존재하는 데이터들을 의미합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;React Query는 React 애플리케이션에서 서버 응답에 대한 상태인 fetch, caching, update와 같은 동작을 쉽게 다룰 수 있도록 하며, Client State와 Server State를 명확하게 분리하여 관리할 수 있도록 도와주는 라이브러리입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;react-query&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;React Query&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Query를 직역하면 질문, 질의문으로 요청으로 볼 수 있습니다. 이때 요청을 보내는 곳이 바로 DB 서버이며 종합적으로는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;DB 서버에 요청을 보내는 것을 Query&lt;/b&gt;라고 볼 수 있습니다.&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;React Query는 서버에게 요청을 보내는 Query와 요청에 대한 응답(서버 데이터)를 캐싱하고 서버 데이터에 대한 적절한 핸들링 등 여러 편리한 기능들을 제공해줍니다.&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;React Query는 클라이언트에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;쿼리와 쿼리에 대한 서버 데이터를 클라이언트 캐시로 관리&lt;/b&gt;합니다. React 코드에서 서버 데이터가 필요할 때 Fetch API나 Axios를 통해 바로 서버에게 요청을 보내지 않고 React Query 캐시를 요청합니다.&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;React Query 클라이언트를 어떻게 구성했느냐에 따라 캐시의 데이터를 유지 관리합니다. 데이터를 관리하는 것은 React Query이지만 서버의 새 데이터로 캐시를 업데이트하는 시기를 설정하는 것은 사용자의 몫입니다.&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;&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;span style=&quot;color: #000000; font-size: 1.44em; letter-spacing: -1px; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif;&quot;&gt;React Query Manages Data&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React Query의 캐시에는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;특정 쿼리에 대한 Key가 존재&lt;/b&gt;하며 해당 키를 통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;쿼리를 식별&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트 캐시의 데이터와 서버의 데이터가 일치하는지 확인해야 하는데 여기에는 두 가지 방법이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;명령형&lt;/b&gt;으로 처리하는 방법이 존재합니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;해당 데이터를 무효화하고 캐시에 교체할 새 데이터를 서버에서 가져오게 지시하는 것&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째로는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;선언형&lt;/b&gt;입니다. 이는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;re-fetch를 트리거하는 특정 조건을 구성하는 것&lt;/b&gt;입니다. 예를 들어, 브라우저 창이 다시 포커스되었을 때 새 데이터를 서버에서 가져오도록 구성하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;react-query-feature&quot; data-ke-size=&quot;size23&quot;&gt;React Query Feature&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가적으로 React Query는 서버 상테 관리에 도움이 되는 많은 도구가 함께 제공됩니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;모든 쿼리의 로딩 및 오류 상태를 유지&lt;/b&gt;해주기 때문에 수동으로 다루어야 할 필요가 없어집니다.&lt;/li&gt;
&lt;li&gt;사용자를 위해 데이터의 Pagination 또는 Infinity Scroll일 때 필요한 경우에 데이터를 가져올 수 있도록하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Lazy loading 도구도 제공&lt;/b&gt;됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;서버 데이터를 미리 pre-fetch하고 캐싱&lt;/b&gt;하여 사용자가 데이터를 필요로할 때 pre-fetch되어 캐싱된 데이터를 제공하기 때문에 요청과 응답에 대한 시간을 줄일 수도 있습니다.&lt;/li&gt;
&lt;li&gt;React Query를 통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;서버의 데이터를 업데이트(Mutation)하여 관리&lt;/b&gt;할 수도 있습니다.&lt;/li&gt;
&lt;li&gt;각 쿼리들은 키로 식별되기 때문에 페이지 내 여러 컴포넌트가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;동일한 데이터를 요청하는 경우 한 번만 요청하도록 중복 요청을 제거&lt;/b&gt;할 수 있습니다.&lt;/li&gt;
&lt;li&gt;서버에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;오류가 발생하는 경우에 대한 재시도를 관리&lt;/b&gt;할 수 있습니다.&lt;/li&gt;
&lt;li&gt;쿼리가 성공하거나 오류가 났을 때를 구별하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;특정 조건에 따라 실행될 콜백함수를 전달&lt;/b&gt;할 수도 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;
&lt;div data-testid=&quot;follow-btn&quot;&gt;&amp;nbsp;&lt;/div&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;</description>
      <category>Development/React</category>
      <author>yjym33</author>
      <guid isPermaLink="true">https://yjym33.tistory.com/167</guid>
      <comments>https://yjym33.tistory.com/167#entry167comment</comments>
      <pubDate>Wed, 24 Jul 2024 09:26:40 +0900</pubDate>
    </item>
  </channel>
</rss>