[Spring]Entity,DTO,DAO 개념정리

윤재열·2022년 2월 11일
0

Spring

목록 보기
20/72
post-custom-banner

DAO란?

repository package

  • 실제로 DB에 접근하는 객체이다.
    -Persistence Layer(DB에 data를 CRUD하는 계층)입니다.
  • Service와 DB를 연결하는 고리의 역할을 합니다.
  • SQL을 사용(개발자가 직접 코딩)하여 DB에 접근한 후 적절한 CRUD API를 제공한다.
    -JPA 대부분의 기볹거인 CRUD 메서드를 제공하고 있습니다.
    -extends JpaRepository<User,Long>
  • 예시(JPA 사용시)
public interface QuestionRepository extends CrudRepository<Question,Long>{
}

DTO(Data Transfer Object)란?

dto package

계층간 데이터 교환을 위한 객체(Java Beans)입니다.

  • 즉, DB에서 데이터를 얻어 Service나 Controller 등으로 보낼 때 사용하는 객체를 말합니다.
  • 로직을 갖고 있지 않는 순수한 데이터 이며, getter/setter 메서드 만을 갖습니다.
  • 하지만 DB에서 꺼낸 값을 임의로 변경할 필요가 없기 때문에 DTO클래스에는 setter가 없다.(대신 생성자에서 값을 할당한다.)

Request와 Response용 DTO는 View를 위한 클래스

  • 자주 변경이 필요한 클래스
  • Presentation Model
  • toEntity()메서드를 통해서 DTO에서 필요한 부분을 이용하여 Entity를 만든다.
  • 또한 Controller Layer에서 Reponse DTO 형태로 Client에 전달한다.

예시

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class UserDto {
  @NotBlank
  @Pattern(regexp = "^([\\w-]+(?:\\.[\\w-]+)*)@((?:[\\w-]+\\.)*\\w[\\w-]{0,66})\\.([a-z]{2,6}(?:\\.[a-z]{2})?)$")
  private String email;

  @JsonIgnore
  @NotBlank
  @Size(min = 4, max = 15)
  private String password;

  @NotBlank
  @Size(min = 6, max = 10)
  private String name;

  public User toEntity() {
      return new User(email, password, name);
  }

  public User toEntityWithPasswordEncode(PasswordEncoder bCryptPasswordEncoder) {
      return new User(email, bCryptPasswordEncoder.encode(password), name);
  }
}
https://gmlwjd9405.github.io/2018/12/25/difference-dao-dto-entity.html

Entity class 란?

domain package

실제 DB의 테이블관 매칭도리 클래스

  • 즉, 테이블의 링크도리 클래스임을 나타낸다.
  • Entity클래스 또는 가장 Core한 클래스라고 부릅니다.
  • @Entity, @Column, @Id 등을 이용

최대한 외부에서 Entity클래스의 getter 메서드를 사용하지 않도록 해당 클래스 안에서 필요한 로직 메서드를 구현합니다.

  • 단, Domain Logic만 가지고 있어야 하고 Presentation Logic을 가지고 있어서는 안됩니다.
  • 여기서 구현한 메서드는 주로 Service Layer에서 사용합니다.

Entity클래스와 DTO 클래스를 분리하는 이유

  • View Layer와 DB Layer의 역할을 철저하게 분리하기 위해서 분리합니다.
  • 테이블과 매핑되는 Entity클래스가 변경되면 여러 클래스의 영향을 끼치게 되는 반면 View와 통신하는 DTO클래스(Request/Response 클래스)는 자주 변경되므로 분리해야 합니다.
  • Domain Model을 아무리 잘 설계했다고 하더라도 각 View내에서 Domain Model의 getter만을 이용해서 원하는 정보를 표시하기가 어려운 경우가 종종 있습니다. 이런 경우 Domain Model내에 Presentation을 위한 필드나 로직을 추가하게 되는데, 이러한 방식이 모델링의 순수성을 깨고 Domain Model 객체를 망가뜨리게 됩니다.
  • 또한 Domain Model을 복합하게 조합한 형태의 Presentation 요구사항들이 있기 떄문에 Domain Model객체를 망가뜨리게 됩니다.
  • 즉 DTO는 Domain Model을 복사한 형태로, 다양한 Presentation Logic을 추가한 정도로 사용하며 Domain Model 객체는 Persistent만을 위해서 사용합니다.
    -예시
