본문 바로가기
[패스트캠퍼스] Spring

패스트캠퍼스 챌린지 28일차

by 엑츄얼리 2022. 2. 20.

Part 1. Spring Framework

 Ch 03. 예제를 만들며 이해하는 스프링 웹 어플리케이션 핵심 기술

  12. Developer Delete(삭제), 트랜잭션 실무 개발

   

package com.fastcampus.programmin.dmaker.service;

import com.fastcampus.programmin.dmaker.Repository.DeveloperRepository;
import com.fastcampus.programmin.dmaker.Repository.RetiredDeveloperRepository;
import com.fastcampus.programmin.dmaker.code.StatusCode;
import com.fastcampus.programmin.dmaker.dto.CreateDeveloper;
import com.fastcampus.programmin.dmaker.dto.DeveloperDetailDto;
import com.fastcampus.programmin.dmaker.dto.DeveloperDto;
import com.fastcampus.programmin.dmaker.dto.EditDeveloper;
import com.fastcampus.programmin.dmaker.entity.Developer;
import com.fastcampus.programmin.dmaker.entity.RetiredDeveloper;
import com.fastcampus.programmin.dmaker.type.DeveloperLevel;
import exception.DMakerException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.transaction.Transactional;

import java.util.List;
import java.util.stream.Collectors;

import static exception.DMakerErrorCode.*;


@Service
@RequiredArgsConstructor
public class dMakerService {
    private final DeveloperRepository developerRepository;
    private final EntityManager em;
    private final RetiredDeveloperRepository retiredDeveloperRepository;

    @Transactional
    public CreateDeveloper.Response createDeveloper(CreateDeveloper.Request request) {
        validateCreateDeveloperRequest(request);
        //business logic start
//        Developer.DeveloperBuilder builder = Developer.builder();
//        builder.developerLevel(request.getDeveloperLevel());
//        builder.developerSkillType(request.getDeveloperSkillType());
//        builder.experienceYears(request.getExperienceYears());
//        builder.memberId(request.getMemberId());
//        builder.name(request.getName());
//        builder.age(request.getAge());
//        Developer developer = builder
//                .build();
        Developer developer = Developer.builder()
                .developerLevel(request.getDeveloperLevel())
                .developerSkillType(request.getDeveloperSkillType())
                .experienceYears(request.getExperienceYears())
                .memberId(request.getMemberId())
                .statusCode(StatusCode.EMPLOYED)
                .name(request.getName())
                .age(request.getAge())
                .build();
        /* A -> B 1만원 송금 */
        // A 계좌에서 1만원 줄임
        developerRepository.save(developer);
        // B 계좌에서 1만원 늘림림
        //developerRepository.delete(developer1);

        return CreateDeveloper.Response.fromEntity(developer);
    }

    private void validateCreateDeveloperRequest(CreateDeveloper.Request request) {
        validateDeveloperLevel(request.getDeveloperLevel(), request.getExperienceYears());

        developerRepository.findByMemberId(request.getMemberId())
                .ifPresent((developer -> {
                    throw new DMakerException(DUPLICATED_MEMBER_ID);
                }));
    }

    public List<DeveloperDto> getAllEmployedDevelopers() {

        return developerRepository.findDeveloperByStatusCodeEquals(StatusCode.EMPLOYED)
                .stream().map(DeveloperDto::fromEntity)
                .collect(Collectors.toList());
    }

    public DeveloperDetailDto getAllDeveloperDetail(String memberId) {
        return developerRepository.findByMemberId(memberId)
                .map(DeveloperDetailDto::fromEntity)
                .orElseThrow(() -> new DMakerException(NO_DEVELOPER));

    }

    @Transactional
    public DeveloperDetailDto editDeveloper(String memberId, EditDeveloper.Request request) {
        validateEditDeveloperRequest(request, memberId);
        validateDeveloperLevel(request.getDeveloperLevel(), request.getExperienceYears());

        Developer developer = developerRepository.findByMemberId(memberId).orElseThrow(
                () -> new DMakerException(NO_DEVELOPER)
        );

        developer.setDeveloperLevel(request.getDeveloperLevel());
        developer.setDeveloperSkillType(request.getDeveloperSkillType());
        developer.setExperienceYears(request.getExperienceYears());

        return DeveloperDetailDto.fromEntity(developer);
    }

    private void validateEditDeveloperRequest(EditDeveloper.Request request, String memberId) {
        validateDeveloperLevel(
                request.getDeveloperLevel(),
                request.getExperienceYears()
        );

    }

