<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>devlsn96.log</title>
        <link>https://velog.io/</link>
        <description>Quantum Jump to class for java….</description>
        <lastBuildDate>Thu, 11 Dec 2025 23:25:02 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. devlsn96.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/liner_123456" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Cloud 용어 정리]]></title>
            <link>https://velog.io/@liner_123456/Cloud-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@liner_123456/Cloud-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Thu, 11 Dec 2025 23:25:02 GMT</pubDate>
            <description><![CDATA[<h2 id="csp와-msp">CSP와 MSP</h2>
<h3 id="1-cloud-service-provider-클라우드-서비스-제공자">1. Cloud Service Provider (클라우드 서비스 제공자)</h3>
<p>: 자체 데이터센터에 IT에 필요한 인프라를 제공해주는 사업자</p>
<ul>
<li>AWS, Azure ...</li>
<li>서버, 저장소, 네트워크, 보안 등을 제공</li>
<li>scale merit : 1인당 감당하는 비용이 합리적, 비용 최적화</li>
<li>capex(자본지출) 중심에서 opex(운용지출) 중심의 운용이 가능 </li>
</ul>
<h3 id="2-managed-service-provider-관리형-서비스-제공자">2. Managed Service Provider (관리형 서비스 제공자)</h3>
<p>: CSP가 운영하는 서비스를 고객 환경에 맞게 컨설팅하는 사업자</p>
<h2 id="데이터센터">데이터센터</h2>
<ul>
<li>글로벌하게 구축</li>
<li>하나 이상의 데이터센터 = 가용영역 (Availability Zone)</li>
<li>가용영역 (Availability Zone) : CSP에서 말하는 데이터센터<ul>
<li><strong>내결함성과 가용성</strong></li>
<li>가용영역 사이는 고속의 프라이빗한 링크로 연결</li>
<li>3개의 가용영역 = 리전 (Region, 물리적인 지역 위치를 의미)</li>
</ul>
</li>
<li>리전 : 인프라로 부터 완전 독립적인 공간, 해당지역의 거버넌스와 비용, 지연시간, 가용성을 고려</li>
</ul>
<h3 id="local-zones와-엣지-로케이션">local Zones와 엣지 로케이션</h3>
<table>
<thead>
<tr>
<th>local Zones</th>
<th></th>
<th>엣지 로케이션</th>
</tr>
</thead>
<tbody><tr>
<td>출장소 개념</td>
<td></td>
<td>데이터를 캐싱해서 전송</td>
</tr>
<tr>
<td>미디어 컨텐츠에 활성화</td>
<td></td>
<td>CDN에 특화된 서비스</td>
</tr>
</tbody></table>
<h2 id="sigle-point-of-failure">Sigle Point Of Failure</h2>
<p><em>&quot;서버는 기본적으로 이중화로 작업&quot;</em></p>
<ul>
<li>단일 장애점이 발생할 수 있기 때문</li>
</ul>
<h2 id="on-premise와-cloud">On-Premise와 Cloud</h2>
<h2 id="cloud-native">Cloud Native</h2>
<h3 id="cloud에-특화된-소프트웨어-개발-방법론">Cloud에 특화된 소프트웨어 개발 방법론</h3>
<ul>
<li>WaterFall</li>
<li>Agile</li>
<li><strong>DevOps</strong></li>
<li>CI/CD</li>
</ul>
<h2 id="클라우드-서비스모델">클라우드 서비스모델</h2>
<h3 id="laas-vs-paas-vs-saas">laas vs Paas vs Saas</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[[데이터 공유하기] Redux ]]></title>
            <link>https://velog.io/@liner_123456/%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B3%B5%EC%9C%A0%ED%95%98%EA%B8%B0-Redux</link>
            <guid>https://velog.io/@liner_123456/%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B3%B5%EC%9C%A0%ED%95%98%EA%B8%B0-Redux</guid>
            <pubDate>Wed, 03 Dec 2025 09:43:12 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>기존의 데이터 공유 prop drilling과 context의 단점을 보완하기 위해 redux라는 녀석이 등장했다. </p>
</blockquote>
<h2 id="step-01-redux">STEP 01. redux</h2>
<ul>
<li>1) 리듀서 함수</li>
<li>2) store에 저장 
<code>createStore()</code></li>
<li>3) store를 등록한다.
<code>Provider 컴포넌트</code> 사용</li>
<li>4) 적용하기 <ul>
<li>dispatch와 useSelector훅을 활용해 상태변화 랜더링</li>
<li></li>
</ul>
</li>
</ul>
<h2 id="step-02-redux-toolkit">STEP 02. redux toolkit</h2>
<ul>
<li>라이브러리 불러오기</li>
<li>slicer를 생성한다. </li>
<li>store에 reducer함수를 등록한다.
<code>configureStore()</code></li>
<li>적용하기 </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JWT ]]></title>
            <link>https://velog.io/@liner_123456/JWT</link>
            <guid>https://velog.io/@liner_123456/JWT</guid>
            <pubDate>Tue, 02 Dec 2025 09:47:47 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[React.js를 보완한 Next.js]]></title>
            <link>https://velog.io/@liner_123456/React.js%EB%A5%BC-%EB%B3%B4%EC%99%84%ED%95%9C-Next.js</link>
            <guid>https://velog.io/@liner_123456/React.js%EB%A5%BC-%EB%B3%B4%EC%99%84%ED%95%9C-Next.js</guid>
            <pubDate>Tue, 02 Dec 2025 04:19:45 GMT</pubDate>
            <description><![CDATA[<ul>
<li><p>리액트의 페이지 이동 기능을 개선한 Next.js</p>
<h3 id="nextjs-특징">Next.js 특징</h3>
</li>
<li><p>routing을 더 쉽게 사용가능</p>
</li>
<li><p>서버에서 제작한 화면을 구현하는 방식 (SSR)</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] react-router]]></title>
            <link>https://velog.io/@liner_123456/React-react-router</link>
            <guid>https://velog.io/@liner_123456/React-react-router</guid>
            <pubDate>Mon, 01 Dec 2025 16:09:46 GMT</pubDate>
            <description><![CDATA[<ul>
<li>리액트는 원래 페이지 이동을 지원하지 않기 때문에 </li>
<li>페이지이동을 지원하기 위한 react-router-dom 라이브러리 설치 필요<h4 id="1-라이브러리-설치">1) 라이브러리 설치</h4>
<code>npm install react router dom</code><h4 id="2-링크-연결">2) 링크 연결</h4>
<code>Link to=&quot;경로&quot;&gt;이름&lt;/Link&gt;</code><h4 id="3-링크-정의">3) 링크 정의</h4>
<code>&lt;Routes&gt;와 &lt;Route&gt;로 element와 path정의</code></li>
</ul>
<h3 id="useparams">useParams</h3>
<ul>
<li>라우터 경로상 파라미터를 받아온다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬으로 시작하기 (2) ]]></title>
            <link>https://velog.io/@liner_123456/%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9D%98-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-2</link>
            <guid>https://velog.io/@liner_123456/%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9D%98-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-2</guid>
            <pubDate>Tue, 30 Sep 2025 15:08:16 GMT</pubDate>
            <description><![CDATA[<h2 id="제어문">제어문</h2>
<h3 id="if문">if문</h3>
<ul>
<li>조건이 끝나면, 콜론(:)으로 마무리하고, 조건에 따른 실행문장은 무조건 들여쓰기한다.</li>
<li>if문은 한줄로도 처리가능하다. <code>if 조건: 실행문장</code><pre><code>if 조건: 
  실행문장</code></pre></li>
</ul>
<h3 id="if문의-다양한-형태">if문의 다양한 형태</h3>
<p>if문 외에도, if ~ else문, if ~ elif ~ else문이 있다.</p>
<blockquote>
<h3 id="-pass-키워드">※ pass 키워드</h3>
<p>처리할 구문이 없거나 해당 조건을 넘기고 싶으면, pass 키워드를 사용할 수 있다.</p>
</blockquote>
<h3 id="for문">for문</h3>
<pre><code>for 변수(인덱스값) in 리스트:
    실행구문</code></pre><ul>
<li>enumerate()함수는 문자열이나 컨테이너자료형(튜플, 집합, 리스트, 딕셔너리 ...)를  index와 요소값을 포함한 객체로 반환해줌</li>
</ul>
<blockquote>
<h3 id="comprehension">Comprehension</h3>
<p>phython이 지향하는 코드?로 구현해줌</p>
</blockquote>
<ul>
<li><p>반복문 코드가 간결해짐</p>
<ul>
<li><code>[&quot;실행문&quot; for &quot;변수&quot; in &quot;객체&quot;]</code><ul>
<li>만약, 조건이 들어가면, <code>[&quot;실행문&quot; for &quot;변수&quot; in &quot;객체&quot; &quot;조건문&quot;]</code></li>
</ul>
</li>
</ul>
</li>
<li><p>items() : 딕셔너리를 for문의 리스트로 사용하여 반환하면, key값과 value값을 모두 보여줄 수 있다.</p>
</li>
</ul>
<h3 id="while문">while문</h3>
<p>조건이 True인 상황에서 구문 안 문장을 반복적으로 실행</p>
<pre><code>while 조건:
    실행문</code></pre><ul>
<li>무한 루프는 while문의 조건을 무조건 True로 하여 계속 반복 실행되도록 한다.</li>
</ul>
<blockquote>
<h4 id="break와-continue">break와 continue</h4>
</blockquote>
<ul>
<li>break : 특정조건 만족할 때 그 구문 실행을 멈추고 다음을 실행한다.</li>
<li>continue : 특정조건 만족할 때 그 구문은 실행하지 않고 다시 반복 실행한다.</li>
</ul>
<h2 id="함수">함수</h2>
<pre><code>def  func(parameter):
    실행문</code></pre><ul>
<li>함수의 결과값을 반환하고 싶으면, 함수 마지막에 return문을 실행하면 됨</li>
</ul>
<blockquote>
<p>*<em>가변인수 *</em></p>
</blockquote>
<ul>
<li>함수실행시, 여러개의 매개변수를 반복적으로 나열해 여러번 실행할 수 있게 한 변수이다. (매개변수 앞에 * 표시)</li>
<li><code>def  func(*parameter): 실행문</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬으로 시작하기]]></title>
            <link>https://velog.io/@liner_123456/%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9C%BC%EB%A1%9C-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@liner_123456/%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9C%BC%EB%A1%9C-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 30 Sep 2025 13:25:12 GMT</pubDate>
            <description><![CDATA[<p><em>파이썬은 전 세계적으로 현재까지는 가장 많이 사용되는 언어 중 하나이다.<br> <code>간결성</code>과 <code>방대한 라이브러리</code>를 바탕으로 <strong>데이터분석</strong>과 <strong>머신러닝</strong> 으로 인공지능을 모델링하는 데 최적화 되었다고 한다.</em></p>
<blockquote>
<h3 id="👌-파이썬의-기본부터-이해하자">👌 파이썬의 기본부터 이해하자!</h3>
</blockquote>
<h4 id="변수는-값을-담는-그릇이나-상자로-생가하면-된다">변수는 값을 담는 그릇이나 상자로 생가하면 된다.</h4>
<ul>
<li>변수에 대입한 값에 의해 변수의 자료형이 결정된다.</li>
<li>코드셀에 변수명만 입력하고 실행하면, 값이 출력된다.<h4 id="변수나-함수를-명명하기-위해-다음의-규칙으로-식별자를-붙인다">변수나 함수를 명명하기 위해 다음의 규칙으로 식별자를 붙인다.</h4>
</li>
<li>예약어은 사용불가 🚫</li>
<li>언더바<code>_</code>, 특수문자, 공백은 포함안됨 🚫</li>
<li>숫자를 먼저 시작하면 안됨 🚫</li>
<li>대소문자 구분하고, 가능하면, <strong>소문자 사용 권고</strong></li>
<li>언더 바로 가능한 가독성 좋게 할것<h4 id="연산자-operator">연산자 (Operator)</h4>
</li>
<li>산술연산자 : 사칙연산 ( <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code> ), <strong>나머자 (<code>%</code>), 몫(<code>//</code>), 제곱(`</strong>`)**</li>
<li>비교연산자 : 변수나 값, 연산결과의 크기를 비교할때 사용한다. <ul>
<li>같다 <code>==</code>, 같지않다 <code>!=</code></li>
<li>연산결과는 True나 False</li>
</ul>
</li>
<li>복합 대입 연산자 : 대입과 연산을 동시애 진행, <em>java의 단항연산자</em> <code>+=</code> <code>-=</code> <code>*=</code> <code>/=</code><h4 id="print-함수">print() 함수</h4>
</li>
<li>단순 연산 값, 변수의 값 등 연산 결과 확인을 위한 함수</li>
<li>여러개의 값을 콤마로 전달하고 싶을 때, 사용한다.<ul>
<li>print() 함수를 사용하지 않고 변수로 값을 표시하면 하나의 값만 표시된다.<h4 id="자료-형변환">자료 형변환</h4>
</li>
</ul>
</li>
<li>float(), int(), str(), bool() 함수<ul>
<li>bool() 함수는 True는 1, False는 0이고, 완전 공백은 False 그 외는 모두 True</li>
</ul>
</li>
<li>type() 함수로 자료형을 알 수 있다.</li>
</ul>
<h2 id="1-자료형">1. 자료형</h2>
<h3 id="문자열-자료형">문자열 자료형</h3>
<ul>
<li><code>&#39;&#39;</code>, <code>&quot;&quot;</code> 사용하여 문자열을 표현</li>
<li>len() 함수 : 문자열의 길이 (포함된 문자 개수) 확인</li>
<li>문자열 앞뒤 따옴표 세 개 사용하거나 <code>\n</code>로 줄 바꿈 표현</li>
<li>문자열의 연산은 문자열의 결합임</li>
<li>문자열에 정수 값을 곱하면, 문자열을 정수 값만큼 반복</li>
<li>문자열 사이에 값을 함께 사용하려면, f-string을 사용한다. <ul>
<li>앞에 f를 쓰고 문자열 안 중괄호 <code>{}</code>에 변수를 대입하면 된다. <em>javascrtipt의 템플릿리터럴과 유사(?)</em><h4 id="문자열-메서드--문자열을-변환하지만-그-결과를-변수에-반영하진-않음">문자열 메서드 : 문자열을 변환하지만, 그 결과를 변수에 반영하진 않음</h4>
</li>
</ul>
</li>
<li>upper() 대문자로, capitalize() 첫문자만 대문자로, title() 단어의 첫문자만 대문자로, lower() 소문자로 </li>
<li>replace(x,y) x를 y로 변경, strip() 양쪽 공백제거 및 특수문자제거</li>
<li>split(x) : x문자를 구분자로 문자열 분리해 문자열을 리스트로 변환</li>
<li>x.join(a) :  x문자를 구분자로 a요소 연결한 문자열로</li>
</ul>
<h2 id="2-컨테이너-자료형">2. 컨테이너 자료형</h2>
<h3 id="1-리스트-자료형">1) 리스트 자료형</h3>
<ul>
<li><code>[]</code> <code>list()</code></li>
<li>sum() 합, max() 최대값, </li>
<li>range() 함수 : 일련의 요소 나열 <ul>
<li>range(n) : 0 ~ <code>n-1</code>까지 정수</li>
<li>range(n, m) : n ~ <code>m-1</code>까지 정수</li>
<li>range(n, m, i) : i만큼 증감값 조건 추가<h4 id="리스트-인덱싱">리스트 인덱싱</h4>
</li>
</ul>
</li>
<li>특정요소를 찾는 위치, 0부터 시작</li>
<li>역방향 인덱싱은 -1부터 시작<h4 id="리스트-슬라이싱">리스트 슬라이싱</h4>
</li>
<li>인덱스로 특정 범위의 요소들을 찾는 것</li>
<li><code>[m:n]</code> : m부터 n-1까지<h4 id="리스트-연산">리스트 연산</h4>
</li>
<li>두 리스트 더하면, 서로 연결된 결괴 출력</li>
<li>정수값 곱하면 그 만큼 리스트 반복<h4 id="요소의-변경-추가-삭제">요소의 변경, 추가, 삭제</h4>
</li>
<li>변경 : 대입연산자 <code>=</code></li>
<li>추가 : append() 맨 뒤에 <strong>요소 하나</strong> 추가, insert(<code>[index]</code>,<code>value</code>) 해당 <code>[index]</code>에 value 값을 추가 (기존 값은 다음 위치로 밀고)</li>
<li>뒤에 리스트 더하기 : extend(<code>리스트</code>)</li>
<li>삭제 : 리스트 요소 앞에<code>del</code> 키워드, clear() 전체삭제<h4 id="리스트-관련-메서드">리스트 관련 메서드</h4>
</li>
<li>upper() 대문자로, reverse() 요소 역순으로, count() 요소 개수, index() 요소가 첨 나오는 인덱스값, sort() 오름차순정렬 (reverse=True 이면 그 반대), remove() 대상의 첫 요소 삭제, pop() 해당 위치 삭제후 그 값 반환, clear() 전체 삭제</li>
</ul>
<h3 id="2-튜플-집합-딕셔너리자료형">2) 튜플, 집합, 딕셔너리자료형</h3>
<ul>
<li>리스트, 튜플, 집합끼리 변환 가능 </li>
</ul>
<blockquote>
<h3 id="튜플">튜플</h3>
</blockquote>
<ul>
<li>소괄호<code>()</code> <code>tuple()</code> 사용</li>
<li>괄호 생략가능</li>
<li>한번 생성후, *<em>변경 불가 *</em></li>
<li>요소 하나이면, 요소 다음 콤마 추가해서 생성해야함</li>
</ul>
<blockquote>
<h3 id="집합">집합</h3>
</blockquote>
<ul>
<li>중괄호 <code>{}</code>, <code>set()</code> 사용 </li>
<li>집합 연산(교집합, 합집합, 차집합, 대칭 차집합)<ul>
<li>교집합 : <code>&amp;</code> <code>intersection()</code></li>
<li>합집합 : <code>|</code> <code>union()</code></li>
<li>차집합: <code>-</code>  <code>difference()</code> </li>
<li>대칭 차집합: <code>^</code>  <code>symmetric_difference()</code> </li>
</ul>
</li>
<li>중복 허용하지 않음 <em>중복 원소는 하나만 제외하고 모두 무시</em></li>
<li>원소의 순서 의미 없음 <em>인덱싱, 슬라이싱 불가</em></li>
</ul>
<h3 id="딕셔너리-java의-json">딕셔너리 <em>java의 json</em></h3>
<ul>
<li>집합과 마찬가지로 중괄호 <code>{ }</code> 를 사용</li>
<li>key : value의 형태<ul>
<li>key를 사용해 값을 확인</li>
</ul>
</li>
<li>요소의 삭제 : 요소 앞에 <code>del</code> 키워드, pop() key를 지정해 요소 삭제후, value 반환,
popitem() 임의 요소 삭제, </li>
<li>요소 확인 : keys() key값 리스트 조회, values() values값 리스트 조회, items() (key, value)형태로 모든 요소 리스트 조회, clear() 모두 삭제</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[스크럼(Scrum)]]></title>
            <link>https://velog.io/@liner_123456/%EC%8A%A4%ED%81%AC%EB%9F%BCScrum</link>
            <guid>https://velog.io/@liner_123456/%EC%8A%A4%ED%81%AC%EB%9F%BCScrum</guid>
            <pubDate>Fri, 18 Jul 2025 10:00:17 GMT</pubDate>
            <description><![CDATA[<h2 id="스크럼scrum기법">스크럼(Scrum)기법</h2>
<ul>
<li>팀이 중심이 되어 개발의 효율성 높이는 기법</li>
<li>팀원스스로 팀 구성, 개발 작업 모두 스스로 해결 가능해야 함</li>
</ul>
<blockquote>
<h3 id="스크럼-팀">스크럼 팀</h3>
<table>
<thead>
<tr>
<th>구성원</th>
<th>role</th>
</tr>
</thead>
<tbody><tr>
<td>제품 책임자</td>
<td>요구사항 담긴 <strong>백로그</strong> 작성 주체, 제품 이해도 🔼, 의사결정가능한 사람, 스프린트 검토 회의 주관</td>
</tr>
<tr>
<td>스크럼마스터</td>
<td>일 수행에 가이드 역할, 스프린트계획회의 주관</td>
</tr>
<tr>
<td>개발팀</td>
<td>그외 모든 팀원</td>
</tr>
</tbody></table>
</blockquote>
<blockquote>
<h3 id="스프린트">스프린트</h3>
<p>2- 4주 정도, 진행하는 과정</p>
</blockquote>
<ul>
<li>일일스프린트 회의 : 소멸차트, 약 15분</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[정처기 필기정리1] 소프트웨어 설계_IPSec]]></title>
            <link>https://velog.io/@liner_123456/%EC%A0%95%EC%B2%98%EA%B8%B0-%ED%95%84%EA%B8%B0%EC%A0%95%EB%A6%AC1-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%84%A4%EA%B3%84IPSec</link>
            <guid>https://velog.io/@liner_123456/%EC%A0%95%EC%B2%98%EA%B8%B0-%ED%95%84%EA%B8%B0%EC%A0%95%EB%A6%AC1-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%84%A4%EA%B3%84IPSec</guid>
            <pubDate>Mon, 03 Feb 2025 10:02:29 GMT</pubDate>
            <description><![CDATA[<h2 id="ipsecip-security이란">IPsec(IP Security)이란?</h2>
<p>: 통신 세션의 각 IP 패킷을 암호화하고, 인증하는 안전한 인터넷 프로토콜(IP) 통신을 위한 <strong>인터넷 프로토콜</strong></p>
<ul>
<li>양방향 암호화 지원한다.</li>
<li>ESP(Encapsulating Security Payload)는 발신지 인증, 데이터 무결성, 기밀성 모두 보장</li>
<li>운영모드는 Tunnel 모드와 Transport모드로 분류</li>
<li>AH는 발신지 호스트를 인증하고, IP패킷의 무결성을 보장한다.</li>
<li>전송모드 (Transport)는 전송계층과 네트워크계층 사이에 전달되는 payload를 보호한다.</li>
<li>터널모드(Tunnel)는 IPsec이 IP헤더를 포함한 IP계층의 모든 것을 보호한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[정처기 필기정리1] 소프트웨어 설계_자료흐름도(DFD, Data Flow Diagram)]]></title>
            <link>https://velog.io/@liner_123456/%EC%A0%95%EC%B2%98%EA%B8%B0-%ED%95%84%EA%B8%B0%EC%A0%95%EB%A6%AC1-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%84%A4%EA%B3%84%EC%9E%90%EB%A3%8C%ED%9D%90%EB%A6%84%EB%8F%84DFD-Data-Flow-Diagram</link>
            <guid>https://velog.io/@liner_123456/%EC%A0%95%EC%B2%98%EA%B8%B0-%ED%95%84%EA%B8%B0%EC%A0%95%EB%A6%AC1-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%84%A4%EA%B3%84%EC%9E%90%EB%A3%8C%ED%9D%90%EB%A6%84%EB%8F%84DFD-Data-Flow-Diagram</guid>
            <pubDate>Mon, 03 Feb 2025 08:19:16 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="특징">특징</h3>