@Entity
@Getter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class User implements Serializable {
  private static final long serialVersionUID = 7342736640368461848L;

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @JsonProperty
  private Long id;

  @Column(nullable = false)
  @JsonProperty
  private String email;

  @Column(nullable = false)
  @JsonIgnore
  private String password;

  // @Override 
  // public boolean equals(Object o) { ... }
  // @Override
  // public int hashCode() { ... }
  // @Override
  // public String toString() { ... }
https://gmlwjd9405.github.io/2018/12/25/difference-dao-dto-entity.html

전체구조(package기준)

controller(web)

기능

  • 해당 요청 url에 따라 적절한 view 와 mapping처리
  • @Autowired Service를 통해 service의 메서드를 이용
  • 적절한 RepositoryEntity(DTO)를 body에 담아 Client에 반환합니다.
  • 예시1
@Controller
@RequestMapping("/")
public class HomeController {
  @GetMapping
  public String home(HttpSession session) {
      if (!SessionUtil.getUser(session).isPresent()) {
          return "login";
      }
      return "index";
  }
}
https://gmlwjd9405.github.io/2018/12/25/difference-dao-dto-entity.html
  • @Controller
    -API와 view를 도잇에 사용하는 경우에 사용
    -대신 API서비스로 사용하는 경우는 @ResponseBody를 사용하여 객체를 반환합니다.
    -view(화면) return이 주목적입니다.

  • 예시2

@RestController
@RequestMapping("/api/users")
public class ApiUserController {
  @Autowired
  private UserService userService;

  @PostMapping("/login")
  public ResponseEntity login(@RequestBody @Valid LoginDto loginDto, HttpSession session) {
      SessionUtil.setUser(session, userService.login(loginDto));
      return new ResponseEntity(HttpStatus.OK);
  }
}
https://gmlwjd9405.github.io/2018/12/25/difference-dao-dto-entity.html
  • @RestController
    -view가 필요없는 API만 지원하는 서비스에서 사용합니다.
    -@RequesMapping 어노테이션이 기본적으로 @ResponseBody 의미를 가정합니다.
    -data(json, xml 등) return이 주목적 return ResponseEntity
    -즉, @RestController = @Controller + @ResponseBody

service

기능

  • @AUtowired Repository를 통해 repository의 메서드를 이용합니다..
  • 적절한 비지니스 로직을 처리합니다.
  • DAO로 DB에 접근하고 DTO로 데이터를 전달 받은 다음, 비지니스 로직을 처리해 데이터를 반환합니다.
  • 예시
@Service
public class UserService {
  @Autowired
  private UserRepository userRepository;
  @Resource(name = "bCryptPasswordEncoder")
  private PasswordEncoder bCryptPasswordEncoder;
  @Autowired
  private MessageSourceAccessor msa;

  public User save(UserDto userDto) {
      if (isExistUser(userDto.getEmail())) {
          throw new UserDuplicatedException(msa.getMessage("email.duplicate.message"));
      }
      return userRepository.save(userDto.toEntityWithPasswordEncode(bCryptPasswordEncoder);
  }
}
https://gmlwjd9405.github.io/2018/12/25/difference-dao-dto-entity.html

repository(Dao)

기능

  • 실제로 DB에 접근하는 객체입니다.
  • Service와 DB를 연결하는 고리의 역할을 합니다.
  • SQL를 사용하여 DB에 접근한 후 적절한 CRUD API를 제공합니다.
profile
블로그 이전합니다! https://jyyoun1022.tistory.com/
post-custom-banner

0개의 댓글