728x90

 

1. 팀

Table

 

Entity

@Entity
@Getter
public class Team {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @Column(nullable = false, length = 20)
    private String name;
    @Column(nullable = false, length = 20)
    private String manager;
    @Column(nullable = false)
    private long employeeCnt;

    protected Team(){}

    public Team(String name, String manager, long employeeCnt) {
        this.name = name;
        this.manager = manager;
        this.employeeCnt = employeeCnt;
    }

    public void updateEmployeeCnt() {
        this.employeeCnt++;
    }

    public void updateManager(String name) {
        this.manager = name;
    }
}

 

1

Controller

@RestController
@RequestMapping("/attendance/team")
public class TeamController {
    private final TeamService service;

    public TeamController(TeamService service) {
        this.service = service;
    }

    @PostMapping("/resister_team")
    public void resisterTeam(@RequestBody RegisterTeamRequest request) {
        service.insertTeam(request);
    }
}

 

Service

@Service
public class TeamService {

    private final TeamRepository repository;

    public TeamService(TeamRepository repository) {
        this.repository = repository;
    }

    public void insertTeam(RegisterTeamRequest request) {
        repository.findByName(request.getName()).ifPresent(team -> {
            throw new IllegalArgumentException("이미 존재하는 팀 이름입니다.");
        });

        repository.save(new Team(request.getName(), 
        request.getManager(), request.getMemberCnt()));
    }
}

 

  • RegisterTeamRequest 객체에서 팀 이름을 꺼내와 등록된 팀이 있는지 확인해준다.
  • 팀이 등록 되어 있다면 Exception을 발생시키고 없다면 새로운 팀을 만들어준다.
  • 팀 등록은 이름, 매니저, 그리고 팀 인원수를 가진 Team 객체를 생성하여 저장된다.

 

Repository

public interface TeamRepository extends JpaRepository<Team, Long> {
     Optional<Team> findByName(String name);
}

 

 

DTO

@Getter
public class RegisterTeamRequest {
    private long id;
    private String name;
    private String manager;
    private long memberCnt;

}

 

 

 

Controller

@RestController
@RequestMapping("/attendance/team")
public class TeamController {
    private final TeamService service;

    public TeamController(TeamService service) {
        this.service = service;
    }

    @GetMapping("/team")
    public List<TeamListResponse> teamList() {
        return service.selectTeamList();
    }
}

 

Service

@Service
public class TeamService {

    private final TeamRepository repository;

    public TeamService(TeamRepository repository) {
        this.repository = repository;
    }

    public List<TeamListResponse> selectTeamList() {
        return repository.findAll().stream()
                .map(team -> new TeamListResponse(team.getName(), 
                team.getManager(), team.getEmployeeCnt()))
                .collect(Collectors.toList());
    }
}
  • JPA에 findAll 메서드를 사용하여 테이블에 저장된 모든 데이터를 가져온다.
  • map()메서드는 TeamListResponse 객체로 변환해준다.
  • collect()메서드를 사용하여 원하는 데이터 타입으로 변환하여 반환해준다.

DTO

@Getter
public class TeamListResponse {
    private String name;
    private String manager;
    private long memberCnt;

    public TeamListResponse(String name, String manager, long memberCnt) {
        this.name = name;
        this.manager = manager;
        this.memberCnt = memberCnt;
    }
}

 

2. 직원

Table

 

Entity

@Entity
@Getter
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @Column(nullable = false, length = 20)
    private String name;
    @Column(nullable = false, length = 20)
    private String teamName;
    @Column(nullable = false, length = 10)
    @Enumerated(EnumType.STRING)
    private Role role;
    @Column(nullable = false)
    private LocalDate birthday;
    @Column(nullable = false)
    private LocalDate workStartDate;

    protected Employee() {}

    public Employee(String name, String teamName, Role role, 
    				LocalDate birthday, LocalDate workStartDate) {
        this.name = name;
        this.teamName = teamName;
        this.role = role;
        this.birthday = birthday;
        this.workStartDate = workStartDate;
    }
}

 

 

Controller

@RestController
@RequestMapping("/attendance/employee")
public class EmployeeController {

    private final EmployeeService service;

    public EmployeeController(EmployeeService service) {
        this.service = service;
    }

    @PostMapping("/register_employee")
    public void resisterEmployee(@RequestBody ResisterEmployeeRequest request) {
        service.insertEmployee(request);
    }
}

 

Service

@Service
public class EmployeeService {

    private final EmployeeRepository repository;
    private final TeamService teamService;

    public EmployeeService(EmployeeRepository repository, TeamService teamService) {
        this.repository = repository;
        this.teamService = teamService;
    }

    @Transactional
    public void insertEmployee(ResisterEmployeeRequest request) {
    	if (request.getRole() == null) {
            throw new IllegalArgumentException("직급을 입력해주세요.");
        }
        
        repository.findById(request.getId()).ifPresent(employee -> {
            throw new IllegalArgumentException("이미 등록된 직원입니다.");
        });

        repository.save(new Employee(request.getName(), request.getTeamName(),
                request.getRole(), request.getBirthday(), request.getWorkStartDate()));

        if (Role.MANAGER.equals(request.getRole())) {
            teamService.updateManager(request.getTeamName(), request.getName());
        }

        teamService.updateEmployeeCnt(request.getTeamName());
    }
}
  • Role이 null인지 확인하고 없다면 예외를 발생시킨다.
  • Id를 사용하여 이미 등록되어 있는 직원인지 확인한다.
  • 있다면 예외를 발생시키고 없다면 새로운 직원을 만들어준다.
  • Employee 객체를 만들어 새로운 직원을 저장한다.
  • 이때 Role이 매니저인 경우 teamService의 updateManager메서드를 실행시킨다.
  • teamService의 updateEmployeeCnt 메서드를 실행하여 해당 팀의 직원 수를 증가시킨다.

