팀과제가 다 처음 배우는 것이라 Today I learned 입니다.
JPA란
‘Java Persistence API’로 자바 ORM(Object Relational Mapping: 객체 관계 매핑)기술로 다음과 같은 기능을 함:
- 쿼리 자동 생성
- 어플리케이션 계층에서 spl 의존성을 낮춰 작업 효율성 상승
- 패러다임 불일치 해결
- 다양한 방언(h2 Database, mySQL, oracle 등) 지원
JPA 사용을 위해서는 Hibernate, EclipseLink 같은 ORM 프레임워크를 사용해아함.
스프링 부트에서는 Hibernate 사용
ORM(객체 관계 매핑)이란?
객체와 DB의 테이블이 매핑을 이루는 것으로 query를 직접 작성하지 않고 메서드 호출로 데이터 조회가 가능함 → 생산성 향상
스프링에서 JPA를 사용할 때 에상 가능하고 반복적인 코드들을 Spring Data JPA가 작성해줌 →JpaRepository 선언
책추천 (추천글/지은이의말 만 읽어도 도움됩니다)
restAPI의 put 과 patch 는 어떤 차이점이 있을까요? 어떤 경우에 사용하면 좋을까요?
- ※참고https://tecoble.techcourse.co.kr/post/2020-08-17-put-vs-patch/https://developer.mozilla.org/ko/docs/Web/HTTP/Methods/PATCH
- https://june0122.github.io/2021/08/05/term-idempotent/
- https://developer.mozilla.org/ko/docs/Glossary/Idempotent
Http Method 중 자원(엔티티)을 수정하는 용도 1)PUT
- 전체 수정(자원 전체 교체) => 자원이 있다면 수정, 없다면 생성
- 수정 시 모든 필드 필요
- 자원 전체를 교체하는 것이기에, Client는 해당 자원 상태를 모두 알고 있다고 가정되어야 함 즉, Payload만으로 자원 전체 상태를 표시할 수 있어야 함
- 멱등성 가짐
2)PATCH
- 부분 수정(자원 부분 교체)
- 수정 시 수정할 필드만 필요
- 별도의 DTO 필요
- 멱등성 가질 수 도, 안 가질 수도 있음
멱등성(idemoitent)
- 연산을 여러번 적용해도, 결과가 달라지지 않는 성질
- 연산을 여러번 반복해도, 한번만 수행된것과 같은 성질
- 동일한 요청을 한번 보내는 것과 여러번 연속 보내는 것이 같은 효과를 가지고, 서버 상태도 동일할 때, HTTP Method가 멱등성을 가졌다고 말함
- ex) f(f(x)) = f(x)
HTTP란?
HyperText Transfer Protocol로 프로토콜, 즉 인터넷 통신 데이터 교환의 기준이 되는 약속이다. Stateless(무상태성)와 Connectionless(비연결성)이 특징으로 요청(request)을 주고 받을 때만 연결이 유지되고 응답(response)하고 나서 서버와 연결을 끊는다.
HTTP 메소드
클라이언트가 웹 서버에 사용자 요청의 목적 또는 종류를 알리는 수단으로 GET, POST, PUT, PATCH, DELETE 가 주로 쓰임
구성요소
- Method (호출/요청 방식)
- GET: 이름 그대로 어떤 리소스를 얻을 때 사용; 브라우저의 주소창에 URL을 입력하면 GET 메서드를 사용해서 서버에 요청을 보냄
- POST: 웹 서버에 데이터를 게시할 때 사용 (ex. 회원가입, 게시글 작성, 댓글 작성)
- Header (추가 데이터. 메타 데이터)
- 브라우저가 어떤 페이지를 원하는지
- 요청 받은 페이지를 찾았는지
- 요청 받은 데이터를 성공적으로 찾았는지
- 어떤 형식으로 데이터를 보낼지
- 위에서 설명 된 메서드도 헤더에 포함되어 서버로 보냄
- Payload (데이터. 실제 데이터)
- 서버가 응답을 보낼 때에는 항상 Payload 보내기 가능
- 클라이언트(브라우저)가 요청을 할 때에도 Payload를 보낼 수 있음
- "GET method를 제외하곤 모두 Payload를 보낼 수 있다" 는게 HTTP에서의 약속
(DB에서)트랜잭션(Transaction)
- 나눌 수 없는 업무 단위
- SQL DML에는 select(조회). insert(생성), update(수정), delete(삭제)가 있다.
- 이 중 insert, update, delete는 Table 안에 data를 변경시킬 수 있는데(생성, 수정, 삭제) insert, update, delete SQL문을 모두 작성한 후 최종 반영(commit)할지, 취소(rollback)할지 결정해야 한다.
- 문서파일에 글을 저장하지 않고 작성하다가 마지막에 닫기(X) 버튼 클릭하면(윈도우 기준) [저장] 또는 [저장안함]이 뜨는데, [저장]하면 사용자가 작성한 내용들이 저장되고, [저장안함]을 선택하면 사용자가 작성한 자료가 반영되지 않는다.
- 여기서 [저장]은 commit, [저장안함]은 rollback이다.
- SQL에서 Transaction이 필요한 이유는, DML 중 insert, update, delete가 사용자들에게 영향을 줄 수 있기 때문이다
- Transaction은 이러한 문제를 해결하기 위해 누군가 특정 data에 작업(insert, update, delete)하려고 한다면, 작업하고 있는 data를 잠금(lock)한다.
- 이 작업이 끝날 때까지 다른 사용자들은 해당 data를 insert, update, delete하지 못하고, 작업중인 사용자가 최종 반영할지(commit), 취소할지(rollback) 결정되면, 그때 감금이 해제된다.
트랜잭션 특징
원자성(Atomicity) :
- 트랜잭션 안의 작업들이 분리되어 작업 불가
- 트랜잭션의 가장 큰 특성 (이게 안되면 무결성이 훼손)
독립성(Isolation) :
- 진행 중인 트랜잭션들은 정보전달, 서로 알아보기 등등 없다.
- 트랜잭션은 하나씩만 열 수 있다. 여러 개를 같이 못함(독립성) (외부와 정보교환 수행 불가, Lock)
일관성(Consistency) :
- 트랜잭션 실행 후 DB의 무결성은 반드시 유지 되어야 함
영속성(Durability) :
- 작업 종료된 트랜잭션의 결과는 반드시 DB에 반영되어야 함
- (JPA에서)트랜잭션(Transaction)
https://scshim.tistory.com/528https://joojimin.tistory.com/68https://hungseong.tistory.com/69
- JPA 자체는 Transaction 관리 기능 제공 않음
- Spring에서 선언적(@Transactional)으로 Transaction 처리 제공 (개발할 때 Transaction 범위를 @Transactional 어노테이션을 사용해 손쉽게 정의 가능)
- class level 또는 method level에 @Transactional 어노테이션이 붙어있는 Service 클래스는 Transaction 관련 코드(트랜잭션 시작, 커밋 또는 롤백, 트랜잭션 종료)가 추가된 Proxy 객체를 Bean으로 등록해 Transaction 기능을 수행
- 기본적으로 읽기전용 인 @Transactional(readOnly=true)는 아무런 @Transactional 설정을 하지 않은 메서드에 적용
- 스프링에서 의존성 주입이란 무엇인가?
- 외부에서 두 객체 간의 관계를 결정해주는 디자인 패턴이다. 인터페이스를 사이에 두고 클래스 레벨에서 의존관계가 고정되지 않도록 한 후에 런타입 시에 관계를 동적으로 주입하여 유연성을 높이고 결합도를 낮출 수 있게 하는 것을 의미한다.
- 예시-문제점) 아래의 코드는 두가지의 문제를 가지고 있다.
→ 만약 다른 타이어를 사용하고자 할 때 Car() 클래스의 직접 수정이 필요하다.→ 구현클래스를 직접 수정해야한다.**문제점 1. 두 클래스의 결합도가 높음**
- 문제점 2. 객체들 사이의 관계가 아닌 클래스같의 관계가 맺어져 있다.
- public class Car() { private Tire kumhoTire; public Car() { this.kumhoTire = new kumhoTire(); } }
- 예시-DI수행) 그럼 스프링에서의 DI를 수행해보자.
- 먼저 Tire 인터페이스를 생성하고 그것을 구현하는 kumhoTire 구현 클래스를 만든다.
- public interface Tire { } public class kumhoTire implements Tire { }
- 그리고 Car의 생성자를 만들고 인자값으로 Tire 객체를 받도록 만든다. 이렇게 함으로써 Car에서 kumhoTire 구체 클래스의 의존성을 제거한다.
- public class Car { private Tire tire; private Car(Tire tire) { this.tire = tire; } }
- 스프링은 애플리케이션 실행 시점에서 필요한 객체(bean)을 DI 컨테이너에서 생성한다. 그리고 의존성이 있는 두 객체를 연결하기 위해 아래와 같이 한 객체를 다른 객체로 주입시킨다.
- public class BeanFactory { // Bean의 생성 Tire kumhoTire = new KumhoTire(); // 의존성 주입 Car car = new Car(kumhoTire); }
- 이러한 개념은 동시에 **제어의 역전(Inversion of Control, IOC)**라고 불린다. 왜냐하면, 어떠한 객체를 사용할지에 대한 책임을 프레임워크에 넘겼기 때문이다. 동시에 자신은 수동적으로 주입받는 객체를 사용하기 때문이다.
스프링에서 IOC (Inversion Of Control)란?
IOC는 제어의 역전, 즉 제어의 흐름을 바꾸는 것이다.
Java 프로그램에서는 각 객체들이 프로그램의 흐름을 결정하고 객체를 직접 생성하여 메소드 호출하는 방식의 작업을 했다.
사용자가 모든 작업을 제어하는 구조이다. ( A객체에서 B 객체에 있는 메소드를 사용하고 싶을 때 B 객체를 직접 A 객체 내에서 생성하고 메소드를 호출)
IOC가 적용된 경우에는 객체의 생성을 특별한 관리 위임 주체에게 맡긴다.
즉, 사용자가 객체를 직접 생성하지 않고 객체의 생성 및 소멸과 같은 생명주기에 관한 제어권을 다른 주체에게 넘긴다.
- 클래스 내부의 객체 생성 -> 의존성 객체의 메소드 호출이 아니라, 스프링에게 제어를 위임하여 스프링이 만든 객체를 주입 -> 의존성 객체의 메소드 호출 구조이다.
- 모든 의존성 객체를 스프링이 실행될 때 만들어 주고 필요한 곳에 주입한다.
Spring이 모든 의존성 객체를 Spring이 실행 될 때 다 만들어 주고 필요한 곳에 주입 시켜줌으로써 Bean들은 싱글톤 패턴의 특징을 갖습니다.
- Bean : Spring IOC 컨테이너가 관리하는 객체
참조 및 내용출처 : 블로그
Layered Architecture 란 ?
복잡한 애플리케이션을 여러 개의 계층으로 나누어 설계하고 개발하는 것 !
각 계층을 전문적으로 다룬다는 목적이 있다. 레이어드 아키텍쳐는 구성요소들이 수평적인 레이어로 조직화되어 있는 다층 구조이며, 모든 구성요소가 연결되어 있지만 독립적이라 말할 수 있다.
- Presentation Layer
클라이언트로 응답을 다시 보내는 역할을 담당하는 모든 클래스가 포함된다.
- Business Layer
시스템을 구현해야하는 로직들을 해당 레이어에서 구현하게 된다. 접근성 , 보안 , 인증 , 유효성 검사 와 같은 로직들이 해당 계층에서 발생한다.
- Persistence Layer
데이터베이스에서 데이터를 저장, 수정, 읽는 등 데이터베이스와 관련된 로직을 구현한다. DAO(Data Access Object)presentation, ORM(Object Relational Mappings) 등을 포함한다.
- Database Layer
데이터 베이스가 저장되는 레이어
특징
레이어드 아키텍쳐는 하위 계층에만 의존한다. 위 그림 계층 구조에서 비즈니스 레이어는 프레젠테이션 레이어로부터 독립적이고 , 퍼시스턴스 레이어에는 의존적이다. 그래서 하위계층의 변경에 있어서는 상위계층은 신경쓰지 않아도 되는 장점이 있다. 이 특징으로 각 계층의 역할들이 명확해지며, 개발과 테스트가 용이해진다.
Entity와 DTO란?
Entity
실제 DB 테이블과 매핑되는 핵심 클래스로, DB 테이블에 존재하는 컬럼들을 필드로 가지는 객체
DTO (Data Transfer Object)
계층간 데이터 교환이 이루어 질 수 있도록 하는 객체
Entity와 DTO를 분리하는 이유 ⇒ 관심사 분리!!
- 관심사의 분리 : Entity와 DTO를 분리해야 하는 가장 근본적인 이유는 관심사가 서로 다르기 때문! (*관심사의 분리(separation of concerns, SoC)는 소프트웨어 분야의 오래된 원칙 중 하나로써, 서로 다른 관심사들을 분리하여 변경 가능성을 최소화하고, 유연하며 확장가능한 클린 아키텍처를 구축하도록 도와줌)
- Entity의 값이 변하면 Repository 클래스의 Entity Manager의 flush가 호출될 때 DB에 값이 반영되고, 이는 다른 로직들에도 영향 미친다. View와 통신 하면서 필연적으로 데이터의 변경이 많은 DTO클래스를 분리해주어야 한다
- 도메인 설계가 아무리 잘 되있다 해도 Getter만을 이용해서 원하는 데이터를 표시하기 어려운 경우가 발생할 수 있는데, 이 경우에 Entity와 DTO가 분리되어 있지 않다면 Entity안에 Presentation을 위한 필드나 로직이 추가되게 되어 객체 설계를 망가뜨리게 된다. 때문에 이런 경우에는 분리한 DTO에 Presentation로직 정도를 추가해서 사용하고, Entity에는 추가하지 않아서 도메인 모델링을 깨뜨리지 않는다.
Singleton Pattern이란?
- 싱글톤 패턴이란 인스턴스를 1개로 제한하며 어디서든 접근 할 수 있도록하는 객체 생성 디자인 패턴이다. 싱글톤 클래스는 본인을 호출하는 static 메소드를 가지고 있으며, 이 메소드를 호출하면 본인을 반환하도록 설계된다.
- 객체 지향 프로그래밍에서는 모든 객체들은 라이프 사이클(객체가 생성되고 GC에 의해 삭제되기 까지)을 가지고 있다. 객체를 여러개 만들지 않고 1개만 만들고 공유하고 싶을 때 사용할 수 있는 패턴이 싱글톤 패턴이다. (ex. DB의 Transaction을 관리하는 클래스)
Singleton Pattern의 문제점
- 싱글톤 패턴을 구현하는 코드 자체가 많이 들어간다.
- 의존 관계 클라이언트가 추상화 클래스에 의존하는 게 아니라 구체 클래스에 의존하게 되면서 객체 지향 설계 5원징인 SOILD 중 DLP(의존관계 역전 원칙)를 위한하고 OCP(개방-폐쇄 원칙)을 위반할 가능성이 높다.
- 내부 속성을 변경하고 초기화하는게 어렵고 private 생성자로 자식 클래스를 만들기가 어렵다.
Spring에서의 Singleton Pattern
- 스프링에서는 클래스 자체에 의해서 객체를 생성하지 않고 스프링 컨테이너에 의해 구현이 된다.
- 스프링 컨테이너는 싱글톤 패턴의 문제를 해결하면서 싱글톤 패턴을 적용하지 않아도 객체의 인스턴스를 싱글톤으로 관리한다.
- 스프링의 싱글톤 레지스트리 - 싱글톤 패턴의 단점을 보완하기 위해 나온것 - 스프링 컨테이너가 싱글톤 컨테이너 역할을 하고 싱글톤 객체를 생성하고 관리하는 기능
- 스프링 컨테이너 기능 덕분에 싱글톤 패턴의 단점을 해결하면서 싱글톤으로 유지할 수 있다.
- 결국 스프링 Bean이 싱글톤으로 관리되는 Bean이다
Factory Method Pattern
- 객체 생성 처리를 서브 클래스로 분리하여 처리하도록 하는 캡슐화 패턴이다. 즉, 객체의 생성 코드를 별도의 클레스/메소드로 분리함으로써 객체 생성의 변화에 대비하여 유용하게 사용할 수 있다.
- Factory Method Pattern의 장단점
- 장점
- 비슷한 성격의 객체를 인터페이스를 통해 하나로 관리할 수 있다. (코드가 간결해진다.)
- 비슷한 유형의 객체가 생성되어도 implement를 통해 쉽게 추가할 수 있다.
- 단점
- 제품 클래스가 바뀔 때 마다 새로운 서브 클래스를 작성해야 한다.
- 클래스가 많아지기 때문에 클래스 계층도 커질 수 있다.
- 장점
Factory Method Pattern의 구조
- Product는 인터페이스를 선언한다. 인터페이스는 생성자와 자식 클래스들이 생성할 수 있는 모든 객체에 공통이다.
- Concrete Prodect들은 제품 인터페이스의 다양한 구현들이다.
- Creator 클래스는 새로운 제품 객체들을 반환하는 Factory Method를 선언한다. 이 때 Factory Method의 반환 유형이 Product 인터페이스와 일치해야한다.
- ConcreteCreator들은 기초 Factory Method를 오버라이드(재정의)하여 다른 유형의 Product를 반환하게 하도록 한다.
- Factory Method는 항상 새로운 인스턴스를 생성해야 할 필요가 없다. 기존 객체들을 캐시, 객체 풀 또는 다른 소스로부터 반환할 수 있다.
Proxy Pattern
- 어떤 객체에 대한 접근을 제어하기 위한 용도로, 실제 객체의 메소드를 호출하면 그 호출을 중간에 가로채는 패턴이다.
- 즉, 제어 흐름을 조정하기 위해 중간에 대리자를 두는 패턴
- 스프링에서는 AOP를 통해서 이런 공통적인 기능들을 별도로 분리해 필요한 곳에서 재사용이 가능
- AOP(Aspect Oriented Programming)이란?
- 관점 지향 프로그래밍 - 공통 기능과 핵심 기능을 분리시켜 공통 기능을 계속 재활용하여 사용하는 방식 (main기능이 아닌 기능(Logging/Transcation)을 묶음으로 하여 Main 기능을 잘 구성할 수 있게 해주는 방식)
Proxy Pattern의 구조
- Client가 해당 함수를 직접 호출하는 것이 아닌 Proxy를 호출한다.
- Proxy Class에서 실제 Class를 호출한다.( Proxy Class는 실제로 호출할 Class를 이미 가지고 있다.
- 실제 Class에서 반환 받은 값을 Client에게 반환한다.
- Proxy Pattern의 장단점
- 장점
- 사이즈가 큰 객체가 로딩되기 전에도 proxy를 통해 참조를 할 수 있다.(이미지, 동영상 등의 로딩에서 반응성 혹은 성능 향상 - 가상 프록시)
- 실제 객체의 public, protected 메소드들을 숨기고 인터페이스를 통해 노출시킬 수 있다.( 안정성 - 보호 프록시 )
- 로컬에 있지 않고 떨어져 있는 객체를 사용할 수 있다. (RMI, EJB 의 분산처리 등 - 원격 프록시)
- 원래 객체의 접근에 대해서 사전처리를 할 수 있다. (객체의 레퍼런스 카운트 처리 - 스마트 프록시 )
- 원본 객체의 참조만 필요할 때는 원본 객체를 사용하다가, 최대한 늦게 복사가 필요한 시점에 원본 객체를 복사하여 사용한다. (Concurrent package의 CopyInWriteArrayList - 변형된 가상 프록시)
- 단점
- 객체를 생성할 때 한단계를 거치게 되므로, 빈번한 객체 생성이 필요한 경우 성능이 저하될 수있다.
- 프록시 안에서 실제 객체 생성을 위해서 thread가 생성되고 동기화가 구현되야하는 경우 서능이 저하되고 로직이 난해해질 수 있다.
- 장점
'TIL' 카테고리의 다른 글
TIL JPA 심화 영속성 컨텍스트 @Enumerated (feat. 꿈에서도 코딩)221202 (0) | 2022.12.03 |
---|---|
TIL 자바 백엔드 공부 로드맵 (feat. 11월 회고) 221201 (0) | 2022.12.01 |
TIL Spring boot 1주차 개인 과제 CRUD Postman JPA 221129 (0) | 2022.11.30 |
TIL H2 Console JPA 기초 상속을 사용해서 생성 수정 시간 관리 221128 (0) | 2022.11.28 |
TIL/WIL 부트캠프 2주차 회고 221127 (1) | 2022.11.27 |