<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>gyqls_12.log</title>
        <link>https://velog.io/</link>
        <description>Hyobin12</description>
        <lastBuildDate>Mon, 10 Apr 2023 04:48:47 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. gyqls_12.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/gyqls_12" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Nozomi Network]]></title>
            <link>https://velog.io/@gyqls_12/Nozomi-Network</link>
            <guid>https://velog.io/@gyqls_12/Nozomi-Network</guid>
            <pubDate>Mon, 10 Apr 2023 04:48:47 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/gyqls_12/post/0df1877c-86f3-428c-b8b2-84ee79ce7a57/image.png" alt=""></p>
<h2 id="📌-개요">📌 개요</h2>
<blockquote>
</blockquote>
<p>산업용 하드웨어 기반으로 
OT, IoT, IT 프로세스에 연관된 모든 디바이스 구성함에 있어
사용되는 네트워크를 미러링을 통해 트래픽을 로딩하고 </p>
<blockquote>
</blockquote>
<p>해당 트래픽에서 추출되는 프로토콜 및 노드 , 접근 등을 
모니터링 함으로써 
보안 취약점 및 공격 탐지 등의 보안 서비스를 제공하는 솔루션 </p>
<h2 id="📌-ot-network">📌 OT Network</h2>
<blockquote>
</blockquote>
<p>Nozomi Networks 솔루션은
제조, 에너지, 교통 등 산업현장에서 사용되는 제어 시스템을 대상으로 서비스함으로</p>
<blockquote>
</blockquote>
<p>IT Network와 달리 &quot;물리적 연결&quot;로 인해 네트워크 구성과 
보안 요구사항을 설정한다.</p>
<blockquote>
</blockquote>
<p>물론 하드웨어 디바이스의 구성이 어떠한들
네트워크 설정 및 서버 제어는 중앙 관리자 1대가 설정한다. 
( </p>
<h2 id="📌-ot-network-vs-it-network">📌 OT Network vs IT Network</h2>
<blockquote>
</blockquote>
<p>OT Network 는 물리적인 장비 ( ICS 시스템 ) 중심이며,
실제 공정에 직접적으로 영향을 주는 
장비의 안정성, 신뢰성, 실시간성 등이 주요 보호대상이다.</p>
<blockquote>
</blockquote>
<p>ICS 시스템은 대부분 오래되고 취약한 프로토콜 이기에
외부 and 내부 공격의 보안 대책이 강화되어야한다.</p>
<blockquote>
</blockquote>
<p>반면에 IT Network는 데이터 통신에 있어
안정성과 기밀성이 주요 보호대상이며 
데이터 유출,해킹, 악성 코드 에 보안 대책을 강화한다. </p>
<h2 id="📌-nozomi-networks-모니터링-요소">📌 Nozomi Networks 모니터링 요소</h2>
<blockquote>
</blockquote>
<ol>
<li>Assets <blockquote>
</blockquote>
 네트워크에 연결된 장비, 시스템 등의 자산정보<blockquote>
</blockquote>
</li>
<li>Nodes<blockquote>
</blockquote>
 네트워크안에서 트래픽을 생성하는 장비 또는 시스템의 노드 정보<blockquote>
</blockquote>
</li>
<li>Links<blockquote>
</blockquote>
 네트워크에 연결되어 있는 링크 정보 <blockquote>
</blockquote>
</li>
<li>Protocols<blockquote>
</blockquote>
 네트워크에 사용되어 있는 모든 프로토콜 정보<blockquote>
</blockquote>
</li>
<li>Sessions<blockquote>
</blockquote>
 네트워크 에서 생성되는 세션 정보<blockquote>
</blockquote>
</li>
<li>Variables <blockquote>
</blockquote>
 네트워크 상에서 발생하는 이벤트 및 경보 등의 변수 모음 <blockquote>
</blockquote>
</li>
</ol>
<p>통합적으로 OT ,IoT, IT 프로세스에 연결된 네트워크 상에서
데이터 통신이 존재하는 모든 요소에서 트래픽 양이나 패턴 등을 파악하여
보안 위협을 탐지하는 서비스 제공 </p>
<h2 id="📌-아키텍쳐">📌 아키텍쳐</h2>
<p><img src="https://velog.velcdn.com/images/gyqls_12/post/d7dd7a37-b6a8-400a-b57e-a2098978d777/image.png" alt=""></p>
<p>중앙 관리자 디바이스 &lt;-&gt; ICS 방화벽 접근( GateWay ) &lt;-&gt; 
<strong>네트워크 서버</strong> &lt;-&gt; Scada Master &lt;-&gt; Operater</p>
<p>PLC/RTU &lt;-&gt; <strong>네트워크 서버 &lt;-&gt; Nozomi Solution</strong> </p>
<p>❗ 이 때 Nozomi Network 가 ICS 구성요소를 모니터링 한다해서
제어 시스템의 퍼포먼스에 전혀 영향이 없고, 
span/moniter 포트를 통해 연결함으로 특정 포트의 트래픽을 미러링한다. </p>
<h2 id="📌-아키텍쳐-2">📌 아키텍쳐 2</h2>
<p><img src="https://velog.velcdn.com/images/gyqls_12/post/847bc0d1-4cbc-4f9d-b598-61c454b097fe/image.png" alt=""></p>
<p>미러링 된 트래픽을 시각화 UI 를 통해 
IP, MAC code, Link 등의 정보 확인 가능 </p>
<p>Master 관리자를 통해 링크된 모든 ICS 디바이스 정보를 확인 가능하다. </p>
<p>Enviroment 탭 을 확인하여
모든 디바이스, 하드웨어 구성요소, 노드 , CWE 등 정보 조회 가능
Session Kill, Block access , </p>
<p>데모판 KallLinux, Linux 사용 </p>
<p>New SCADA function Code - Linux Address 에 따른 Connecting dvice monitering </p>
<p>❗PLC - Scada RTU 구현에 사용되며 전자 입출력 모듈 </p>
<p>❗RTU - 원격 터미널 유닛, 독립형 데이터 수집 및 제어 장치 
        원격에 위치한 장비를 모니터링 하고 제어하는 프로세서 </p>
<p>❗Scada - 다수의 원격 터미널 유닛 ( 또는 RTU ) 통신 시스템을 통해
        마스터 스테이션에 접속된 필드데이터를 수집하는 단계</p>
<h2 id="📌-cisco-ise">📌 Cisco ISE</h2>
<ul>
<li><p>네트워크 접근제어 및 인증, 권한 부여,
게스트 네트워크 액세스 및 BYOD ( Bring Your Own Device ) 등을 포함해 다양한 보안 정책을 관리하는 플랫폼 </p>
</li>
<li><p>Nozomi Networks 와 엔드포인트 장치에서 플랫폼 연동작업 하기도 한다. </p>
</li>
<li><p>독립적으로 관리해야했던 보안 관리자에게 
중앙 집중식 관리 및 통합된 보안 솔루션을 제공하여 
유지보수 절감 및 보안 정책 강화 가능 </p>
</li>
</ul>
<h2 id="📌-알고리즘">📌 알고리즘</h2>
<h4 id="dpi">DPI</h4>
<ul>
<li><p>Deep Packet Inspection </p>
</li>
<li><p>트래픽에서 악성 코드나 공격에 사용되는 패턴을 탐지하고 차단하는 기술</p>
</li>
</ul>
<h4 id="bad">BAD</h4>
<ul>
<li><p>Behavioral Anomaly Detection </p>
</li>
<li><p>산업용 제어 시스템에서 이상 행위를 감지하는 기술 </p>
</li>
<li><p>트래픽 모니터링에 있어 확인 되지 않은 트래픽은 이상 트래픽으로 간주</p>
</li>
</ul>
<h4 id="ai--머신러닝">AI &amp; 머신러닝</h4>
<ul>
<li><p>딥러닝 알고리즘을 사용해 스스로 학습하여 시스템 보안 강화</p>
</li>
<li><p>지속적인 학습을 통해 새로운 유형의 공격이나 이상 행위를 탐지하고 대응 </p>
</li>
<li><p>IoT 환경에서 머신러닝 기반 위협 인식 제공 </p>
</li>
</ul>
<p> 참고
 <a href="https://www.youtube.com/watch?v=GLjQ89HgjcQ">https://www.youtube.com/watch?v=GLjQ89HgjcQ</a>
 <a href="https://www.nozominetworks.com/ko/">https://www.nozominetworks.com/ko/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[클라우드 서비스 (Cloud) ]]></title>
            <link>https://velog.io/@gyqls_12/%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%84%9C%EB%B9%84%EC%8A%A4-Cloud</link>
            <guid>https://velog.io/@gyqls_12/%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%84%9C%EB%B9%84%EC%8A%A4-Cloud</guid>
            <pubDate>Fri, 07 Apr 2023 05:42:08 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/gyqls_12/post/5ab5d0d6-bdc0-46ce-9f78-abdd64b0cf84/image.png" alt=""></p>
<h2 id="📌-클라우드-서비스">📌 클라우드 서비스</h2>
<ul>
<li><p>인터넷을 통해 컴퓨터 하드웨어, 소프트웨어 및 기술 리소스에 대한
접근과 사용을 가능케 하는 기술 </p>
</li>
<li><p><strong>인터넷이 가능한 환경</strong>에서 모든 가상화 서비스가 이루어지는 공간 </p>
</li>
</ul>
<blockquote>
<ul>
<li>예시로 구글 드라이브, 네이버 Box 와 같이 인터넷을 통해 단순 저장공간을 제공하는 서비스부터</li>
</ul>
</blockquote>
<ul>
<li>AWS 와 IBM Cloud 와 같이 Linux 서버 제공, VMware, SAP, 자동화 애플리케이션 등 리소스로 구성된 서비스를 인터넷 하나로 
별도의 하드웨어, 소프트웨어 없이도 제공받을 수 있다. <blockquote>
<ul>
<li>해당 클라우드 서비스를 제공하기 위해 필요한 
대규모 데이터 처리, 저장, 분석 및 전송 ( 빅 데이터 ) 기술을 
사용자가 인터넷만 있다면 간단히 제공받을 수 있다. </li>
</ul>
</blockquote>
</li>
</ul>
<h2 id="📌-클라우드-특징">📌 클라우드 특징</h2>
<ol>
<li><p>내결함성 Falut tolerance </p>
<p> 운영중이던 시스템의 데이터가 손실되거나 진행중인 작업이 
 손상되지 않도록 백업이 상시화 되어있다. </p>
</li>
<li><p>높은 가용성 High availability </p>
<p> 시스템이 오랜 기간 사용하고 있어도 
 정상운영이 가능하다 = 절대 고장나지 않는다.</p>
</li>
<li><p>확장성 Scalability</p>
<p> 온-프레미스 서버라면 서버를 확장하는데 물리적으로 시간이 많이 필요한 반면,
 클라우드 서비스는 적은 시간으로 서버 확장이 가능하다. 
 scale Up or Down 요구사항에 즉각 대응이 가능하다</p>
</li>
<li><p>민첩성 Agility </p>
<p> 서버 확장시 수 초내에, 빠르게 서버를 배포하고 서비스를 지속적으로 이어갈 수 있다.</p>
</li>
<li><p>탄력성 Elasticity </p>
<p> 필요시 마다 언제든 확장 - 축소 가 가능하다. </p>
</li>
<li><p>글로벌 지원 Global reach </p>
<p> 엔드 유저 (클라이언트, 사용자 ) 에게 기본적으로 글로벌 지원이 가능하다. </p>
</li>
<li><p>응답 속도 Customer latency </p>
<p> 클라우드 지역에 데이터센터를 두고, 빠른 응답속도를 지원한다.</p>
</li>
<li><p>예측 비용 Prediciv cos </p>
<p> 쓴 만큰 금액이 청구되기에, 클라우드 사용량에 따라 비용 예측에 장점이 있다. </p>
</li>
<li><p>보안 Security</p>
<p> 암호화, 감사 등의 기술적인 부분 외에도 고객의 워크로드를 올려서 서비스하기에
 지역적, 산업적인 준수사항 및 요구사항을 만족하도록 구현하고 검증받는다.</p>
</li>
</ol>
<h2 id="📌-클라우드-장점">📌 클라우드 장점</h2>
<ol>
<li><p>비용 절감 </p>
<p>기업의 입장에서 하드웨어 유지보수 및 업그레이드 할 필요가 없기에
비용절감이 가능하고, 사용량 데이터량 만큼만 비용을 지불하기에 
합리적인 비용으로 서비스를 제공받을 수 있다.</p>
</li>
<li><p>유연성</p>
<p>필요한 만큼 리소스를 확장 또는 축소할 수 있기에
기업의 입장에서 트래픽 증가 또는 감소를 조정하기 쉽다.</p>
</li>
<li><p>접근성</p>
<p>인터넷만 있다면 어디에서나 액세스 할 수 있다.
그렇기에 협업에 있어서도 강점이 있다. </p>
</li>
<li><p>보안성</p>
<p>하나의 데이터 센터에서 서비스를 제공하기에
하나에만 보안을 집중할 수 있어 보안 위험을 최소화 할 수 있다.</p>
</li>
</ol>
<h2 id="📌-클라우드-서비스-모델">📌 클라우드 서비스 모델</h2>
<p><img src="https://velog.velcdn.com/images/gyqls_12/post/fe00bbee-1470-413a-9cb4-0d345062881e/image.png" alt=""></p>
<h4 id="❗-packed-software">❗ Packed Software</h4>
<blockquote>
</blockquote>
<p>소프트웨어 업체가 소프트웨어를 개발하고 유지보수하는 모델로
일반적으로 서버 또는 클라우드 인프라에서 실행 할 수 있도록 패키지로 제공되는 소프트웨어를 말한다. </p>
<blockquote>
</blockquote>
<p>사용자가 직접 유지보수 할 수 있다.</p>
<h4 id="❗-iaas--infra-structure-as-a-service-">❗ IaaS ( Infra-Structure As A Service )</h4>
<p>Networking - Stroge - Servers - Virtualization</p>
<blockquote>
</blockquote>
<p>가장 기본적인 클라우드 서비스
책임지고 관리할 부분이 많으며 
자동차로 비유하면 자차 </p>
<blockquote>
</blockquote>
<p>가상화된 컴퓨터 자원을 제공하는 것으로 
가상서버, 스토리지, 네트워크, 운영체제 및 기본 IT 인프라를 제공하는 모델</p>
<h4 id="❗-paas--platfrom-as-a-service-">❗ PaaS ( Platfrom As A Service )</h4>
<p>O/S - Middleware - Runtime</p>
<blockquote>
</blockquote>
<p>Web, App 등 소프트웨어를 개발하고 테스트 및 배포에 
가장 좋은 환경을 제공하는 모델
자동차로 비유하면 렌트카 </p>
<blockquote>
</blockquote>
<p>클라우드 제공 업체가 응용 프로그램 개발 및 배포를 위한 
플랫폼을 제공하는 것으로, 
개발자가 응용 프로그램을 직접 구축, 테스트, 배포하고 관리가 가능한 모델</p>
<blockquote>
</blockquote>
<p>기본 인프라를 제공하는 IaaS와 달리
사용자가 직접 애플리케이션 코드를 구현하고 실행하는데 
필요한 모든 것을 제공하여 
IDE, 런타임 시스템, DB, 메세징, 보안 및 서비스 통합에 해당되는 모델</p>
<h4 id="❗saas--software-as-a-service-">❗SaaS ( Software As A Service )</h4>
<p>Data - Application</p>
<blockquote>
</blockquote>
<p>Email, MS Office 365 와 같이
커스터마이징할 수 있는 부분이 거의 없으며
중앙 클라우드 업체가 호스팅 및 관리하는 모델이다. 
자동차로 비유하면 택시 </p>
<blockquote>
</blockquote>
<p>클라우드가 소프트웨어 애플리케이션을 제공하는 것으로
인터넷을 통해 애플리케이션에 액세스가 가능한 모델 </p>
<blockquote>
</blockquote>
<p>예시로 공동작업, 문서관리, 고객 관계 관리 ( CRM) 및 인사 관리</p>
<h2 id="📌-클라우드-컴퓨팅의-유형">📌 클라우드 컴퓨팅의 유형</h2>
<p>모든 클라우드는 네트워크 전반에서 확장 가능한 리소스를 
추상화, 풀링, 공유하며 </p>
<p>일반적으로 OS, 플랫폼, 애플리케이션 프로그래밍 인터페이스 를 
거의 항상 포함하여 혼합된 기술을 제공한다. </p>
<p>제공 받는 서비스의 범위에 따라 유형이 각기 다르다. </p>
<h2 id="📌-퍼블릭-클라우드">📌 퍼블릭 클라우드</h2>
<blockquote>
</blockquote>
<p>일반적으로 최종 사용자가 소유하지 않은 IT인프라에서
생성되는 클라우드 환경이며 
대표적으로 
AWS, Google Cloud, IBM Cloud, MS Azure 등 이있다.</p>
<blockquote>
</blockquote>
<p>파티셔닝 또는 재배포가 모든 사용자에게 연결되어 있는 클라우드를
퍼블릭 클라우드 라고 명시한다. 
IaaS, PaaS 모델이 대표적인 퍼블릭 클라우드 이다. </p>
<h2 id="📌-프라이빗-클라우드">📌 프라이빗 클라우드</h2>
<blockquote>
</blockquote>
<p>최종 사용자 또는 그룹의 전용 클라우드 환경</p>
<blockquote>
</blockquote>
<p>완전히 독립적인 액세스 권한이 있는 단일 고객 기반으로 하여
서비스를 제공하는 유형이다.</p>
<h2 id="📌-하이브리드-클라우드">📌 하이브리드 클라우드</h2>
<blockquote>
</blockquote>
<p>단일 IT 환경 처럼 보이나, 실제로 여러 환경이 
LAN, WAN, VPN 또는 API를 통해 연결된 형태로 </p>
<blockquote>
</blockquote>
<p>1개 프라이빗 + 1개 퍼블릿 클라우드
2개 이상 프라이빗 클라우드 또는 퍼블릿 클라우드 Only</p>
<blockquote>
</blockquote>
<p>애플리케이션은 개별적이지만, 다중 환경에서 이동할 수 있는 경우를
하이브리드 클라우드 유형이라 칭한다.</p>
<h2 id="📌-멀티-클라우드">📌 멀티 클라우드</h2>
<blockquote>
</blockquote>
<p>2곳 이상의 클라우드 공급업체가 제공하는 방식</p>
<blockquote>
</blockquote>
<p>하이브리드 클라우드와 유사하나
명확한 목적, 주요 데이터를 더 효과적으로 제어하기 위해 
이중 스토리지 공간으로 활용하는 경우 멀티 클라우드 유형으로 명시한다.</p>
<blockquote>
</blockquote>
<p>기업 입장에서 보안과 성능 강화를 위해 멀티 클라우드가 보편화 되고 있다.</p>
<p>참고자료 ( thanks to ) 
<a href="https://www.ibm.com/kr-ko/cloud">https://www.ibm.com/kr-ko/cloud</a></p>
<p><a href="https://www.redhat.com/ko/topics/cloud-computing/public-cloud-vs-private-cloud-and-hybrid-cloud">https://www.redhat.com/ko/topics/cloud-computing/public-cloud-vs-private-cloud-and-hybrid-cloud</a></p>
<p><a href="https://velog.io/@younge/%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9CCloud%EB%9E%80-%ED%8A%B9%EC%A7%95-%EC%A2%85%EB%A5%98-%EC%84%B1%EA%B2%A9">https://velog.io/@younge/%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9CCloud%EB%9E%80-%ED%8A%B9%EC%A7%95-%EC%A2%85%EB%A5%98-%EC%84%B1%EA%B2%A9</a></p>
<p><a href="https://velog.io/@minidoo/%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9CCloud%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C">https://velog.io/@minidoo/%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9CCloud%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[OSI 7 계층]]></title>
            <link>https://velog.io/@gyqls_12/OSI-7-%EA%B3%84%EC%B8%B5</link>
            <guid>https://velog.io/@gyqls_12/OSI-7-%EA%B3%84%EC%B8%B5</guid>
            <pubDate>Tue, 04 Apr 2023 05:11:35 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/gyqls_12/post/45e5c8a1-9085-4d18-8ca9-52dc5e8eb7a8/image.png" alt=""></p>
<h2 id="📌-osi-7-계층">📌 OSI 7 계층</h2>
<blockquote>
</blockquote>
<ul>
<li>Open System Interconnection - 7 Layer<blockquote>
</blockquote>
</li>
<li>네트워크에서 데이터를 전송하는데 필요한 과정을 7개의 계층으로 나누어 정의한 모델<blockquote>
</blockquote>
</li>
<li>다양한 네트워크 장비 및 프로토콜의 기반 </li>
</ul>
<h2 id="📌-osi-7계층-작동-원리">📌 OSI 7계층 작동 원리</h2>
<blockquote>
</blockquote>
<ol>
<li>OSI 7계층은 데이터 통신을 목적으로 
각 하위 계층의 서비스를 이용하고, 상위 계층에 서비스를 제공한다.
서비스가 완료된 후, 데이터는 상위 계층에서 하위계층으로 서비스를 제공한다. <blockquote>
</blockquote>
</li>
<li>전송시 7계층 -&gt; 1계층으로 각 레이어마다 인식할 수 있는 헤더를 붙인다.( 캡슐화 사용 ) <blockquote>
</blockquote>
</li>
<li>수신 시 1계층 -&gt; 7계층으로 헤더를 떼어낸다. ( 디캡슐화 )<blockquote>
</blockquote>
</li>
<li>출발지에서 데이터가 전송될 때, 헤더가 추가되는데 2계층에서만 오류제어를 위해 꼬리부분에서 추가된다.<blockquote>
</blockquote>
</li>
<li>물리계층에서 1,0 의 신호가 되어 전송매체 
( 케이블 , 광섬유 ) 등을 통해 전송 </li>
</ol>
<h2 id="📌-1---물리계층--physical-layer-">📌 1 - 물리계층 ( Physical Layer )</h2>
<ul>
<li><p>물리적 접근 </p>
<ul>
<li><p>7계층 중 최하위</p>
</li>
<li><p>주로 전기,기계 등의 특성을 이용해 데이터를 전송</p>
</li>
<li><p>데이터는 0과 1 의 2진수 - On/Off 의 전기 신호상태로 이루어져 
오로지 데이터 전달기능을 가짐</p>
</li>
<li><p>데이터 전달기능만 있기에 알고리즘, 오류제어 기능 X </p>
</li>
<li><p>주 장비로는 케이블, 광섬유, 무선 주파수 등이 있다. </p>
</li>
</ul>
</li>
</ul>
<h2 id="📌-2---데이터-링크-계층--date-link-layer-">📌 2 - 데이터 링크 계층 ( Date Link Layer )</h2>
<ul>
<li><p>신뢰성 데이터 전송 제어 </p>
<ul>
<li><p>물리적인 연결을 통해 인접한 두 장치간의 신뢰성 있는 정보 전송을 담당</p>
</li>
<li><p>물리 계층에서 전송된 비트열을 프레임 단위로 나누는 역할</p>
</li>
<li><p>MAC 주소를 통하여 통신하며, 오류 나 재전송 하는 기능이 존재한다. </p>
</li>
<li><p>주로 이더넷, Wi-fi 등이 있다. </p>
</li>
</ul>
</li>
</ul>
<h2 id="📌-3---네트워크-계층--network-layer">📌 3 - 네트워크 계층 ( Network Layer)</h2>
<ul>
<li><p>전송 경로 설정 담당 계층 </p>
<ul>
<li><p>라우딩, 패킷 전송 등을 담당하는 계층
( 목적지 까지 가장 안전하고 빠르게 데이터 보내는 기능 ) </p>
</li>
<li><p>데이터 단위는 패킷 ( Packet )</p>
</li>
<li><p>컴퓨터에게 데이터를 전송할 지 주소를 갖고 있어 통신가능 ( = IP ) </p>
</li>
<li><p>주로 IP, ICMP 등 </p>
</li>
</ul>
</li>
</ul>
<h2 id="📌-4---전송-계층--transport-layer">📌 4 - 전송 계층 ( Transport Layer)</h2>
<ul>
<li><p>종단(HOST) &lt;-&gt; 목적지(Procesee) 간의 신뢰성 데이터 전송 담당</p>
<ul>
<li><p>송 &lt;-&gt; 수신자 간의 신뢰성있고 효율적인 데이터를 전송하기 위해
오류검출 및 복구, 흐름제어, 중복검사 등을 실행</p>
</li>
<li><p>데이터 전송을 위해 포트 번호 ( Port ) 를 사용
대표적으로 TCP 와 UDP </p>
</li>
<li><p>데이터 단위는 세그먼트 ( Segment ) </p>
</li>
</ul>
</li>
</ul>
<h2 id="📌-5---세션-계층--session-layer-">📌 5 - 세션 계층 ( Session Layer )</h2>
<ul>
<li><p>응용 프로그램 간의 논리적 연결 생성 및 제어 담당 </p>
<ul>
<li><p>컴퓨터 간 통신 세션을 설정, 유지, 종료 하는 역할을 담당 
( 연결 세션에서 데이터 교환과 에러 발생 시의 복구를 관리 ) </p>
</li>
<li><p>데이터 전송 전에는 세션을 설정하고, 전송 후에는 세션을 해제한다.</p>
</li>
<li><p>데이터 전송 중에 발생하는 오류, 재전송, 다중 세션등의 처리를 담당.</p>
</li>
<li><p>대표적으로 API, RPC , 트랜잭션 관리, 로그인, 로그아웃 등 </p>
</li>
</ul>
</li>
</ul>
<h2 id="📌-6---표현-계층--presentation-layer">📌 6 - 표현 계층 ( Presentation Layer)</h2>
<ul>
<li><p>데이터 표현방식. 번역 - 압축 - 암호화 규정 계층 </p>
<ul>
<li><p>데이터를 어떻게 표현할 것인지를 정하는 계층. 
( 데이터 표현에 대한 독립성을 제공하는 계층 ) </p>
</li>
<li><p>총 3가지 기능 ( 번역, 압축 , 암호화 ) 으로</p>
</li>
</ul>
<ol>
<li>송신자에게 온 데이터를 해석하기 위한 응용계층 데이터 변화 또는 부호화 ( 번역 ) </li>
<li>수신자에서 데이터의 압축을 풀 수 있는 방식으로 된 데이터 압축 ( 압축 ) </li>
<li>데이터의 암호화와 복호화
 ( ex . EBCDIC 인코딩 코드 -&gt; ASCII 인코등 코드 복호화 )
 ( 암호화 ) </li>
</ol>
</li>
</ul>
<h2 id="📌-7---응용-계층--application-layer">📌 7 - 응용 계층 ( Application Layer)</h2>
<pre><code>+ 사용자와 가장 밀접한 계층으로 인터페이스 역할

+ 사용자 &lt;-&gt; 네트워크 접속 &lt;-&gt; 응용 프로그램 상호작용 구조를 가짐

+ 사용자의 요구사항을 처리하기 위한 프로토콜과 인터페이스 제공

+ 응용 프로페스 간의 정보 교환 담당.
ex) 이메일, 인터넷, 동영상 플레이어 </code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[RDBMS - DDL DML DCL TCL]]></title>
            <link>https://velog.io/@gyqls_12/RDBMS-DDL-DML-DCL-TCL</link>
            <guid>https://velog.io/@gyqls_12/RDBMS-DDL-DML-DCL-TCL</guid>
            <pubDate>Sat, 25 Mar 2023 09:36:26 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/gyqls_12/post/e3de6de9-c5c5-4041-ae61-bd840e74db81/image.png" alt=""></p>