</blockquote>
<ul>
<li>구조적 분석 기법에 이용된다.</li>
<li>자료 흐름 그래프 또는 버블(bubble) 차트라고도 한다.</li>
<li>시간 흐름을 명확하게 표현할 수 없다.</li>
</ul>
<blockquote>
<h3 id="구성-요소">구성 요소</h3>
<p><img src="https://velog.velcdn.com/images/liner_123456/post/65b94fbd-3f7c-46cd-91cd-55462340e551/image.png" alt=""></p>
</blockquote>
<ul>
<li>process : 원</li>
<li>data flow : 화살표</li>
<li>terminator: 사각형</li>
<li>data store: 평행선</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[정처기 필기정리1] 소프트웨어 설계_디자인 패턴]]></title>
            <link>https://velog.io/@liner_123456/%EC%A0%95%EC%B2%98%EA%B8%B0-%ED%95%84%EA%B8%B0%EC%A0%95%EB%A6%AC1-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%84%A4%EA%B3%84%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@liner_123456/%EC%A0%95%EC%B2%98%EA%B8%B0-%ED%95%84%EA%B8%B0%EC%A0%95%EB%A6%AC1-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%84%A4%EA%B3%84%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Mon, 03 Feb 2025 07:37:05 GMT</pubDate>
            <description><![CDATA[<h2 id="디자인-패턴-design-pattern">디자인 패턴 (Design Pattern)</h2>
<p><em>자주 사용되는 설계형태를 정형화하여 유형별로 설계 템플릿을 만들어 두고, 소프트웨어 개발 중 나타나는 과제를 해결하기 위한 방법</em></p>
<h3 id="장단점">장/단점</h3>
<table>
<thead>
<tr>
<th align="center">장점</th>
<th align="center">단점</th>
</tr>
</thead>
<tbody><tr>
<td align="center">개발자간 원활한 의사소통 지원</td>
<td align="center">객체지향 설계/구현 위주로 사용</td>
</tr>
<tr>
<td align="center">소프트웨어 구조파악 쉬움</td>
<td align="center">초기 투자 비용 부담 多</td>
</tr>
<tr>
<td align="center">재사용을 통한 개발시간 단축</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">설계 변경 요청에 유연한 대처가능</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">객체지향 설계 및 구현의 생산성을 높이는 데 적합</td>
<td align="center"></td>
</tr>
</tbody></table>
<h2 id="gof-gangs-of-four디자인-패턴">GoF (Gangs of Four)디자인 패턴</h2>
<ul>
<li>객체지향 설계 단계 중, 재사용에 관한 유용한 설계를 디자인 패턴화</li>
<li>생성패턴, 구조패턴, 행위패턴으로 분류한다.</li>
</ul>
<h3 id="1-생성패턴">1) 생성패턴</h3>
<p>: 객체생성과 관련된 패턴</p>
<ul>
<li>Factory Method</li>
<li><a href="https://velog.io/@liner_123456/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4Design-Pattern">Singleton</a> : 전역변수 사용하지 않고, 객체를 하나만 생성</li>
<li>Prototype</li>
<li>Builder</li>
<li>Abstraction Factory</li>
</ul>
<h3 id="2-구조패턴">2) 구조패턴</h3>
<p>: 클래스나 객체를 조합해 더 큰 구조를 만드는 패턴</p>
<ul>
<li>Adapter</li>
<li>Bridge</li>
</ul>
<h3 id="3-행위패턴">3) 행위패턴</h3>
<p>: 반복적으로 사용되는 상호작용을 패턴화</p>
<ul>
<li>클래스나 객체들이 상호작용하는 방법과 책임을 분산하는 방법을 정의</li>
<li>Mediator (중재자) ...</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[정처기 필기정리1] 소프트웨어 설계_SW 아키텍쳐 패턴]]></title>
            <link>https://velog.io/@liner_123456/SW-%EC%95%84%ED%82%A4%ED%85%8D%EC%B3%90-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@liner_123456/SW-%EC%95%84%ED%82%A4%ED%85%8D%EC%B3%90-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Mon, 03 Feb 2025 07:29:55 GMT</pubDate>
            <description><![CDATA[<h2 id="아키텍처-패턴">아키텍처 패턴</h2>
<p>: 소프트웨어 아키텍처를 설계하는데, 발생하는 문제점을 해결하기 위한 재사용가능한 솔루션으로 디자인 패턴과 유사하나, 더 큰 범위에 속한다.</p>
<h3 id="1-계층-layered-패턴">1) 계층 (Layered) 패턴</h3>
<ul>
<li>소프트웨어를 계층단위(Unit)로 분할하며, <strong>N-tier 아키텍처 패턴</strong>이라고도 한다.</li>
<li>계층적으로 조직화 할 수 있는 서비스로 구성된 애플리케이션에 적합하다.</li>
<li>전통적인 방법으로 층 내부의 응집도를 높이는 것이 중요하다.</li>
<li>모듈들의 응집된 집합 계층 간의 관계는 사용 가능의 관계로 표현된다. <h3 id="2-mvc-model-view-controller패턴">2) MVC (Model View Controller)패턴</h3>
: 대화형 애플리케이션을 Model, View, Controller 로 분류한다.</li>
</ul>
<table>
<thead>
<tr>
<th align="center">애플리케이션</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Model</td>
<td align="center">핵심기능 + 데이터</td>
</tr>
<tr>
<td align="center">View</td>
<td align="center">사용자에게 정보를 표시 ( 다수의 View 정의 가능)</td>
</tr>
<tr>
<td align="center">Controller</td>
<td align="center">사용자로부터 입력을 처리</td>
</tr>
<tr>
<td align="center">### 3) 클라이언트 서버 (Client-Server) 패턴</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">: 하나의 서버와 다수 클라이언트로 구성</td>
<td align="center"></td>
</tr>
</tbody></table>
<blockquote>
<p>클라이언트가 서버에 서비스를 요청히면 커뮤니케이션이 이뤄진다.  </p>
</blockquote>
<ul>
<li>서버는 응답을 위해 항상 대기 중이어야 한다. </li>
</ul>
<h3 id="4-파이프-필터-pipe-filters">4) 파이프 필터 (Pipe-Filters)</h3>
<ul>
<li>데이터 흐름(data stream)을 생성하고, 처리하는 시스템을 위한 구조</li>
<li><code>필터</code> : <code>파이프</code>를 통해 받은 데이터를 변경시키고, 그 결과를 <code>파이프</code>로 전송한다.</li>
<li><code>파이프</code> : 데이터의 흐름, 버퍼링 또는 동기화 목적으로 사용될 수 있다.</li>
<li>각 처리과정은 필터 컴포넌트에서 이뤄진다.</li>
<li>컴파일러, 연속한 필터들은 어휘 분석, 파싱, 의미분석, 코드 생성을 수행</li>
</ul>
<h3 id="5-peer-to-peer">5) Peer to Peer</h3>
<h3 id="6-브로커-broker">6) 브로커 (Broker)</h3>
<h3 id="7-블랙보드-black-board">7) 블랙보드 (Black Board)</h3>
<h3 id="8-이벤트-버스-event-bus">8) 이벤트 버스 (Event-Bus)</h3>
<h3 id="9-인터프리터-interpreter">9) 인터프리터 (Interpreter)</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[[정처기 필기정리1] 소프트웨어 설계_모듈의 응집도와 결합도]]></title>
            <link>https://velog.io/@liner_123456/%EB%AA%A8%EB%93%88%EC%9D%98-%EC%9D%91%EC%A7%91%EB%8F%84%EC%99%80-%EA%B2%B0%ED%95%A9%EB%8F%84</link>
            <guid>https://velog.io/@liner_123456/%EB%AA%A8%EB%93%88%EC%9D%98-%EC%9D%91%EC%A7%91%EB%8F%84%EC%99%80-%EA%B2%B0%ED%95%A9%EB%8F%84</guid>
            <pubDate>Mon, 03 Feb 2025 03:36:17 GMT</pubDate>
            <description><![CDATA[<h2 id="응집도cohesion">응집도(Cohesion)</h2>
<p>: 한 모듈 내에 있는 처리요소들 사이의 기능적인 연관정도를 나타낸다.</p>
<table>
<thead>
<tr>
<th align="center">강함</th>
<th align="center">...</th>
<th align="center">약함</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>기능적 응집도</strong></td>
<td align="center">&gt; 순차적 응집도 &gt; 교환적 응집도 &gt; 절차적 응집도 &gt; 시간적 응집도 &gt; 논리적 응집도 &gt;</td>
<td align="center">우연적 응집도</td>
</tr>
</tbody></table>
<h2 id="결합도">결합도</h2>
<p>: 모듈들이 변수를 공유하지 않도록, 결합도를 낮추어야 한다. </p>
<table>
<thead>
<tr>
<th align="center">낮음</th>
<th align="center">...</th>
<th align="center">높음</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>데이터 결합도</strong></td>
<td align="center">&gt; 스탬프 결합도 &gt; 제어 결합도 &gt; 외부 결합도&gt; 공통 결합도 &gt;</td>
<td align="center">내용 결합도</td>
</tr>
</tbody></table>
<h2 id="💌-효과적인-모듈화-설계-방법">💌 효과적인 모듈화 설계 방법</h2>
<ul>
<li>응집도는 강하게, 결합도는 약하게 설계한다.</li>
<li>복잡도와 중복성을 줄이고, 일관성을 유지할 수 있도록 설계한다.</li>
<li>유지보수가 용이하도록 설계한다.</li>
<li>모듈크기는 시스템의 전반적인 기능과 구조를 이해하기 쉬운 크기로 설계한다.</li>
<li>모듈기능이 예측가능해야 하며, 지나치게 제한적이어서는 안된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Final Project] Spring 팀 프로젝트 개발 후기]]></title>
            <link>https://velog.io/@liner_123456/Final-Project-Spring-%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B0%9C%EB%B0%9C-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@liner_123456/Final-Project-Spring-%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B0%9C%EB%B0%9C-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Tue, 24 Dec 2024 00:00:46 GMT</pubDate>
            <description><![CDATA[<h2 id="📆-제작-일정">📆 제작 일정</h2>
<p><code>2024년 11월 04일 ~ 2024년 12월 24일</code></p>
<blockquote>
<p>7월부터 시작한 자바프로그래밍 국비 지원 프로그램의 대장정의 끝을 마무리하며 프로젝트의 후기를 정리해본다.
<img src="https://velog.velcdn.com/images/liner_123456/post/f491dc86-182f-4fe5-aa15-9743c29ce330/image.jpg" alt=""></p>
</blockquote>
<h2 id="🤝-팀원-역할소개">🤝 팀원 역할소개</h2>
<p><img src="https://velog.velcdn.com/images/liner_123456/post/bfff31fd-a758-4ab1-a637-5980f05a6bd4/image.png" alt=""></p>
<h3 id="🧑💻-내가-맡은-역할은">🧑‍💻 내가 맡은 역할은?</h3>
<p>소셜로그인을 포함한 로그인 및 회원가입 가능구현과 마이페이지 화면 UI 디자인을 구현하는 것입니다.</p>
<h2 id="🔎-주제-선정-및-프로젝트-설계">🔎 주제 선정 및 프로젝트 설계</h2>
<p>트립자바는 국내 여행자들을 위한 숙박 예약을 도와주는 웹사이트 서비스입니다. 숙박 예약 사이트를 주제로 선정한 이유는 최근 숙박 예약 플랫폼은 여행, 출장 등에서 필수적인 서비스로 자리 잡았습니다.</p>
<ul>
<li><code>여기어때</code> 사이트를 참조하여 제작하였습니다.</li>
</ul>
<blockquote>
<h3 id="📌-주요-기능">📌 주요 기능</h3>
</blockquote>
<ul>
<li>사용자 친화적인 인터페이스를 통한 다양한 숙소를 검색 및 예약 기능</li>
<li>소셜 로그인을 통한 간편한 회원가입</li>
<li>리뷰 기능</li>
<li>지도 기반 위치 서비스를 제공</li>
<li>실시간 예약 및 결제 시스템, 예약 및 결제 정보의 실시간 동기화
<img src="https://velog.velcdn.com/images/liner_123456/post/4494620e-e59f-4ae8-bb95-2799c4ff6e90/image.png" alt=""></li>
</ul>
<blockquote>
<h3 id="📌-개발환경-및-사용기술">📌 개발환경 및 사용기술</h3>
<p><img src="https://velog.velcdn.com/images/liner_123456/post/591f70a1-3cb8-4ae4-823c-a604c27dfc1f/image.png" alt=""></p>
</blockquote>
<ul>
<li>개발 환경 : Eclipse, Visual Studio Code, Spring Boot, JPA Hibernate, React </li>
<li>사용 언어 : JavaScript, HTML5, CSS3, Java, JPQL, QueryDSL </li>
<li>협업 : Github</li>
<li>서버 : Apache Tomcat</li>
<li>데이터베이스 툴 : DBeaver</li>
<li>API : 카카오 로그인 API, 네이버 지도 API, 토스 결제 API, 한국관광공사 공공데이터 API</li>
</ul>
<blockquote>
<h3 id="📌-내가-담당한-기능의-플로우-차트">📌 내가 담당한 기능의 플로우 차트</h3>
<p><img src="https://velog.velcdn.com/images/liner_123456/post/607d1572-1b3f-4887-b94b-698b395b96a9/image.png" alt=""></p>
</blockquote>
<blockquote>
<h3 id="📌-erd-설계">📌 ERD 설계</h3>
<p><img src="https://velog.velcdn.com/images/liner_123456/post/b81653dd-496a-4c91-922e-a5d59ef5035c/image.png" alt=""></p>
</blockquote>
<h2 id="🖥️-기능-구현">🖥️ 기능 구현</h2>
<p>웹사이트의 회원정보를 관리하는 역할이라 보면 된다. </p>
<ul>
<li>완성된 전체 프로젝트 <a href="https://github.com/devlsn96/Final_project.git">다음 링크</a>와 같습니다.</li>
</ul>
<h3 id="✅-로그인회원가입-기능">✅ 로그인/회원가입 기능</h3>
<blockquote>
<h4 id="이메일에서-로그인">이메일에서 로그인</h4>
<blockquote>
<p><img src="https://velog.velcdn.com/images/liner_123456/post/8da1c3f3-53e7-430d-a61e-cfc8e19bd9fc/image.png" alt=""></p>
</blockquote>
</blockquote>
<ul>
<li>리액트 컴포넌트 구성 : 입력박스 태그의 재사용 가능성이 많으므로  input 태그를 컴포넌트로 구성하였습니다. </li>
<li>각 입력요소에 커서가 벗어날 때 마다, 입력된 값에 대해서 입력값의 형식, 빈 값 여부, 글자수 등을 확인하는 유효성 검증을 진행하여 로그인을 위한 기본 조건을 만족하는 값들만 데이터를 전송할 수 있도록 하였습니다.</li>
<li>JPQL을 통한 로그인 정보 조회 : 유저 테이블에 저장된 email, password 값과 입력한 이메일, 비밀번호 값의 일치하는 검색 쿼리를 만들어서 일치여부에 따라 로그인이 진행될 수 있도록 하였습니다.</li>
</ul>
<blockquote>
<h4 id="이메일로-회원가입">이메일로 회원가입</h4>
<blockquote>
<p><img src="https://velog.velcdn.com/images/liner_123456/post/7c9642dd-325f-4231-8f8c-b6c69156f456/image.png" alt=""></p>
</blockquote>
</blockquote>
<ul>
<li>위의 로그인 페이지와 동일한 방식으로 input 컴포넌트를 사용하여 페이지 컴포넌트를 구성하였습니다.</li>
<li>위의 로그인 페이지와 동일한 방식으로 유효성 검증을 진행하여 회원정보 데이터를 전송했습니다.</li>
<li>Spring에서 DB처리를 하는데 유용한 JPA를 사용하여 회원정보를 데이터베이스에 반영하였습니다.</li>
</ul>
<h3 id="✅-마이페이지-기능">✅ 마이페이지 기능</h3>
<blockquote>
<h4 id="내정보관리">내정보관리</h4>
<blockquote>
<p><img src="https://velog.velcdn.com/images/liner_123456/post/35e37c9c-e0a5-4d53-bce8-3439f2a96a8d/image.jpg" alt=""></p>
</blockquote>
</blockquote>
<ul>
<li>페이지 이동 기능 : 리액트 라우터에서 사용가능한 기능으로 jsx 코드 내에 NavLink를 사용하여 해당 페이지로의 이동과 그에 따른 동적 스타일링을 진행하였습니다.</li>
<li>리스트 출력 기능 
① 사용자가 회원가입시 작성한 정보가 나타나도록 input jsx 코드로 나열하였습니다.
② 회원 정보 테이블의 인덱스 값인 user_id으로 회원정보를 조회하여 데이터베이스의 검색 성능을 개선하면서 처리하였습니다.</li>
<li>리스트 수정 기능 
① useState hook함수를 사용하여 편집 가능 여부에 따라 동적으로 데이터 처리하여 조회되는 회원정보 입력을 하도록 처리하였습니다.
② 변경된 회원정보를 입력후, 저장버튼을 누르면, 회원가입 시 데이터 저장 방식과 동일하게 데이터 베이스에 저장 처리하였습니다.</li>
</ul>
<blockquote>
<h4 id="예약내역">예약내역</h4>
<blockquote>
<p><img src="https://velog.velcdn.com/images/liner_123456/post/a435c372-cde4-4b0c-9074-906f5a48ed8f/image.png" alt=""></p>
</blockquote>
</blockquote>
<ul>
<li>페이지 이동 기능 : 마이페이지의 내 정보 관리에서 동일한 방식으로 기능합니다.</li>
<li>예약 리스트 출력 및 삭제 기능 
① useEffect 훅을 사용하여 컴포넌트가 마운트될 때 또는 userId가 변경될 때 예약 데이터를 가져왔습니다.
② 예약 취소 버튼을 통해서 State변수에 저장하고 확인 모달창을 거쳐 서버에 취소 요청 처리를 하였습니다.</li>
</ul>
<blockquote>
<h4 id="위시리스트">위시리스트</h4>
<blockquote>
<p><img src="https://velog.velcdn.com/images/liner_123456/post/44bf53be-70f7-49d0-9739-413b09728214/image.png" alt=""></p>
</blockquote>
</blockquote>
<ul>
<li>페이지 이동 기능 : 마이페이지의 내 정보 관리에서 동일한 방식으로 기능합니다.</li>
<li>위시리스트 출력 기능 : useEffect 훅을 사용하여 위시리스트 데이터를 가져왔습니다.</li>
<li>위시리스트 삭제 기능 : 
① 삭제 버튼을 사용하여, 특정 위시리스트 id 값을 삭제했습니다.
hoveredItemId 상태 변수를 이용해서 마우스 상태를 업데이트하고, 삭제 버튼을 표시했습니다.
② 삭제 버튼이 클릭시, 클릭이벤트가 부모로 전달되지 않도록 하여 accomId에 해당하는 숙소 상세페이지로 이동하는 기능을 제한 하였습니다.</li>
</ul>
<h2 id="🤔-소감">🤔 소감</h2>
<p>프로젝트를 진행하면서, 여행을 하고 샆은 사용자들에게 중요한 숙소정보를 웹사이트로 제공할 수 있는 서비스를 직접 제작했습니다. 이러한 과정이 실제 사용자에게 유용한 서비스가 될 수 있다는 생각에 보람을 가질 수 있어 즐거웠습니다. 
이번 프로젝트에서는 웹서비스의 가장 기본적인 회원관리 기능을 주도적으로 담당하였는데, 다음 프로젝트를 진행할 기회가 된다면 웹서비스의 가장 핵심적이고 특징적인 기능에 참여하여 개발자로서 더 성장할 수 있는 기쁨을 누리고 싶습니다.</p>
<h3 id="🥺-아쉬운-점">🥺 아쉬운 점</h3>
<p>프로젝트를 하면서 아쉬웠던 점은 로그인, 회원가입 기능을 담당하였는데, 프로젝트 말미에  통합 중 각 회원정보에 대해서 리뷰와 예약 및 결제 정보, 찜하기 정보 데이터가 실제 담는 과정에서 회원정보를 삭제 시, 데이터의 무결성이 충족되지 않는다는 것을 알게되었습니다. 이를 해결하기 위해 테이블간 연결된 외래키 컬럼값에 cascade 제약조건을 추가하여 데이터의 무결성이 되도록 해결하였습니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React 기본 개념 정리]]></title>
            <link>https://velog.io/@liner_123456/React-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@liner_123456/React-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 04 Nov 2024 08:46:27 GMT</pubDate>
            <description><![CDATA[<h2 id="1-reactjs-기본-개발환경-설정"><a href="https://react.dev/">1. React.js 기본 개발환경 설정</a></h2>
<ul>
<li>Facebook (Meta)에서 개발한 <strong>JavaScript 라이브러리</strong>이다.</li>
<li>UI를 구현하는 도구로 javascript 언어를 기반으로 사용한다. </li>
<li>&quot;반응하다&quot; 라는 의미로 javascript 중심으로 사용되는 정의형 프로그래밍이 아닌 반응형 프로그래밍이다.</li>
<li>화면상에 출력될 코드를 컴포넌트의 return문을 이용해서 jsx코드로 표현하는 것이 목적이다.</li>
<li>자바스크립트의 이벤트 역할을 하는 것이 <strong>리액트의 컴포넌트</strong>이다.</li>
</ul>
<blockquote>
<h3 id="vanilla-javascript">Vanilla JavaScript</h3>
</blockquote>
<ul>
<li>자바스크립트만으로 작성한 언어로 간단한 FE 코드를 작성하는 것은 다수의 코드양이 필요하다.</li>
<li>자바스크립트의 코드가 길어질수록 에러를 내재할 확률이 높아지기 때문에, 유지 보수가 어렵다.</li>
<li>따라서, React가 이를 보완하기 위해 <strong>JSX위주의 프로그램 방식을 채택하였다.</strong></li>
</ul>
<blockquote>
<h3 id="nodejs-설치"><a href="https://nodejs.org/en">Node.js 설치</a></h3>
</blockquote>
<ul>
<li>리액트 프로젝트에서 원할한 서버 구축을 위한 웹서버 프로그램</li>
<li>리액트 프로젝트 만든 후, 디렉토리 접근한다.<ul>
<li>npm create vite@latest (프로젝트이름)
cd (프로젝트이름)</li>
<li>테스트용 서버 설치 및 실행 
npm install
npm run dev</li>
</ul>
</li>
</ul>
<blockquote>
<h3 id="vite"><a href="https://ko.vite.dev/guide/">vite</a></h3>
</blockquote>
<ul>
<li>리액트 프로젝트의 디렉토리 구조를 만들어 주는 툴</li>
</ul>
<h3 id="spasingle-page-app">SPA(Single Page App)</h3>
<ul>
<li>페이지 하나에서 구현되는 것</li>
<li>레이아웃의 변화는 적지만, 그 안에서 실시간으로 변화가 많을때 적합한 방식이다.</li>
</ul>
<h2 id="2-컴포넌트">2. 컴포넌트</h2>
<p>프로그램의 모든 실행을 위한 구성단위로 함수로 표현한다.</p>
<pre><code>function App (){
state(); // state로 변수 선언
return; // return 키워드안에 JSX코드
}</code></pre><ul>
<li>보통, 1개의 파일에는 1개의 컴포넌트가 권장사항이지만, 예외도 있다.</li>
</ul>
<h3 id="2-1-웹-페이지를-구성하는-리액트">2-1. 웹 페이지를 구성하는 리액트</h3>
<table>
<thead>
<tr>
<th align="center">웹페이지</th>
<th align="center">역할</th>
<th align="center">리액트</th>
</tr>
</thead>
<tbody><tr>
<td align="center">HTML</td>
<td align="center">뼈대</td>
<td align="center">컴포넌트의 <strong>JSX</strong></td>
</tr>
<tr>
<td align="center">CSS</td>
<td align="center">살</td>
<td align="center">CSS</td>
</tr>
<tr>
<td align="center">JavaScript</td>
<td align="center">내장기관</td>
<td align="center">JavaScript</td>
</tr>
</tbody></table>
<h3 id="2-2-컴포넌트를-왜-이용하는가">2-2. 컴포넌트를 왜 이용하는가</h3>
<ul>
<li>재사용성<ul>
<li>컴포넌트는 결국 함수로서, 재사용이 가능하다.</li>
<li>(레고 블록처럼) 작은 블록을 제작하고, UI로써 조립해서 사용가능하다는 장점이 있다.</li>
</ul>
</li>
<li>모듈화 : 컴포넌트는 내부에 html, css, javascript 코드를 모두 품고 있어 모듈화가 가능하다.</li>
</ul>
<h3 id="2-3-컴포넌트의-생성-규칙">2-3. 컴포넌트의 생성 규칙</h3>
<ul>
<li>컴포넌트는 자바스크립트 함수의 형태이다.</li>
<li>컴포넌트의 이름의 첫글자는 언제나 대문자이다.</li>
<li>return되는 코드는 리액트가 랜더링 할 수 있는 JSX코드여야만 한다.</li>
</ul>
<h3 id="2-4-jsx">2-4. JSX</h3>
<ul>
<li>html태그와 유사한 형태로 return 키워드 안 코드이다.</li>
<li>컴포넌트가 랜더링시, <strong>실제 랜더링이 되는 대상</strong>이 된다.<pre><code>return (
  &lt;div&gt;
    &lt;Header /&gt;
    &lt;main&gt;
        &lt;h2&gt;시작해봅시다!&lt;/h2&gt;
    &lt;/main&gt;
  &lt;/div&gt;
);</code></pre><h3 id="2-5-jsx의-표현식">2-5. JSX의 표현식</h3>
</li>
<li><code>{  }</code> 안에 자바스크립트 표현식을 사용한다.<ul>
<li>삼항연산자, <code>map()</code>, <code>with()</code>등을 사용가능하다.</li>
<li>조건절은 사용불가</li>
</ul>
</li>
<li>JSX코드는 JSX문법만을 사용해야 하지만, 자바스크립트의 &quot;식&quot;을 이용하고 싶다면 JSX 코드 내부에서 중괄호를 이용해서 접근해서 사용하면 된다.</li>
</ul>
<h2 id="3-reactdom-라이브러리">3. ReactDOM 라이브러리</h2>
<ul>
<li>리액트에서 사용하는 가상 DOM가 있다. </li>
<li>JSX으로 만들어진 가상 DOM이 있는데, 각각의 DOM 객체를 조립하여 사용한다.</li>
<li>이렇게 조립된 객체는 ReactDOM 라이브러리를 통해 리액트가 브라우저 상에 노출되는 DOM으로 변환하여 랜더링한다.<ul>
<li>ReactDOM의 createRoot메서드를 활용하여</li>
<li><code>&lt;App /&gt;</code>로 랜더링되는 컴포넌트를 표현</li>
</ul>
</li>
<li>실제 DOM 객체와 가상 DOM 객체는 일치하게 된다.</li>
<li>ReactDOM의 <code>render()</code>함수가 해당 컴포넌트를 랜더링을 하며 진입을 시작한다.<pre><code>import ReactDOM from &quot;react-dom/client&quot;;
import App from &quot;./App.jsx&quot;;
ReactDOM.createRoot(
document.getElementById(&quot;root&quot;)
).render(&lt;App /&gt;);</code></pre><blockquote>
<p>각각의 컴포넌트는 <code>Tree구조</code>로 표현할 수 있다.</p>
</blockquote>
<ul>
<li>리액트는 &quot;트리형태의 컴포넌트 구조&quot;를 만든다.
<img src="https://velog.velcdn.com/images/liner_123456/post/0ca93aef-2dd5-484e-b5d3-ac266173c191/image.PNG" alt=""></li>
</ul>
</li>
<li>컴포넌트의 데이터 접근은 <code>HTML</code> &gt; <code>JS</code> &gt; <code>jsx</code>로 진입한다.
즉, javascript를 통해 리액트 코드를 실행시킨다.</li>
</ul>
<h2 id="4-props">4. Props</h2>
<ul>
<li>매개변수를 사용해서 로직을 구현할 수 있다.<ul>
<li>이때의 매개변수는 별개의 properties의 변수명으로 나열하는 방식이 아니라 객체를 매개변수로 담아주는 것처럼 Props(프랍)을 사용한다.</li>
</ul>
</li>
<li>매개변수의 네이밍은 제약이 없다.</li>
</ul>
<h2 id="5-state">5. State</h2>
<ul>
<li>변경이 감지되면, 랜더링된다. </li>
<li>set함수로 상태를 변경한다. </li>
<li>변수와 수정할 함수로 구성된 리스트로 이뤄져 있다.</li>
</ul>
<h2 id="6-usestate와-useref">6. useState와 useRef</h2>
<p>useState는 변경감지시, 랜더링되는 반면, 
Ref는 변경감지 되어도 랜더링되지 않는다.</p>
<ul>
<li>ref객체의 current객체로 해당 DOM에 접근함</li>
</ul>
<h2 id="7-useeffect">7. useEffect</h2>
<h3 id="컴포넌트에는-생명주기가-있다">컴포넌트에는 생명주기가 있다.</h3>
<ul>
<li>특정시점에 작동하는 기능을 useEffect를 실행시키면 구현가능  <pre><code>useEffect(() =&gt; {
      // 실행 구문
      return () =&gt; {
      // 컴포넌트가 사라지기 전에 호출 
      }
}, [변경감지할 변수]);</code></pre><blockquote>
<p>그러나, 변경이 감지 될때마다 랜더링이 계송실행되므로 쓸데없는 메모리 낭비 발생할 수 있다. 굳이 알아야 할 필요 없다면, 랜더링 방지할 필요있음 </p>
<blockquote>
<p><strong>useMemo</strong> 사용하면됨</p>
</blockquote>
</blockquote>
</li>
</ul>
<h2 id="8-usememo">8. useMemo</h2>
<pre><code>useMemo(()=&gt;{
        return 
        // 랜더링하지 않을 구문
},[랜더링하지 않을 변수]);</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[QueryDSL 개념 정리]]></title>
            <link>https://velog.io/@liner_123456/QueryDSL-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@liner_123456/QueryDSL-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Thu, 31 Oct 2024 06:33:31 GMT</pubDate>
            <description><![CDATA[<p>JPQL은 검색에 대한 null 처리가 너무 복잡하기 때문에 검색 쿼리에 대한 더 좋은 유지관리를 위해 QueryDSL을 사용한다.</p>
<blockquote>
<h2 id="querydsl-설정하기">QueryDSL 설정하기</h2>
</blockquote>
<ul>
<li>먼저, QueryDSL에 대한 라이브러리를 추가한다. (gradle방식)
<code>implementation &#39;com.querydsl:querydsl-jpa:5.0.0:jakarta&#39;
annotationProcessor &quot;com.querydsl:querydsl-apt:5.0.0:jakarta&quot;
annotationProcessor &quot;jakarta.annotation:jakarta.annotation-api&quot;
annotationProcessor &quot;jakarta.persistence:jakarta.persistence-api&quot;</code></li>
<li>Q클래스를 저장할 공간 지정을 위한 설정을 추가 한다.<pre><code>def querydslDir = &quot;$buildDir/generated/querydsl&quot;
sourceSets {
  main.java.srcDirs += [ querydslDir ]
}
tasks.withType(JavaCompile) {
  options.generatedSourceOutputDirectory = file(querydslDir)
}
clean.doLast {
  file(querydslDir).deleteDir()
}</code></pre></li>
<li>Qclass생성을 위해 Gradle task에서 해당 프로젝트의 build파일을 실행해준다.
<img src="https://velog.velcdn.com/images/liner_123456/post/af451c52-ba6e-4c54-b374-2961905a37e8/image.png" alt=""></li>
<li>다음과 같은 build폴더가 생기면 QueryDSL을 작성할 준비가 된거다!!
<img src="https://velog.velcdn.com/images/liner_123456/post/bef74f0c-f0a2-4704-a81c-3b9f95bcf811/image.png" alt=""></li>
</ul>
<h2 id="querydsl-사용하기">QueryDSL 사용하기</h2>
<h3 id="01-querydsl-객체를-선언">01. queryDSL 객체를 선언</h3>
<p><code>JPAQueryFactory queryFactory = new JPAQueryFactory(em);</code></p>
<h3 id="02-q엔티티객체-생성과-별칭명을-부여한다">02. Q엔티티객체 생성과 별칭명을 부여한다.</h3>
<ul>
<li>예를 들어, QMember 가 있다고 한다면, QMember객체의 이름은 &#39;m&#39;이다.
<code>QMember m = new QMember(&quot;m&quot;);</code>
<code>QMember m = QMember.m;</code></li>
<li>상단에 <code>import static</code> 구문으로 변수를 직접 지정할 수도 있다.
<code>import static com.codingbox.querydsl.entity.QMember.*;</code></li>
</ul>
<h3 id="03-쿼리-작성">03. 쿼리 작성</h3>
<p><code>select m from Member m where m.username = :username</code>
과 같은 쿼리는 아래와 같이 표현할 수 있다. </p>
<pre><code>queryFactory.select(member)
            .from(member)
            .where(member.username.eq(&quot;member1&quot;))
            .fetchOne();</code></pre><ul>
<li><code>.select(member)</code>하는 대상과 <code>.from(member)</code>하는 대상이 동일하면, <code>.selectFrom(member)</code>이 가능하다.</li>
</ul>
<h4 id="sql-예약어와-querydsl-내장함수-비교">SQL 예약어와 QueryDSL 내장함수 비교</h4>
<table>
<thead>
<tr>
<th align="center">SQL</th>
<th align="center">QueryDSL</th>
</tr>
</thead>
<tbody><tr>
<td align="center">AND절</td>
<td align="center">.and() (또는, and()를 콤마(,)로 구분가능하다)</td>
</tr>
<tr>
<td align="center">order by asc, order by desc절</td>
<td align="center">.orderBy(필드값.desc()나 .asc())</td>
</tr>
<tr>
<td align="center">null은 마지막에 위치</td>
<td align="center">.nullsLast()</td>
</tr>
<tr>
<td align="center">group by절</td>
<td align="center">.groupBy()</td>
</tr>
<tr>
<td align="center">having 조건절</td>
<td align="center">.having()</td>
</tr>
<tr>
<td align="center">left outer join절</td>
<td align="center">.leftJoin(&quot;조인객체&quot;,&quot;객체이름&quot;).on(&quot;조인되는필드값&quot;)</td>
</tr>
<tr>
<td align="center">inner join절</td>
<td align="center">.join().on()</td>
</tr>
<tr>
<td align="center">IN절</td>
<td align="center">.in()</td>
</tr>
<tr>
<td align="center">concat절</td>
<td align="center">.concat(&quot;&quot;)</td>
</tr>
</tbody></table>
<h4 id="쿼리-조회">쿼리 조회</h4>
<ul>
<li><code>fetch()</code> : 리스트로 조회</li>
<li><code>fetchOne()</code> : 단 건으로 조회</li>
</ul>
<h4 id="페이징-처리">페이징 처리</h4>
<ul>
<li><code>.offset()</code> : JPQL의 setFirstResult(), 해당 인덱스부터 조회</li>
<li><code>.limit()</code> : JPQL의 setMaxResults(), 해당 건까지 조회</li>
</ul>
<h4 id="집합-함수-처리">집합 함수 처리</h4>
<p>jpql의 count(*), sum(m.age), avg(m.age), max(m.age), min(m.age)등 집계함수에 대한 처리는 queryDSL에서도 <code>Tuple</code>이라는 라이브러리를 사용하면 가능하다. 
<code>select count(m), sum(m.age), avg(m.age), max(m.age), min(m.age) from Member m</code></p>
<h4 id="서브-쿼리">서브 쿼리</h4>
<ul>
<li>Q엔티티 객체를 하나 더 생성해서 <code>JPAExpressions</code>로 서브 쿼리문으로 활용<pre><code>queryFactory.selectFrom(member)
          .where(member.age.eq(
              JPAExpressions.select(memberSub.age.max())
                          .from(memberSub)
          ))</code></pre></li>
</ul>
<h4 id="case-구문">case 구문</h4>
<p>| when ~ then문 | .when(조건).then(&quot;값&quot;).otherwise(&quot;기타 값&quot;) |</p>
<ul>
<li>좀 더 복잡한 case문은 <code>new CaseBuilder()</code> 객체를 통해 생성할 수 있다.</li>
</ul>
<h3 id="dto-객체를-조회할-때">DTO 객체를 조회할 때,</h3>
<ul>
<li><code>Projections</code>객체를 활용하여 bean, fields, 생성자를 조회할 수 있다. </li>
<li>bean<pre><code>.select(Projections.bean(MemberDTO.class, member.username, member.age))</code></pre></li>
<li>fields (만약, fields값이 다르면, <code>.as()</code>를 붙혀 이름을 동일하게 변경한다.)<pre><code>.select(Projections.fields(MemberDTO.class, member.username, member.age))</code></pre><pre><code>.select(Projections.fields(UserDTO.class, member.username.as(&quot;name&quot;), member.age))</code></pre></li>
<li>생성자<pre><code>.select(Projections.constructor(MemberDTO.class, member.username, member.age))</code></pre></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[가변길이 인자]]></title>
            <link>https://velog.io/@liner_123456/%EA%B0%80%EB%B3%80%EA%B8%B8%EC%9D%B4-%EC%9D%B8%EC%9E%90</link>
            <guid>https://velog.io/@liner_123456/%EA%B0%80%EB%B3%80%EA%B8%B8%EC%9D%B4-%EC%9D%B8%EC%9E%90</guid>
            <pubDate>Wed, 30 Oct 2024 01:57:56 GMT</pubDate>
            <description><![CDATA[<h2 id="java에서의-가변길이-인자">Java에서의 가변길이 인자</h2>
<h3 id="배경">배경</h3>
<p>enum 클래스와 마찬가지로, 버전 업데이트가 되면서 사용되는 개념으로, 자바에서는 파라미터의 갯수가 다르면 다른 메서드로 인식하기 때문에 동일한 기능을 하지만 파라미터가 가변적으로 변경되는 경우, <strong>오버로딩(Overloading)</strong>한다.</p>
<h3 id="가변인자의-사용">가변인자의 사용</h3>
<p>오버로딩은 파라미터 개수에 맞춰 메서드가 계속 늘어나는 구조인데, 가변인자를 사용하면 동적으로 파라미터(parameter)를 받을 수 있다.</p>
<ul>
<li>사용법은 변수 타입 뒤에 기호 <code>...</code> 붙여주면 된다.</li>
<li>메서드 호출 역시 일반 메서드 호출하듯이 호출해주면 된다.</li>
</ul>
<pre><code>// 매개변수 없이 호출
test();            // 출력 X
// 매개변수 담아 호출
test(&quot;A&quot;, &quot;B&quot;);  // A B 출력
// 배열객체에 담아 호출
test(new String[] {&quot;A&quot;, &quot;B&quot;, &quot;C&quot;});        // A B C 출력</code></pre><ul>
<li>매개변수를 동적으로 담아 메서드를 생성할 수 있다.<pre><code>public static void test(String... param) {
      // 배열로 파라미터 값을 할당
      String[] array = param;    
      // 배열객체를 반복해서 출력
      for (String str : param) {
          System.out.println(str);
      }
}</code></pre></li>
<li>오버로딩으로 다른 인자를 담은 메서드를 생성 가능하고, 이렇게 가변인자와 함께 사용하는 경우는 <strong>가변인자를 가장 뒤에 위치시킨다.</strong><pre><code>public static void test(int num, String... param) {        
      String[] array = param;    
      for (String str : param) {
          System.out.println(str);
      }
}</code></pre></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Enum [Enumeration]]]></title>
            <link>https://velog.io/@liner_123456/Enum-Enumeration</link>
            <guid>https://velog.io/@liner_123456/Enum-Enumeration</guid>
            <pubDate>Mon, 28 Oct 2024 07:56:20 GMT</pubDate>
            <description><![CDATA[<h3 id="1-enum이란">1. Enum이란?</h3>
<p>자바 버전이 업데이트가 되면서 추가된 개념인데, 데이터 중에는 요일(월 화 수 목 금 토 일), 계절(봄 여름 가을 겨울) 등 과 같이 몇 가지 한정된 값을 갖는 경우가 흔히 있는데, 요일, 계절과 같이 한정된 데이터만을 가지는 타입을 Enumeration Type 이라고 한다.</p>
<ul>
<li>열거상수(Enumeration constant) : 열거 타입에 들어가는 값(월, 화, 수 등..)들<pre><code>public enum Week {
  MONDAY, TUESDAY, WEDNESDAY, THUSDAY, FRIDAY, SATURDAY, SUNDAY;
}</code></pre><ul>
<li>enum 데이터 타입</li>
</ul>
</li>
<li>관례적으로, Java class명처럼 타입이름의 첫글자를 대문자로 하고, 열거상수를 적을 때도 대문자로 적는다. </li>
<li>서로 관련있는 상수들을 모아서 하나의 자료형으로 선언한다.</li>
<li>열거형으로 선언된 순서에 따라 0부터 index 값을 가지며, 1씩 증가한다.</li>
</ul>
<h3 id="2-enum의-장점">2. Enum의 장점</h3>
<h4 id="1-코드가-단순해지며-가독성이-좋아진다">1. 코드가 단순해지며 가독성이 좋아진다.</h4>
<h4 id="2-인스턴스-생성과-상속을-방지하여-상수값의-안정성이-보장됨">2. 인스턴스 생성과 상속을 방지하여 상수값의 안정성이 보장됨</h4>
<h4 id="3-상수-자료형을-정의함으로써-해당-자료형-이외의-상수-값은-저장되지-못하게-한다">3. 상수 자료형을 정의함으로써 해당 자료형 이외의 상수 값은 저장되지 못하게 한다.</h4>
<h4 id="4-enum-예약어를-사용하므로-열거-의도를-분명히-한다">4. enum 예약어를 사용하므로 열거 의도를 분명히 한다.</h4>
<h3 id="3-열거-상수를-다른-값과-연결하기">3. 열거 상수를 다른 값과 연결하기</h3>
<ul>
<li>열거 상수 각각이 열거 객체이므로 열거 객체에 생성자를 사용해서 
다음과 같이 열거상수에 다른 값을 할당할 수 있다.<ul>
<li><code>상수 (&quot;열거 문자&quot;)</code>, <code>상수(값)</code>과 같은 형태로  작성</li>
<li>상수들은 열거 끝에 <code>;(세미콜론)</code> 작성<pre><code>WALKING(&quot;워킹화&quot;),
RUNNING(&quot;러닝화&quot;),
TRACKING(&quot;트래킹화&quot;),
HIKING(&quot;등산화&quot;);</code></pre></li>
</ul>
</li>
<li>해당 자료형에 맞는 <code>private</code>생성자 필요하다.
외부 클래스에서 상속 또는 인스턴스 생성을 하지 못하도록 함
(private가 아닌 경우 에러)<pre><code>private Type(String name) {    this.name = name; }</code></pre></li>
<li>연결한 값을 반환해 줄 getter 메서드 필요하다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JPQL의 개념]]></title>
            <link>https://velog.io/@liner_123456/JPQL%EC%9D%98-%EA%B0%9C%EB%85%90</link>
            <guid>https://velog.io/@liner_123456/JPQL%EC%9D%98-%EA%B0%9C%EB%85%90</guid>
            <pubDate>Mon, 28 Oct 2024 07:03:02 GMT</pubDate>
            <description><![CDATA[<p>JPA에서 다양한 쿼리 방법을 지원하는 데 한계가 있고, 특히 검색쿼리 (select)를 실행할 때 복잡한 쿼리문을 가지므로 좀 더 직관적으로 이해하기 쉬운 Query 개념을 소개해본다. </p>
<ul>
<li>JPQL, JPA Criteria(java 표준스펙에서 제공하는 자바 코드를 짜서 JPA를 빌드해주는 generator모음), QueryDSL (JPQL의 한계인 동적인 쿼리에 대한 부분을 보완), 네이티브 SQL(특정 DB에 종속적인 쿼리를 사용해야할 경우), JDBC API를 직접 사용하거나  Mybatis, SpringJDBCTemplate을 함께 사용하여 쿼리를 구현한다.</li>
</ul>
<h2 id="1-jpql">1. JPQL</h2>
<p>JPA를 사용하면, 엔티티 객체를 중심으로 개발할 수 있는데, 검색 쿼리의 경우에도, 테이블이 아닌 엔티티 객체를 대상으로 검색하기 위해서 JPQL을 사용한다.</p>
<ul>
<li>JPA는 SQL을 추상화하는 JPQL이란 객체지향 쿼리 언어(SQL과 문법 유사한 select, from, where, group by, having, join 지원 제공하는 언어로 엔티티 객체를 대상으로 쿼리를 작성한다)</li>
<li>SQL은 데이터베이스 테이블을 대상으로 쿼리 작성하는데, SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다.</li>
<li>JPA는 JPQL을 분석한 후 적절한 SQL을 만들어 데이터베이스를 조회한다.</li>
</ul>
<blockquote>
<p>** 🧨 JPQL 사용시, 주의할 사항 ** </p>
</blockquote>
<ul>
<li><code>JPQL 키워드</code>는 대소문자를 구분하지 않지만, 엔티티와 속성은 대소문자를 구분하기 때문에 사용시 주의할 것! </li>
<li>테이블 이름 대신 엔티티 이름을 사용한다.  <ul>
<li><code>@Entity(name=&quot;...&quot;)</code>으로 설정 가능 엔티티명 설정 가능하지만, 기본 값을 이름으로 사용하길 추천한다.</li>
</ul>
</li>
<li>JPQL의 경우는 별칭은 필수적이다. (AS는 생략 가능하다.)</li>
</ul>
<h3 id="1-1-jpql의-문법">1-1. JPQL의 문법</h3>
<ul>
<li>SQL 쿼리와 문법이 유사하다. (dbms 개념을 참고할 것)</li>
<li><code>select m from Member as m where m.age &gt; 18</code><ul>
<li>엔티티와 속성은 대소문자를 구분해야 하기에, Member나 age로 반드시 대소문자까지 동일하게 작성한다.</li>
<li>JPQL키워드는 대소문자를 구분하지 않아도 된다.
(select, FROM, where, ...)</li>
<li>별칭은 필수값으로 입력한다. (m, as는 생략가능하다)</li>
</ul>
</li>
</ul>
<h2 id="2-typequery와-query">2. TypeQuery와 Query</h2>
<h3 id="2-1-typequery">2-1. TypeQuery</h3>
<ul>
<li>반환타입이 명확할 때 사용한다.
<code>TypeQuery&lt;Member&gt; query = em.createQuery(&quot;select m from Member m&quot;, &quot;Member.class&quot;);</code><h3 id="2-2-query">2-2. Query</h3>
</li>
<li>반환타입이 명확하지 않을 때 사용한다.
<code>Query query = em.createQuery(&quot;select m.username, m.age from Member m&quot;);</code></li>
</ul>
<h3 id="2-3-결과-조회-api">2-3. 결과 조회 API</h3>
<h4 id="1-querygetresultlist">1) query.getResultList();</h4>
<ul>
<li>결과가 하나 이상일때 리스트 반환하고, 결과가 없으면 빈 리스트를 반환한다.</li>
<li>빈 collection이 반환되기 때문에, <code>NullPointerException</code>에 대한 걱정은 하지 않아도 된다.<h4 id="2-querygetsingleresult">2) query.getSingleResult();</h4>
</li>
<li>단일 객체 반환하는 함수로 결과가 <strong>정확히 하나</strong>여야 하고, 결과가 없으면 <code>NoResultException</code>를 발생시키고, 둘 이상이면, <code>NonUniqueResultException</code>를 발생시킨다.</li>
</ul>
<h3 id="2-4-파라미터-바인딩">2-4. 파라미터 바인딩</h3>
<h4 id="1-✅-이름-기준">1) ✅ 이름 기준</h4>
<pre><code>select m from Member m where m.username = :username
query.setParameter(&quot;username&quot;,usernameParam);</code></pre><h4 id="2-위치-기준">2) 위치 기준</h4>
<pre><code>select m from Member m where m.username = ?1
query.setParameter(1, usernameParam);</code></pre><h2 id="3-프로젝션">3. 프로젝션</h2>
<ul>
<li>select절에 조회할 대상을 지정하는 것</li>
<li>프로젝션 대상은 엔티티, 임베디드타입, 스칼라 타입 (숫자, 문자등 기본 데이터 타입) 이다.<h3 id="3-1-엔티티-조회">3-1. 엔티티 조회</h3>
<code>select m from Member m</code><h3 id="3-2-임베디드-타입을-조회">3-2. 임베디드 타입을 조회</h3>
<code>select m.address from Member m</code><h3 id="3-3-스칼라-타입을-조회">3-3. 스칼라 타입을 조회</h3>
<code>select m.username, m.age from Member m</code></li>
</ul>
<blockquote>
<h3 id="페이징-api">페이징 API</h3>
<p>JPA는 페이징을 다음 두 API로 추상화할 수 있다. 
<code>(몇 번째)부터 (몇 개) 가지고 올래?</code></p>
</blockquote>
<h4 id="1-setfirstresultint-startposition">1) setFirstResult(int startPosition);</h4>
<p>: (0부터 시작하는) 조회 시작 위치</p>
<h4 id="2-setmaxresultsint-maxresult">2) setMaxResults(int maxResult);</h4>
<p>: 조회할 데이터 수</p>
<h3 id="3-4-조인-join-엔티티-조회">3-4. 조인 join 엔티티 조회</h3>
<h4 id="1-inner-join">1) inner join</h4>
<ul>
<li>inner는 생략가능하다.
<code>select m from Member m inner join m.team t</code><h4 id="2-outer-join">2) outer join</h4>
</li>
<li>outer는 생략가능하다.
<code>select t from Member m left outer join m.team t</code></li>
</ul>
<h3 id="3-5-서브-쿼리">3-5. 서브 쿼리</h3>
<p><code>select m from Member m
where m.age &gt; (select avg(m2.age) from Member m2)</code></p>
<ul>
<li>JPA 표준 스펙에서는 where, having절에서만 서브쿼리 사용하다.</li>
<li>(하이버네이트에서 지원해주기 때문에) select 절도 가능하다.</li>
<li>from절의 서브쿼리는 현재 jqpl에서 불가능하다.
(join으로 해결할 수 있으면 해결 가능하다)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JPA] 엔티티의 개념 ]]></title>
            <link>https://velog.io/@liner_123456/JPA-%EC%97%94%ED%8B%B0%ED%8B%B0%EC%9D%98-%EA%B0%9C%EB%85%90</link>
            <guid>https://velog.io/@liner_123456/JPA-%EC%97%94%ED%8B%B0%ED%8B%B0%EC%9D%98-%EA%B0%9C%EB%85%90</guid>
            <pubDate>Thu, 24 Oct 2024 08:03:11 GMT</pubDate>
            <description><![CDATA[<h2 id="1-엔티티-매핑">1. 엔티티 매핑</h2>
<p>엔티티를 매핑할 때는 애너테이션을 이용하여 각 요소들을 매핑한다.</p>
<ul>
<li>객체와 테이블 매핑 : <code>@Entity</code>, <code>@Table</code></li>
<li>필드와 컬럼매핑 : <code>@Column</code></li>
<li>기본키 매핑 : <code>@Id</code></li>
<li>연관관계매핑 : <code>@ManyToOne</code>, <code>@JoinColumn</code> </li>
</ul>
<h3 id="1-entity">1. @Entity</h3>
<ul>
<li><code>@Entity</code>가 붙은 클래스는 JPA가 관리하는 엔티티라고 한다.</li>
<li>JPA를 사용해 테이블과 매핑할 클래스는 @Entity가 필수이다.</li>
<li>✨ 주의할 사항은 <ul>
<li>기본 생성자는 필수적으로 생성한다.</li>
<li><code>final class</code>, <code>enum</code>, <code>interface</code>, <code>inner클래스</code>에서는 사용하지 않는다.</li>
<li>저장할 필드에는 <code>final</code> 사용하지 않는다.</li>
<li>클래스 이름을 그대로 사용하고, 같은 클래스 이름이 없으면, 기본값을 사용한다.</li>
</ul>
</li>
</ul>
<h3 id="2-table">2. @Table</h3>
<ul>
<li>@Table은 엔티티와 매핑할 테이블을 지정하고</li>
<li>속성은 다음과 같다.<blockquote>
</blockquote>
<table>
<thead>
<tr>
<th align="center">속성</th>
<th align="center">기능</th>
<th align="center">기본값</th>
</tr>
</thead>
<tbody><tr>
<td align="center">name</td>
<td align="center">매핑할 테이블이름</td>
<td align="center">엔티티 이름을 사용한다.</td>
</tr>
<tr>
<td align="center">catalog</td>
<td align="center">DB의 catalog 매핑</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">schema</td>
<td align="center">DB의 schema 매핑</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">uniqueConstraints(DDL)</td>
<td align="center">DDL생성 시에 유니크 제약 조건 생성</td>
<td align="center"></td>
</tr>
</tbody></table>
</li>
</ul>
<blockquote>
<h2 id="데이터베이스-스키마-자동-생성">데이터베이스 스키마 자동 생성</h2>
</blockquote>
<ul>
<li>DDL을 애플리케이션 실행 시점에 (다음 표와 같은 옵션으로)테이블 자동 생성한다.
<img src="https://velog.velcdn.com/images/liner_123456/post/9e0100b0-a73e-475e-8023-06fc889de36b/image.PNG" alt=""></li>
<li>테이블에서 객체 중심으로 작업을 처리를 하기 위해 데이터베이스 방언을 활용해서 데이터베이스에 맞는 적정 DDL를 생성한다. <ul>
<li>이렇게 생성된 DDL은 개발 장비에서만 사용 (운영에서 사용해서는 안된다)</li>
<li>생성된 DDL은 운영서버에서는 사용하지 않거나, 적절히 다듬은 후 사용한다.</li>
</ul>
</li>
<li>운영 장비에는 절대 create, create-drop, update 사용하면 안된다.<ul>
<li>개발 초기 단계 : create 또는 update,</li>
<li>테스트 서버 단계 : update 또는 validate,</li>
<li>스테이징과 운영서버 단계 : validate 또는 none를 사용한다.<blockquote>
<h3 id="ddl생성-기능">DDL생성 기능</h3>
<h4 id="제약조건-추가">제약조건 추가</h4>
<ul>
<li>회원이름은 필수, 10자 추가 제한 조건일 때, <code>@Column(nullable=false, length=10)</code><h4 id="unique제약-조건-추가-조건-일-때">unique제약 조건 추가 조건 일 때,</h4>
</li>
<li><code>@Table(uniqueConstraints = {@UniqueConstraint(name=&quot;NAME_AGE_UNIQUE&quot;, columnNames{&quot;NAME&quot;,&quot;AGE&quot;})})</code></li>
<li>DDL 생성기능은 DDL을 자동 생성할 때만 사용되고, JPA의 실행로직에는 영향을 주지 않는다.</li>
</ul>
</blockquote>
</li>
</ul>
</li>
</ul>
<h3 id="3-lob">3. @Lob</h3>
<ul>
<li>데이터베이스 BLOB, CLOB타입과 매핑</li>
<li>지정할 수 있는 속성이 없다.</li>
</ul>
<h3 id="4-transient">4. @Transient</h3>
<ul>
<li>필드 매핑X</li>
<li>데이터베이스에 저장X, 조회X</li>
<li>주로 메모리 상에만 임시로 어떤값을 보관하고 싶을때 사용한다.</li>
</ul>
<h3 id="5-기본키-매핑">5. 기본키 매핑</h3>
<h4 id="id--id만-사용하여-직접-할당한다">@Id : @Id만 사용하여 직접 할당한다.</h4>
<h4 id="generatedvalue">@GeneratedValue</h4>
<ul>
<li>자동 생성에는 4가지 전략(Strategy)이다.<ul>
<li>INDENTITY : 데이터베이스에 위임 (MySQL에 사용)</li>
<li>SEQUENCE** : 데이터베이스 시퀀스 오브젝트 사용 (Oracle에서 사용)</li>
<li>TABLE : 키 생성용 테이블 사용, 모든 DB에서 사용 가능한 방법, <code>@TableGenerator</code>이 필요</li>
<li>AUTO : 방언에 따라 자동 지정한다. (기본값)<ul>
<li>즉, AUTO는 DB방언에 맞춰 INDENTITY, SEQUENCE, TABLE 3개 중 하나가 선택이 된다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="6-연관관계-매핑">6. 연관관계 매핑</h3>
<p>객체를 테이블에 맞춰 데이터 중심으로 모델링하면 협력관계를 만들 수 때문에,
(테이블은 외래키로 조인을 사용해서 연관된 테이블을 찾고, 객체는 참조를 사용해서 연관된 객체를 찾는 테이블과 객체 사이에 차이) 
따라서, <strong>객체지향 모델링 방식으로 연관관계</strong>를 표현한다.</p>
<h4 id="1-단방향-연관관계">1) 단방향 연관관계</h4>
<ul>
<li>객체지향 모델링으로 진행한다.</li>
</ul>
<h4 id="2-양방향-연관관계">2) 양방향 연관관계</h4>
<p>가급적 단방향 연관관계로 처리하되, 필요에 따라서는 양방향 연관관계 매핑을 추가한다.</p>
<blockquote>
<p>** 연관관계 주인 **</p>
</blockquote>
<ul>
<li>외래키가 있는 객체가 연관관계의 &quot;주인&quot;이다.</li>
<li>테이블에서는 FK만 잘 걸려 있으면, 양방향으로 이동할 수 있다.</li>
<li>객체의 양방향 관계는 양방향이 아니라, <strong>서로 다른 단방향 관계가 2개이다.</strong></li>
</ul>
<blockquote>
<h4 id="🧨-문제점">🧨 문제점!!</h4>
<p>연관관계에 있는 엔티티 둘 중 하나로 외래키를 관리해야 하는데, 
*<em>그러나, 수정을 할 때에 어느 쪽의 테이블을 수정해야 하는 지에 대한 이슈가 발생 *</em></p>
</blockquote>
<h4 id="연관관계의-주인owner">연관관계의 주인(Owner)</h4>
<ul>
<li>양방향 매핑의 규칙에서 필요하다.</li>
<li>객체의 두 관계 중 하나를 연관관계의 주인(외래키가 있는 객체)으로 지정한다.<ul>
<li>연관관계의 주인만이 외래키를 관리(등록과 수정 등)할 수 있다.</li>
<li>주인이 아닌 객체는 읽기만 가능하다.</li>
<li>주인은 mappedBy 속성을 사용하지 않는다. (값을 넣어봐야 아무일도 벌어지지 않는다)</li>
<li>주인이 아니면, mappedBy속성으로 주인을 지정한다. (List형태로 객체를 담는다)</li>
</ul>
</li>
</ul>
<blockquote>
<h4 id="🧨-양방향-연관관계시-주의사항-🧨">🧨 양방향 연관관계시, 주의사항 🧨</h4>
</blockquote>
<ul>
<li>순수 객체 상태를 고려해서 항상 양쪽에 값을 설정하자!</li>
<li>연관관계 편의 메서드를 생성하자!</li>
<li>양방향 매핑시에 무한 루프를 조심하자!
(toString() 메서드, lombok에서의 toString, ..)</li>
<li><ul>
<li>따라서, 연관관계 편의 메서드를 생성한다. **<ul>
<li>연관관계 객체 둘 중에 하나만 넣자, 
만약    둘 다 넣으면, 무한루프가 걸리는 경우가 있다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="양방향-매핑-결론">양방향 매핑 결론</h4>
<ul>
<li>단방향 매핑만으로도 이미 연관관계 매핑은 완료되었고,
양방향 매핑은 반대방향으로 조회 기능이 추가 된 것 뿐이다.</li>
<li>**양방향을 사용하는 이유는<ul>
<li>JPQL, QueryDSL에서 역방향으로 탐색할 일이 많음 **</li>
</ul>
</li>
<li>단방향 매핑을 먼저 진행하고, 양방향은 필요할 때 추가해도 된다. (테이블에 영향을 주지 않는다.)</li>
</ul>
<h2 id="2-임베디드-타입embedded-type">2. 임베디드 타입(Embedded type)</h2>
<p>임베디드 타입이란, 사전적 정의로 내장 타입이란 뜻으로 *<em>새로운 값 타입을 직접 정의할 수 있다. *</em> </p>
<ul>
<li>JPA가 대표적인 임베디드 타입이다.<ul>
<li>주로 기본값 타입을 모아 만들어서 복합값 타입이라고도 한다.</li>
<li>int, String과 같은 값 타입</li>
</ul>
</li>
</ul>
<h3 id="jpa에서의-embedded-type-사용법">JPA에서의 Embedded type 사용법</h3>
<ul>
<li><code>@Embeddable</code> : 값 타입을 정의하는 곳에 표시</li>
<li><code>@Embedded</code> : 값 타입을 사용하는 곳에 표시</li>
<li>사용하기 위해서는, 기본 생성자가 필수로 있어야 한다. </li>
<li><code>@Embedded</code>나, <code>@Embeddable</code> 둘 중에 하나만 써도 기능은 된지만, 둘 다 넣는 것을 권장한다.</li>
</ul>
<h3 id="임베디드-타입의-장점">임베디드 타입의 장점</h3>
<ul>
<li>재사용이 목적이고, 높은 응집도를 가진다.</li>
<li>객체 지향적 설계가 가능하다.</li>
<li>임베디드 타입을 포함한 모든 값의 타입은 값 타입을 소유한 &quot;엔티티에 생명주기&quot;에 의존한다. </li>
</ul>
<h3 id="embedded-type에-의한-테이블-매핑은">Embedded type에 의한 테이블 매핑은</h3>
<ul>
<li>객체 입장에서 mapping만 변경될 뿐, DB 테이블 입장에서는 변화가 없다.</li>
<li>테이블은 그대로 생성되었고, <strong>좀 더 객체지향적으로 사용할 수 있다.</strong><ul>
<li>임베디드 타입은 엔티티의 값일 뿐이다</li>
</ul>
</li>
<li>객체와 테이블을 아주 세밀하게 매핑하는 것이 가능하다.</li>
<li>따라서, 잘 설계된 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많다.</li>
</ul>
<h3 id="attributeoverride-속성-재정의의-사용">@AttributeOverride (속성 재정의)의 사용</h3>
<p>한 엔티티에서 같은 값 타입을 사용하면 컬럼명이 중복되기 때문에, <code>@AttributeOverrides</code>, <code>@AttributeOverride</code>를 사용해서 컬럼명 속성을 재정의한다.</p>
<ul>
<li>Address라는 임베디드 타입을 개인주소, 그리고 회사주소로 컬럼이름만 변경하여 재정의하고자 할 때, 이용할 수 있다.<pre><code>@Embedded
@AttributeOverrides({
      @AttributeOverride(name = &quot;city&quot;, column = @Column(name=&quot;WORK_CITY&quot;)), 
      @AttributeOverride(name = &quot;street&quot;, column = @Column(name=&quot;WORK_STREET&quot;)),
      @AttributeOverride(name = &quot;zipcode&quot;, column = @Column(name=&quot;WORK_ZIPCODE&quot;)), 
  })
private Address workAddress;</code></pre><h3 id="영속성-전이-cascade란">영속성 전이 (CASCADE)란?</h3>
특정 엔티티에 대한 특정한 작업을 수행하면, 관련된 엔티티에도 동일한 작업을 수행한다는 의미이다. </li>
<li><code>cascade = CascadeType.ALL</code> : &quot;모든 cascade 를 적용한다.&quot;</li>
</ul>
<h4 id="1-cascade--cascadetypeall의-역할">1. cascade = CascadeType.ALL의 역할</h4>
<p> JPA에서 CascadeType.ALL은 엔티티 관계를 정의하는데 사용되는 옵션 중 하나로, 이 옵션은 부모 엔티티의 변경사항이 자식 엔티티에 모두 전파되도록 지정한다.</p>
<ul>
<li>부모 엔티티가 저장 될 때 자식 엔티티도 함께 저장한다.</li>
<li>부모 엔티티가 업데이트될 때, 자식 엔티티도 함께 업데이트한다.</li>
<li>부모 엔티티가 삭제될 때, 자식 엔티티도 함께 삭제한다.</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>