    private void validateDeveloperLevel(DeveloperLevel developerLevel, Integer experienceYears) {
        if (developerLevel == DeveloperLevel.SENIOR
                && experienceYears < 10) {
            throw new DMakerException(LEVEL_EXPERIENCE_YEARS_NOT_MATCHED);
        }
        if (developerLevel == DeveloperLevel.JUNGNior
                && (experienceYears < 4 || experienceYears > 10))
            throw new DMakerException(LEVEL_EXPERIENCE_YEARS_NOT_MATCHED);
        if (developerLevel == DeveloperLevel.JUNIOR && experienceYears > 4)
            throw new DMakerException(LEVEL_EXPERIENCE_YEARS_NOT_MATCHED);
    }

    @Transactional
    public DeveloperDetailDto deleteDeveloper(String memberId) {
        //트랜잭션 2개중 최소 1개는 성공되어야함
        //1. EMPLOYED -> RETIRED
        Developer developer = developerRepository.findByMemberId(memberId)
                .orElseThrow(() ->new DMakerException(NO_DEVELOPER));
        developer.setStatusCode(StatusCode.RETIRED);

        //2. save into RetiredDeveloper
        RetiredDeveloper retiredDeveloper = RetiredDeveloper.builder()
                .memberId(memberId)
                .name(developer.getName())
                .build();
        retiredDeveloperRepository.save(retiredDeveloper);
        return DeveloperDetailDto.fromEntity(developer);
    }
}



<DMakerService.java>

 

package com.fastcampus.programmin.dmaker.service;

import com.fastcampus.programmin.dmaker.Repository.DeveloperRepository;
import com.fastcampus.programmin.dmaker.Repository.RetiredDeveloperRepository;
import com.fastcampus.programmin.dmaker.code.StatusCode;
import com.fastcampus.programmin.dmaker.dto.CreateDeveloper;
import com.fastcampus.programmin.dmaker.dto.DeveloperDetailDto;
import com.fastcampus.programmin.dmaker.dto.DeveloperDto;
import com.fastcampus.programmin.dmaker.dto.EditDeveloper;
import com.fastcampus.programmin.dmaker.entity.Developer;
import com.fastcampus.programmin.dmaker.entity.RetiredDeveloper;
import com.fastcampus.programmin.dmaker.type.DeveloperLevel;
import exception.DMakerException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.transaction.Transactional;

import java.util.List;
import java.util.stream.Collectors;

import static exception.DMakerErrorCode.*;


@Service
@RequiredArgsConstructor
public class dMakerService {
    private final DeveloperRepository developerRepository;
    private final EntityManager em;
    private final RetiredDeveloperRepository retiredDeveloperRepository;

    @Transactional
    public CreateDeveloper.Response createDeveloper(CreateDeveloper.Request request) {
        validateCreateDeveloperRequest(request);
        //business logic start
//        Developer.DeveloperBuilder builder = Developer.builder();
//        builder.developerLevel(request.getDeveloperLevel());
//        builder.developerSkillType(request.getDeveloperSkillType());
//        builder.experienceYears(request.getExperienceYears());
//        builder.memberId(request.getMemberId());
//        builder.name(request.getName());
//        builder.age(request.getAge());
//        Developer developer = builder
//                .build();
        Developer developer = Developer.builder()
                .developerLevel(request.getDeveloperLevel())
                .developerSkillType(request.getDeveloperSkillType())
                .experienceYears(request.getExperienceYears())
                .memberId(request.getMemberId())
                .statusCode(StatusCode.EMPLOYED)
                .name(request.getName())
                .age(request.getAge())
                .build();
        /* A -> B 1만원 송금 */
        // A 계좌에서 1만원 줄임
        developerRepository.save(developer);
        // B 계좌에서 1만원 늘림림
        //developerRepository.delete(developer1);

        return CreateDeveloper.Response.fromEntity(developer);
    }

    private void validateCreateDeveloperRequest(CreateDeveloper.Request request) {
        validateDeveloperLevel(request.getDeveloperLevel(), request.getExperienceYears());

        developerRepository.findByMemberId(request.getMemberId())
                .ifPresent((developer -> {
                    throw new DMakerException(DUPLICATED_MEMBER_ID);
                }));
    }

    public List<DeveloperDto> getAllEmployedDevelopers() {

        return developerRepository.findDeveloperByStatusCodeEquals(StatusCode.EMPLOYED)
                .stream().map(DeveloperDto::fromEntity)
                .collect(Collectors.toList());
    }

    public DeveloperDetailDto getAllDeveloperDetail(String memberId) {
        return developerRepository.findByMemberId(memberId)
                .map(DeveloperDetailDto::fromEntity)
                .orElseThrow(() -> new DMakerException(NO_DEVELOPER));

    }

    @Transactional
    public DeveloperDetailDto editDeveloper(String memberId, EditDeveloper.Request request) {
        validateEditDeveloperRequest(request, memberId);
        validateDeveloperLevel(request.getDeveloperLevel(), request.getExperienceYears());

        Developer developer = developerRepository.findByMemberId(memberId).orElseThrow(
                () -> new DMakerException(NO_DEVELOPER)
        );

        developer.setDeveloperLevel(request.getDeveloperLevel());
        developer.setDeveloperSkillType(request.getDeveloperSkillType());
        developer.setExperienceYears(request.getExperienceYears());

        return DeveloperDetailDto.fromEntity(developer);
    }