<h2 id="📌-rdbms---관계형-데이터베이스-관리-시스템">📌 RDBMS - 관계형 데이터베이스 관리 시스템</h2>
<ul>
<li><p>여러개의 데이터베이스 를 구성하는 테이블 간의 관계를 기반으로 
데이터를 저장, 조회, 수정, 삭제하는데 사용하는 소프트웨어 시스템.</p>
</li>
<li><p>테이블 간의 관계를 기반으로 구성되기에 SQL를 사용하여 데이터를 처리한다. </p>
</li>
<li><p>RDBMS 는 대규모 데이터 처리를 하는데 적합하며 
다중 사용자 환경에서 동시에 데이터 처리를 할 수 있음. </p>
</li>
<li><p>데이터의 일관성, 무결성, 보안 등을 보장하며 안정적인 데이터 관리를 제공. </p>
<h4 id="❗-sql---structured-query-language">❗ SQL - Structured Query Language</h4>
<ul>
<li>데이터베이스에서 데이터를 삽입, 검색, 수정, 삭제하는데 사용되는 표준언어 </li>
</ul>
</li>
</ul>
<h2 id="📌-ddl---data-definition-languege">📌 DDL - Data Definition Languege</h2>
<ul>
<li><p>데이터베이스의 구조를 정의하는데 사용되는 명령어 
ex) 테이블, 인덱스, 뷰 생성 및 삭제 </p>
</li>
<li><p>대표적으로 <strong>Create , Alter , Drop , Truncate</strong> 명령어가 있음
( 생성 , 수정, 테이블 삭제, 데이터삭제(테이블은 유지)  ) </p>
</li>
</ul>
<ul>
<li>데이터베이스, 테이블, 인덱스, 뷰 를 생성, 수정 또는 삭제할 때 사용 </li>
</ul>
<h2 id="📌-dml---data-manipulation-languege">📌 DML - Data Manipulation Languege</h2>
<ul>
<li><p>데이터베이스 안의 데이터를 조작하는데 사용되는 SQL 명령어.</p>
</li>
<li><p>대표적으로 <strong>Select, Insert, Update, Delete</strong> 가 있음.
( 조회, 추가, 수정, 삭제 ) </p>
</li>
<li><p>데이터를 조회, 삽입, 수정, 삭제에 사용되며 주로 개발자나 데이터베이스 사용자가 사용한다. </p>
</li>
<li><p>주의할 점은 데이터를 변경할 때 다른 사용자의 데이터를 동시에 수정하면 충돌이 발생함으로,
동시성 제어 기능을 사용해 충돌을 방지해야하며 언제든지 롤백할 수 있는 트랜잭션을 사용하여 
안전한 환경에서 제어해야한다. </p>
</li>
</ul>
<h2 id="📌-dcl---data-control-languege">📌 DCL - Data Control Languege</h2>
<ul>
<li><p>데이터베이스 의 보안 및 권한 설정을 관리하는데 사용되는 SQL 명령어.</p>
</li>
<li><p>대표적으로 <strong>Grant , Revoke</strong> 가 있음.
( 권한 부여, 권한 삭제 ) </p>
</li>
<li><p>DCL 명령어를 통해 데이터베이스 객체에 권한을 관리할 때, 
최소한의 권한만 부여하는 식으로 보안을 강화해야한다. </p>
</li>
<li><p>불필요한 권한 부여는 데이터베이스가 공격당할 가능성이 높다. </p>
</li>
</ul>
<h2 id="📌-tcl---transaction-control-languege">📌 TCL - Transaction Control Languege</h2>
<ul>
<li><p>데이터베이스 트랙잭션을 제어하는데 사용되는 SQL 명령어.</p>
</li>
<li><p>대표적으로  <strong>COMMIT , Rollback, SvaePoint</strong> 등이 있다.
( 트랙잭션 변경, 트랙잭션 이전으로 회귀, 트랙잭션 특정 지점 저장 ) </p>
</li>
<li><p>데이터베이스의 일관성과 무결성을 관리하여 중간에 예외가 발생하거나, 오류가 발생하며 
이전상태로 되돌리는 식으로 효율적인 데이터베이스 관리를 목적으로 한다. </p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS - 백엔드 서버 구축 ]]></title>
            <link>https://velog.io/@gyqls_12/AWS-%EC%84%9C%EB%B2%84-%EA%B5%AC%EC%B6%95</link>
            <guid>https://velog.io/@gyqls_12/AWS-%EC%84%9C%EB%B2%84-%EA%B5%AC%EC%B6%95</guid>
            <pubDate>Wed, 08 Mar 2023 09:13:28 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-서버---클라이언트-개념-정리">📌 서버 - 클라이언트 개념 정리</h2>
