엔티티
데이터베이스의 테이블을 객체 지향 프로그래밍 언어에서 사용할 수 있도록 객체로 표현한 것을 의미. 각 엔티티는 데이터베이스 테이블의 한 행(row)를 나타내고, 테이블의 구조를 반영하는 여러 속성 (attribute)을 가진다.
사용목적
데이터베이스의 데이터를 객체로 매핑하여 애플리케이션에서 사용하기 용이하게 하는 것으로, DB와의 상호작용을 객체를 통해 직관적으로 할 수 있음.
Entity가 되기 위한 요구사항은 무엇일까?
- 기본 생성자: 엔티티 클래스는 기본 생성자가 필요하며, 이는 public 또는 protected로 선언되어야 한다.
- 필드 접근성: 모든 지속성을 가지는 필드 (데이터베이스에 저장되는 필드)는 private 또는 protected로 선언되어야하며, 이는 데이터의 캡슐화와 보안 유지에 중요

Entity에서 Setter 구조를 쓰는 것을 권장하지 않는 이유는?
- 값을 생성하는 것인지, 값을 변경하는 것인지 구분하기 어려움
- setter는 public으로 항상 접근 가능하기 때문에 의도치 않은 곳에서 값이 변경될 수 있다.
-> 생성자를 통해서 entity 값을 설정해야한다 (lombok builder 통해 설정)
DTO
- DB에서 꺼낸 데이터를 저장하는 entity를 controller와 같은 클라이언트단과 직접 마주하는 계층에 직접 전달하는 대신 DTO를 통해 데이터를 교환한다.
- DTO의 역할은 계층간 데이터 교환이 이루어질 수 있도록 하는 객체이기 때문에, 특별한 로직을 가지지 않는 순수한 객체여야한다.
- DB에서 꺼낸 값을 DTO에서 임의로 조작할 필요가 없기 때문에 DTO에서는 Setter를 만들 필요가 없고, 생성자 또는 Builder 패턴을 통해 값을 할당한다.

Entity와 DTO를 분리하는 이유
1) 관심사의 분리
- Entity: 주로 데이터베이스와 관련돤 비즈니스 개체를 표현하는 데에 사용
- DTO: 클라이언트와의 데이터 교환을 위해 사용
- 특정 작업을 수행하기 위해 필요한 데이터만 포함함
2) 유연성과 확장성
- Entity의 값이 변경되는 경우 Repository 클래스의 Entity Manager의 flush가 호출될 때, DB에 변경값이 반영된다. DTO를 이용해서 Entity의 변경으로 인한 영향을 최소화할 수 있고, 클라이언트에게 전달되는 데이터를 쉽게 조정하고 확장이 가능
3) 데이터 은닉
- Entity는 데이터베이스와 직접적으로 관련되어 있으므로, 일부 데이터는 애플리케이션의 내부에서만 사용되는 경우가 있을 수 있음. DTO를 사용하면 클라이언트에게 필요한 데이터만을 선택하여 전달하므로, 불필요한 정보 노출을 방지하고 데이터 은닉을 보장할 수 있음.
Entity와 DTO의 변환은 어디서 처리해야할까?
Controller Layer에서 변환하는 경우

장점
- Presentation Logic 분리: DTO는 주로 클라이언트에게 데이터를 전달하기 위한 용도로 사용되므로, Controller에서 DTO와의 변환 작업을 수행하면 Presentation Logic을 Controller 내부로 격리시킬 수 있음
- Controller 레벨에서의 유효성 검사: Controller에서 DTO의 변환 과정을 수행하면서 유효성 검사를 수행할 수 있음
- Service의 독립성 유지: Service 레이어에서 Entity에만 의존하고 DTO 변환 작업을 수행하지 않으면, Service 레이어의 독립성과 재사용성으 높아짐
단점
- 반복적인 작업: DTO와 Entity간의 변환 작업은 여러 Controller 메소드에서 반복적으로 수행되어 코드 중복이 발생
* 비즈니스 로직과 혼재: DTO와의 변환 작업을 Controller에서 수행하면, 비즈니스 로직과 DTO 변환 로직이 혼재되어 코드의 가독성과 유지보수성이 저하됨
Service Layer에서 변환하는 경우
장점
- 단일 장소에서 변환 작업 관리: Service는 비즈니스 로직을 관리하는 곳이므로, DTO와 Entity간의 변환 작업을 Service 내에서 수행하면 변환 자겅ㅂ을 단일한 장소에서 관리할 수 있음
- 코드 중복 감소: Service 내에서 DTO와 Entity간의 변환 작업을 수행하면, 여러 Controller 메소드에서 동일한 변환 작업을 반복할 필요가 없음
- 비즈니스 로직과 분리: DTO와의 변환 작업을 Service에서 수행하면, 비즈니스 로직과 변환 로직을 분리하여 코드를 관리할 수 있음
단점
- Service의 복잡도 증가: Service에 변환 작업까지 포함되면 역할이 복잡해질 수 있음
- 코드 재사용성 하락: Service에서 특정 DTO에 의존하게 되면 여러 종류의 Controller에서 해당 Service를 이용할 수 없어 코드 재사용성이 떨어지게 됨
참고: https://velog.io/@smc2315/DTO-Entity-%EB%B3%80%ED%99%98-%EB%A9%94%EC%84%9C%EB%93%9C-%EA%B5%AC%ED%98%84-%EC%9C%84%EC%B9%98%EB%8A%94-%EC%96%B4%EB%94%94%EA%B0%80-%EC%A2%8B%EC%9D%84%EA%B9%8C
https://velog.io/@smc2315/DTO-Entity-%EB%B3%80%ED%99%98-%EB%A9%94%EC%84%9C%EB%93%9C-%EA%B5%AC%ED%98%84-%EC%9C%84%EC%B9%98%EB%8A%94-%EC%96%B4%EB%94%94%EA%B0%80-%EC%A2%8B%EC%9D%84%EA%B9%8C