반응형

1. 직원등록 기능

직원등록 기능

1. 직원이름 ,매니저인지 아닌지여부 ,입사일자 ,생일을 파라미터로 받는다.

 

예외처리

1. 각 파라미터 요소들은 값을 필수로 넣어주어야한다.

 

DTO

@Getter
public class MemberSaveRequest {
    @NotBlank
    private String name;
    @NotNull
    private Boolean isManager;
    @NotNull
    private LocalDate startDate;
    @NotNull
    private LocalDate birthDay;
}

Controller

@RestController
@RequestMapping("/member")
@RequiredArgsConstructor
public class MemberController {

    private final MemberService service;

    @PostMapping
    public void saveMember(@Valid @RequestBody MemberSaveRequest request) {
        service.saveMember(request);
    }
}

Service

@Service
@RequiredArgsConstructor
public class MemberService {

    private final MemberRepository repository;

    @Transactional
    public void saveMember(MemberSaveRequest request) {
        repository.save(new Employee(request));
    }
}

repository

public interface MemberRepository extends JpaRepository<Employee,Long> {
    Employee findByName(String name);
}

Entity객체

@Entity
@Getter
@NoArgsConstructor
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToOne
    @JoinColumn(name = "position_id")
    private Position position; // 직급
    
    private Boolean isManager;//직책

    @ManyToOne
    @JoinColumn(name = "team_id")
    private Team team;

    @OneToMany(mappedBy = "employee")
    private List<CommuteHistory> commuteHistories;

    @OneToMany(mappedBy = "employee")
    private List<AnnualLeaveRegister> annualLeaveRegisters;

    private LocalDate startDate;
    private LocalDate birthDay;

    public Employee(MemberSaveRequest request) {
        this.name = request.getName();
        this.startDate = request.getStartDate();
        this.birthDay = request.getBirthDay();
        this.isManager = request.getIsManager();
    }
}

 

에러핸들러

@RestControllerAdvice
public class commuteServiceException {

    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<String> illegalArgumentExceptionHandle(IllegalArgumentException e) {
        return ResponseEntity.badRequest().body("error : " + e.getMessage());
    }
	
    //Valid에서 발생시키는 에러를 처리.
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        Map<String, String> errors = new HashMap<>();
        e.getBindingResult().getAllErrors()
                .forEach(c -> errors.put(((FieldError) c).getField(), c.getDefaultMessage()));
        return ResponseEntity.badRequest().body(errors);
    }

}

빈값을 보내면 에러가 발생

 

 

 

요청을 보낸대로 잘 등록된걸 확인할수있다.

요청에서 이름 , 직책여부, 입사일, 생일 데이터만을 보내줬기때문에

나머지 필드는 null이 되어있다.

이 값들은 따로 지정해줄수있도록 만들어주었다.

//DTO
@Getter
public class MemberPositionSetDto {
    private String employeeName;
    private Long positionId;
}

@Getter
public class MemberTeamSetDto {
    private String employeeName;
    private Integer teamId;
}

//Service
@Transactional
public void setTeam(MemberTeamSetDto request) {
    Employee target = repository.findByName(request.getEmployeeName());
    Team team = teamRepository.findById(Long.valueOf(request.getTeamId()))
            .orElseThrow(IllegalArgumentException::new);
    target.setTeam(team);
}
@Transactional
public void setPosition(MemberPositionSetDto request) {
    Employee employee = repository.findByName(request.getEmployeeName());
    Team team = teamRepository.findById(request.getPositionId())
            .orElseThrow(IllegalArgumentException::new);
    employee.setTeam(team);
}

//Controller
    @PostMapping("/setTeam")
    public void setTeam(@RequestBody MemberTeamSetDto request) {
        service.setTeam(request);
    }

    @PostMapping("/setPosition")
    public void setPosition(@RequestBody MemberPositionSetDto request){service.setPosition(request);}

이 기능도 나중에 프론트가 생긴다면 조회한 직원의 필드값들을 input태그에 하나씩 넣어주었다가