<p><img src="https://velog.velcdn.com/images/gyqls_12/post/aadfee39-4840-4411-8f21-23f3a40e7868/image.png" alt=""></p>
<p>서버 = 클라이언트 요청의 응답을 담당 </p>
<ul>
<li><p>비지니스 로직 구조에서 첫 시작점
클라이언트 &lt;-&gt; 서버 &lt;-&gt; BackEnd 로직 &lt;-&gt; DB </p>
</li>
<li><p>서버 예시 
( 웹 서버 - Apache , Ngix , Tomcat, Express
사용언어 - ASP, JSP , PHP , Node.js(Express), Django , Spring 
DBMS - MySql , MSSQL , Oracle, Mongo )</p>
</li>
<li><p>서버 주소 
IP , 클라이언트에게는 도메인 ( www. ) 으로 보여진다. </p>
</li>
</ul>
<p>( !  cmd - nslookup (도메인주소) 로 IP 주소를 확인할 수 있다. ) </p>
<h2 id="📌-프로토콜-과-포트">📌 프로토콜 과 포트</h2>
<p>클라이언트가 서버에 접근하기 이전 
접근하는 방법과 주소를 뜻한다. 
ex ) 프로토콜 = 도보 차량 지하철 , 포트 = 입구 </p>
<ul>
<li><p>프로토콜 = 클라이언트 &lt;-&gt; 서버에 접근하는 방법 
ex) HTTP , HTTPS(보안) , SSH , SFTP, FTP , MySql </p>
</li>
<li><p>포트(Port) = 클라이언트가 서버에 접근할 수 있는 주소 
각 프로토콜 마다 각기 다른 포트가 정해져 있어 
정해진 포트에 접근 시 특정 프로토콜로 연결이 가능하다. 
ex) HTTP - 80 , HTTPS - 443 , SSH , SFTP - 22 , FTP - 21 , MySQl- 3306 </p>
</li>
<li><p>HTTP , HTTPS = 일반적인 접근 방법 </p>
</li>
<li><p>SSH , SFTP , FTP(파일전송) , MySql(DB관련) 포트 - 관리자 접근 방법 </p>
</li>
</ul>
<h2 id="📌-aws-서버구축-설정">📌 AWS 서버구축 설정</h2>
<h3 id="1-ec2-서비스-선택">1. EC2 서비스 선택</h3>
<h3 id="2-인스턴스-생성">2. 인스턴스 생성</h3>
<ul>
<li>인스턴스 시작 - Ubuntu 18.04 ver </li>
<li>인스턴스 유형 - t2.micro ( 기본 값 ) </li>
<li>키 페어 - 새 키 페어 생성 </li>
<li>스토리지 구성 - 8gb gp2 ( 기본 값 ) ※ 최대 32기가 가능 </li>
</ul>
<h3 id="3-탄력적-ip-설정--고정-ip-">3. 탄력적 IP 설정 ( 고정 IP )</h3>
<ul>
<li>탄력적 IP  - 작업 - 탄력적 IP 생성<br>기존에 있는 인스턴스 IP 키와 연동 후 탄력적 IP 생성 </li>
</ul>
<h2 id="📌-winscp--putty-설정">📌 Winscp , Putty 설정</h2>
<p>Putty =  SSH 프로토콜 접근 클라이언트
Windscp = FHP 프로토콜 접근 클라이언트</p>
<p>다운로드 링크 
<a href="https://gunbin91.github.io/aws/2020/01/10/aws_1_putty,winscp_.html">https://gunbin91.github.io/aws/2020/01/10/aws_1_putty,winscp_.html</a> </p>
<ul>
<li>Winscp ( 64비트 , 개인설정에 맞게 ) </li>
<li>putty.exe 다운로드 </li>
</ul>
<h3 id="winscp--putty-연동">Winscp + Putty 연동</h3>
<ul>
<li>환경설정 - 통합 (프로그램 ) - 내 Putty 위치경로 설정 
= Putty 자동연결 성공 </li>
</ul>
<h3 id="new-세션-생성">New 세션 생성</h3>
<p><img src="https://velog.velcdn.com/images/gyqls_12/post/76313f09-42c4-4bf7-9d4e-e5446c5fbd0c/image.png" alt=""></p>
<ul>
<li><p>세션 생성</p>
</li>
<li><p>호스트이름 = 탄력성 IP 주소 </p>
</li>
<li><p>사용자 이름 = 생성한 인스턴스 이름 ( ex. ubuntu ) </p>
</li>
<li><p>비밀번호 = 생성한 pair 파일 
( 모든 key 설정 후 putty 파일로 자동 변환 필요 ) </p>
</li>
<li><p>저장 후 로그인 </p>
</li>
<li><p>Crtl + P 로 Putty 명령창이 뜬다면 성공 </p>
</li>
</ul>
<h2 id="📌-putty-터미널-설정">📌 putty 터미널 설정</h2>
<p><img src="https://velog.velcdn.com/images/gyqls_12/post/1cd0c98f-439c-4533-8455-4a380d7eb606/image.png" alt=""></p>
<ul>
<li><p>sudo su = 관리자 권한으로 변경 </p>
</li>
<li><p>apt-get update = 패키지, 서버 , node , SQL 업데이트 </p>
</li>
<li><p>apt-get nginx install - ngix 설치 </p>
</li>
</ul>
<h2 id="📌-생성한-nginx-포트-설정">📌 생성한 Nginx 포트 설정</h2>
<ul>
<li><ol>
<li>생성한 인스턴스 페이지 -&gt; 보안 탭 -&gt; 인바운스 규칙 </li>
</ol>
</li>
<li><ol start="2">
<li>인바운스 규칙 편집 
<img src="https://velog.velcdn.com/images/gyqls_12/post/bd93021e-dbcf-4cad-a111-f5089211060e/image.png" alt=""></li>
</ol>
</li>
</ul>
<ul>
<li><p>인바운드 규칙 추가 -&gt; HTTP 유형 - &gt; 소스 ipv4 유형 설정 후 규칙저장 </p>
</li>
<li><p>Mysql/Aurora 유형 -&gt; ipv4 유형 설정 후 추가 </p>
</li>
<li><ol start="3">
<li>웹 브라우저에 IP 주소 입력 후 서버에 접근 </li>
</ol>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gyqls_12/post/be9e60fd-8da1-47f1-8664-cf3e5b6420fd/image.png" alt=""></p>
<p>해당 결과가 나온다면 웹 서버 설치 성공 </p>
<h2 id="📌-nodejs-설정">📌 Node.js 설정</h2>
<ul>
<li><p>putty 터미널에서 
apt-get install nodejs 명령 후 설치 
( 기본 8 버전이 설치됨 ) </p>
</li>
<li><p>node.js 14 버전 설치 ( putty 터미널 입력 코드 ) </p>
<p>   curl -sL <a href="https://deb.nodesource.com/setup_14.x">https://deb.nodesource.com/setup_14.x</a> | sudo -E bash -</p>
<p>  sudo apt-get install -y nodejs</p>
</li>
</ul>
<ul>
<li>node -v , npm -v - 버전 및 설치 확인 </li>
</ul>
<h2 id="📌-db--mysql-서버--설정">📌 DB ( Mysql 서버 ) 설정</h2>
<ul>
<li><p>apt-get install mysql-server - DB ( mysql ) 설치 </p>
</li>
<li><p>mysql -u root -p = mysql 접속 
( 초기 password 는 입력 없이 바로 엔터 ) </p>
</li>
<li><p>루트 계정 비밀번호 생성 </p>
<p>  ALTER USER &#39;root&#39;@&#39;localhost&#39; IDENTIFIED WITH mysql_native_password&#39; BY &#39;원하는 비밀번호&#39; </p>
</li>
<li><p>이후 
mysql -u root -p 통하여 mysql 재접속 </p>
</li>
</ul>
<h4 id="❗-비밀번호-잊었거나-잘못-설정했다면-">❗ 비밀번호 잊었거나 잘못 설정했다면 ?</h4>
<p>관리자 권한으로 수정해야한다 
해당 페이지 참조 &gt;&gt;&gt;<a href="https://bscnote.tistory.com/77">링크텍스트</a>&lt;&lt;&lt;</p>
<h2 id="📌-mysql-외부-접속">📌 Mysql 외부 접속</h2>
<ul>
<li><p>mysql 접속후 모든 IP 허용 </p>
<p>   grant all privileges on <em>.</em> to ‘root’@‘%’ identified by ‘000001’;</p>
</li>
<li><p>변경 저장 완료 
  flush privileges;</p>
</li>
<li><p>LISTEN IP대역 변경<br>ubuntu 터미널에서 아래 코드 입력 </p>
<pre><code>  vi /etc/mysql/mysql.conf.d/mysqld.cnf </code></pre></li>
<li><p>bind-address ( 로컬호스트만 접근가능 ) 
부분을 주석처리 
( &#39;i&#39; = 수정 &#39;#&#39; = 주석처리 &#39;esc&#39; = 뒤로가기 ) </p>
</li>
<li><p>이후 :wq! ( 저장하고 종료 ) 
저장이 되지 않는다면 관리자 권한으로 수정
  :w !sudo tee % &gt; /dev/null
  :q! #나가기 </p>
</li>
</ul>
<h4 id="📌-모든-설정-이후-mysql-workbench-또는-datagrip-에서-생성한-db-조회-및-수정이-가능하다">📌 모든 설정 이후 Mysql workbench 또는 Datagrip 에서 생성한 DB 조회 및 수정이 가능하다</h4>
<h4 id="🖇️-ubuntu--putty-터미널-에러-해결-방법--링크텍스트">🖇️ ubuntu , putty 터미널 에러 해결 방법  &gt;&gt;&gt;<a href="https://patiencelee.tistory.com/610">링크텍스트</a>&lt;&lt;&lt;</h4>
<h4 id="🖇️-영상-참고-자료-링크텍스트">🖇️ 영상 참고 자료 <a href="https://www.youtube.com/watch?v=8IGgeaLlYW8&amp;list=LL&amp;index=3">링크텍스트</a></h4>
]]></description>
        </item>
        <item>
            <title><![CDATA[Linux 운영체제 - Ubuntu · Red Hat]]></title>
            <link>https://velog.io/@gyqls_12/Linux-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Ubuntu-Red-Hat</link>
            <guid>https://velog.io/@gyqls_12/Linux-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Ubuntu-Red-Hat</guid>
            <pubDate>Fri, 24 Feb 2023 07:23:47 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-리눅스-linux">📌 리눅스 Linux</h2>
<ul>
<li><p>Linux 커널을 기반으로 한 운영체제 이며, 
Window나 Mac과 달리 Linux는 분리/정의가 깔끔한 운영체제는 아니다.</p>
<ul>
<li>*<em>Linux는 커스터마이즈된 OS를 만들 수 있는 커널이며,
커스텀 OS 만들기에 특화된 운영체제 이다. *</em></li>
</ul>
</li>
<li><p>Linux 아키텍처는 커널, 시스템 라이브러리, 시스템 도구, 도구 및 최종 사용자 도구 외 다양한 오픈소스 라이브러리를 사용하여 활용하기에 용이하다.</p>
</li>
<li><p>장치 메모리를 관리하고 프로세스 관리하는 것이 편리하다.</p>
</li>
</ul>
<h2 id="📌-커널-kernel">📌 커널 Kernel</h2>
<ul>
<li><p>컴퓨터 운영체제의 핵심이 되는 컴퓨터 프로그램</p>
</li>
<li><p>시스템의 모든것을 완전히 통제하고 다른 응용 프로그램 수행에 필요한 서비스를 제공 </p>
</li>
<li><p>운영체제의 핵심이면서, 보안·자원관리·추상화 역할도 수행한다. </p>
</li>
</ul>
<h3 id="❗-운영체제와-커널의-차이">❗ 운영체제와 커널의 차이</h3>
<ul>
<li><p>운영체제 ( 사용자 응용 ) 
사용자 영역으로 응용프로그램·애플리케이션을 이용하기 위한 공간 
핵심적인 역할만 담당하여 사용 </p>
</li>
<li><p>커널 ( 자원관리 )
커널은 운영 체제의 일부분, 사용자 영역에서 사용자의 관리활동을 
안전하고 효율적으로 작동하기 위해 컴퓨터의 자원관리하는 영역 </p>
</li>
</ul>
<h2 id="📌-ubuntu">📌 Ubuntu</h2>
<ul>
<li><p>대표적인 데스크톱 리눅스 배포판으로, 초보자들이 쉽게 접근할 수 있도록 설계된 Linux 플랫폼</p>
</li>
<li><p>개인용 컴퓨터에 적합하며 
Ubuntu Server - 클라우드 및 서버관리
Ubuntu Core - IoT 기반 장치 개발 에 적합하다. </p>
</li>
<li><p>Ubuntu GUI , CLI 통해 개발 및 관리하며, 
Ubuntu 소프트웨어 · 다른 APT 기반 패키지 관리 도구 를 통해
많은 무로ㅛ 소프트웨어 도구를 다운로드·활용 이 가능하다. </p>
</li>
<li><p>또한 바이러스, 웜, 스파이웨어 등 악성 소프트웨어로 부터
데이터 및 리소스 보호하는 보안 운영체제이다. </p>
</li>
</ul>
<h4 id="❗-ubuntu-gui">❗ Ubuntu GUI</h4>
<ul>
<li>그래픽 사용자 인터페이스, 단추 창, 텍스트 상자 등 그래픽 구성요소 사용을 쉽게 수행할 수 있다.</li>
</ul>
<h4 id="❗-ubuntu-cli">❗ Ubuntu CLI</h4>
<ul>
<li>CLI 는 명령을 입력하고 신속하게 실행하는 것을 도와준다. </li>
</ul>
<h2 id="📌-red-hat">📌 Red Hat</h2>
<ul>
<li><p>오픈 소스 기술을 바탕으로 하는 기업용 Linux 운영체제 배포판</p>
</li>
<li><p>높은 안정성과 보안성으로 기업 사용률이 매우 높다 
또한 오픈 소스 기반이기에 다양한 소프트웨어 와 서비스를 제공하며 
Kubernetes, OpenStack, Ansible, JBoss Enterprise Middleware 등의 오픈 소스 프로젝트를 지원하며, 이를 활용하여 클라우드, 가상화, 컨테이너, 애플리케이션 개발 등 다양한 IT 분야에서 사용된다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git - Github Push ]]></title>
            <link>https://velog.io/@gyqls_12/Spring-Boot-Git-Bash-%EC%97%B0%EB%8F%99</link>
            <guid>https://velog.io/@gyqls_12/Spring-Boot-Git-Bash-%EC%97%B0%EB%8F%99</guid>
            <pubDate>Thu, 09 Feb 2023 09:41:55 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/gyqls_12/post/44ca8b91-eddc-4c4d-9822-0c3fc8efd762/image.png" alt=""></p>
<h2 id="📌-개요">📌 개요</h2>
<p> Git Bash 를 통해 Spring 프로젝트를 Git Repository 와 연동하고 
 Push/Pull 사용 방법에 대해 작성하는 페이지 </p>
<p> <a href="https://git-scm.com/downloads">+ Git 다운로드 필요 </a>
 <a href="https://github.com/">GitHub 회원가입 및 Repository 생성 필요</a> </p>
<h2 id="📌-git-config">📌 Git Config</h2>
<p> ** Git **을 사용하기전 필수 사전정보 입력 
 Git 원격 저장소와 연동할 폴더 - 마우스 우클릭 - &quot;Git Bash here&quot; 통해 
 Git 터미널을 호출한다.
 <img src="https://velog.velcdn.com/images/gyqls_12/post/ad1837b5-d146-4cd7-bc56-d655cf3c7487/image.png" alt=""></p>
<h4 id="❗-나의-정보--username--useremail--을-설정하기">❗ 나의 정보 ( user.name , user.email ) 을 설정하기</h4>
<pre><code class="language-git">      $ git config --global user.name &quot;나의 이름&quot;

        $ git config --global user.email &quot;example@gmail.com&quot;

      // user.name , email 정보가 정상적으로 입력되어있는지 확인 
       $ git config --list 