    private void validateEditDeveloperRequest(EditDeveloper.Request request, String memberId) {
        validateDeveloperLevel(
                request.getDeveloperLevel(),
                request.getExperienceYears()
        );

    }

    private void validateDeveloperLevel(DeveloperLevel developerLevel, Integer experienceYears) {
        if (developerLevel == DeveloperLevel.SENIOR
                && experienceYears < 10) {
            throw new DMakerException(LEVEL_EXPERIENCE_YEARS_NOT_MATCHED);
        }
        if (developerLevel == DeveloperLevel.JUNGNior
                && (experienceYears < 4 || experienceYears > 10))
            throw new DMakerException(LEVEL_EXPERIENCE_YEARS_NOT_MATCHED);
        if (developerLevel == DeveloperLevel.JUNIOR && experienceYears > 4)
            throw new DMakerException(LEVEL_EXPERIENCE_YEARS_NOT_MATCHED);
    }

    @Transactional
    public DeveloperDetailDto deleteDeveloper(String memberId) {
        //트랜잭션 2개중 최소 1개는 성공되어야함
        //1. EMPLOYED -> RETIRED
        Developer developer = developerRepository.findByMemberId(memberId)
                .orElseThrow(() ->new DMakerException(NO_DEVELOPER));
        developer.setStatusCode(StatusCode.RETIRED);

        //2. save into RetiredDeveloper
        RetiredDeveloper retiredDeveloper = RetiredDeveloper.builder()
                .memberId(memberId)
                .name(developer.getName())
                .build();
        retiredDeveloperRepository.save(retiredDeveloper);
        return DeveloperDetailDto.fromEntity(developer);
    }
}



<RetiredDeveloper.java>

 

package com.fastcampus.programmin.dmaker.code;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum StatusCode {
    EMPLOYED("고용"),
    RETIRED("해직");

    private final String description;
}

<StatusCode.java>

 

package com.fastcampus.programmin.dmaker.controller;

import com.fastcampus.programmin.dmaker.dto.CreateDeveloper;
import com.fastcampus.programmin.dmaker.dto.DeveloperDetailDto;
import com.fastcampus.programmin.dmaker.dto.DeveloperDto;
import com.fastcampus.programmin.dmaker.dto.EditDeveloper;
import com.fastcampus.programmin.dmaker.service.dMakerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

@Slf4j
@RestController //사용자의 요청을 받아 json 형태로 응답을 반환 //ctrl + 클릭
@RequiredArgsConstructor

// DMakerController(Bean)   DMakerService(Bean)   DeveloperRepository(Bean)
//===========================Spring Application =============================
//
//


public class DMakerController {
    private final dMakerService dMakerService;

    @GetMapping("/developers") //사용자 요청이 /developers를 통해 들어온다면 (ex] GET /developers HTTP/1.1)
    public List<DeveloperDto> getALlDevelopers(){
                // GET /Developers HTTP/1.1
        log.info("GET /developers HTTP/1.1");
        return dMakerService.getAllEmployedDevelopers();
    }

    //
//    public List<DeveloperDto> getAllDevelopers() {
//        // GET /Developers HTTP/1.1
//        log.info("GET /developers HTTP/1.1");
//
//        return dMakerService.getAllDevelopers();
//        //return Arrays.asList("snow", "elsa", "Olaf");
//    }

    @GetMapping("/developer/{memberId}")
    public DeveloperDetailDto getDeveloperDetail(
            @PathVariable String memberId
    ) {
        log.info("GET /developers HTTP/1.1");

        return dMakerService.getAllDeveloperDetail(memberId);
    }

    @PostMapping("/create-developer")

    public CreateDeveloper.Response createDevelopers(
            @Valid @RequestBody CreateDeveloper.Request request
    ) {
        log.info("request : {}", request);

        return dMakerService.createDeveloper(request);

        //return Collections.singletonList("Olaf");
    }

    @PutMapping("developer/{memberId}")
    public DeveloperDetailDto editDeveloper(
            @PathVariable String memberId,
            @Valid @RequestBody EditDeveloper.Request request
            ) {
        log.info("GET /developers HTTP/1.1");

        return dMakerService.editDeveloper(memberId, request);
    }

    @DeleteMapping("/developer/{memberId}")
    public DeveloperDetailDto deleteDeveloper(
            @PathVariable String memberId
    ){
        return dMakerService.deleteDeveloper(memberId);
    }

}

<DMakerController.java>

 

-----------------------------------------------------------------------------------------------------------------------------------------

 

 

https://bit.ly/37BpXic

댓글