Skip to content

SpringBoot, Java, MySql, 인프런 스터디 클럽 BE 0기 레포지토리 미니프로젝트 저장소

Notifications You must be signed in to change notification settings

nakyeonko3/Inflearn_BE0_Study_mini

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Inflearn_BE0_Study_mini 직원 관리 API

  • 인프런 스터디 클럽 BE 0기 레포지토리 미니프로젝트 저장소
  • 간단한 직원 등록, 조회, 삭제, 업데이트 기능을 갖춘 CRUD restful 구현

목차

실행 방법

  1. 프로젝트를 클론
git clone https://github.com/backgom1/Inflearn_BE0_Study_mini.git
  1. 프로젝트 디렉토리로 이동
cd Inflearn_BE0_Study_mini
  1. 의존성을 설치합니다.
./gradlew build
  1. 서버를 실행합니다.
./gradlew bootRun
  1. 브라우저에서 다음 URL로 접속합니다.
    http://localhost:8080

요구사항

  • 1. 직원 등록 기능
  • 2. 팀 등록 기능
  • 3. 팀 조회 기능
  • 4. 직원 조회 기능
  • 5. 등록된 직원의 팀 등록 기능

개발 스펙

소스코드 링크

프로젝트 기능별 설명

해당 프로그램의 각 기능들은 아래의 방식으로 설명한다.

  • 기능: 해당 개발 프로젝트가 수행해야 되는 기능에 대해 상세히 설명함.
  • 필수 입력 데이터: 해당 기능을 사용하기 위해서 반드시 입력되어야 하는 데이터를 말함.
  • CASE: 각 기능들의 유효성 처리, 특정 조건, 예외 상황 발생 시 조치 등을 적었다. 한걸음 더 부분에 해당

ERD

ERD는 다음과 같다.

직원과 팀은 N:1 관계이다. 팀 하나에 팀이 여러명이 있을 수 있다.

employee테이블과 team테이블을 생성하는 ddl문을 작성했다.

해당 테이블들의 특징은 크게 두 가지가 있다.

  1. not null: work_start_date를 제외한 모든 프로퍼티를 not null로 처리해서 db에 들어갈 데이터가 누락되지 않게 했다. 이를 통해 DB 자체에서도 유효성 검사를 할 수 있도록 했다.

  2. unique key: 팀이름을 unique key로 지정해서 팀 이름이 중복 되서 들어가지 않게 했다

1. 직원 등록 기능

기능

  • 직원을 등록 할 수 있어야 한다.
  • 같은 이름을 가진 직원 등록을 허용한다.
  • 필수 입력 데이터: 직원 이름(name), 직무(role), 회사에 들어온 날짜(workStartDate), 생일(birthday), 직원 아이디(id)

CASE

  • 해당 기능 수행 시 필수 정보가 전부 다 등록 되지 않으면 다시 등록 절차를 수행한다.

처음에 동일한 이름이 등록되는 것을 막기 위해 경고 메시지를 출력하려 했지만, 다른 스터디원의 피드백을 듣고 지나치게 과한 처리라고 생각하고 삭제 했다.


- 한국에서 동명이인만 해도 수십명이 되는 경우가 있다.

  • 직무(role)은 MANAGERMANAGER 외의 다른 문자열 입력을 허용하지 않는다. 매니저와 직원은 직무 외의 다른 직무 등록은 허용하지 않는다.

    이 부분은 Role Enum 클래스에 MANAGERMANAGER 만 등록 해둬서 다른 문자열 입력은 받지 않도록 했다.

2-1. 팀 등록 기능

기능

  • 팀을 등록 할 수 있는 기능
  • 필수 입력 데이터: 팀 이름(name)

CASE

  • 해당 기능 수행 시 필수 정보가 전부 다 등록 되지 않으면 다시 등록 절차를 수행한다.
  • 한 번에 1개의 팀을 등록 가능, 한 번에 2개의 팀을 등록 할 수 없다.
  • 팀 이름은 중복 될 수 없다. 같은 이름의 팀 등록시 오류 메시지를 출력한다.

상세 구현

팀 엔티티와 팀 컨트롤러, 팀 서비스, 팀 리포지토리 클래스를 각각 만들어준다.

팀 등록 기능 구현시 팀 이름만 입력 받으면 되서 DTO는 만들지 않았다.

컨트롤러에서 팀 이름을 받고 서비스에서 팀 이름을 도메인을 가지고 리포지토리에 전달하도록 했다.

2-2. 직원의 팀 등록 기능

기능

  • 직원이 처음에 팀을 등록하지 않기 때문에 등록된 기능이 팀을 등록할 수 있도록 이 기능을 만들었다.
  • 등록된 직원이 팀을 등록할 수 있는 기능이다.
  • 필수 입력 데이터: 팀 이름(name), 직원(id)

CASE

  • 해당 기능 수행 시 필수 정보가 전부 다 등록 되지 않으면 다시 등록 절차를 수행한다.
  • 한 번에 1개의 직원을 등록 가능, 한 번에 2명의 직원을 등록 할 수 없다.
  • 입력된 직원 아이디를 검색하고 검색 결과가 없다면 오류 메시지를 출력한다. 등록되지 않은 직원의 등록을 허용하지 않는다.
  • 팀 이름을 검색하고 검색 결과가 없다면 오류 메시지를 출력한다. 등록되지 않은 팀의 등록을 허용하지 않는다.