</code></pre>
<h2 id="📌-git-push">📌 Git Push</h2>
<ol>
<li><p>$ git init</p>
<p>git 초기화 명령어 
실행시 원격 저장소와 연동된 폴더에 [숨긴 파일] 형태로 
.git 폴더가 생성되고 저장소에 파일을 이동할 준비를 갖는다.</p>
</li>
<li><p>$ git remote add origin &quot;git repository 주소&quot;</p>
<p>해당 폴더가 전송할 Git Repository 주소와 연동하는 명령어 </p>
<pre><code class="language-git"> $ git remote -v </code></pre>
<p>명령어를 통해 현재 Repository 주소 확인이 가능하다. </p>
</li>
<li><p>$ git add . </p>
<p>연동된 폴더에 존재하는 모든 변경사항을 .git 폴더에 추가한다. </p>
</li>
<li><p>$ git status</p>
<p>변경사항이 적용이 되어있는지 상태 조회 명령어
변동사항이 적용되어있지 않는다면 - 빨간색 글씨와 해당 log가 출력 된다. ( add . 명령어 실행이 필요하다 ) 
변동사항이 적용되어 있다면 초록색 글씨와 함께 변동된 log가 출력 된다. </p>
</li>
<li><p>$ git commit -m &quot;메세지&quot; </p>
<p>변경사항을 &quot;메세지&quot; 와 함께 commit 하는 명령어
팀원들이 쉽게 파악할 수 있도록 가독성이 좋을수록 좋다. </p>
</li>
<li><p>$ git push origin &quot;branch 주소&quot; 
$ git push -u origin &quot;branch 주소&quot;</p>
<p>commit 된 변경사항을 git 원격 저장소로 push 하는 명령어.
별도의 branch 주소가 없다면 master branch로 push하면 접근 가능하다. </p>
<p>ex) </p>
<pre><code class="language-git"> $ git push origin master </code></pre>
</li>
</ol>
<h2 id="📌-그-외-git-명령어">📌 그 외 git 명령어</h2>
<pre><code class="language-git">
       // 저장소 복사 
      $ git clone &quot;http://클론할 git Repository 주소&quot;

      // 브랜치 목록 조회
    $ git branch

    // 새 브랜치 생성 
    $ git branch &quot;브랜치 이름&quot;

    // 해당 브랜치로 이동
    $ git checkout -b &quot;브랜치 이름&quot;

    // 저장소 pull 도잇에 현재 브랜치와 병합
    $ git pull remote &quot;브랜치 이름&quot;

    // 현재 원격 저장소 pull 
    $ git pull 

    // 다른 브랜치와 병합
    $ git merger &quot;브랜치 이름&quot;

    // git diff - 변경내용 조회
    $ git diff &quot;브랜치이름&quot; &quot;다른 브랜치 이름&quot;

    // git log 조회
    $ git log 

    // 로컬 변경사항을 이전으로 되돌리기
    $ git checkout

    // 원격으로 저장된 git 프로젝트의 현 상태 다운로드
    $ git fetch origin
</code></pre>
<p>  Git 명령어 참조
  <a href="https://velog.io/@delilah/GitHub-Git-%EB%AA%85%EB%A0%B9%EC%96%B4-%EB%AA%A8%EC%9D%8C#1-2-cli-command-line-interface-%EB%AA%85%EB%A0%B9%EC%96%B4!%5B%5D(https://velog.velcdn.com/images/gyqls_12/post/26a3b58d-a4d6-4462-a3dd-a93f51cf2672/image.png)">https://velog.io/@delilah/GitHub-Git-%EB%AA%85%EB%A0%B9%EC%96%B4-%EB%AA%A8%EC%9D%8C#1-2-cli-command-line-interface-%EB%AA%85%EB%A0%B9%EC%96%B4![](https://velog.velcdn.com/images/gyqls_12/post/26a3b58d-a4d6-4462-a3dd-a93f51cf2672/image.png)</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DevOps 와  개발 Container  ]]></title>
            <link>https://velog.io/@gyqls_12/DevOps-Docker-Container</link>
            <guid>https://velog.io/@gyqls_12/DevOps-Docker-Container</guid>
            <pubDate>Tue, 31 Jan 2023 07:16:44 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-devops">📌 DevOps</h2>
<p><img src="https://velog.velcdn.com/images/gyqls_12/post/b65d62ff-e03b-4d50-b80a-729e42e92f21/image.png" alt=""></p>
<ul>
<li><p>Develepoer(개발자) 와 Operator(운영팀) 의 협업 · 소통</p>
</li>
<li><p>DevOps는 애플리케이션과 서비스를 빠른 속도로 제공할 수 있도록 
조직의 역량을 향상시키는 문화 철학 및 도구의 조합</p>
</li>
<li><p>기존 소프트웨어 개발 및 인프라 관리 프로세스를 보다 더 빠르고 혁신적이게 개선할 수 있는 환경 </p>
</li>
<li><p>작업속도 , 신속한 제공 , 안정성, 확장, 보안 그리고 협업 강화를 제공</p>
</li>
<li><p>개발 초기부터 실행이 가능한 상태로 코드를 유지하고 
소프트웨어와 질적 향상과 배포하는 데에 시간을 줄이며
운영팀과 소통을 통해 고객에게 완벽한 개발 아이템을 제공하는 팀 프로젝트 구조 </p>
</li>
</ul>
<h2 id="📌-container">📌 Container</h2>
<ul>
<li>팀 프로젝트 · 개발 함에 있어
서버 OS · 하드웨어 · 하이퍼바이저 ·클라이언트 OS · 애플리케이션 구조를 생성할 때 </li>
<li><em>하드웨어, 클라이언트 OS , 하이퍼바이저 등의 무거운 요소*</em>를 뺀 상태에서
작업환경을 구축하는 기법 
( ex - 이러한 작업환경을 Docker 컨테이너가 제공해준다.) </li>
</ul>
<h4 id="🤔-웹-서버-컨테이너-스프링-컨테이너-는">🤔 웹 서버 컨테이너, 스프링 컨테이너 는?</h4>
<p>스프링 컨테이너 - 작업환경 구축 및 애플리케이션 제공 
웹 서버 컨테이너 - 오직 서버와 클라이언트의 비지니스 로직 환경만을 구축 </p>
<h2 id="📌-docker">📌 Docker</h2>
<p><img src="https://velog.velcdn.com/images/gyqls_12/post/6c97e069-5f0a-4023-8b87-82a12787b7ab/image.png" alt=""></p>
<ul>
<li><p>라이브러리, 시스템 도구, 코드 , 런타임 등을 
소프트웨어를 실행하기 위해 필요한 모든것이 담겨진 <strong>컨테이너</strong> </p>
</li>
<li><p>Docker가 서버 하드웨어를 가상으로 만들고 직접 관리하는 서버 운영 체제를 제공한다. </p>
</li>
</ul>
<h3 id="docker-이점">Docker 이점</h3>
<ul>
<li>빠른 코드전달 · 애플리케이션 운영 표준화 · 높은 리소스 사용률 
안정성 · 다양하고 많은 소프트웨어 제공 </li>
</ul>
<h2 id="📌jeus">📌JEUS</h2>
<ul>
<li><p>국내 티맥스소프트 에서 개발한 WAS 중 하나 </p>
</li>
<li><p>어플리케이션의 트랜잭션 관리, 세션 유지, 부하 분산 등의 기능 제공을 통해 
계층화된 구조와 유연성, 기능 확장성에 용이하다. </p>
</li>
</ul>
<h4 id="🤔-트랜잭션-">🤔 트랜잭션 ?</h4>
<pre><code>DB의 상태를 변경하기 위해 수행하는 작업 단위 </code></pre><ul>
<li><p>주로 동적 데이터( JSP , DB 연결 등)을 제공하기 위해 사용 </p>
</li>
<li><p>Domain / Domain Administration Server / Node Manager / Managed Server / Apllication으로 구성되어 있다. </p>
<p>  ++ Domain - 관련 서버들의 그룹이자 기본 관리 단위</p>
<p>  ++ Domain Adminstration Server ( DAS ) - 관리자용 서버 , 단     하나만 구축한다. </p>
<p>  관리자 서버가 죽더라도 Managed Server( MS ) 가 멀쩡하면 서비스     제공에 문제가 없다. </p>
<p>  ++ Node Manager : DAS 가 MS 를 관리하기 위해 사용하는 프로세스</p>
<p>  ++ Managed Server ( MS ) : 작업을 수행하는 프로세스 ,인스턴스     또는 컨테이너. 흔히 서버라고 칭한다.</p>
<p>  ++ Application - MS 에 의해 제공되는 서비스 ex) HTML, JSP </p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[웹 애플리케이션 서버 ( WAS ) ]]></title>
            <link>https://velog.io/@gyqls_12/HttpServlet-request-response</link>
            <guid>https://velog.io/@gyqls_12/HttpServlet-request-response</guid>
            <pubDate>Tue, 31 Jan 2023 06:07:05 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/gyqls_12/post/1fd68f1e-119b-48ed-a960-c4d97a2dafeb/image.png" alt=""></p>
<h2 id="📌-was--web-applicaiton-server-">📌 WAS ( Web Applicaiton Server )</h2>
<ul>
<li><p>WAS 란 DB 조회 혹은 다양한 로직 처리를 요구하는 동적 컨텐츠를 제공하기 위해 만들어진 애플리케이션 이다. </p>
</li>
<li><p>HTTP 프로토콜을 기반으로 사용자 디바이스에 애플리케이션을 수행해주며, 주로 DB 서버와 같이 수행된다. </p>
</li>
<li><p>WAS는 JSP, Servlet 구동환경을 제공해주기에 &quot;웹 컨테이너&quot; 라고 불린다</p>
</li>
<li><p>Tomcat , JBoss, WebSphere 등이 있다. </p>
</li>
</ul>
<h2 id="📌-servlet">📌 Servlet</h2>
<ul>
<li><p>동적 웹 페이지에 사용되는 JAVA 기반 웹 애플리케이션 프로그래밍 기술</p>
</li>
<li><p>동적 데이터를 처리하여 정적인 페이지로 생성해주는 &#39; 서블릿 컨테이너 &#39; 에 사용되는 기법이다. </p>
</li>
</ul>
<h2 id="📌-tomcat--apache-tomcat-">📌 Tomcat ( Apache Tomcat )</h2>
<ul>
<li><p>전 세계적으로 가장 많이 사용되는 오픈 소스 웹 컨테이너 
JAVA Servlet을 지원하기 위한 JAVA 플랫폼 </p>
</li>
<li><p>웹 애플리케이션의 다양한 규격을 준수하여 JSP,HTML 파일들로 구성된 .war파일을 배포해주는 엔진</p>
</li>
</ul>
<h2 id="📌-httpservlet---request">📌 HttpServlet - Request</h2>
<ul>
<li>사용자 ( 클라이언트 ) 가 view 영역을 통해 
서버에 요청을 보내면 Servlet 웹 컨테이너가 HttpServletRequest 객체를 생성하여 
사용자의 요청정보를 가져와 서버에서 로직 처리를 수행할 수 있게 해준다.</li>
</ul>
<p>ex ) </p>
<p>만약  <a href="http://localhost:8080/getInfo?id=mangdo&amp;year=2021">http://localhost:8080/getInfo?id=mangdo&amp;year=2021</a> 
으로 사용자가 요청하였다면 </p>
<pre><code class="language-java">HttpServletRequest request

request.getRequestURI();
request.getRequestURL();
request.getQueryString();
request.getParameter(&quot;id&quot;);
request.getServerName();
request.getServerPort();
request.getMethod();
request.getHeader(&quot;referer&quot;);</code></pre>
<p>Console </p>
<pre><code class="language-java">RequestURL : http://localhost:8080/getInfo
RequestURI : /getInfo
QueryString : id=mangdo&amp;year=2021
Get parameter : mangdo
ServerName(도메인) : localhost
ServerPort : 8080
Method : GET
Referer : http://localhost:8080/getInfo 
(Refer? 현재 요청된 페이지의 링크 이전의 웹 페이지 주소)</code></pre>
<p>request 객체의 메소드를 통해 사용자의 요청을 활용할 수 있게된다. </p>
<h2 id="📌-httpservlet---response">📌 HttpServlet - Response</h2>
<ul>
<li>HttpServletRequest 를 통해 얻게된 사용자의 요청을 
서블릿 컨테이너 영역에서 로직 처리를 모두 수행한 후 
사용자에게 응답 메세지 또는 동적 컨텐츠를 제공하는 객체이다. </li>
</ul>
<h2 id="📌-동적-페이지--dynamic-page-">📌 동적 페이지 ( Dynamic Page )</h2>
<ul>
<li>= 동적 컨텐츠, 
사용자의 요청에 의해 서버가 수행한 결과를 담아 응답하는 페이지 
사용자마다 다른 페이지가 보여질 수 있다. </li>
</ul>
<h2 id="📌-정적-페이지--static-page-">📌 정적 페이지 ( Static Page )</h2>
<ul>
<li>별도의 서버 처리가 없어도 
사용자에게 보여줄 수 있는 페이지, 모든 사용자에게 동일한 페이지가 보여진다. 
ex) HTML , CSS , JS </li>
</ul>
<p><img src="https://velog.velcdn.com/images/gyqls_12/post/479f9124-6ff2-4728-aad9-9f3e87bf9cad/image.png" alt=""></p>
<h2 id="📌-동기-통신--동기적-프로그래밍-">📌 동기 통신 ( 동기적 프로그래밍 )</h2>
<ul>
<li><p>동기 Synchronous : 동시에 일어나는 </p>
</li>
<li><p>프로그래밍 로직이 &#39; 한 방향 &#39; 으로 되어있으며
다음 업무를 진행하기 위해선 이전 업무 수행이 반드시 필요하다.</p>
</li>
<li><p>일부 영역이라도 데이터 변화를 하기 위해서는 
전체 영역을 서버에 재요청해야한다.</p>
</li>
<li><p>어떤 의미에서는 정적 페이지와 유사 </p>
</li>
</ul>
<h2 id="📌-비동기-통신--비동기적-프로그래밍-">📌 비동기 통신 ( 비동기적 프로그래밍 )</h2>
<ul>
<li><p>비지니스 로직이 여러 갈래로 되어있으며 
이전 업무 수행 없이도 특정 업무만 따로 수행시킬 수 있다.</p>
</li>
<li><p>일부 영역에 데이터 갱신을 하더라도 나머지 전체 영역은 
멈추는 것이 아닌 프로그램이 계속 돌아간다. </p>
</li>
<li><p>어떤 의미에서는 동적 페이지와 유사 </p>
</li>
</ul>
<p>ex) AJAX </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] Overload / Override]]></title>
            <link>https://velog.io/@gyqls_12/JAVA-Overload-Override</link>
            <guid>https://velog.io/@gyqls_12/JAVA-Overload-Override</guid>
            <pubDate>Mon, 30 Jan 2023 07:10:33 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-overload">📌 Overload</h2>
<ul>
<li>동일이름 메소드를 여러개를 가지나, 
다른 파라미터를 사용하여 활용하는 것 </li>
</ul>
<h3 id="❗-overload-조건">❗ Overload 조건</h3>
<ol>
<li><p>서로의 파라미터 데이터 타입이 달라야 한다.</p>
</li>
<li><p>파라미터 데이터 타입이 같더라도 순서가 달라야한다. 
( 즉, Overload 하고자 하는 메소드와 똑같으면 안된다 ! ) </p>
</li>
</ol>
<p>ex ) 
<img src="https://velog.velcdn.com/images/gyqls_12/post/3ec04a69-167a-4de8-af51-95d3a6948732/image.png" alt=""></p>
<p>같은 메소드 , 다른 매개변수 
addAllAttributes(); 
addAttribute();</p>
<p>에서 각각 다른 매개변수를 입력하여 활용하는 방식 
( ❗ 개발자가 실수로 다른 매개변수 메소드를 선택했어도 
알맞은 메소드에 자동으로 적용해준다 ) </p>
<h2 id="📌-override">📌 Override</h2>
<ul>
<li>상속관계인 부모 클래스에 정의된 메소드를 
자식 클래스에서 다시 가져와 재정의 하는 것 </li>
</ul>
<p><img src="https://velog.velcdn.com/images/gyqls_12/post/fe17608a-0d53-41e9-83da-5ecdfc537b43/image.png" alt="">
(부모클래스 = Filter ) </p>
<p>부모 클래스의  &#39; doFilter &#39; 메소드를 가져와 
개발자의 로직으로 재정의하는 것 </p>
<p>부모 클래스의 &#39; doFilter &#39; 메소드는 삭제되지 않으나
Override 된 메소드가 우선적으로 적용된다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리눅스 vs 윈도우 OS]]></title>
            <link>https://velog.io/@gyqls_12/%EB%A6%AC%EB%88%85%EC%8A%A4-vs-%EC%9C%88%EB%8F%84%EC%9A%B0-OS</link>
            <guid>https://velog.io/@gyqls_12/%EB%A6%AC%EB%88%85%EC%8A%A4-vs-%EC%9C%88%EB%8F%84%EC%9A%B0-OS</guid>
            <pubDate>Mon, 30 Jan 2023 06:38:08 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-linux-특징">📌 Linux 특징</h2>
