From ddfa35b10004606d921ffc8cf6eba90581980fe8 Mon Sep 17 00:00:00 2001 From: Gopistol <104254012+Gopistol@users.noreply.github.com> Date: Tue, 1 Aug 2023 16:51:14 +0900 Subject: [PATCH 1/6] =?UTF-8?q?[4=EC=A3=BC=EC=B0=A8]COW-Spring-1=20?= =?UTF-8?q?=ED=95=99=EC=8A=B5(Gopistol)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- http/Gopistol.md | 469 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 469 insertions(+) create mode 100644 http/Gopistol.md diff --git a/http/Gopistol.md b/http/Gopistol.md new file mode 100644 index 0000000..3cc9518 --- /dev/null +++ b/http/Gopistol.md @@ -0,0 +1,469 @@ +
+인터넷과 네트워크 +
+ + ### 인터넷 + + 인터넷 프로토콜 스위트(TCP/IP)를 기반으로 하여 여러 컴퓨터가 각각 클라이언트와 서버로써 전 세계적으로 연결되어있는 컴퓨터 네트워크 통신망 + + ### 네트워크 + + > 몇 개의 독립적인 장치가 적절한 영역내에서 적당히 빠른 속도의 물리적 통신 채널을 통하여 서로가 직접 통신할 수 있도록 지원해 주는 데이터 통신 체계 +
*IEEE(Institute of Electrical and Electronics Engineers:국제 전기 전자 공학회)* + > + + ### IP(인터넷 프로토콜) + + IP주소를 부여함으로써 메시지를 보낼 수 있음 + + IP 역할 + + - 지정한 IP Address에 데이터 전달 + - Packet (통신 단위)로 데이터 전달 + + 전달되는 IP 패킷에는 출발지 IP, 목적지 IP가 들어가야 함 + + 클라이언트 패킷 전달 - 노드들을 통해 목적이 IP까지 정확히 도달하게 됨 + + 서버 패킷 전달 - 같은 방식으로 클라이언트로 패킷을 전달함, 노드를 통해 전달되므로 전달 경로는 클라이언트 패킷의 경로와 다를 수 있음(인터넷망) + + IP 프로토콜의 한계 + + - 비연결성 + - 패킷을 수신할 대상 X, 서비스 불능 상태여도 패킷이 전송됨 + - 비신뢰성 + - 패킷이 중간에 사라지거나 순서대로 도착하지 않을 수 있음 + - 프로그램 구분 + - 같은 IP를 사용할 때(인터넷 게임을 하면서 음악 듣기 등) 어떻게 구분? + + → TCP, UDP를 통해 위와 같은 한계 문제를 해결할 수 있음 + + ### TCP, UDP + + 인터넷 프로토콜 스택의 4계층 + + - 애플리케이션 계층 - HTTP, FTP + - 전송 계층 - TCP, UDP + - 인터넷 계층 - IP + - 네트워크 인터페이스 계층 + + ![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9aa6c793-1d62-4f78-b581-8fd751b1b0e0/Untitled.png) + + TCP 특징 - 전송 제어 프로토콜(Transmission Control Protocol) + + - 연결지향 - TCP 3 way handshake(가상 연결) + - 컴퓨터가 꺼져 있어도 우선 가상으로 연결시킴 + 1. 클라이언트에서 서버로 SYN 메시지를 보냄 + 2. 서버가 성공적으로 받으면 SYN+ACK 을 클라이언트에게 다시 보냄 + 3. 클라이언트가 받게 되면 ACK 메시지를 서버에게 보냄 (데이터도 같이 전송 가능) + + → 클라이언트와 서버가 서로 믿을 수 있음 (서로 연결되었다는 것) + + → 진짜 연결이 된 것이 아니라, 논리적인 연결을 말함. + + - 데이터 전달 보증 + - 클라이언트에서 서버로 데이터를 전송하면, 서버에서 클라이언트에게 데이터를 잘 받았다는 메시지를 전송함 + - 순서 보장 + - 만약 클라이언트에서 패킷 1,2,3 순서로 전송했지만 서버가 1,3,2 순서로 받았을 때, 서버는 클라이언트에게 1번 다음에 3번이 왔으므로 2번부터 다시 보내라는 메시지를 전송함 + - 신뢰할 수 있는 프로토콜, 대부분 TCP 사용 + - TCP/IP 패킷에는 출발지, 목적지 IP 뿐만 아니라 출발지 목적지 PORT, 전송 제어 정보, 순서 정보, 검증 정보 등이 포함되기 때문에 신뢰성이 높아짐 + + UDP 특징 - 사용자 데이터그램 프로토콜(User Datagram Protocol) + + - 기능이 거의 없음 + - 데이터 전달 및 순서가 보장되지 않지만, 단순하고 빠름 + - IP와 비슷 + PORT + 체크섬(메시지가 제대로 받았는지 검증해주는 데이터) + - 최근에 뜨는 이유: HTTP3 - UDP 프로토콜을 사용 (최적화를 위해, 3 way handshake 사용 X) + + ### PORT + + IP만 가지고는 나에게 날아오는 패킷들이 어떤 작업에 필요한 패킷인지 알 수가 없어서, 이것을 구분하기 위해 PORT를 사용함 + + 같은 IP 내에서 프로세스 구분 + + IP : 아파트 + + PORT : 몇 동 몇 호 + + ### DNS + + IP는 + + - 기억하기 어렵다 + - 변경될 수 있다(나중에 접근 X) + + → 도메인 네임 시스템(Domain Name System) + + DNS 서버에 도메인 명 등록 가능 + + 전화번호부 같은 역할 + + but 정확히 이해가 안감 + + ### URI와 웹 브라우저 요청 흐름 + + Uniform Resource Identifier: 리소스를 식별하는 통합된 방법? + + Uniform: 리소스 식별하는 통일된 방식 + + Resource: 자원, URI로 식별할 수 있는 모든 것(제한 X) + + Identifier: 다른 항목과 구분하는데 필요한 정보 + + URI 는 Locater, Name 또는 둘 다 추가로 분류될 수 있다. + + URL - 리소스의 위치 ex: 김영한이 사는 위치 + + URN - 리소스의 이름 ex: ‘김영한’ 그자체 + + URN은 이름을 부여해 버려서 찾기 힘듦 그래서 거의 URL만 씀 + + → URI = URL + + Content-Type: 응답 언어의 종류와 형식 +
+
+ +
+http +
+ + ### HTTP + + Hypertext Transfer Protocol 의 약자로, 클라이언트와 서버 간 통신을 위한 통신 규칙 세트 또는 프로토콜 + + 80번 포트를 사용함 + + 1.1 버전이 가장 많이 사용 + + ### HTTPS + + Hypertext Transfer Protocol Secure 의 약자로, 브라우저와 서버가 데이터를 전송하기 전에 안전하고 암호화된 연결을 설정함 + + 443번 포트를 사용함 + + 암호화 방식은 두 가지가 있는데, 둘 다 사용함 + + - 대칭키 암호화 + - 클라이언트, 서버가 동일한 키를 사용해 암호화/복호화를 진행함 + - 키 노출 시 위험하지만, 연산 속도가 빠름 + - 비대칭키 암호화 + - 1개의 쌍으로 구성된 공개키, 개인키를 암호화/복호화 하는 데 사용함 + - 공개키: 모두에게 공개 가능한 키 + - 개인키: 나만 가지고 알고 있어야 하는 키 + - 키 노출 시 비교적 안전하지만, 연산 속도가 느림 + + 공개키, 개인키 암호화 방식 + + - 공개키 암호화: 공개키로 암호화를 하면 개인키로만 복호화할 수 있다. -> 개인키는 나만 가지고 있으므로, 나만 볼 수 있다. + - 개인키 암호화: 개인키로 암호화하면 공개키로만 복호화할 수 있다. -> 공개키는 모두에게 공개되어 있으므로, 내가 인증한 정보임을 알려 신뢰성을 보장할 수 있다. + + ### 클라이언트 서버 구조 + + 비즈니스 로직, 데이터 등을 서버에 다 밀어넣고 + + 클라이언트는 UI, 사용성에 집중함 + + ### 특징 + + ### Stateful, Stateless + + stateless + + - 서버가 클라이언트의 상태 보존 X + - 점원이 바껴도 문제 X + + → 무한한 서버 증설 가능, 수평 확장 유리 + + 상태 유지로 설계해야 하는 것 + + - 로그인 + - 브라우저 쿠키와 세션 등을 사용 + - 상태 유지는 최소한으로 사용(어쩔 수 없이) + + ### Connectionless 비연결성 + + 연결을 유지하지 않으면 서버는 최소한의 자원만 유지하면 된다 + + HTTP는 기본이 연결을 유지하지 않는 모델이다 + + 서버 자원을 매우 효율적으로 사용 가능 + + - 서버 개발자는 같은 시간에 딱 발생하는 대용량 트래픽을 어려워함 + - 가능하면 상태 유지는 최소화! + +
+
+ +
+http 메소드 +
+ + ### 주요 메소드 + + - GET: 리소스 조회 요청 + - POST: 요청 데이터를 처리함, 주로 데이터 등록에 사용됨 + - PUT: 리소스를 대체하고, 해당 리소스가 없으면 생성함 + - DELETE: 리소스를 삭제함 + - PATCH: 리소스의 일부를 변경함. + - PUT vs PATCH (대체, 수정) + + PUT은 리소스를 수정하는 것이 아니라 **리소스를 요청 바디에 담긴 내용으로 대체**하는 것이므로 사용 시 요청 본문에 리소스 전체를 표현하여 보내야 한다. 하지만 PATCH는 현재 저장된 리소스에 수정을 가하는 행위를 의미하므로 수정하지 않은 사항을 요청 본문에 담아줄 필요가 없다. 따라서 PATCH 메소드가 ‘**수정**’이라는 의미를 가지기에 더욱 적합하다고 볼 수 있다. + + + ### 기타 메소드 + + - HEAD: GET과 동일하지만 메시지 부분을 제외하고 상태 줄과 헤더만 반환함 + - CONNECT: 대상 리소스로 식별되는 서버로의 터널을 정해줌 + - OPTIONS: 목적 리소스의 통신을 설정하는 데 사용됨 + - TRACE: 목적 리소스의 경로를 따라 메시지 loop-back 테스트를 함 + + ### 속성 + + - 안전성 + - 메소드 호출을 계속해도 리소스를 변경하지 않는다. + - GET 메소드가 안전하다고 할 수 있음 + - 멱등성 + - 메소드를 계속 호출해도 결과가 똑같음 + - GET, PUT, DELETE는 멱등성을 보장한다고 할 수 있음 + - POST, PATCH는 멱등성을 보장한다고 할 수 없음 + - POST: 리소스를 새롭게 생성하는 행위이므로 여러 번 수행할 때 수행 결과가 매번 달라짐 + - PATCH: 스펙 상 구현 방법에 대한 제한이 없으므로 API를 어떻게 구현하느냐에 따라서 멱등성이 보장될 수도 있고(단순 수정할 부분만 보내는 경우), 안 될수도 있음 + [https://evan-moon.github.io/2020/04/07/about-restful-api/#rest가-의미하는-것이-무엇인가요](https://evan-moon.github.io/2020/04/07/about-restful-api/#rest%EA%B0%80-%EC%9D%98%EB%AF%B8%ED%95%98%EB%8A%94-%EA%B2%83%EC%9D%B4-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94) + +
+
+ +
+http 상태코드 +
+ +
세 자리 숫자로 되어 있는데 첫 번째 숫자는 HTTP 응답의 종류를 구분하고, 나머지 2개의 숫자는 세부적인 응답 내용을 위한 번호이다
+ + - 100번대 (정보 제공)- 현재 클라이언트의 요청까지는 처리되었으므로 진행하라. + - 100: 계속 진행하라 + - 101: 프로토콜을 전환하라 + - 102: 처리 중이다 + - 200번대 (성공) - 클라이언트의 요청이 서버에서 성공적으로 처리됨. + - 200: 서버가 요청을 성공적으로 처리했다 + - 201: 요청이 처리되어서 새로운 리소스가 생성되었다 + - 202: 요청을 접수했지만 처리가 완료되지 않았다 + - 300번대 (리다이렉션) - 완전한 처리를 위해 추가 동작이 필요함. 서버 주소 또는 요청 URI 웹 문서가 이동되었으니 그 주소로 다시 시도하라. + - 300: 선택 항목이 여러 개 있다 + - 301: 지정한 리소스가 새로운 URI로 이동했다 + - 302: 요청한 리소스를 다른 URI에서 찾았다 + - 303: 다른 위치로 요청하라 + - 304: 마지막 요청 이후 그 페이지를 수정되지 않았다 + - 307: 임시로 리다이렉션 요청이 필요하다 + - 400번대 (클라이언트 에러) - 클라이언트의 요청 메시지 내용이 잘못됨. + - 400: 요청 구문이 잘못되었다 + - 401: 지정한 리소스에 액세스 권한이 없다 + - 403: 지정한 리소스에 액세스가 금지되었다 + - 404: 지정한 리소스를 찾을 수 없다 + - 500번대 (서버 에러) - 서버에서 메시지 처리에 문제가 발생함. 주로 서버 부하, DB 오류, 서버 예외 등이 발생하는 경우. + - 500: 서버에 에러가 발생했다 + - 501: 요청 URI에 대해 서버가 구현하고 있지 않다 + - 502: 게이트웨이 또는 프록시 역할을 하는 서버가 그 뒷단의 서버로부터 잘못된 응답을 받았다 + - 503: 현재 서버에서 서비스를 제공할 수 없다 + - 504: 프록시 서버가 타임아웃이 발생하였다 + +
+
+ +
+http 헤더 +
+ + ## 종류 + + ### HTTP 공통 헤더 + + 주요 항목 + + - Date + - HTTP 메시지 생성 일시 + - `Date: Sat, 2 Oct 2018 02:00:12 GMT` + - Connection + - 클라이언트, 서버 간 연결에 대한 옵션 설정 + - Connection: close + - 현재 Http 메시지 직후에 TCP 접속을 끊는다는 것을 알림 + - Connection: Keep-Alive + - 현재 TCP 커넥션을 유지함 + - Cache-Control + - 쿠키, 캐시 관련 헤더 + - Pragma + - Trailer + + ### HTTP 엔티티 관련 헤더 + + HTTP 메시지 내 포함된 선택적인 개체에 대한 구체적인 미디어 타입 등의 설명 + + 주요 항목 + + - Content-Type + - 해당 개체에 포함되는 미디어 타입 정보 + - 타입, 서브타입으로 구성됨 + - `Content-Type: text/html; charset-latin-1` + - Content-Language + - Content-Encoding + - 해당 개체 데이터의 압축 방식 + - Content-Length + - 전달되는 개체의 바이트 길이 또는 크기 + - 응답 메시지 본문의 길이 지정함 + - Content-Location + - Content-Disposition + - 응답 본문을 브라우저가 어떻게 표시해야할 지 알려줌 + - inline: 화면에 표시, attachment: 다운로드 + - `Content-Disposition: inline` + - `Content-Disposition: attachment; filename='filename.csv'` + - Content-Security-Policy + - Location + - 리소스가 리다이렉트 된 때에 이동된 주소, 또는 새로 생성된 주소를 명시함 + - Last-Modified + - Transfer-Encoding + + ### HTTP 요청 헤더 + + 요청 헤더는 HTTP 요청 메시지 내에서만 나타나며 가장 크다 + + 주요 항목 + + - Host + - 요청하는 호스트명 및 포트번호 (필수) + - 도메인명 및 호스트명 모두를 포함한 전체 URI 지정이 필요함 + - User-Agent + - 클라이언트 소프트웨어 명칭 및 버전 정보 + - From + - 클라이언트 사용자 메일 주소 + - Cookie + - 서버에 의해 Set-Cookie로 클라이언트에게 설정된 쿠키 정보 + - Referer + - 바로 직전에 머물렀던 웹 링크 주소 + - Authorization + - 인증 토큰을 서버로 보낼 때 사용하는 헤더 + - “토큰 종류 + 실제 토큰 문자”를 전송 + + 요청 헤더 예시 + + ```java + GET /home.html HTTP/1.1 + Host: developer.mozilla.org + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0 + Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/ *;q=0.8 + Accept-Language: en-US,en;q=0.5 + Accept-Encoding: gzip, deflate, br + Referer: https://developer.mozilla.org/testpage.html + Connection: keep-alive + Upgrade-Insecure-Requests: 1 + If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT + If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a" + Cache-Control: max-age=0 + + https://gmlwjd9405.github.io/2019/01/28/http-header-types.html + ``` + + ### HTTP 응답 헤더 + + 주요 항목 + + - Server + - 서버 소프트웨어 정보 + - Set-Cookie + - 서버측에서 클라이언트에게 세션 쿠키 정보를 설정 + - Expires + - 리소스가 지정된 일시까지 캐시로써 유효함을 나타냄 + - `Expires: Thu, 26 Jul 2018 07:28:00 GMT` + - Age + - max-age 시간 내 얼마나 흘렀는지 초 단위로 알려줌 + - Access-Control-Allow-Origin + - 요청을 보내는 프론트 주소와 백엔드 주소가 다르면 CORS 에러 발생 + - 서버에서 이 헤더에 프론트 주소를 적어 주어야 에러가 발생하지 않음 + - 프로토콜, 서브도메인, 도메인, 포트 중 하나만 달라도 에러가 발생함 + + 예시 + + ```java + 200 OK + Access-Control-Allow-Origin: * + Connection: Keep-Alive + Content-Encoding: gzip + Content-Type: text/html; charset=utf-8 + Date: Mon, 18 Jul 2016 16:06:00 GMT + Etag: "c561c68d0ba92bbeb8b0f612a9199f722e3a621a" + Keep-Alive: timeout=5, max=997 + Last-Modified: Mon, 18 Jul 2016 02:36:04 GMT + Server: Apache + Set-Cookie: mykey=myvalue; expires=Mon, 17-Jul-2017 16:06:00 GMT; Max-Age=31449600; Path=/; secure + Transfer-Encoding: chunked + Vary: Cookie, Accept-Encoding + X-Backend-Server: developer2.webapp.scl3.mozilla.com + X-Cache-Info: not cacheable; meta data too large + X-kuma-revision: 1085259 + x-frame-options: DENY + https://gmlwjd9405.github.io/2019/01/28/http-header-types.html + ``` + +
+
+ + +
+RestAPI +
+ + ### REST란? + + Representational State Transfer의 약자로서 로이 필딩의 박사학위 논문에서 최초로 소개되었다. HTTP의 주요 저자 중 하나인 그는 당시 웹의 장점을 최대한 활용할 수 있는 아키텍처로써 REST를 발표했다 + + ### 구성 + + - 자원(Resource) - URI + - 행위(Verb) - HTTP Method + - 표현(Representations) + + ### 특징 + + - Uniform Interface - URI로 지정한 리소스에 대한 조작을 통일되고 한정적인 인터페이스로 수행하는 아키텍처 스타일 + - Stateless - 상태정보를 따로 저장하고 관리하지 않음. 그러므로 API 서버는 들어오는 요청만을 단순히 처리하면 됨 + - Cacheable - HTTP의 캐싱 기능 적용 가능 + - Self-descriptiveness - REST API 메시지만 보고도 이를 쉽게 이해할 수 있는 표현 구조로 되어있음 + - Client-Server - 서버는 API 제공, 클라이언트는 사용자 인증이나 컨텍스트(세션, 로그인 정보)를 직접 관리하는 구조, 서로의 역할이 명확해지고 의존성이 줄어들음 + - 계층형 구조 - 다중 계층으로 구성될 수 있으며 보안, 로드밸런싱, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있음 + + ### 디자인 가이드 + + - URI는 정보의 자원을 표현해야 함 + - 자원에 대한 행위는 HTTP Method로 표현함 + + ```java + GET /members/show/1 (x) + GET /members/1 (o) + ``` + + - 슬래시 구분자(/)는 계층 관계를 나타내는 데 사용 + + ```java + http://restapi.example.com/houses/apartments + http://restapi.example.com/animals/mammals/whales + ``` + + - 리소스 간 관계 표현 + + ```java + GET : /users/{userid}/devices (일반적으로 소유 ‘has’의 관계를 표현할 때) + ``` + + - 자원을 표현하는 Collection, Document + - Collection은 문서들의 집합, 객체들의 집합 → 복수로 사용 + - Document는 단순 문서, 하나의 객체 → 단수로 사용 + + ```java + http:// restapi.example.com/sports/soccer/players/13 + ``` + + sports, players → Collection (복수) + + soccer, 13 → Document (단수) + +
+
From 6d6c42216fb5d7c2b603911a64074436bfc06994 Mon Sep 17 00:00:00 2001 From: Gopistol <104254012+Gopistol@users.noreply.github.com> Date: Tue, 1 Aug 2023 16:59:29 +0900 Subject: [PATCH 2/6] Update Gopistol.md --- http/Gopistol.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/http/Gopistol.md b/http/Gopistol.md index 3cc9518..dea20e8 100644 --- a/http/Gopistol.md +++ b/http/Gopistol.md @@ -47,7 +47,8 @@ - 인터넷 계층 - IP - 네트워크 인터페이스 계층 - ![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9aa6c793-1d62-4f78-b581-8fd751b1b0e0/Untitled.png) + 스크린샷 2023-07-31 오후 6 11 53 + TCP 특징 - 전송 제어 프로토콜(Transmission Control Protocol) @@ -358,8 +359,6 @@ If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a" Cache-Control: max-age=0 - - https://gmlwjd9405.github.io/2019/01/28/http-header-types.html ``` ### HTTP 응답 헤더 @@ -400,7 +399,6 @@ X-Cache-Info: not cacheable; meta data too large X-kuma-revision: 1085259 x-frame-options: DENY - https://gmlwjd9405.github.io/2019/01/28/http-header-types.html ``` From 32f8d9416e027cef1d1282a3933b31959d600859 Mon Sep 17 00:00:00 2001 From: Gopistol <104254012+Gopistol@users.noreply.github.com> Date: Sat, 5 Aug 2023 23:06:12 +0900 Subject: [PATCH 3/6] =?UTF-8?q?[5=EC=A3=BC=EC=B0=A8]COW-Spring-1=20?= =?UTF-8?q?=ED=95=99=EC=8A=B5(Gopistol)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- springcore/Gopistol.md | 393 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 393 insertions(+) create mode 100644 springcore/Gopistol.md diff --git a/springcore/Gopistol.md b/springcore/Gopistol.md new file mode 100644 index 0000000..97e8de7 --- /dev/null +++ b/springcore/Gopistol.md @@ -0,0 +1,393 @@ +### Spring + +자바 언어 기반의 프레임워크 + +OOP 어플리케이션 개발에 적합하다 + +### SOLID 원칙 + +- 정리 + - SRP(single responsibility principle) 단일 책임 원칙 + - 변경이 있을 때 파급 효과가 적은 것 ex) UI 변경, 객체의 생성과 사용을 분리 + - 하나의 객체는 한 가지의 책임을 가져야 한다. + - **OCP(Open/closed principle) 개방-폐쇄 원칙**(가장 중요!) + - 확장에는 열려 있으나 변경에는 닫혀 있어야 함 + - 구현 객체를 변경하려면 클라이언트 코드를 변경해야 하는데 그렇게 되면 OCP 원칙을 지킬 수 없다 + - 이 문제를 해결하기 위해 스프링 컨테이너를 통해 객체 생성, 연관관계를 맺어주는 별도의 조립, 설정자를 만들 수 있다. + - LSP(Liskov substitution principle) 리스코프 치환 원칙 + - 다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다는 것 + - ex: 자동차에서 엑셀을 밟으면 앞으로 가야 함. 뒤로 가면 LSP 위반하는 것임 + - ISP(Interface segregation principle) 인터페이스 분리 원칙 + - 특정 클라이언트를 위한 인터페이스를 분리하는 것은 범용 인터페이스 하나보다 낫다 + - 인터페이스가 명확해지고, 대체 가능성이 높아짐 + - DIP(Dependency inversion principle) 의존관계 역전 원칙 + - 구현 클래스에 의존하지 말고, 인터페이스에 의존해야 한다 + - 한 역할을 맡은 배우가 특정 배우하고만 연기하고 싶어한다면, 변경이 어렵기 때문 + +기존 자바의 다형성만으로는 OCP, DIP를 지키기 어렵다 + +스프링은 DI와 DI 컨테이너로 이 단점을 해소해준다 + +### 스프링 컨테이너 + +자바 객체의 생명 주기를 관리함 + +스프링 빈: 스프링 컨테이너에 의해 관리되는 자바 객체 + +스프링 컨테이너는 객체를 싱글톤으로 관리하기에 **싱글톤 컨테이너**라고도 한다 + +### 왜 쓸까? (IoC Inversion of Control) + +개발자는 프로그래밍을 하며 로직 상 필요한 객체들을 관리해야 한다. 객체를 어떻게 관리하는지 묻는다면, 객체를 적재적소에 사용하기 위해 그때그때마다 직접 생성하고 필요한 메소드를 호출하는 작업 등을 하는 것이라고 답할 수 있겠다. + +하지만 백엔드 개발자라면, 비즈니스 로직에 대해 고민하기에도 바쁠 것이다. 그래서 스프링에서는 객체 관리를 스프링 컨테이너에서 대신 해주는데, 이것이 스프링의 중요한 특징인 **제어의 역전(Inversion of Control)**이다. + +개발자는 스프링 컨테이너에 미리 생성되어 있는 객체를 가져와서 사용할 수 있다. 이 객체의 생성에서 소멸까지의 모든 과정이 스프링 컨테이너에서 관리된다. 이는 객체에 대한 제어권을 개발자가 아닌 스프링이 가지고 있기 때문에 **제어의 역전**이라고 한다. + +### 싱글톤 패턴이란? + +생성 패턴 중 하나로, 생성 패턴이란 인스턴스를 만드는 절차를 추상화하는 패턴임 + +클래스의 인스턴스가 **딱 하나만 생성**되는 것을 보장하는 디자인 패턴 + +### 왜 만들어졌을까? + +클래스 하나 당 하나의 인스턴스만을 가져도 되는 상황이 있음 + +대표적으로 로깅 객체, 쓰레드 풀, 윈도우 관리자 등의 객체가 있다. + +> 전역 변수를 사용하는 방법도 있지 않은가? +> + +이것도 가능한 방법이지만, 클래스가 자신만의 유일한 인스턴스를 가지며 그 인스턴스로 접근하는 방법을 관리하는 차원에서 싱글톤 패턴이 더욱 좋다고 할 수 있다. + +### 구현 방법 + +다양한 방법이 있지만, 공통된 특징이 있다 + +- private 생성자 사용으로 외부로부터 인스턴스 생성을 차단 +- 싱글톤 구현 클래스 내부 멤버 변수에 private static 사용 +- public static 메소드를 통해 외부에서 접근할 수 있는 접점 제공 + +1. **Eager Initialization** + + 싱글톤 클래스의 인스턴스를 컴파일 단계에서 생성하는 방법 + + ```java + public class Singleton { + + private static final Singleton instance = new Singleton(); + + // private constructor to avoid client applications to use constructor + private Singleton(){} + + public static Singleton getInstance(){ + return instance; + } + } + ``` + + 단점 + + - 큰 리소스를 다루는 싱글톤을 구현할 때는 리소스 낭비가 심함 + - 예외 처리를 다루지 않음 + +2. ****Static Block Initialization**** + + 위와 유사하지만 static block을 통해 예외를 처리할 수 있음 + + ```java + public class Singleton { + + private static Singleton instance; + + private Singleton(){} + + //static block initialization for exception handling + static{ + try{ + instance = new Singleton(); + }catch(Exception e){ + throw new RuntimeException("Exception occured in creating singleton instance"); + } + } + + public static Singleton getInstance(){ + return instance; + } + } + ``` + + +1. ****Lazy Initialization**** + + 인스턴스를 조회하는 메소드를 호출할 때에 인스턴스 유무를 검사하고, 없다면 생성해줌 + + ```java + public class Singleton { + + private static Singleton instance; + + private Singleton(){} + + public static Singleton getInstance(){ + if(instance == null){ + instance = new Singleton(); + } + return instance; + } + } + ``` + + 인스턴스 낭비에 대한 문제는 해결되지만, **멀티 쓰레드 환경에서의 동기화 문제**가 발생함 + + → 인스턴스가 생성되지 않았을 때 여러 쓰레드에서 동시에 인스턴스를 호출한다면 예상치 못한 결과를 얻을 수 있음 + + 따라서 단일 쓰레드 환경이 보장되어야 함 + +2. ****Thread Safe Singleton**** + + 위의 문제를 해결하기 위해, 조회 메소드에 synchronized를 사용하는 방법임 + + synchronized 키워드는 Critical Section을 형성하여 해당 영역에 오직 하나의 쓰레드만 접근할 수 있게 해줌 + + ```java + public class Singleton { + + private static Singleton instance; + + private Singleton(){} + + public static synchronized Singleton getInstance(){ + if(instance == null){ + instance = new Singleton(); + } + return instance; + } + } + ``` + + 단점 + + synchronized 자체에 대한 비용이 크기 때문에 인스턴스 호출이 잦으면 성능이 떨어짐 + + 이를 보완하기 위해 double checked locking 방식이 있음 + + ```java + public static Singleton getInstance(){ + if(instance == null){ + synchronized (Singleton.class) { + if(instance == null){ + instance = new Singleton(); + } + } + } + return instance; + } + ``` + + synchronized 키워드의 사용 범위를 더욱 축소해 인스턴스가 없을 경우에만 동작함 + +3. ****Bill Pugh Singleton Implementaion**** + + inner static helper class를 사용하는 방식 + + 앞의 방식들의 문제점을 대부분 해결한 방식으로, 현재 가장 널리 쓰임 + + ```java + public class Singleton { + + private Singleton(){} + + private static class SingletonHelper{ + private static final Singleton INSTANCE = new Singleton(); + } + + public static Singleton getInstance(){ + return SingletonHelper.INSTANCE; + } + } + ``` + + SingletonHelper 클래스는 싱글톤 인스턴스가 호출된 시점에서야 JVM 메모리에 로드된다. + +4. ****Enum Singleton**** + + 앞의 모든 방법은 class 안에서 싱글톤을 생성하므로 java reflection을 통해 파괴될 수 있는 위험이 있음 + + java reflection: 구체적인 클래스를 모르더라도 해당 클래스의 메소드나 변수에 접근할 수 있게 해주는 API + + enum을 통해 싱글톤을 구현하는 방법 + + ```java + public enum EnumSingleton { + + INSTANCE; + + public static void doSomething(){ + //do something + } + } + ``` + + 하지만 이 방법 역시 1, 2번처럼 메모리 문제와 유연성 저하의 문제가 있음 + + + + +주의해야 할 점은, 다음과 같이 상태를 유지하게 설계하면 문제가 발생한다 + +```java +public class StatefulService { + private int price; //상태를 유지하는 필드 + public void order(int price) { + this.price = price; //문제 지점 + } + public int getPrice() { + return price; + } +} +``` + +하나의 객체 인스턴스를 공유하므로 다른 price로 두 번을 호출했을 때, 가장 나중에 호출된 값이 저장되는 문제가 발생한다 + +따라서 무상태성을 가지도록 설계해야 함 + +### 컴포넌트 스캔 + +@Bean 어노테이션을 통해 자동으로 스프링 빈을 등록하는 방법 + +싱글톤 방식으로 빈들을 관리하기 위해 구성 정보를 지정해주는 AppConfig class를 사용함 + +```java +@Configuration +public class AppConfig { + + @Bean + public MemberService memberService() { + return new MemberServiceImpl(memberRepository()); + } + + @Bean + public OrderService orderService() { + return new OrderServiceImpl(memberRepository(), discountPolicy()); + } + + @Bean + public MemberRepository memberRepository() { + return new MemoryMemberRepository(); + } +} +``` + + + +1. Configuration 클래스 및 Annotation에 사용하는 설정들을 파싱 +2. basePackage 밑의 모든 .class 자원을 불러와서 component 후보인지 확인하여 BeanDefinition 생성 +3. 생성된 빈 정의를 바탕으로 빈을 생성하고 의존성 있는 빈들을 주입 + +### 의존관계 주입 + +객체 간 의존성을 외부에서 런타임 시점에 결정하는 것 + +- 생성자 주입: 생성자를 통해 의존 관계를 주입받는 방법 + + 특징 + + - 생성자가 호출되는 시점에 한 번만 호출된다 + - 생성자가 한 개만 있을 경우 @Autowired를 생략해도 자동 주입된다 + - NullPointerException 방지 + - 주입받는 필드를 final로 선언해 불변하고 필수적인 특성을 가질 수 있다 + + lombok 을 통해 편하게 멤버 변수에 private final로만 선언하는 방식을 사용함 + + ```java + @Service + @RequiredArgsConstructor // 생성자 생략 가능 + public class MemberServiceImpl implements MemberService { + private final MemberRepository memberRepository; + } + ``` + +- Setter 주입: 수정자 setter를 이용해 의존 관계를 주입하는 방법 + + 특징 + + - 선택, 변경 가능성이 있는 의존 관계에 사용함 + - @Autowired를 꼭 붙여줘야 함 + + ```java + @Component + public class CoffeeService { + private final MemberRepository memberRepository; + private final CoffeeRepository coffeeRepository; + + @Autowired + public void setMemberRepository(MemberRepository memberRepository) { + this.memberRepository = memberRepository; + } + + @Autowired + public void setCoffeeRepository(CoffeeRepository coffeeRepository) { + this.coffeeRepository = coffeeRepository; + } + } + ``` + +- 필드 주입: 필드에 @Autowired를 붙여서 바로 주입하는 방법 + + 특징 + + - 외부에서 변경이 불가능해 테스트하기 어렵다 + - DI 프레임워크가 없으면 아무것도 못한다 + + ```java + @Component + public class CoffeeService { + @Autowired + private final MemberRepository memberRepository; + @Autowired + private final CoffeeRepository coffeeRepository; + } + ``` + + 가급적 쓰지 말자 + +- 메소드 주입: 일반 메소드를 통해 의존관계를 주입받는 방법 + + 특징 + + 한 번에 여러 필드를 주입받을 수 있음 + + +### DI vs DIP + +DI: Dependency Injection (의존성 주입) + +DIP: Dependency Inversion Principle + +추상화(인터페이스)에 의존함으로써 구현체의 의존 관계를 숨겨라 + +### @Component vs @Bean + +@Component + +- 클래스 레벨에서 적용 +- Class 자체를 빈으로 등록할 때 + +@Bean + +- 메소드 레벨에서 적용 +- 사용자가 제어하지 못하는 외부 라이브러리 등록에 사용 + +### Reference + +[https://velog.io/@hyun-jii/스프링-component-scan-개념-및-동작-과정](https://velog.io/@hyun-jii/%EC%8A%A4%ED%94%84%EB%A7%81-component-scan-%EA%B0%9C%EB%85%90-%EB%B0%8F-%EB%8F%99%EC%9E%91-%EA%B3%BC%EC%A0%95) + +https://prodo-developer.tistory.com/107 From f0305fc09a722eb7396a2cd651544a560eb5fe88 Mon Sep 17 00:00:00 2001 From: Gopistol <104254012+Gopistol@users.noreply.github.com> Date: Tue, 15 Aug 2023 23:19:54 +0900 Subject: [PATCH 4/6] Create Gopistol.md --- db-sql-basic/Gopistol.md | 197 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 db-sql-basic/Gopistol.md diff --git a/db-sql-basic/Gopistol.md b/db-sql-basic/Gopistol.md new file mode 100644 index 0000000..4ab87a5 --- /dev/null +++ b/db-sql-basic/Gopistol.md @@ -0,0 +1,197 @@ +## 관계형 데이터베이스 (RDBMS) + +Relational Database Management System의 약자로, 데이터를 관계형 모델로 표현하고 데이터를 효율적으로 관리하기 위해 SQL을 사용한다. + +관계형 모델로 표현한다는 것은, 행과 열의 형태로 데이터를 저장하고 데이터 테이블 간 관계를 정의하는 것을 말한다. RDBMS의 대표적인 예로 Oracle, MySQL 등이 있다. + +비관계형 데이터베이스(NoSQL)도 있는데, NoSQL에는 키-값 형태로 데이터를 저장하거나, 문서, 그래프 데이터 등의 다양한 데이터 저장 방식을 사용한다. + +RDBMS는 정형화된 데이터를 다루며, 데이터의 무결성, 일관성을 보장할 수 있다. 하지만 대규모 데이터 처리에는 한계가 있을 수 있다. + +NoSQL은 비정형화된 데이터를 다루며, 대용량 데이터 처리에 용이하다. 하지만 RDBMS처럼 데이터의 일관성, 무결성을 보장할 수 없다. + +## DDL, DML, DCL + +SQL 문법은 DDL, DML, DCL로 나눌 수 있다. + +### DDL + +데이터베이스의 구조 정의에 사용하는 언어로, 테이블이나 관계의 구조를 생성할 때 사용한다. + +- CREATE: 테이블, 뷰 또는 인덱스와 같은 새 데이터베이스 개체를 만든다 +- ALTER: 기존 데이터베이스의 개체를 수정한다. +- DROP: 기존 테이블을 제거한다. +- TRUNCATE: 기존 테이블을 초기화한다. +- RENAME: 기존 테이블의 이름을 변경한다. + +### DML + +데이터 조작어로, 데이터베이스에 저장된 자료들을 입력, 수정, 삭제, 조회하는 언어이다. + +- SELECT: 저장된 데이터를 조회한다. +- INSERT: 새로운 데이터를 저장한다. +- UPDATE: 저장된 데이터를 수정한다. +- DELETE: 저장된 데이터를 삭제한다. + +### DCL + +데이터 제어어로, 데이터베이스에 대한 각종 권한을 부여, 회수한다. + +- GRANT: 유저에게 권한을 부여한다. +- REVOKE: 유저에게 권한을 회수한다. + +### TCL + +트랜잭션 제어어로, DCL에서 트랜잭션을 컨트롤하는 명령어를 TCL이라고 분류한다. DCL로 분류하는 경우도 있다. + +- COMMIT: 올바르게 완료한 작업의 데이터를 데이터베이스에 영구적으로 반영한다. +- ROLLBACK: 작업 시작 이전의 상태로 되돌린다. +- SAVEPOINT: 저장점을 지정해, 이후 ROLLBACK과 함께 사용하여 특정 지점까지 롤백이 가능하다. + +## 엔터티, 테이블, 필드, 레코드 + +### 엔터티 + +데이터 모델링에서 사용되는 객체이다. 예를 들어 학교, 학생처럼 눈에 보이는 개념일 수도 있고, 주문이나 결제처럼 눈에 보이지 않는 개념일 수도 있다. + +스크린샷 2023-08-14 오후 11 40 06 + +그림처럼 엔터티는 테이블 하나라고 생각할 수 있다. + +### 특징 + +- 유일한 식별자가 있어야 함 +- 두 개 이상의 인스턴스의 집합이어야 함 +- 속성을 포함해야 함 +- 다른 엔터티와의 관계가 존재해야 함 + +### 테이블 + +관계 데이터베이스 모델에서 자료의 구조를 2차원의 표(행과 열)로 나타낸 것이다. 키를 지정함으로써 자료를 쉽고 빠르게 찾을 수 있다. + +### 필드 + +항목, 어떠한 의미를 지니는 정보로써 데이터베이스 시스템에서 처리되는 최소 단위이다. + +### 레코드 + +데이터베이스에서 하나의 단위로 취급되는 자료의 집합 +하나의 레코드는 테이블에서 가로 한 줄, 행, 튜플이라고도 한다. + +## 키(기본키, 외래키) + +### 기본키 + +후보키들 중 하나를 선택한 키로, 최소성과 유일성을 만족한다. + +테이블 하나 당 오직 1개만 지정할 수 있다. + +NULL값을 가질 수 없고, 중복된 값을 가질 수 없다. + +대체키: 후보키가 두 개 이상일 경우 기본키로 지정되지 않고 남은 후보 키를 말한다. + +### 외래키 + +기본키를 참조하는 속성으로, 테이블 간 관계를 나타내기 위해 사용한다. + +외래키가 참조하는 테이블은 외래키가 있는 테이블보다 먼저 만들어져야 한다. + +참조될 열의 값은 참조될 테이블의 기본키여야 한다. + +## 관계(1:1, 1:N, N:M) + +한쪽 엔터티와 관계를 맺은 엔터티 쪽이 하나의 객체만 가지는지, 여러 개의 객체를 가질 수 있는지에 따라 세 가지로 나뉜다. + +### 1:1 + +하나의 레코드가 다른 테이블의 레코드 하나와 연결된 경우 + +### 1:N + +하나의 레코드가 서로 다른 여러 개의 레코드와 연결된 경우 + +### N:M + +여러 개의 레코드가 다른 테이블의 여러 개의 레코드와 관계가 있는 경우 + +## WHERE, GROUP BY, HAVING, ORDER BY + +### WHERE + 비교대상 + 비교연산자 + 비교할 값 + +SELECT와 FROM 절까지는 똑같고, WHERE 옆에 조건문을 적어주면 된다. + +비교 연산자 종류 + +- =: 값이 같은지 비교 +- ≠, <>, ^=: 값이 다른지 비교 +- <, >: 작거나 큰지 비교 +- BETWEEN A AND B: 값이 A ~ B 안에 있는지 비교 +- IN: 비교할 대상들 안에 비교되는 값이 포함되는지 비교 +- LIKE: 특정 값과 비슷한 값 탐색 가능 +- IS NULL: 칼럼이 NULL인지 비교 + +### GROUP BY, HAVING + +같은 값을 가진 행끼리 하나의 그룹으로 뭉쳐줌 + +Having 절은 Group by 를 통해 그룹핑한 행에만 사용할 수 있음 (조건) + +## SELECT 쿼리 실행 순서 + +각각의 쿼리가 언제 실행되는지 모르면 에러가 날 수 있다. + +스크린샷 2023-08-15 오후 11 12 24 + +### FROM + +조회할 테이블을 지정함 +이후 JOIN을 실행해 하나의 가상 테이블로 결합 + +### LIMIT + +결과 중 몇 개의 행을 보여줄지 선택 + +SELECT → FROM → WHERE 순으로 쿼리를 작성하곤 하지만, 실행 순서에 맞추어 FROM → WHERE → SELECT 순으로 작성하게 되면 성능적으로 튜닝할 수 있는 요소를 발견하기 쉽다고 한다. + +## Programmers SQL Practice + +1번 + +```sql +SELECT FACTORY_ID, FACTORY_NAME, ADDRESS +FROM FOOD_FACTORY +WHERE ADDRESS LIKE '%강원도%' +ORDER BY FACTORY_ID +``` + +2번 + +```sql +SELECT NAME +FROM ANIMAL_INS +ORDER BY DATETIME ASC LIMIT 1 +``` + +3번 + +```sql + +SELECT ANIMAL_ID, NAME +FROM ANIMAL_INS +WHERE INTAKE_CONDITION = 'Sick' +``` + +4번 + +```sql +SELECT COUNT(DISTINCT NAME) +FROM ANIMAL_INS +WHERE NAME IS NOT NULL; +``` + +5번 + +```sql +SELECT MAX(PRICE) AS MAX_PRICE +FROM PRODUCT +``` From 5d252b7cb79b30e78e3d3a6bd6c085cffd84880c Mon Sep 17 00:00:00 2001 From: Gopistol <104254012+Gopistol@users.noreply.github.com> Date: Tue, 22 Aug 2023 14:19:44 +0900 Subject: [PATCH 5/6] Create gopistol.md --- springmvc/gopistol.md | 171 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 springmvc/gopistol.md diff --git a/springmvc/gopistol.md b/springmvc/gopistol.md new file mode 100644 index 0000000..e3e6e66 --- /dev/null +++ b/springmvc/gopistol.md @@ -0,0 +1,171 @@ +## MVC 패턴이란? + +Model-View-Controller의 약자로, 애플리케이션을 세 가지 역할로 구분한 방법론 + +### 모델 + +데이터를 가진 객체 + +규칙 + +- 사용자가 편집하려는 모든 데이터를 가지고 있어야 함 +- 뷰, 컨트롤러에 대한 어떤 정보도 알지 말아야 함 + +### 뷰 + +사용자에게 보여지는 부분 + +규칙 + +- 모델이 가진 정보를 저장하면 안 됨 +- 모델, 컨트롤러와 같이 다른 구성 요소를 알면 안 됨 + +### 컨트롤러 + +사용자의 요청을 파악 후 요청에 맞는 데이터를 모델로부터 뷰로 전달함 + +규칙 + +- 모델, 뷰에 대해 알고 있어야 함 + + + +- Model + - 데이터 베이스 및 데이터 표현 + - 유저가 입력하는 숫자를 저장, 이전 계산 기록을 저장 +- View + - 계산 결과를 보여줌 + - 현재 입력중인 숫자나 사칙연산이 무엇인지 보여줌 +- Controller + - 입력값이 초과하지 않았는지 + - 사용자가 View에서 입력한 숫자를 Model로 변경 해 줌 + - 사칙연산 계산 + +다음과 같이 구성할 수 있다. + +### MVC 패턴의 한계 + +시스템의 규모가 커질수록, 모델과 뷰가 M : N 관계로 매우 복잡해진다. 이렇게 서로 높아진 의존성은 문제를 일으킬 수 있다. + +컨트롤러에 모든 로직이 들어가 역할 분산의 필요성이 생긴다. + +## Layerd Architecture + +Presentation Layer: 사용자 - 애플리케이션 간 인터페이스 담당, 요청과 응답을 처리함 + +Business Layer (Service, Domain): 핵심 비즈니스 로직을 담당한다. + +Persistance Layer: 데이터베이스와 상호작용한다. (데이터에 대한 영속성 유지) + +Database Layer: 데이터베이스를 뜻한다. + +계층형 아키텍처는 상위 계층이 하위 계층에 의존하는 구조를 가짐 + +각 계층은 그 하위 계층에 대해서만 의존하기 때문에 특정 계층의 유지보수, 확장이 용이하다. + +변경의 영향을 줄이기 위해서 각 계층은 닫혀 있는 관계이다. 닫혀 있다는 것은 한 계층에서 다른 계층으로 이동할 때, 그 사이에 계층이 있다면 무조건 그 계층도 통과해야 함을 뜻한다. + +## 서블릿 + +웹 애플리케이션 서버 내에서 실행되는 Java 프로그램 + +동적 웹 페이지를 만들고 웹 응용 프로그램을 구현함 + +Apache Tomcat은 서블릿이 웹 애플리케이션으로 실행되게 해주는 서블릿 컨테이너 중 하나임 + +### 웹 서버 + +- HTTP 프로토콜을 기반으로 요청을 받으면 정적 컨텐츠를 제공하는 서버 +- Apache, Nginx 등 + +### WAS + +- DB 조회 등 다양한 로직 처리 요구하는 동적 컨텐츠 제공 +- JSP, Servlet 구동환경을 제공해주기 때문에 서블릿 컨테이너, 웹 컨테이너라고도 불림 +- Tomcat, JBoss 등 + +요청 → WAS에 위임 → WAS는 각 요청에 해당하는 서블릿 실행 → 서블릿은 결과를 반환해 클라이언트로 응답 전송 + +## 스프링 MVC 구조 + +스크린샷 2023-08-22 오전 1 24 08 + +### DispatcherServlet + +HTTP 프로토콜로 들어오는 모든 요청을 **가장 먼저 받아 적합한 컨트롤러에 위임**해주는 프론트 컨트롤러 + +정적 자원 요청까지도 모두 가로채기 때문에 정적 자원을 불러오지 못하는 경우도 생겼다. 그래서 정적 자원 요청과 애플리케이션 요청을 분리하거나, 먼저 애플리케이션 요청을 탐색하고 없다면 정적 자원 요청으로 처리하는 방식을 사용한다. + +### 디스패처 서블릿의 동작 과정 + +1. 클라이언트 요청을 디스패처 서블릿이 받음 +2. 요청 정보를 통해 요청을 위임할 컨트롤러를 탐색함 +3. 요청을 컨트롤러로 위임할 핸들러 어댑터를 찾아서 전달함 +4. 핸들러 어댑터가 컨트롤러로 요청을 위임함 +5. 비즈니스 로직을 처리함 +6. 컨트롤러가 값을 반환함 +7. 핸들러 어댑터가 반환값을 처리함 +8. 서버의 응답을 클라이언트로 반환함 + +### HandlerMapping + +한 요청에 대해 어느 컨트롤러가 그 요청을 처리할 수 있는지를 식별하는 역할을 함 + +요청이 오면 Http Method나 URI를 사용해 요청 정보를 만들고, HashMap에서 요청을 처리할 대상(HandlerMethod)을 찾은 후 HandlerExecutionChain으로 감싸서 반환한다. 이는 컨트롤러로 요청을 넘겨주기 전에 처리해야 하는 인터셉터 등을 포함하기 위해서이다. + +## 어노테이션 / Spring 프레임워크의 주요 어노테이션 + +### 어노테이션이란? + +프로그램에게 추가적인 정보를 제공해주는 메타데이터 + +코드 사이에 주석처럼 쓰이며 특정 의미, 기능을 갖게 하는 기술 + +### 어노테이션 사용 이유 + +컴파일러에게 코드 작성 문법 에러를 검사하도록 정보를 제공함 + +빌드, 배치 시 코드를 자동으로 생성할 수 있도록 정보를 제공함 + +런타임 시 특정 기능을 실행하도록 정보를 제공함 + +### 종류 + +- @ComponentScan + +@Component 어노테이션이 붙은 클래스에 대해 bean 인스턴스를 생성함 + +- @Component + +개발자가 직접 작성한 클래스를 Bean으로 등록함 + +- @Bean + +개발자가 제어할 수 없는 외부 라이브러리 등을 Bean으로 등록할 때 사용됨 (메소드 단위) + +- @Autowired + +필드, 주입자, 생성자에서 사용되며 의존성을 주입해줌 + +- @Configuration + +클래스에 적용하고 @Bean을 메소드에 적용하면 @Autowired로 Bean을 부를 수 있다. + +- @Qualifier(”id123”) + +같은 타입의 Bean 객체가 있을 때 해당 아이디를 적어 원하는 Bean이 주입될 수 있도록 하는 어노테이션 + +- @PostConstruct, @PreConstruct + +의존하는 객체 생성 이후 초기화 작업을 위해 객체 생성 전 / 후에 실행해야 할 메소드 앞에 붙임 + +- @PreDestroy + +객체 제거하기 전에 해야 할 작업을 수행하기 위해 사용 + +- @RequestMapping + +요청 URL을 어떤 Method가 처리할 지 매핑해주는 어노테이션 From 1de8ff14a6f93f86a2c1f962fb81638e972dd868 Mon Sep 17 00:00:00 2001 From: Gopistol <104254012+Gopistol@users.noreply.github.com> Date: Wed, 13 Sep 2023 02:14:29 +0900 Subject: [PATCH 6/6] =?UTF-8?q?[9~10=EC=A3=BC=EC=B0=A8]=20=ED=95=99?= =?UTF-8?q?=EC=8A=B5=20=EB=82=B4=EC=9A=A9=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jpa/Gopistol.md | 276 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 jpa/Gopistol.md diff --git a/jpa/Gopistol.md b/jpa/Gopistol.md new file mode 100644 index 0000000..083e80d --- /dev/null +++ b/jpa/Gopistol.md @@ -0,0 +1,276 @@ +## 1주차 + +- JPQL +- 영속성 컨텍스트 +- 엔티티 매핑 + +## 2주차 + +- 연관관계 매핑 + - 다양한 매핑 + - 단방향, 양방향 +- Spring Data JPA + +## JPQL + +### JPQL이란? + +JPA가 제공하는 SQL을 추상화한 객체 지향 쿼리 언어 + +엔티티 객체를 대상으로 쿼리가 작성됨 + +SQL을 추상화했기 때문에 특정 데이터베이스 SQL에 의존하지 않는다 + +### 예시 + +```java +String jpql = "select m From Member m where m.name like ‘%hello%'"; +List result = em.createQuery(jpql, Member.class).getResultList(); + +for (Member member : result) { + System.out.println("member = " + member); +} +``` + +Member 객체를 대상으로 이름에 “hello”가 포함된 모든 회원을 뽑아준다. + +### 단점 + +기본 문자열(String)로 작성되기 때문에 쿼리에 문제가 있어도 컴파일 시 에러가 발생하지 않는다. + +동적으로 쿼리를 작성하기 비효율적이다. (ex: 특정 조건에서 서로 다른 쿼리를 실행하고 싶은 경우) + +### 특징 + +- 엔티티와 속성은 대소문자를 구분함. + - 엔티티는 첫 글자를 대문자, 속성은 다 소문자 + - @Entity의 name을 지정하지 않으면 클래스 이름이 엔티티 이름이 된다. +- JPQL 키워드는 대소문자를 구분하지 않음 +- 테이블 이름을 사용하지 않음 +- 별칭은 필수적으로 사용함 +- as 생략 가능 +- 반환 타입이 명확할 경우 두 번째 인자로 타입 정보를 작성할 수 있음 (TypeQuery) + - 예시 + + ```java + TypedQuery query1 = em.createQuery("select m from Member m", Member.class); + TypedQuery query2 = em.createQuery("select m.username from Member m", String.class); + ``` + +- 반환 타입이 명확하지 않을 때 (Query) + - 예시 + + ```java + Query query3 = em.createQuery("select m.username, m.age from Member m"); + ``` + + +## 영속성 컨텍스트 + +엔티티를 영구 저장하는 환경 + +- 비영속 상태(new/transient): 영속성 컨텍스트와 관계 없는 상태 + +```java +//객체를 생성한 상태(비영속) +Member member = new Member(); +member.setId("member1"); +member.setUsername("회원1"); +``` + +- 영속 상태(managed): 영속성 컨텍스트에 저장된 상태 + +```java +//객체를 생성한 상태(비영속) +Member member = new Member(); +member.setId("member1"); +member.setUsername(“회원1”); +EntityManager em = emf.createEntityManager(); +em.getTransaction().begin(); +//객체를 저장한 상태(영속) +em.persist(member); +``` + +- 준영속 상태(detached): 영속성 컨텍스트에 저장되었다가 분리된 상태 + +```java +//회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태 +em.detach(member); +``` + +- 삭제된 상태(removed + +```java +//객체를 삭제한 상태(삭제) +em.remove(member); +``` + +### 장점 + +- 1차 캐시 + +영속 상태의 엔티티를 1차 캐시에 저장하기 때문에 엔티티 조회 시 1차 캐시에 데이터가 존재한다면 DB를 찾아보지 않아도 된다. + +- 영속 엔티티의 동일성 보장 + +Repetable Read 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공한다. + +- 트랜잭션을 지원하는 쓰기 지연 + +```java +EntityManager em = emf.createEntityManager(); +EntityTransaction transaction = em.getTransaction(); +//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다. +transaction.begin(); // [트랜잭션] 시작 + +em.persist(memberA); +em.persist(memberB); +//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다. + +//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다. +transaction.commit(); // [트랜잭션] 커밋 +``` + +em.persist()로 영속성 컨텍스트에 객체를 저장해도, DB에 INSERT 쿼리를 날리지 않는다. SQL 쿼리들을 모아두어 flush될 때, 모아둔 쿼리를 모두 날린다. (쓰기 지연) + +- 변경 감지(Dirty Checking) + +영속성 컨텍스트에서 엔티티를 조회해 해당 엔티티를 수정한다고 할 때, 업데이트를 위한 코드 없이 알아서 변경된 데이터를 비교해 존재한다면 UPDATE 쿼리를 자동으로 생성한다. + +- 지연 로딩 + +연관 관계 매핑되어 있는 엔티티 조회 시 우선 프록시 객체를 반환하고, 실제로 필요할 때 쿼리를 날려 가져온다. 즉, 필요한 시점에 연관된 데이터를 불러오는 것 + +```java +@ManyToOne(fetch = FetchType.LAZY) //Team을 조회할 때 지연로딩을 사용하곘다! +@JoinColumn(name = "team_id") +Team team; +``` + +```sql +//Team을 조회하는 쿼리가 나가지 않음! +select + member0_.id as id1_0_, + member0_.team_id as team_id3_0_, + member0_.username as username2_0_ +from + Member member0_ +``` + +만약 Member 1명 조회 시 연관된 Team이 100개라면, 즉시 로딩(Eager) 시 100개의 Team을 조회하는 쿼리가 생성되었을 것이다. 이러한 비효율성을 극복하기 위해 지연 로딩을 사용한다. + +## 엔티티 매핑 + +실제 데이터베이스의 테이블과 엔티티를 정확하게 매핑하는 것은 중요하다. + +이를 위해 다양한 매핑 어노테이션을 알아두어야 하는데, 대표적으로 4가지로 분류할 수 있다. + +- 객체 - 테이블 매핑: @Entity, @Table +- 기본 키 매핑: @Id +- 필드 - 컬럼 매핑: @Column +- 연관관계 매핑: @ManyToOne, @JoinColumn, @OneToMany + +### @Entity + +테이블과 매핑할 클래스에 붙이는 어노테이션 + +- 기본 생성자 필수 +- final, enum, interface, inner 클래스에서는 사용 X +- 필드에 final 사용 X + +### @Table + +엔티티와 매핑할 테이블을 지정함 + +```java +@Entity +@Table(name = "MEMBER") // Member 엔티티를 테이블 명 MEMBER로 매핑 +public class Member {} +``` + +### 기본 키 매핑 + +JPA의 기본 키 생성 전략엔 두 가지가 있다 + +- 직접 할당: 기본 키를 어플리케이션에서 직접 할당함 +- 자동 생성: 대리 키를 사용함 + +IDENTITY: 기본 키 생성을 DB에 위임함 + +SEQUENCE: DB 시퀀스를 사용해 기본 키를 할당함 + +TABLE: 키 생성 테이블을 사용함 + +### 필드 - 컬럼 매핑 + +- @Enumerated: enum 타입 매핑 시 사용 + - EnumType.ORIGINAL: enum 순서를 데이터베이스에 저장 + - EnumType.STRING: enum 이름을 데이터베이스에 저장 + + ```java + @Enumerated(EnumType.STRING) + private RoleType roleType; + + member.setRoleType(RoleType.ADMIN); //-> DB에 문자 ADMIN으로 저장됩니다. + ``` + + +- @Transient: 선언된 필드는 매핑되지 않음. 객체에 임시로 값을 보관하고 싶을 때 사용 +- @Access: JPA가 엔터티 테이블에 접근하는 방식을 지정함 + +## 연관관계 매핑 + +객체를 테이블 중심으로 모델링하면, 협력 관계를 만들 수 없음 + +- 테이블은 외래 키 조인을 사용해 연관 테이블을 찾음 +- 객체 참조를 사용해 연관된 객체를 찾음 + +⇒ 객체 지향 프로그래밍과 데이터베이스 사이의 패러다임 불일치 발생 + +### 단방향, 양방향 관계 + +데이터베이스 테이블은 FK로 양 쪽 테이블 조인이 가능하다. 따라서 단방향, 양방향을 나눌 필요가 없다. + +하지만 객체는 참조용 필드가 있는 객체만 다른 객체를 참조할 수 있으므로, 두 객체 사이에 한 객체만 참조용 필드가 있는 경우 단방향 관계, 두 객체 모두 서로 참조하는 필드가 있다면 양방향 관계라고 한다. + +단방향, 양방향 관계를 고민할 때 중요하게 생각해야 할 것은 두 객체의 참조가 필요한지의 여부이다. 무조건 양방향을 택했을 때, 필요 이상의 엔티티와 연관 관계를 가짐으로써 객체의 클래스가 매우 복잡해지게 된다. 그래서 기본적으로 단방향 매핑 관계를 가지고, 추후 역방향의 객체 탐색이 필요하다고 느껴지면 양방향 관계를 맺으면 된다. + +### 연관 관계의 주인 + +두 객체가 단방향 관계일 때, 제어의 권한을 가진 객체를 연관 관계의 주인이라고 한다. + +연관 관계의 주인은 두 객체 사이에서 CRUD가 가능하지만, 주인이 아닌 객체는 조회만 가능하다. + +주인이 아닌 객체에서는 mappedBy 속성으로 주인을 지정해주어야 한다. + +### JPA vs Hibernate vs Spring Data JPA + +- JPA + +Java Persistence API의 약자로, 자바에서 관계형 데이터베이스를 사용하는 방식을 정의하는 인터페이스이다. 자바 클래스와 DB를 매핑해 객체를 통해서 간접적으로 DB data를 다룬다. + +- Hibernate + +JPA 인터페이스의 구현체로, JPA의 핵심 인터페이스인 `EntityManagerFactory`, `EntityManager`, `EntityTransaction` 을 **Hinbernate** 에서 각각 `SessionFactory`, `Session`, `Transaction` 으로 상속받고 각각 Impl 로 구현된다. + +곧, 우리가 JPA를 사용하는 데 있어 Hibernate를 무조건 사용해야 되는 것은 아니다. 필요에 따라 직접 구현하여 사용할 수 있다. + +- Spring Data JPA + +Spring에서 제공하는 모듈 중 하나로, JPA를 더 쉽고 편하게 사용할 수 있도록 도와줌 + +JPARepository를 사용한다는 점에서 차이가 있다. + +사용자가 Repository 인터페이스에 정해진 규칙대로 메소드를 입력하면 Spring은 알아서 해당 메소드 이름에 적합한 쿼리를 날리는 구현체를 만들어서 Bean으로 등록해준다. + +스크린샷 2023-09-13 오전 2 11 45 + +### Reference + +https://ittrue.tistory.com/270 + +https://developer-hm.tistory.com/37 + +[https://velog.io/@sa1341/JPA-Entity-매핑](https://velog.io/@sa1341/JPA-Entity-%EB%A7%A4%ED%95%91) + +https://velog.io/@heoseungyeon/JPA-vs-Spring-Data-JPA