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;
}
}
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를 주입 받아 사용하는 방법을 사용하여
내가 원하던 기능을 구현할 수 있었다.
이게 맞는 것인지 잘 모르겠고 아직 트랜잭션에 대한 개념이 확실하지 않아 조금 더 공부한 뒤
만들어본 코드를 다듬어 보아야겠다.
잘못된 부분 부족한 부분이 있다면 편하게 댓글로 남겨주세요☺️
강의 링크 👉 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
'개발 > 인프런 워밍업 스터디' 카테고리의 다른 글
[인프런 워밍업 클럽 0기 BE] 오프라인 수료식 후기 (1) | 2024.03.17 |
---|---|
[인프런 워밍업 클럽 0기 BE] 3주차 발자국 (0) | 2024.03.10 |
[인프런 워밍업 클럽 0기 BE] 2주차 발자국 (0) | 2024.03.03 |
[인프런 워밍업 클럽 0기 BE] 7일차 - JPA (1) | 2024.02.27 |
[인프런 워밍업 클럽 0기 BE] 6일차 - Controller - Service - Repository (0) | 2024.02.26 |