<ul>
<li>오픈소스 운영체제 중 하나 커널 자체를 의미하기도 한다. </li>
<li>대형 기종에서 작동하던 Unix 를 개인용 컴퓨터에 상용한 것 </li>
<li>CPU , 메모리 , 스토리지 처럼 시스템의 하드웨어와 리소스를 
직접 관리하는 소프트웨어</li>
<li>소스 코드가 공개되어 있는 &#39; 자유 소프트웨어&#39; 와 &#39; 오픈소스 개발&#39; 의 표본 </li>
<li>다중 사용자, 다중 프로그램, 다중 스레드를 지원하는 네트워크 운영체제(NOS) 로써, 
여러사람이 하나의 리눅스 시스템에 접속하여 다수의 프로그램을 동시에 실행 할 수 있다. </li>
<li>전산 시스템 하드웨어, 스마트 폰, 냉장고 , TV 등의
하드웨어 운영체제로 적합하다. </li>
</ul>
<h2 id="📌-윈도우-os-특징">📌 윈도우 OS 특징</h2>
<ul>
<li>마이크로소프트 사의 운영체제 </li>
<li>멀티 태스킹 과 GUI 환경을 제공하기 위해 출시</li>
<li>압도적인 접근성 ( 점유율 90% ) , 뛰어난 호환성  </li>
<li>리눅스에 비해 폐쇄적인 시스템 </li>
</ul>
<h4 id="🤔-gui----마우스로-아이콘이나-메뉴를-선택하여-서버-작업이-가능하다">🤔 GUI ? - 마우스로 아이콘이나 메뉴를 선택하여 서버 작업이 가능하다</h4>
<ul>
<li>선점형 멀티태스킹
동시에 여러개의 프로그램을 실행하여 운영체제가 각 작업의 CPU 
이용시간을 제어하는 방식 </li>
<li>PnP ( 플러그 앤 플레이 ) 
컴퓨터 시스템에 하드웨어를 설치했을 때, 운영체제가 
설치한 하드웨어의 환경을 자동으로 구성해주는 기능 </li>
<li>OLE 
다른 응용 프로그램의 문서 , 그림 등의 객체를 
현재 작성중인 문서에 자유롭게 연결해주고, 편집까지 가능한 기능 </li>
</ul>
<h2 id="📌-linux-vs-window-차이점">📌 Linux vs Window 차이점</h2>
<h3 id="1-비용적-측면">1. 비용적 측면</h3>
<ul>
<li><p>리눅스
무료 + 공개 OS
라이센스 제한이 없고, 상용 배포판이더라도 저렴한 비용 요구 
( 기본 애플리케이션 무상 혹은 저렴한 비용 )</p>
</li>
<li><p>윈도우
유로 
기본 애플리케이션 이용시 추가 비용 </p>
</li>
</ul>
<h3 id="2-안정성-및-신뢰도">2. 안정성 및 신뢰도</h3>
<ul>
<li><p>리눅스 
안정성과 신뢰도가 높은 운영체제로 사용되며 
개발업체 나 개발자들이 수시로 업데이트 하는 운영체제</p>
</li>
<li><p>윈도우 
MS 에서 전문 보안 솔루션을 제공하기 때문에
보안 및 안정성이 월등하다. </p>
</li>
</ul>
<h3 id="3-성능">3. 성능</h3>
<ul>
<li><p>리눅스 
응용프로그램에 대해 좋은 성능을 발휘하며
낮은 성능 서버 = 고성능 이 가능하다</p>
</li>
<li><p>윈도우 
윈도우 개발언어로 개발된 서비스의 경우
최고성능 을 발휘한다. </p>
</li>
</ul>
<h3 id="4-보안성">4. 보안성</h3>
<ul>
<li><p>리눅스
다중 사용자 체제이므로 관리자 권한이 로그인 하지 않으면 
다른 사용자는 보호 모드에서 사용하므로 
바이러스 가 적고 보안성이 높다. 
단, 오픈 소스이기에 Window OS 보단 취약하다. 
떄문에 초기 서버 구축단계에서 신중을 가해야 한다. </p>
</li>
<li><p>윈도우
시스템 버그나 보안 취약점 발견시 패치를 기다려야하며 오랜 시간이 걸린다. 
단, MS 사의 전문 보안 솔루션이 존재한다. </p>
</li>
</ul>
<h3 id="5-응용-프로그램">5. 응용 프로그램</h3>
<ul>
<li><p>리눅스 
다양한 무료 오픈소스 프로그램 존재 
직접 소스 수정 및 제작이 가능 </p>
</li>
<li><p>윈도우
적은 무료 프로그램 수 
직접 소스 수정 및 제작이 불가능 </p>
</li>
</ul>
<h3 id="6-상용-애플리케이션">6. 상용 애플리케이션</h3>
<ul>
<li><p>리눅스
윈도우 OS 보다 적은 상용 애플리케이션 </p>
</li>
<li><p>윈도우
다른 운영체제보다 많은 애플리케이션을 보유 
WMA 스트리밍 서비스와 같이 ASP로 개발된 페이지를 구동해야하는 경우가 대표적 </p>
</li>
</ul>
<h3 id="7-운영관리-측면">7. 운영관리 측면</h3>
<ul>
<li>리눅스 &amp; 윈도우 
기술 지원 측면에서는 리눅스가 전문적으로 신속하나
운영 관리 측면에서는 윈도우가 더 편리하다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Boot - 회원가입 / 로그인]]></title>
            <link>https://velog.io/@gyqls_12/Spring-Boot-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85-%EB%A1%9C%EA%B7%B8%EC%9D%B8</link>
            <guid>https://velog.io/@gyqls_12/Spring-Boot-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85-%EB%A1%9C%EA%B7%B8%EC%9D%B8</guid>
            <pubDate>Thu, 26 Jan 2023 07:49:16 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-개요">📌 개요</h2>
<p> 상품 등록 및 수정하는 사이트에서 
 사용자의 정보 ( id, pw ) 를 가져오고
 Cookie 와 Session 에 담아 회원가입 / 로그인 / 로그아웃 기능을 구현 </p>
<h2 id="📌-member">📌 Member</h2>
<p>사용자가 회원가입할 때 입력한 정보를 담는 클래스 </p>
<pre><code class="language-java">@Data
public class Member {

    /*
     *  로그인 사용자의 정보를 담을 자바 클래스 
     *  ID 넘버 , 회원 ID, 회원 이름, 회원 패스워드 
     */

    private Long id;
    private String loginId;
    private String name;
    private String password;
}</code></pre>
<h2 id="📌-membercontroller">📌 MemberController</h2>
<p>사용자의 요청처리 중 회원가입 업무를 담당하는 컨트롤러 영역
Thymeleaf를 통해 사용자가 입력한 정보를 가져오고 
Repository에 저장 한 후 페이지를 새로고침하여 회원가입을 완료한다. </p>
<pre><code class="language-java">@Controller
@RequiredArgsConstructor
@RequestMapping(&quot;/member&quot;)
public class MemberController {

    private final MemberRepository memberRepository;

    /*
     * 1. 멤버 회원등록 ( addForm ) 
     *  &quot;/member/add&quot; 의 사용자 요청을 받으면 
     *  &quot;members/addMemberForm&quot; 으로 이동하고 
     *  사용자가 입력폼에 입력한 값을 
     *  memberRepository.save 통해 로그인 멤버 정보 저장 
     *  
     *  정보 저장이 완료되면 redirect 실행 
     */

    @GetMapping(&quot;/add&quot;)
    public String addForm( @ModelAttribute(&quot;member&quot;) Member member) {
        return &quot;members/addMemberForm&quot;;
    }

    @PostMapping(&quot;/add&quot;)
    public String save( @ModelAttribute Member member) {
        memberRepository.save(member);
        return &quot;redirect:/&quot;;
    }
}</code></pre>
<h2 id="📌-memberrepository">📌 MemberRepository</h2>
<p> 컨트롤로 영역에서 사용자가 요청한 데이터를 담는 레포지토리 영역
 HashMap 타입으로 정보를 담아오고 회원가입이 완료되면 
 회원 아이디를 sequence++ 통해 고유 id를 서버 영역에 저장한다. 
 ( ❗ 중복회원가입을 방지하기 위함 ) </p>
<pre><code class="language-java"> @Repository
public class MemberRepository {

    private static Map&lt;Long, Member&gt; store = new HashMap&lt;&gt;();
    private static long sequence = 0L;

    /*
     * 1. 멤버 회원등록 
     *     Member DTO 값을 HashMap 타입으로 변환하고 
     *  사용자가 입력한 데이터를 MemberDTO 에 저장 
     *  ( ! 중복회원을 방지하기 위해 sequence++ 추가 ) 
     */
    public Member save(Member member) {
        member.setId(sequence++);
        store.put(member.getId(), member);
        return member;
    }

    /*
     * 2. 로그인 하기 
     * 
     * 사용자의 로그인 정보를  LoginController -&gt; LoginService 통해
     * 받아오고, 해당 로그인 정보가 일치한지 검증하는 로직 
     * 
     *  MemberRepository 에서 사용자가 입력한 String LoginId 값을 
     *  통해 전체 조회하고 
     *  
     *  조회한 값 = 사용자가 입력한 값이 일치한다면 
     *  해당 정보를 리턴 
     */

    public Member findById(Long id) {
        return store.get(id);
    }

    public List&lt;Member&gt; findAll(){
        return new ArrayList&lt;Member&gt;(store.values());
    }

    public Member findByLoginId(String loginId) {
        List&lt;Member&gt; all = findAll();
        for( Member m : all) {
            if (m.getLoginId().equals(loginId)) {
                return m;
            }
        }
        // 사용자가 입력한 값이 일치하지 않는다면 
        // null 값 리턴 
        return null;
    }

}</code></pre>
<h2 id="📌-loginform">📌 LoginForm</h2>
<p> 사용자의 로그인 정보 ( id , pw ) 를 담는 클래스 </p>
<pre><code class="language-java">@Data
public class LoginForm {
&gt;
    private String loginId;
    private String password;
} </code></pre>
<h2 id="📌-logincontroller">📌 LoginController</h2>
<pre><code class="language-java"> @Controller
@RequiredArgsConstructor
public class LoginController {

    private final LoginService loginService;

    /*
     * 1. 로그인 으로 이동 
     * 사용자가 &quot;login&quot; URI 에서 요청시
     * &quot;login/loginForm&quot; 위치로 이동 
     */

    @GetMapping(&quot;login&quot;)
    public String loginForm(@ModelAttribute(&quot;loginForm&quot;) LoginForm loginform) {
        return &quot;login/loginForm&quot;;
    }

    /*
     * 2-1. 로그인 하기 
     * 
     * Cookie 사용 시 
     */

//    @PostMapping(&quot;/login&quot;)
    public String login (@ModelAttribute LoginForm form,
            Model model, RedirectAttributes redirectAttributes, HttpServletResponse response) {

        Member loginMember = loginService.login(form.getLoginId(), form.getPassword());

        // 로그인 실패 시 - &quot;login/loginForm&quot; 으로 이동
        if ( loginMember == null) {
            model.addAttribute(&quot;msg&quot;, &quot;로그인 실패&quot;);
            return &quot;login/loginForm&quot;;
        }

        // 로그인 성공 시 
        Cookie idCookie = new Cookie(&quot;memberId&quot;, String.valueOf(loginMember.getId()));
        response.addCookie(idCookie);

        redirectAttributes.addFlashAttribute(&quot;msg&quot;, &quot;로그인 성공&quot;);

        return &quot;redirect:/&quot;;
    }

    /*
     * 2-2 로그인 하기 
     * Session 사용시 
     */

//    @PostMapping(&quot;/login&quot;)
    public String login2(@ModelAttribute LoginForm form,
            Model model, RedirectAttributes redirectAttributes, HttpServletRequest req) {

        Member loginMember = loginService.login(form.getLoginId(), form.getPassword());

        // 로그인 실패 
        if( loginMember == null) {

            model.addAttribute(&quot;msg&quot;, &quot;로그인 실패&quot;);
            return &quot;login/loginForm&quot;;
        }

        // 로그인 성공 
        HttpSession session = req.getSession();

        // 세션에 로그인 회원 정보 보관
        session.setAttribute( SessionConst.LOGIN_MEMBER, loginMember);

        redirectAttributes.addFlashAttribute(&quot;msg&quot;, &quot;로그인 성공&quot;);
        return &quot;redirect:/&quot;;

    }

    @PostMapping(&quot;/login&quot;)
    public String login3 (@ModelAttribute LoginForm form,
            Model model, RedirectAttributes redirectAttributes
            , HttpServletRequest req
            , @RequestParam(defaultValue = &quot;/&quot;)String redirectURL) {

        Member loginMember = loginService.login(form.getLoginId(), form.getPassword());

        // 로그인 실패 
        if( loginMember == null) {
            model.addAttribute(&quot;msg&quot;, &quot;로그인 실패&quot;);
            return &quot;login/loginForm&quot;;
        }

        // 로그인 성공
        HttpSession session = req.getSession();

        session.setAttribute( SessionConst.LOGIN_MEMBER, loginMember);

        redirectAttributes.addFlashAttribute(&quot;msg&quot;, &quot;로그인 성공&quot;);
        return &quot;redirect:/&quot;;
    }

    /*
     *  3-1. 로그아웃 ( 쿠키 사용 ) 
     *  로그아웃 시 이전화면 이동 + 동시에 쿠키 값 리셋 
     */
//    @PostMapping(&quot;/logout&quot;)
    public String logout( HttpServletResponse response) {

        // cookie 안에 memberId 에 null 을 할당 
        Cookie cookie = new Cookie(&quot;memberId&quot;, null);

        cookie.setMaxAge(0);
        response.addCookie(cookie);

        return &quot;redirect:/&quot;;
    }

    /*
     * 3-2 로그아웃 ( 세션 사용 ) 
     * 
     * 로그아웃 시 이전 화면 이동 + 동시에 세션 값 삭제 
     */

    @PostMapping(&quot;/logout&quot;)
    public String logout2( HttpServletRequest req) {

        /*
         *  req.getSession(true)
         *      세션이 있으면 기존 세션을 반환
         *      단, 세션이 없으면 새로운 세션을 생성해서 반환한다 
         *  
         *  req.getSession(false)
         *      세션이 있으면 기존 세션을 반환
         *      세션이 없으면 새로운 세션을 생성하지 않고 null 로 반환 
         */
        HttpSession session = req.getSession(false);

        // 만약 session이 삭제 되지 않는다면 
        // 세션 무효화 = .invalidate() 통해 삭제 
        if( session != null) {
            session.invalidate();
        }
        return &quot;redirect:/&quot;;
    }
}</code></pre>
<h2 id="📌-loginservice">📌 LoginService</h2>
<pre><code class="language-java"> @Service
@RequiredArgsConstructor
public class LoginService {

    // loginService date -&gt; MemberRepository 로 이동 
    private final MemberRepository memberRepository;

    /*
     *  2. 로그인 하기 
     *  로그인 Controller 영역에서 사용자가 입력한
     *  id, pw 가 일치하면 해당 값을 MemberRepository 에 가져와 
     *  반환 동시에 로그인 성공을 리턴 
     *  
     *  만약 사용자 정보 != MemberRepository 정보가 일치하지 않는다면
     *  null 값 리턴 
     */

    public Member login(String loginId, String password) {
        Member member = memberRepository.findByLoginId(loginId);

        // 로그인 성공시 
        if ( member != null &amp;&amp; member.getLoginId().equals(loginId)) {
            return member;
        //로그인 실패 시 
        }else {
            return null;
        }
    }

}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Boot - item 수정]]></title>
            <link>https://velog.io/@gyqls_12/Spring-Boot-%EC%88%98%EC%A0%95%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@gyqls_12/Spring-Boot-%EC%88%98%EC%A0%95%ED%95%98%EA%B8%B0</guid>
            <pubDate>Mon, 09 Jan 2023 09:24:16 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-개요">📌 개요</h2>