TeamService

@Service
public class TeamService {

    private final TeamRepository repository;

    public TeamService(TeamRepository repository) {
        this.repository = repository;
    }

    @Transactional
    public void updateEmployeeCnt(String teamName) {
        Team team = findTeamByName(teamName);

        team.updateEmployeeCnt();
    }

    @Transactional
    public void updateManager(String teamName, String name) {
        Team team = findTeamByName(teamName);

        team.updateManager(name);
    }

    private Team findTeamByName(String name) {
        return repository.findByName(name)
        	.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 팀 입니다."));
    }
}

 

  • findTeamByName 메서드를 사용하여 존재하는 팀 인지 확인한다.
  • 있다면 각 메서드를 실행하여 DB에 저장해준다.

Repository

public interface EmployeeRepository extends JpaRepository<Employee, Long> {
    Optional<Employee> findById(long id);
}

 

DTO

@Getter
public class ResisterEmployeeRequest {
    private long id;
    private String name;
    private String teamName;
    private Role role;
    private LocalDate birthday;
    private LocalDate workStartDate;
}

 

Controller

@RestController
@RequestMapping("/attendance/employee")
public class EmployeeController {

    private final EmployeeService service;

    public EmployeeController(EmployeeService service) {
        this.service = service;
    }

    @GetMapping("/employee_list")
    public List<EmployeeListResponse> employeeList() {
        return service.selectEmployeeList();
    }
}

 

Service

@Service
public class EmployeeService {

    private final EmployeeRepository repository;
    private final TeamService teamService;

    public EmployeeService(EmployeeRepository repository, TeamService teamService) {
        this.repository = repository;
        this.teamService = teamService;
    }

    public List<EmployeeListResponse> selectEmployeeList() {
        return repository.findAll().stream()
                .map(employee -> new EmployeeListResponse(employee.getName(), 
                	employee.getTeamName(),employee.getRole(), employee.getBirthday(), 
                    employee.getWorkStartDate()))
                .collect(Collectors.toList());
    }
}
  • JPA에 findAll 메서드를 사용하여 테이블에 저장된 모든 데이터를 가져온다.
  • map()메서드는 TeamListResponse 객체로 변환해준다.
  • collect()메서드를 사용하여 원하는 데이터 타입으로 변환하여 반환해준다.

DTO

@Getter
public class EmployeeListResponse {
    private String name;
    private String teamName;
    private Role role;
    private LocalDate birthday;
    private LocalDate workStartDate;

    public EmployeeListResponse(String name, String teamName, Role role, 
    		LocalDate birthday, LocalDate workStartDate) {
        this.name = name;
        this.teamName = teamName;
        this.role = role;
        this.birthday = birthday;
        this.workStartDate = workStartDate;
    }
}

 

github - https://github.com/ddonydev/inflearn_study

 

[정리]

JPA를 다뤄본지 얼마 되지 않아 조금 어려웠고,

계층을 어떻게 나누어야할지 모르겠어서 그냥 강사님이 강의해서 해주신 그대로 만들어 보았다.

 

직원을 등록할때 Role이 Manager인 경우 팀 테이블에 있는 Manager 컬럼에 해당 직원의 이름을 넣어주고,

등록할때 마다 직원의 수를 update해주고 싶었는데 이를 어떻게 해결해야할지 이틀을 고민하였다.

 

그래서 생각한 것이 직원을 구현하고 있는 Service에 팀 Service를 주입 받아 사용하는 방법 밖에 떠오르지 않았고,

이게 맞는 것인지 다시 고민에 빠졌다.

 

"Service에 다른 도메인 Service 호출"이라는 키워드로 검색해 보았고, 의견은 많이 갈리는 것 같았다.

Controller에 여러 서비스를 호출하여 사용하는 방법, Service는 무조건 DAO와의 의존 관계를 갖게 하는 등 여러가지 방법이 있었다.

 

하지만 나는 JPA로 사용했기 때문에 DAO에 해당하는 Mapper는 사용하지 못할 것이라고 판단하였고,

Controller에서 여러 서비스를 호출하면 트랜잭션 문제가 생긴다는 글을 보았다.

 

그래서 결국 내가 처음 생각한 Service에 팀 Service를 주입 받아 사용하는 방법을 사용하여

내가 원하던 기능을 구현할 수 있었다.

 

이게 맞는 것인지 잘 모르겠고 아직 트랜잭션에 대한 개념이 확실하지 않아 조금 더 공부한 뒤

만들어본 코드를 다듬어 보아야겠다.

 

잘못된 부분 부족한 부분이 있다면 편하게 댓글로 남겨주세요☺️

 

 

강의 링크 👉 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]

728x90

+ Recent posts