수정해서 다시 요청하도록 처리하면 2개를 하나로합쳐서 직원정보 수정으로 변경할수있을것같다.

2. 직원조회 기능

DTO

@Getter
@Setter
@NoArgsConstructor
public class EmployeeResponse {
    private String name;
    private String teamName;
    private String role;
    private String birthDay;
    private String WorkStartDate;
    public void setRole(Boolean isManager){
        if(isManager){
            this.role = "Manager";
        }else{
            this.role = "MEMBER";
        }
    }
}

 

//Controller
@GetMapping
public List<EmployeeResponse> getEmployee() {
    return service.getEmployee();
}

//Service
public List<EmployeeResponse> getEmployee() {
                return repository.findAll().stream()
                .map(result -> {
                    EmployeeResponse response = new EmployeeResponse();
                    response.setName(result.getName());
                    response.setBirthDay(String.valueOf(result.getBirthDay()));
                    response.setRole(result.getIsManager());
                    response.setTeamName(Optional.ofNullable(result.getTeam()).map(Team::getTeamName).orElse(""));
                    response.setWorkStartDate(String.valueOf(result.getStartDate()));
                    return response;
                }).collect(Collectors.toList());
        
    }

 

처음에는 이렇게 모든 직원객체를 조회해서 DTO객체인 EmployResponse로 매핑해주는 방법으로 해주었다. 

이렇게 하니 서비스계층의 메서드가 너무 길어지는 문제가 생겼다. 

그래서 중간에 List<Employee> 를 받아서 --> List<EmployResponse> 로 매핑할 클래스를 하나 만들어주었다.

@Getter
public class ListEmployeeResponse {
    private final List<EmployeeResponse> employeeResponseList;

    public ListEmployeeResponse(List<Employee> employeeList) {
        this.employeeResponseList = employeeList.stream().map(result -> {
            EmployeeResponse response = new EmployeeResponse();
            response.setName(result.getName());
            response.setBirthDay(String.valueOf(result.getBirthDay()));
            response.setRole(result.getIsManager());
            response.setTeamName(Optional.ofNullable(result.getTeam()).map(Team::getTeamName).orElse(""));
            response.setWorkStartDate(String.valueOf(result.getStartDate()));
            return response;
        }).collect(Collectors.toList());
    }
}

이 객체에서 직원리스트를 받아서 응답리스트로 매핑을한다음 필드로 가지고있게된다. 

이런걸 일급컬렉션이라고 한다고 하는데. 그냥 사용해본거라 정확한 개념은 나중에 찾아봐야할것같다.

이렇게하면 서비스계층의 뚱뚱한메서드를 한줄로 줄일수있게된다.

public List<EmployeeResponse> getEmployee() {
    return new ListEmployeeResponse(repository.findAll()).getEmployeeResponseList();
}

[

    {
        "name": "김동현",
        "teamName": "개발팀",
        "role": "Manager",
        "birthDay": "1999-01-13",
        "workStartDate": "2024-03-02"
    },
    {
        "name": "박민주",
        "teamName": "디자인",
        "role": "Manager",
        "birthDay": "1999-07-02",
        "workStartDate": "2023-02-28"
    },
    {
        "name": "방세원",
        "teamName": "개발팀",
        "role": "Manager",
        "birthDay": "1999-07-02",
        "workStartDate": "2022-01-18"
    },
    {
        "name": "김민지",
        "teamName": "",
        "role": "MEMBER",
        "birthDay": "2000-01-18",
        "workStartDate": "2023-03-19"
    }

]

 

이렇게 응답을 잘 받아왔다. 

 

1단계의 팀처리기능을 끝내고 직원의 처리기능을 마무리했다.

세세한 로직들에서 어떻게 처리해주어야할지 고민이 많았는데 우선은 큰 에러처리없이 값을 잘 넘겨주도록 해주었다. 

이번에도 하다보니 더 공부해봐야할 내용들이 많이보여서 스프링이 정말 기능이 많다고 느꼈다. 

 

알아볼내용: @Valid , 일급컬렉션

반응형

+ Recent posts