<blockquote>
</blockquote>
<pre><code class="language-java">@Getter @Setter
public class Item {
&gt;    
    private Long id;
    private String itemName;
    private Integer price; 
    private Integer quantity;
    &gt;
    private Boolean open;
    private List&lt;String&gt; regions; 
    private ItemType itemType;
    private String deliveryCode;
    &gt;
    public Item() {}
&gt;
    public Item(Long id, String itemName, Integer price, Integer quantity) {
        super();
        this.itemName = itemName;
        this.price = price;
        this.quantity = quantity;
    }</code></pre>
<p>Spring 컨테이너 내부에서 
Item() 데이터를 사용자와 주고 받는 예제 이다. </p>
<p>regions, itemType, deliveryCode 는 개발자가 명시된 범위에서 사용자가 요청하게 된다. </p>
<p>해당 비지니스 로직은
사용자의 itemId 를 조회하여 item() 데이터를 수정하는 로직이다. </p>
<h2 id="📌-edit-controller">📌 Edit Controller</h2>
<p>item 수정은 메소드가 2개 필요하다 </p>
<p>1 - 수정 할 상품을 조회할 메소드 ( GET )
2 - 수정 된 상품을 저장 후 redirect 로 사용자에게 요청처리 할 메소드 </p>
<blockquote>
<p>1-1. item 조회 Controller 메소드 </p>
</blockquote>
<pre><code class="language-java">    @GetMapping(&quot;/{itemId}/edit&quot;)
    public String editForm( @PathVariable Long itemId, Model model) {
&gt;        
        Item item = itemRepository.findById(itemId);
        model.addAttribute(&quot;item&quot;, item);
        return &quot;basic/editForm&quot;;
    }</code></pre>
<p> editForm.html 에서 
 item 객체의 정보를 사용자에게 할당받는다. </p>
<blockquote>
<p>1-2. item 조회 Repository 메소드 </p>
</blockquote>
<pre><code class="language-java">    public Item findById(Long itemId) {
        return store.get(itemId);
    }
&gt; 
store 에는 HashMap 타입으로 
Key 값은 itemId, value 값으로 item 데이터가 담겨져 있다.
&gt;
private static final Map&lt;Long, Item&gt; store = new HashMap&lt;Long, Item&gt;(); </code></pre>
<blockquote>
<p>2-1. item 수정 후 redirect 요청처리 메소드 </p>
</blockquote>
<pre><code class="language-java">    @PostMapping(&quot;/{itemId}/edit&quot;)
    public String edit( @PathVariable Long id , @ModelAttribute Item item) {
&gt;        
        itemRepository.update(id, item);
&gt;        
        return &quot;redirect:/basic/items/{itemId}&quot;;
    }</code></pre>
<p>editForm 에서 할당받은 사용자의 데이터를
item Repository 를 통해 update(수정) 시킨 후 </p>
<p>redirect 방식으로 
items.html 에 적용시킨다. </p>
<blockquote>
<p>2-2. item 수정 Repository 메소드 </p>
</blockquote>
<pre><code class="language-java">    public void update(Long itemId , Item updateParam) {
&gt;        
        // 수정할 아이템 id 를 조회 
        Item findItem = findById(itemId);
&gt;        
        // 조회된 id 의 값의 모든 정보를 사용자가 입력한 정보로 수정(=update) 
        findItem.setItemName(updateParam.getItemName());
        findItem.setPrice(updateParam.getPrice());
        findItem.setQuantity(updateParam.getQuantity());
&gt;        
        findItem.setOpen(updateParam.getOpen());
        findItem.setRegions(updateParam.getRegions());
        findItem.setItemType(updateParam.getItemType());
&gt;        findItem.setDeliveryCode(updateParam.getDeliveryCode());
    }</code></pre>
<h4 id="코드-보기---github">코드 보기 - GitHub</h4>
<p><a href="https://github.com/AntonioA12/SpringBoot_Practice">링크텍스트</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Boot - 사용자 요청 방식]]></title>
            <link>https://velog.io/@gyqls_12/Spring-Boot-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%9A%94%EC%B2%AD-%EB%B0%A9%EC%8B%9D</link>
            <guid>https://velog.io/@gyqls_12/Spring-Boot-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%9A%94%EC%B2%AD-%EB%B0%A9%EC%8B%9D</guid>
            <pubDate>Mon, 09 Jan 2023 08:00:04 GMT</pubDate>
            <description><![CDATA[<p>*<em>❗ 사용자 ( URI 리소스 ) 와 서버 ( Spring 컨테이너 ) 가 
서로 데이터를 주고 받기 위해 사용되는 기법들 *</em></p>
<h2 id="📌-pathvariable-경로변수">📌 PathVariable 경로변수</h2>
<p>*<em>❗URI 리소스와 Spring Controller 메소드 파라미터와 
바인딩할 때 사용하는 어노테이션 *</em></p>
<blockquote>
</blockquote>
<p>PathVariable 예시</p>
<pre><code class="language-java">    /*
     * 1-1 상품 아이템id로 조회
     */
    @GetMapping(&quot;/{itemId}&quot;)
    public String item(@PathVariable Long itemId, Model model ) {
        Item item = itemRepository.findById(itemId);
        model.addAttribute(&quot;item&quot;, item);
&gt;        
        return &quot;basic/item&quot;;
    }</code></pre>
<p>예시와 같이 GetMapping 으로 받아오는 URI 리소스 중 
itemid 값을 경로변수(PathVariable) 로 선언하여 
해당 리소스 값을 Spring 컨테이너 내부에서 활용하는 기법이다. </p>
<h2 id="🤔-바인딩-이란-">🤔 바인딩 이란 ?</h2>
<p>Spring 사용자 관점에서 사용자가 입력한 값을 
어플리케이션 도메인 객체에 동적으로 할당하는 기능 
( = 도메인 과 Controller 영역 간의 정보 전달 하기 위함 ) </p>
<p>쉽게 말해, Spring 컨테이너 내부의  도메인 과 Controller 를 연결 시키는 작업 </p>
<h2 id="📌-requestparam">📌 @RequestParam</h2>
<p>*<em>❗Controller 메소드의 파라미터와 웹 요청 파라미터를 매핑하기 위해 
사용하는 어노테이션 *</em></p>
<blockquote>
<p>@RequestParam 예시</p>
</blockquote>
<pre><code class="language-java">    @PostMapping(&quot;/add&quot;)
    public String save(    @RequestParam String     itemName,
                        @RequestParam int        price,
                        @RequestParam Integer    quantity,
                        Model model) {
        Item item = new Item();
        item.setItemName(itemName);
        item.setPrice(price);
        item.setQuantity(quantity);
&gt;
        itemRepository.save(item);
&gt;
        model.addAttribute(&quot;item&quot;, item);
        return &quot;basic/item&quot;;
    }</code></pre>
<p>사용자의 요청을 통해 명시된 URI 리소스 
** &quot;ex) /itemName=name&amp;price=100&amp;quantity=30 &quot; ** 에서 
String, int, Integer 데이터를 받아 
Item() 객체에 할당하고 </p>
<p>Repository 영역으로 이동해 할당된 item()객체 데이터를 
DB영역에 저장하도록 설계된 예시이다. </p>
<h2 id="📌-modelattribute">📌 @ModelAttribute</h2>
<p>*<em>❗ Controller 메소드의 파라미터 나 리턴값을 
Model 객체와 바인딩 하기 위한 어노테이션 *</em></p>
<p>*<em>❗ @RequestParam 를 다중으로 선언한 것과 같다  *</em></p>
<blockquote>
<p>@ModelAttribute 예시</p>
</blockquote>
<pre><code class="language-java">    @PostMapping(&quot;/add&quot;)
    public String saveV2( @ModelAttribute(&quot;item&quot;)Item item) {
        // @ModelAttribute 가 해주는 역할
//        Item item = new Item();
//        item.setItemName(itemName);
//        item.setPrice(price);
//        item.setQuantity(quantity);
    &gt;
        itemRepository.save(item);
    &gt;
//        model.addAttribute(&quot;item&quot;, item);
        return &quot;basic/item&quot;;
    }</code></pre>
<p>@RequestParam 을 통해 다수의 데이터를 주고 받을 때
Model 타입 객체 하나로 통일하여 다수의 데이터를 주고 받을 때 사용한다</p>
<p>URI 리소스의 데이터를 Model 객체로 가져와 view단에 즉시 적용 및 Repository 영역으로 이동 등 활용사례가 다양하다. </p>
<p>*<em>❗ Spring 3 버전에서 @ModelAttirbute 어노테이션 선언 없이 
Model 객체 선언하는 것만으로도 적용이 되지만, 가독성 이슈로 인해 선언해 주자 *</em></p>
<h2 id="📌-redirectattributes">📌 RedirectAttributes</h2>
<p>사용자 요청에 맞춰 데이터를 전달하는 방식에 사용되는 클래스 </p>
<p>Spring Controller 메소드의 파라미터에서 선언하여
데이터를 할당하고 redircet 형태로 할당된 데이터를 활용한다. </p>
<p><strong>❗RedirectAttribute 는 GET 방식의 요청에서만 사용가능하다 !</strong></p>
<blockquote>
<p>RedirectAttribute 예시</p>
</blockquote>
<pre><code class="language-java">    @PostMapping(&quot;/add&quot;)
    public String saveV6( Item item, RedirectAttributes redirectAttributes) {
&gt;    
        Item saveItem =  itemRepository.save(item);
        redirectAttributes.addAttribute(&quot;itemId&quot;, saveItem.getId());
        redirectAttributes.addAttribute(&quot;status&quot;,true);
&gt;        
        return &quot;redirect:/basic/items/{itemId}&quot;;
    }</code></pre>
<p>사용자의 요청에 전달받은 itemid 를 
saveItem 메소드의 id 데이터 로 할당하여 </p>
<p>사용자의 itemid 가 변경될 때 마다 
그 에 맞는 saveItem 메소드가 실행된다.</p>
<h2 id="📌-bindingresult">📌 BindingResult</h2>
<p>Validation Check 에서 검증오류를 보관하는 객체 
ex) 사용자가 int 필드에 String 값을 입력한 경우 
타입오류로 발생하는 에러시 Spring BindingResult 에 자동으로 넣어준다. </p>
<p>이 부분을 개발자가 직접 검증을 수행해서 BindingResult 에  넣어줄 수 있다. </p>
<p>BindingResult 가 설정되어 있ㅎ으면 
쿼리 파라미터를 Model Attribute에 객체로 바인딩하는 것에 실패해도
Controller가 실행된다. </p>
<p>*<em>❗ BindingResult 는 핸들러 매개변수에서 자신이 검증할 객체 
바로 다음에 위치 시켜야한다 *</em></p>
<p>*<em>❗ BindingResult 는 Model 객체에 자동 할당된다. *</em></p>
<blockquote>
<p>BindingResult 예시</p>
</blockquote>
<pre><code class="language-java">    /*
     *  BindingResult : Item 객체에 값이 잘 담기지 않을 때, 
     *      BindingResult 객체에 값이 담긴다.
     *      Spring 에서 제공하는 검증 오류를 보관하는 객체, 검증 오류가 발생시 여기에 보관 
     *  
     *      주의 ) BindingResult 는 검증할 대상 바로 다음에 설정해야한다 ( 순서 중요 ) 
     *      BindingResult 는 Model 에 자동으로 포함된다.
     */
    @PostMapping(&quot;/add&quot;)
    public String saveV7( Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
&gt;
        // StringUtils.hasText
        // 값이 있을경우 true , 공백이나 null 들어올 경우에는 false를 반환하게 된다.
        if ( ! StringUtils.hasText(item.getItemName()) ) {
            // FieldError : Field 단위에 error를 처리하는 Spring 제공 객체 
            bindingResult.addError( new FieldError(&quot;item&quot;, &quot;itemName&quot;, &quot;상품 이름은 필수 입니다.&quot;));
        }
&gt;        
        // 검증에 실패하면 다시 addForm 화면으로 돌아가도록 설정
&gt;        
        if ( bindingResult.hasErrors()) {
            System.out.println(&quot;errors= &quot; + bindingResult);
            return &quot;basic/addForm&quot;;
        }
&gt;        
        // Price 조건
&gt;        
        if (item.getPrice() == null || item.getPrice() &lt; 1000 
                || item.getPrice() &gt; 10000000) {
            bindingResult.addError( new FieldError(&quot;item&quot;, &quot;price&quot;, &quot;가격은 1000~1000000 사이여야합니다&quot;));
        }
&gt;        
        // quantity 조건
&gt;        
        if ( item.getQuantity() == null || item.getQuantity() &gt; 100000) {
            bindingResult.addError( new FieldError(&quot;item&quot;, &quot;quantity&quot;, &quot; 수량은 최대 9999개 까지 가능합니다&quot;));
        }
&gt;        
        System.out.println(&quot;item.open = &quot; + item.getOpen());
        System.out.println(&quot;item.regions = &quot; + item.getRegions());
        System.out.println(&quot;item.itemType = &quot; + item.getItemType());
&gt;
        Item saveItem =  itemRepository.save(item);
        redirectAttributes.addAttribute(&quot;itemId&quot;, saveItem.getId());
        redirectAttributes.addAttribute(&quot;status&quot;,true);
    &gt;    
        return &quot;redirect:/basic/items/{itemId}&quot;;
    }</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[REST 와 REST API]]></title>
            <link>https://velog.io/@gyqls_12/Spring-Boot-REST-API-%EB%9E%80</link>
            <guid>https://velog.io/@gyqls_12/Spring-Boot-REST-API-%EB%9E%80</guid>
            <pubDate>Thu, 05 Jan 2023 11:06:16 GMT</pubDate>
            <description><![CDATA[<h1 id="📌-rest">📌 {REST}</h1>
<p>** 웹 하이퍼미디어 시스템을 위한 개발 아키텍쳐**</p>
<ul>
<li>웹의 기존 기술과 HTTP 프로토콜을 그대로 활용하고
웹의 장점을 최대한 활용할 수 있는 아키텍쳐 스타일 </li>
</ul>
<h2 id="📌-rest-개념">📌 REST 개념</h2>
<p>HTTP URI를 통해 리소스를 명시하고 
HTTP METHOD( POST / GET / UPDATE / DELETE ) 를 통해
해당 자원의 <em>CRUD Operation을 적용하는것을 의미
(</em>CRUD Operation = Create(POST) / Read(GET) / Update / Delete ) </p>
<h2 id="🤔-rest-가-필요한-이유">🤔 REST 가 필요한 이유</h2>
<ul>
<li>애플리케이션 분리 와 통합</li>
<li>어떠한 클라이언트 , 플랫폼 (ex 크롬, 파이어폭스, 안드로이드 , 애플 ) 
에서도 통신이 가능해야 하기 때문이다. </li>
</ul>
<h2 id="📌-rest-장점">📌 REST 장점</h2>
<ul>
<li>서버와 클라이언트를 완전히 분리</li>
<li>HTTP 표준을 사용하기 에 별도의 인프라 없이 모든 플랫폼에서 사용가능</li>
<li>REST API 를 통해 의도하는 바를 쉽게 파악가능</li>
</ul>
<h2 id="📌-rest-구성-요소">📌 REST 구성 요소</h2>
<ul>
<li>자원(Resoruce) - URI</li>
<li>행위(Verb) - HTTP METHOD</li>
<li>표현(Representations)</li>
</ul>
<p>로 구성되어 있으며 웹 서비스 내에서
<strong>자원의 이름 ( 자원의 표현)</strong> 으로 구분하여 해당 <strong>자원의 상태(정보)</strong>를 주고 받는 모든 것을 의미한다.</p>
<ul>
<li><p>자원의 표현 ( Resource Representaiton)</p>
<ul>
<li><p>자원(Resource) : 해당 소프트웨어가 관리하는 모든것 
  Ex) 데이터, 그림&amp;문서 , 해당 소프트웨어 자체 ... 등등</p>
</li>
<li><p>자원의 표현: 그 자원을 표현하기 위한 이름
  Ex) DB에서 &quot;ID&quot; 의 데이터가 자원일 때, &#39;id&#39; 를 자원의 표현으로 지정한다. </p>