3. 팀 조회 기능

기능

  • 모든 팀 조회 기능
  • 필수 입력 데이터: 없음
  • 조회 데이터에는 팀이름(name), 매니저 이름(manager), 팀 인원수(memberCount)가 명시되어야함

CASE

  • 모든 팀의 정보를 한 번에 조회 할 수 있어야 한다.
  • 특정 입력 데이터 없이도 팀 조회 기능 사용 가능하다.
  • 팀 매니저 명은 누락될 수 있다. 특정 팀은 팀명만 등록되고 매니저 명은 등록되지 않을 수 있다.
  • 팀 인원수 변수는 만들었다가 제거했다. 이유는 sql 쿼리문 count를 이용해서 충분히 팀 인원수를 구할 수 있다.
  • 한 팀 당 다수의 매니저가 존재 할 수도 있다. 매니저의 숫자는 명시 되지 않았다.

4. 직원 조회 기능

기능

  • 모든 직원의 정보를 한 번에 조회할 수 있어야 함.

  • 조건 없이 직원 정보를 전체를 조회 할 수 있음.

  • 필수 입력 데이터: 없음

  • 조회 된 데이터에는 직원 이름( name), 매니저명(manager), 직무(role), 생일(birthday), 회사에 들어온 날짜(workStartDate) 가 명시 되어야 한다.

CASE

  • 모든 직원의 정보를 한 번에 조회 할 수 있어야 한다.
  • 특정 입력 데이터 없이도 직원 조회 기능 사용 가능하다.
  • 직원 아이디를 이용해 조회해야 한다. 직원 이름은 동일한 이름이 여러 개 존재할 수 있다.

프로젝트 개선 사항

  • API 문서화 필요

  • count 함수를 이용해서 팀 인원수를 구할 수 있으니, 팀 인원 수를 DB에 굳이 저장을 할 필요가 없다.

  • 생일(birthday) 부분은은 dateime을 쓰기 보다는 date를 쓰는 것을 추천한다.

  • sql은 snake case로 작성 하는 걸 추천함  user_login_log

  • url은 케밥 케이스로 작성하는 걸 추천한다.  user-login-log

  • 동명이인에 대한 검사는 이메일이나 email이나 주민번호 같은 것으로 검사하는 것이 좋다.

  • 미국은 최소 수십명의 동명이인이 존재한다. 동명이인이 입력 될 때 마다 동일한 이름이 입력될 때 마다 경고 메시지를 보내는 것은 과하다.

  • 생각해보면 email이나 주민번호로 아이디 중복을 막는 것이 좋다.

  • 같은 팀이름이 중복되서 등록되지 않도록, Mysql에서 테이블에 팀이름 필드에 unique key제약 조건을 걸어주는 것이 괜찮을까? 아니면 Spring에서 service 레이어에서 팀이름 중복을 검사하는 것이 좋을까?

  • 서비스 클래스에서 읽기 전용 메서드는 트랜잭션을 @Transaction(readOnly=True)로 바꾸는 것이 좋다.

  • readOnly=True로 지정하여 읽기 전용 메서드로 지정되면 jpa에서 변경감지, 스냅샷 저장을 하지 않는다. 메모리상 성능 이점을 크게 누릴 수 있다.

트러블 슈팅 기록

Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource. ambiguous mapping. Cannot map method

동일한 url을 가진 레스트컨트롤러 메서드가 존재하면 이런 에러가 난다.


.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Ambiguous mapping. Cannot map 'employeeController' method
com.group.companytimeclockapp.controller.EmployeeController#saveEmployee(EmployeeSaveRequest)
to {POST [/employee]}: There is already 'employeeController' bean method

Error: creating bean with name 'requestMappingHandlerMapping' defined in class path resource.

아래 메시지는 스프링 빈에서requestMappingHandlerMapping 를 생성하는 중에 에러가 발생했다는 뜻이다.

아래 에러 로그 영문을 해석 해보면 employeeController가 {POST [/employee]} 에 매핑된 메서드가 존재한다는 뜻이다.

같은 uri 주소를 가지는 메서드가 2개 이상 존재하기 때문에 이런 오류가 난 것이다. `


.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Ambiguous mapping. Cannot map 'employeeController' method
com.group.companytimeclockapp.controller.EmployeeController#saveEmployee(EmployeeSaveRequest)
to {POST [/employee]}: There is already 'employeeController' bean method

에러 메시지를 확인하고 바로 어디서 에러가 났는지 확인 할 수 있었기 때문에 큰 문제가 아니였다.

RequestMappingHandlerMapping 은 스프링 웹 MVC 프레임워크 코드의 일부로 @Controller 클래스 안에 정의된 @RequestMapping 어노테이션을 인스턴스로 생성하는 클래스이다.

참고 자료

About

SpringBoot, Java, MySql, 인프런 스터디 클럽 BE 0기 레포지토리 미니프로젝트 저장소

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 100.0%