</li>
</ul>
</li>
<li><p>상태(정보) 전달</p>
<ul>
<li>데이터가 요청되어지는 시점에서 자원의 상태(정보)를 전달한다.<pre><code>Ex) 주로 JSON 혹은 XML 을 통해 데이터를 주고 받는 것이 일반적</code></pre></li>
<li>**Spring 에서는 Controller 영역에서 사용자의 업무를 처리할 때 <pre><code>    Mapping 단계에서 정보를 주고받는다 **</code></pre></li>
</ul>
</li>
</ul>
<h2 id="📌-rest-특징-6가지">📌 REST 특징 6가지</h2>
<h3 id="1-서버---클라이언트-구조">1. 서버 &lt;-&gt; 클라이언트 구조</h3>
<ul>
<li><p>서버 와 클라이언트 를 명확히 구분하여 
서로 간의 의존성을 두지 않는다.</p>
</li>
<li><p>서버 : API 를 제공하고 비지니스 로직 처리 및 저장을 관리하고 책임진다. </p>
</li>
<li><p>클라이언트 : 사용자의 인증 , 세션 및 로그인 정보를 직접 관리하고 책임진다</p>
</li>
</ul>
<h3 id="2-stateless-무상태">2. Stateless 무상태</h3>
<ul>
<li><p>HTTP 프로토콜 의 무상태성으로 
세션·쿠키에 신경쓰지 않아도 되기에 구현이 단순해야한다.</p>
</li>
<li><p>** ❗ 서버에서 요청을 완전히 별개의 것으로 인식하여
각각의 요청을 별도로 처리한다.** </p>
</li>
</ul>
<p>ex) 각 API 서버는 클라이언트 요청만을 단순 처리한다.
이 때, 이전 요청이 다음 요청의 처리에 연관되어서는 안된다. 
( 물론 이전 요청이 DB를 수정하여 DB에 의해 바뀌는 것은 허용 ) 
이로인해 서버의 처리방식에 일관성이 부여되고, 부담이 줄어들며 서비스의 자유도가 높아진다.</p>
<h3 id="3-cacheable-캐시-처리-가능">3. Cacheable 캐시 처리 가능</h3>
<ul>
<li>HTTP의 인프라를 사용하여
HTTP의 캐싱 기능이 사용가능해야한다.</li>
</ul>
<p>+캐싱 기능을 통해 응답이 빨라 지고 
서버 트랜잭션이 발생하지 않고 서버자원 이용률을 향상시킨다.</p>
<h3 id="4-layered-system-계층화">4. Layered System 계층화</h3>
<ul>
<li><p>클라이언트가 오직 REST API 서버만 호출한다
따라서 REST 서버는 다층으로 구현해야한다.</p>
</li>
<li><p>API 서버는 순수 비지니스 로직을 수행하고
보안 · 로드밸런싱 · 암호화 · 사용자인증 등의 구조는 
다른계층에 설정하여 구조상의 유연성에 유리하다.</p>
</li>
</ul>
<h3 id="5-code---on---demand--❗optional-">5. Code - On - Demand ( ❗Optional )</h3>
<ul>
<li>서버로부터 스크립트를 받아 클라이언트에서 실행한다. 
❗ 이 옵션은 필수가 아닌 선택옵션이다 </li>
</ul>
<h3 id="6-uniform-interface-인터페이스-일관성">6. Uniform Interface 인터페이스 일관성</h3>
<ul>
<li><p>URI로 지정한 Resource 에 대한 조작을 통일되고 한정된 인터페이스로 수행한다.</p>
</li>
<li><p>HTTP 표준 프로토콜은 모든 플랫폼에서 사용 가능해야하기에 
특정 언어 나 기술에 종속되어선 안된다. </p>
</li>
</ul>
<h1 id="📌-rest-api">📌 REST API</h1>
<h4 id="application-programming-interface">Application Programming Interface</h4>
<ul>
<li>API 란 
데이터와 기능의 집합을 제공하여 프로그램간 서로 정보를 교환가능 하도록 하는 것.</li>
</ul>
<p>REST 기반으로 서비스 API 를 구현한 것을 <strong>REST API</strong>라 부른다 </p>
<h2 id="📌-rest-api-특징">📌 REST API 특징</h2>
<ul>
<li><p>REST 기반으로 시스템을 분산하여 확장성과 재사용성을 높히고 
유지보수 · 운용을 편리하게한다. </p>
</li>
<li><p>REST 기반이기에 당연히 HTTP 표준 프로토콜을 기반으로 하며,
HTTP 의 서버 &lt;-&gt; 클라이언트의 구조를 구현할 수 있다.</p>
</li>
</ul>
<h2 id="📌-rest-api-규칙">📌 REST API 규칙</h2>
<ol>
<li><p>URI 는 정보의 자원을 표현해야 한다.</p>
</li>
<li><p>자원에 대한 행위는 HTTP METHOD ( POST , GET , UPDATE , DELETE ) 로 표현해야한다.</p>
</li>
<li><p>슬래시 (/) 는 계층 관계를 나타내는데 사용한다. </p>
</li>
<li><p>하이픈 (-) URI 가독성을 높이기 위해 사용 가능하다</p>
</li>
<li><p>언더바 (_) 는 URI에서 사용하지 않는다</p>
</li>
<li><p>URI 경로에 대문자 사용을 피하도록한다.</p>
</li>
<li><p>파일 확장자 (.file) 은 URI 에 포함하지 않는다  </p>
</li>
</ol>
<h4 id="❗-rest-api-설계-예시">❗ REST API 설계 예시</h4>
<p><img src="https://velog.velcdn.com/images/gyqls_12/post/02684c2c-def7-458b-9d45-046a0efb3c6e/image.png" alt=""></p>
<h1 id="📌-restful">📌 RESTful</h1>
<ul>
<li><p>REST 아키텍쳐를 구현하는 웹 서비스를 평가하는 용어 </p>
</li>
<li><p>REST 개념과 특징을 잘 사용 · 표현한 웹 서비스를 
&quot;RESTful&quot; 로 형용한다</p>
</li>
</ul>
<h2 id="📌-restful의-목적">📌 RESTful의 목적</h2>
<ul>
<li>이해하기 쉽고 사용하기 쉬워야한다
또한 클라이언트의 어떠한 환경 · 요청이여도 호환하여 
비지니스 로직을 처리해야한다.</li>
</ul>
<h2 id="📌-not-restful">📌 Not RESTful</h2>
<ul>
<li><p>CRUD 기능을 POST로만 처리하는 경우</p>
</li>
<li><p>REST API 규칙 · 특징에 맞지 않는 경우 </p>
</li>
</ul>
<h4 id="자료-출저">자료 출저</h4>
<p><a href="https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html">https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Boot - QueryDSL setting]]></title>
            <link>https://velog.io/@gyqls_12/Spring-Boot-QueryDSL-setting</link>
            <guid>https://velog.io/@gyqls_12/Spring-Boot-QueryDSL-setting</guid>
            <pubDate>Wed, 14 Dec 2022 05:55:15 GMT</pubDate>
            <description><![CDATA[<h2 id="orderlist">OrderList</h2>
<h4 id="주문조회-repository-에-응용">주문조회 Repository 에 응용</h4>
<h2 id="cascadetypeall">CascadeType.ALL</h2>
<ul>
<li>특정</li>
</ul>
<h2 id="셋팅-방법">셋팅 방법</h2>
<ul>
<li>build.gradle 에서
buildscript 추가 </li>
</ul>
<pre><code class="language-java">buildscript {
   dependencies {
      classpath(&quot;gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.10&quot;)
   }
}</code></pre>
<ul>
<li>dependencies 에
implementation 추가</li>
</ul>
<pre><code class="language-java">implementation &#39;com.querydsl:querydsl-jpa&#39;
implementation &#39;com.querydsl:querydsl-apt&#39;</code></pre>
<p>+plugins 아래에 
apply 추가</p>
<pre><code class="language-java">apply plugin: &quot;com.ewerk.gradle.plugins.querydsl&quot; </code></pre>
<ul>
<li>build.gradle 맨 아래에 
queryDSL 추가</li>
</ul>
<pre><code class="language-java">//querydsl 추가 
def querydslDir = &#39;src/main/generated&#39; 
//def querydslDir = &quot;$buildDir/generated/querydsl&quot; 
querydsl { 
   library = &quot;com.querydsl:querydsl-apt&quot; 
   jpa = true 
   querydslSourcesDir = querydslDir 
} 

sourceSets { 
   main { 
      java { 
         srcDirs = [&#39;src/main/java&#39;, querydslDir] 
      } 
   } 
} 

compileQuerydsl{ 
   options.annotationProcessorPath = configurations.querydsl 
}

configurations {
   querydsl.extendsFrom compileClasspath 
} </code></pre>
<h4 id="window---showview---other-통해">window - showView - other 통해</h4>
<h4 id="gradle-tasks-gradle-executuions-하단에-추가">Gradle Tasks, Gradle Executuions 하단에 추가</h4>
<ul>
<li>build 폴더 우클릭 run Gradle Tasks 실행 </li>
</ul>
<h2 id="최종적으로-generated-폴더-생성">최종적으로 generated 폴더 생성</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Boot - JPQL 2]]></title>
            <link>https://velog.io/@gyqls_12/Spring-Boot-</link>
            <guid>https://velog.io/@gyqls_12/Spring-Boot-</guid>
            <pubDate>Mon, 12 Dec 2022 02:24:03 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-프로젝션">📌 프로젝션</h2>
<ul>
<li><p>select 절에 조회할 대상을 지정하는 것 </p>
</li>
<li><p>select m from Member m 
= Member 엔티티 전체 조회</p>
</li>
<li><p>select m.team from Member m 
= Member 엔티티 에서 team 을 조회  </p>
</li>
</ul>
<blockquote>
</blockquote>
<pre><code class="language-java">&gt;
    List&lt;Member&gt; result = em.crateaQuery(&quot;select m from Member m&quot; , Member.class).getResultList;     
    &gt;
    // result 객체의 0번째 항목을 
    // age = 20 으로 설정한다
    // IF ) 이 부분이 update 가 된다면 영속성 컨텍스트에서 관리가 된다 는 뜻
    // update 가 X = 영속성 컨텍스트가 아님 
    Member findMember = result.get(0);
    findMember.setAge(20);
&gt;</code></pre>
<h4 id="join-을-사용해서-조회하기--추천-">Join 을 사용해서 조회하기 ( 추천 )</h4>
<pre><code class="language-java">    Main 2 

       List&lt;Member&gt; result = em.crateaQuery(&quot;select t from Member m join m.team t&quot;  , Team.class).getResultList; 

</code></pre>
<h4 id="main-3">Main 3</h4>
<pre><code class="language-java">
    // JPQL 쿼리 조회 - Order 테이블 , address 데이터 
    1.  em.createQuery(&quot;select o.address from Order o&quot;, Address.class ).getResultList();

    2. em.createQuery(&quot;select o.address from Address o&quot;, Address.class ).getResultList();</code></pre>
<p>1번은 Order 테이블에 address가 조회가 되지만</p>
<p>2번은 Address 테이블이 엔티티 객체가 아님으로
조회가 불가능 </p>
<pre><code class="language-java">
    em.createQuery(&quot;select distinct m.username, m.age from Member m&quot;).getResultList();

    // 두번째 파라미터 가 없다 = 반환 타입이 없다 
    // 반환 타입이 없기에 단순 객체를 생성하여
    // 해당 객체에 값을 담는 방법 
    Object o = result.get(0);
    Object[] result = (object[])o;

    syso(&quot;username= &quot; + result[0] );
    syso(&quot;age = &quot; + result[0] );

    해당 데이터가 object 배열안에 순서대로 할당된다 
    값이 많아지면 어캄? 

    List&lt;Object[]&gt; resultList = em.createQuery(&quot;select m.username, m.age from Member m&quot;).getResultList;

    object[] result = resultList.get(0);
    syso(&quot;username= &quot; + result[0] );
    syso(&quot;age = &quot; + result[0] );</code></pre>
<pre><code class="language-java">
        List&lt;Object[]&gt; resultList = em.createQuery(&quot;select new MemberDTO  패키지 주소  (m.username, m.age) from Member m&quot;).getResultList;

        MemberDTO mDTO = new MemberDTO;
        mDTO.getUsername();
        mDTO.getAge(); 

        통해 조회가 가능하다 
</code></pre>
<pre><code>MemberDTO 패키지 주소를
객체를 생성하듯이 new 를 붙여 JPQL 주소에 선언 후
() 안에 조회할 데이터를 선언한다

**선언과 동시에 MemberDTO 변수에 할당된다. **</code></pre><h2 id="📌-페이징처리">📌 페이징처리</h2>
<ul>
<li>setFirstResult(int startPoint)
= 조회 시작 위치 ( 디폴트 값 1  ) </li>
</ul>
<ul>
<li>setMaxResults(int maxResult)
= 조회할 데이터 수 설정 
= 몇번째 부터 몇 개 까지 조회 ? </li>
</ul>
<p> 11~20 을 조회하고자 하면
 setFirstResult(10)
 setMamxResult(20) </p>
<p> 으로 설정하면 된다 .</p>
<pre><code class="language-java">
     String jpql = &quot;select m from Member m order by m.id&quot;;
    List&lt;Member&gt; resultList = em.createQuery( jpql , Member.class )
        .setFirstResult(10)
        .setMaxResult(20)
        .getResultList();

     jpql 변수의 주소에서
    11번째 데이터 부터 
    20번째 데이터까지
    전체 조회 ( Member 타입으로 리턴 ) 

    // size() = 20 
    resultList.size()

    // ToString 통해 전체조회 
    // 11번 ~ 30번 member 의 정보가 조회된다 
    for ( Member m1 : resultList ) {
        syso(&quot; member1 = &quot; + member1.toString() ); 
    }</code></pre>
<h4 id="jqpl-에서-join-사용하기">JQPL 에서 join 사용하기</h4>
<pre><code class="language-java">
    // inner join = inner는 생략가능 하다
    String sql = &quot;select m from member m inner join m.team t where t.name = :teamName&quot;;

    List&lt;member&gt; resultList = em.createQuery(sql, Member.class)
            .getResultList();</code></pre>
<pre><code class="language-java">
          String sql = &quot;select m from member m left outer join m.team t&quot;;

    List&lt;member&gt; resultList = em.createQuery(sql, Member.class)
            .getResultList();</code></pre>
<h2 id="📌-jpql-서브쿼리의-한계">📌 JPQL 서브쿼리의 한계</h2>
<ul>
<li><p>Where, having 절 에서만 사용가능한 기법 = JPA 표준 스펙 </p>
</li>
<li><p>select 절에서도 가능하다 ( Hibernate 지원 )  </p>
</li>
<li><p>from 절의 서브쿼리는 현재 JPQL 에서 불가능 </p>
</li>
</ul>
<pre><code class="language-java">    String sql = &quot;select m from Member m where m.age &gt; (select avg(m2.age) from Member m2 &quot;

     List&lt;member&gt; resultList = em.createQuery(sql, Member.class)
            .getResultList();</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Boot - JPQL]]></title>
            <link>https://velog.io/@gyqls_12/Spring-Boot-JPQL</link>
            <guid>https://velog.io/@gyqls_12/Spring-Boot-JPQL</guid>
            <pubDate>Fri, 09 Dec 2022 05:02:02 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-jpql">📌 JPQL</h2>
<ul>
<li><p>JPA 사용이 가능하며
JPA 사용시 앤테티 객체를 중심으로 개발한다</p>
</li>
<li><p>단, 검색쿼리 작성시 어렵다</p>
</li>
<li><p>검색쿼리시 테이블이 아닌 엔티티 객체를 대상으로 검색&amp;조회 해야한다</p>
</li>
<li><p>JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어 제공</p>
</li>
<li><p>SQL 과 문법 유사, DDL , where , having join 등</p>
</li>
<li><p>JPQL은 엔티티 객체를 대상으로 쿼리 </p>
</li>
</ul>
<h2 id="📌-규칙">📌 규칙</h2>
<h4 id="엔티티-이름">엔티티 이름</h4>
<p>= 테이블 명 대신 엔티티 명을 사용한다. @Entitiy(name = &quot;&quot; ) 으로 따로 설정은 가능하다
= 지정하지 않는다면 [ 클래스 이름 ] 이 곧 @Entitiy name 속성이 된다</p>
<h4 id="❗-별칭은-필수--as-">❗ 별칭은 필수 ( as )</h4>
<p>=    JPQL에서는 별칭이 필수 이다.
( 단, as 는 생략가능 ) </p>
<blockquote>
</blockquote>
<pre><code class="language-java">&gt;
    public class Jpa_Main(){
        EntitiyManagerFactory emf = Persistence.createENtityManagerFactory(&quot;hello&quot;);
        EntityManager em = emf.createEntityManager();
        EntitiyTransaction tx = em.getTransaction();
           tx.begin()
        &gt;
        tx.commit();
        try{
        &gt;
            //em.createQuery(String, qlString) 
            em.createQuery(&quot;!JPQL&quot;, Member.class);
            em.createQuery(&quot;
                select m from Member m where m.username like &#39;%kim%&#39;&quot; // * 로 호출하는 것이 아닌 as 통해 호출 
            , Member.class).getResultList(); // = 결과 값은 List 형태로 담긴다
            &gt;
            for (Member member : result){
                System.out.println(&quot;member = &quot; + member ); 
            }
            &gt;
        }catch{
            tx.rollback()
        }finally{
            em.close();
            emf.close();
        }
         &gt;    
    &gt;
    }
&gt;</code></pre>
<h2 id="📌-jpql-문법">📌 JPQL 문법</h2>
<ul>
<li>select<ul>
<li>from </li>
<li>select </li>
<li>where </li>
<li>group by </li>
<li>having</li>
<li>order by </li>
</ul>
</li>
<li>update<ul>
<li>update </li>
<li>where</li>
</ul>
</li>
<li>delete<ul>
<li>delete</li>
<li>where </li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<pre><code class="language-java">    @Entity( name = &quot;&quot; ) 
    public class Member{
    &gt;
           @Entity 어노테이션에 name 속성을 추가로 설정할 수 있으나,
        기본값이 클래스 명이기에 그냥 클래스명을 쓰면 된다 ( 굳이 할 필요없다 ) 
    }</code></pre>
<h2 id="📌-jpql-집계함수">📌 JPQL 집계함수</h2>
<h4 id="일반-sql문과-달리-jpql-에서는">일반 SQL문과 달리 JPQL 에서는</h4>
<h4 id="-을-사용하지않고-as-이름-명으로-직접-호출해야한다">* 을 사용하지않고 as 이름 명으로 직접 호출해야한다</h4>
<h4 id="ex">Ex)</h4>
<ul>
<li><p>count(m)</p>
</li>
<li><p>sum(m.age)</p>
</li>
<li><p>avg(m.age)</p>
</li>
</ul>
<h2 id="📌-typedquery--query">📌 TypedQuery , Query</h2>
<h4 id="typedquery">TypedQuery</h4>
<ul>
<li><p>select 한 결과 값 타입이 ( 반환타입이 )
명확한 경우 사용한다</p>
</li>
<li><p>ex ) 반환 타입이 명확할 때 </p>
<pre><code class="language-java">  TypedQuery&lt;Member&gt; query = 
      (&quot; select m from member m&quot; , Member.class);
  TypedQuery&lt;String&gt; query = 
      (&quot; select m.username from member m&quot; , String.class);
  Query </code></pre>
</li>
<li><p>ex ) 반환타입이 명확하지 않을 때 
= 리턴을 String, int 등 복수 타입으로 리턴받을 경우 Query 를 사용한다 </p>
</li>
</ul>
<pre><code class="language-java">    Query query = 
        (&quot; select m.username, m.age from member m&quot; , Member.class);
        m.username = String
        m.age = int </code></pre>
<h3 id="결과조회">결과조회</h3>
<h4 id="querygetresultlist">query.getResultList();</h4>
<ul>
<li><p>query 안에 담겨진 List 결과값을 반환
결과 값이 없다면 빈 리스트가 반환 *<em>( null 값 아님 ) *</em></p>
</li>
<li><p>빈 collection 이 반환되기 때문에 nullPointerException 에 대한 걱정은 안해도 된다 </p>
</li>
</ul>
<h4 id="querygetsingleresult">query.getSingleResult();</h4>
<ul>
<li><p>조회 할 결과 값이** 딱 하나 일 때, ( 단일 객체를 조회할 경우 )** 사용 </p>
</li>
<li><p>결과 값이 없을경우 exception 발생 -&gt; NoResultException 예외처리 발생 
또는 결과값이 2개 이상일 경우 exception 발생 -&gt; NonUniqueException 예외처리 발생 </p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring boot JPA 4 - 연관관계 테이블 매핑]]></title>
            <link>https://velog.io/@gyqls_12/Spring-boot-%EC%8B%A4%EC%8A%B5-4-</link>
            <guid>https://velog.io/@gyqls_12/Spring-boot-%EC%8B%A4%EC%8A%B5-4-</guid>
            <pubDate>Thu, 08 Dec 2022 07:39:11 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-개요">📌 개요</h2>
<p><img src="https://velog.velcdn.com/images/gyqls_12/post/b4748b9e-5d02-4dcd-ae13-40292008ecf0/image.png" alt=""></p>
<h4 id="상단의-테이블-구조를-jpa---연관관계-매핑을-통해-설계하고자-한다">상단의 테이블 구조를 JPA - 연관관계 매핑을 통해 설계하고자 한다</h4>
<h2 id="📌-member-테이블">📌 MEMBER 테이블</h2>
<blockquote>
</blockquote>
<pre><code class="language-java">@Entity
@Getter @Setter
public class Member {
&gt;
    @Id @GeneratedValue
    @Column(name = &quot;MEMBER_ID&quot;)
    private Long id;
    private String name;
    private String city;
    private String street;
    private String zipcode;
&gt;    
    @OneToMany(mappedBy = &quot;member&quot;)
    private List&lt;Order&gt; orders = 
        new ArrayList&lt;Order&gt;();
&gt;    
    public void addOrder(Order order) {
        order.setMember(this);
        this.orders.add(order);
    }
&gt;    
}</code></pre>
<h2 id="📌-orders-테이블">📌 ORDERS 테이블</h2>
<blockquote>
</blockquote>
<pre><code class="language-java">@Entity
@Table(name = &quot;ORDERS&quot;)
@Getter @Setter
public class Order {
&gt;
    @Id @GeneratedValue
    @Column(name = &quot;ORDER_ID&quot;)
    private Long id;
//    @Column(name = &quot;MEMBER_ID&quot;)
//    private Long memberId;
    private LocalDateTime orderDate;
    private String status;
&gt;    
    @ManyToOne
    @JoinColumn(name = &quot;MEMBER_ID&quot;)
    private Member member;
&gt;    
    @OneToMany(mappedBy = &quot;order&quot;)
    private List&lt;OrderItem&gt; orderItems
         = new ArrayList&lt;OrderItem&gt;();
&gt;    
    public void addOrderItem(OrderItem orderItem) {
        orderItem.setOrder(this);
        this.orderItems.add(orderItem);
    }
&gt;    
}
&gt;</code></pre>
<h2 id="📌-order_item-테이블">📌 ORDER_ITEM 테이블</h2>
<blockquote>
</blockquote>
<pre><code class="language-java">@Entity
@Getter @Setter
public class OrderItem {
&gt;
    @Id @GeneratedValue
    @Column(name = &quot;ORDER_ITEM_ID&quot;)
    private Long id;
//    @Column(name = &quot;ORDER_ID&quot;)
//    private Long orderId;
//    @Column(name = &quot;ITEM_ID&quot;)
//    private Long itemId;
    private int orderPrice;
    private int count;
&gt;    
    @ManyToOne
    @JoinColumn(name = &quot;ORDER_ID&quot;)
    private Order order;
&gt;    
    @ManyToOne
    @JoinColumn(name = &quot;ITEM_ID&quot;)
    private Item item;
&gt;    
}</code></pre>
<h2 id="📌-item-테이블">📌 ITEM 테이블</h2>
<blockquote>
</blockquote>
<pre><code class="language-java">@Entity
@Getter @Setter
public class Item {
&gt;
    @Id @GeneratedValue
    @Column(name = &quot;ITEM_ID&quot;)
    private Long Id;
    private String name;
    private int price;
    private int stockQuantity;
&gt;    
    @OneToMany(mappedBy = &quot;item&quot;)
    private List&lt;OrderItem&gt; orderItems
        = new ArrayList&lt;OrderItem&gt;();
&gt;    
    public void addOrderItem(OrderItem orderItem) {
        orderItem.setItem(this);
        this.orderItems.add(orderItem);
    }
&gt;    
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Boot JPA 3 - 양방향 매핑 , 연관관계 테이블 ]]></title>
            <link>https://velog.io/@gyqls_12/Spring-Boot-%EC%8B%A4%EC%8A%B5-3-%EC%96%91%EB%B0%A9%ED%96%A5-%EB%A7%A4%ED%95%91-%EC%97%B0%EA%B4%80%EA%B4%80%EA%B3%84-%ED%85%8C%EC%9D%B4%EB%B8%94</link>
            <guid>https://velog.io/@gyqls_12/Spring-Boot-%EC%8B%A4%EC%8A%B5-3-%EC%96%91%EB%B0%A9%ED%96%A5-%EB%A7%A4%ED%95%91-%EC%97%B0%EA%B4%80%EA%B4%80%EA%B3%84-%ED%85%8C%EC%9D%B4%EB%B8%94</guid>
            <pubDate>Thu, 08 Dec 2022 05:31:10 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-양방향-매핑">📌 양방향 매핑</h2>
<h4 id="객체참조">객체참조</h4>
<ul>
<li><p>외래 키(FK) 역할을 객체 참조를 통해 선언하는 역할 </p>
</li>
<li><p>현재 객체는 Member 가 Team을 가졌으나,
Team 은 Member를 가지지 못한다</p>
</li>
<li><p>이것이 객체 참조와 외래키 (FK ) 의 가장 큰 차이점</p>
</li>
<li><p>테이블은 FK만 있으면 양쪽에 연관관계를 알 수 있다.</p>
</li>
</ul>
<blockquote>
</blockquote>
<pre><code class="language-java">// TEAM 테이블 
    @OneToMany(mappedBy = &quot;team&quot;) // Member테이블의 변수명과 동일해야한다
    private List&lt;Member&gt; member = new ArrayList&lt;Member&gt;();
&gt;
&gt;
// Member 테이블 
    @ManyToOne    // Team 클래스에서 &quot;하나&quot; 가져오기 
    @JoinColumn(name = &quot;TEAM_ID&quot;) // 연관 컬럼 이어주기 , TEAM 명칭과 반드시 동일해야한다 
    private Team team;</code></pre>
<ul>
<li>Member -&gt; Team         =    N개 -&gt; 1개    =    @ManyToOne</li>
<li>Team -&gt; Member         =    1개 -&gt; N개    =    @oneToMany</li>
</ul>
<h2 id="📌-테이블-연관관계">📌 테이블 연관관계</h2>
<ul>
<li><strong>관계 1개</strong>
= Member테이블 입장에서 Team 테이블로 조인 가능
또한, Team 테이블 입장에서 Member 테이블 조인이 가능하다</li>
</ul>
<h2 id="📌-객체-연관관계">📌 객체 연관관계</h2>
<ul>
<li><p><strong>관계 2개</strong>
Member 객체 에서 -&gt; Team 객체로 연관관계 1개    ( 단 방향 )
Team 객체에서 -&gt;     Member객체로 가는 연관관계 1개 ( 단 방향 ) 
= 따라서 관계는 2개 </p>
</li>
<li><p>양방향 매핑이긴 하나</p>
</li>
<li><p><em>사실은 단방향 매핑이 2개*</em>가 있는 것.</p>
</li>
</ul>
<h2 id="📌-관리의-딜레마">📌 관리의 딜레마</h2>
<ul>
<li>둘 중 하나로 외래키를 관리해야한다 ( 둘다는 못함 ) </li>
<li>그렇다면 누가 관리 등록 수정을 담당해야하는가? </li>
</ul>
<h4 id="객체-입장">객체 입장</h4>
<ul>
<li><p>Member 에서 Team 으로 가는 Team 참조 값과,    ( Member to Team )
Team 에서 Member로 가는 Member 참조 값이 있다.    ( Team to Member )</p>
</li>
<li><p>그런데 만약
Member 에서 Team 값이 수정 되었을 때, Member 테이블의 TEAM_ID 가 수정되어야 하는지,
Team 에서 Member 값을 수정해야하는지 딜레마 가 있다. </p>
</li>
</ul>
<h4 id="db-입장">DB 입장</h4>
<ul>
<li><p>양방향 테이블에서 수정이 발생할 때,
DB입장에서는 Member 테이블에 있는 TEAM_ID 만 Update 시키면 된다.</p>
</li>
<li><p>단, 이때 <strong>양방향 매핑 규칙(연관관계의 주인)</strong> 을 따라야 한다. </p>
</li>
</ul>
<h2 id="📌-연관관계의-주인">📌 연관관계의 주인</h2>
<ul>
<li><p>객체의 두 관계 중 하나를 연관관계의 주인으로 지정</p>
</li>
<li><p>오직 연관관계의 주인만이 외래 키를 관리 및 수정이 가능하다.
( 주인이 아니라면 읽기 전용 ) </p>
</li>
<li><p>*<em>주인은 @MappedBy 속성을 사용하지 않는다. *</em></p>
</li>
<li><p>따라서 Member 테이블에서 수정하면 
TEAM 테이블 은 수정사항이 반영이 되는 구조.</p>
</li>
</ul>
<h2 id="📌-양방향-연관관계의-주의사항">📌 양방향 연관관계의 주의사항</h2>
<ul>
<li>순수 객체 상태를 고려해서 항상 양쪽에 값을 설정해야한다</li>
<li>연관관계 편의 메소드를 생성하라</li>
<li>양방향 매핑시 무한루프에 조심하자
ex) toString, lombok lib 조심할 것</li>
</ul>
<blockquote>
<pre><code class="language-java">member.setTeam(team);
</code></pre>
</blockquote>
<p>team.getMember().add(member);</p>
<blockquote>
</blockquote>
<pre><code>
하위 테이블에도 TEAM 단방향 추가 +
상위 테이블에도 MEMBER 단방향 추가 + 

+ 2개중 하나라도 방향이 선언되지 않으면
DB 구조가 분열될 수 있다.
따라서 1개의 메소드로 
단향뱡 2개를설정함으로써 해결한다

### ❗ lombok 을 이용해 단방향 2개 동시 설정하기
### @Setter( value = AccessLevel.NONE) 

+ 세터 기능 중지 

### MEMBER 테이블 
&gt;
```java
    @ManyToOne    // Team 클래스에서 &quot;하나&quot; 가져오기 
    @JoinColumn(name = &quot;TEAM_ID&quot;) // 연관 컬럼 이어주기 , TEAM 명칭과 반드시 동일해야한다 
    @Setter(value = AccessLevel.NONE) // lombok 옵션 setter 설정을 막는다 
    private Team team;
    &gt;
        // 단방향 2개 설정 메소드 
    public void changeTeam(Team team) {
        this.team = team;
        team.getMember().add(this);
        // = team.getMember().add(member);
    }
}</code></pre><h3 id="team-테이블">TEAM 테이블</h3>
<ul>
<li>TEAM 테이블에도 마찬가지로 
단방향 설정을 해야한다</li>
</ul>
<blockquote>
</blockquote>
<pre><code class="language-java">    public void addMember(Member member) {
        member.setTeam(this);
        this.member.add(member);
    }</code></pre>
<h2 id="📌-양방향-매핑-정리">📌 양방향 매핑 정리</h2>
<ul>
<li><p>단 방향 매핑 만으로도 연관관계 매핑을 완료가 된다 
양 방향 매핑은 반대 방향으로 조회기능이 추가된 것 뿐이다. </p>
</li>
<li><p>양방향 사용이유 = JPQL 에서 역방향으로 탐색(조회)할 일이 많음
단 방향매핑을 필수로 하되, 양 방향매핑은 필수적이지 않다
( 테이블에 영향을 주지않기에 필요할 경우에만 양 방향매핑 기능을 추가한다 )</p>
</li>
</ul>
<h2 id="📌-연관관계의-주인을-정하는-기준">📌 연관관계의 주인을 정하는 기준</h2>
<ul>
<li>연관관계의 주인은 <strong>외래 키(FK) 의 위치</strong>를 기준으로 정해야 한다</li>
<li>비지니스 로직을 기준으로 연관관계의 주인을 선택하면 안된다</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>