Develop

29일차_Spring-MyBatis 초기 설정 본문

백엔드/KDT_Programmers

29일차_Spring-MyBatis 초기 설정

230801 2025. 4. 12. 03:42

안녕하세요!

오늘은 데브코스 29일차(6주 5일차) 입니다

 

오늘은 스프링+마이바티스로 DB 관리를 위해 초기 셋팅을 실시했습니당

 

  • pom.xml 에 의존성 추가
  • application.properties에 DB 접속 정보 및 마이바티스 설정 작성
  • ResourceDatabasePopulator를 활용해 Bean 으로 DB 초기데이터 생성자 주입
  • Mapper Interface 와 XML 파일을 매핑하여 쿼리 구성

 


 

ResponseEntity를 활용한 REST API 응답 처리

  • ResponseEntity는 HTTP 응답을 개발자가 직접 커스터마이징할 수 있게 해주는 래퍼 클래스
  • API 응답은 상태 코드 + 사용자 메시지 형태로 전달하는 걸 권장함
  • 용도
    • 프론트에서 응답 받을 때 일관된 구조를 보장해줌
    • 필요하면 상태코드도 자유롭게 변경 가능
    @PostMapping("upload")
        public ResponseEntity<ApiResponse<?>> upload(
            @Valid MultipartForm form) {
            log.info("multiPartFile : {} ", form.files()
            );
    
            multipartService.upload(form);
            return ResponseEntity.ok(ApiResponse.noContent());
        }
    

 

 

ResponseCode 클래스

  • 사용자에게 보여줄 메시지를 포함한 응답 코드 정의용 DTO
  • API 성공/실패 여부 및 클라이언트 메시지를 직관적으로 전달 가능
public enum ResponseCode {
    OK("0000", HttpStatus.OK, "정상적으로 완료되었습니다."),
    BAD_REQUEST("4000", HttpStatus.BAD_REQUEST, "잘못된 요청입니다."),
    UNAUTHORIZED("4001", HttpStatus.UNAUTHORIZED, "권한이 없습니다."),
    INTERNAL_SERVER_ERROR("5000", HttpStatus.INTERNAL_SERVER_ERROR, "서버에러 입니다.");
...
}

 

 

유효성 검사 & 예외 처리 흐름

  • Spring의 @RestControllerAdvice를 활용해 전역 예외 처리 설정
  • 각 컨트롤러 영역에 따라 Advice를 다르게 지정할 수 있함
@RestControllerAdvice(basePackages = "com.grepp.spring.app.controller.api")
public class ApiExceptionHandler {
    // API용 예외 처리
}

@ControllerAdvice(basePackages = "com.grepp.spring.app.controller.web")
public class WebExceptionHandler {
    // Web용 예외 처리
}

 

 

Bean Validation 에러 메시지 커스터마이징

  • 예외 발생 시 BindingResult.getFieldErrors()를 사용하면 필드별 에러 정보를 추출할 수 있함
  • getAllErrors()로 전체 에러 메시지도 가져올 수 있지만, 상세 처리는 getFieldErrors() 추천!
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError error : fieldErrors) {
    Systemout.println(error.getField() + ": " + error.getDefaultMessage());
}

 

기타 - 예외 처리

  • 각 예외는 한 번만 처리됨 (웹/REST 예외 중 하나만 수행됨)
  • AOP 관점에서 포인트컷 지정으로 URL 또는 패키지 단위로 예외 적용 범위 제어 가능

파일 업로드 (Multipart)

 

설정

<bean class="org.springframework.web.multipart.support.StandardServletMultipartResolver"
      id="multipartResolver"/>

 

구현 포인트

  • MultipartFile.transferTo()로 파일을 서버에 저장
  • 날짜별 폴더로 저장 경로 분리
  • 파일 이름은 UUID로 재명명 → 중복 걱정 없음
String uuid = UUIDrandomUUID()toString();
String savedName = uuid + "_" + originalFilename;

 

기타

  • 파일은 외부 디렉토리에 저장해야 안전 (내부에 저장하면 배포 때마다 날아감)
  • 경로는 하드코딩 X → ServletContext, 환경변수(Property Placeholder) 활용
  • @PropertySource 또는 application.properties 외부화하여 재시작만으로 설정 변경 가능

데이터베이스 연결 (MyBatis + HikariCP)

 

기본 개념

  • DataSource는 자바에서 제일 많이 쓰는 커넥션 풀 라이브러리인 히카리(HikariCP)를 사용함
  • 우리가 직접 JDBC 연결하듯, 커넥션을 직접 관리하지 않고 Hikari가 대신 처리
  • 용도
    • DB 랑 연결을 최대한 빠르고 효율적으로 하게 도와줌 -> 연결/해제하는 비용을 줄여줌
    • application.properties에서 datasource 를 설정해놓으면 HikariDataSource가 자동 주입됨
@Bean
public DataSource dataSource() {
    HikariDataSource ds = new HikariDataSource();
    ds.setJdbcUrl("jdbc:mysql://localhost:3306/db");
    ds.setUsername("user");
    ds.setPassword("password");
    return ds;
}

 

주의 사항

  • MySQL 커넥션과 충돌이 일어날 수 있어, 서버 종료 전 안전하게 자원 해제 필요
  • 이를 위해 @PreDestroy 어노테이션 사용
@PreDestroy
public void close() {
    if (dataSource != null) {
        ((HikariDataSource) dataSource).close();
    }
}

DB 초기화

  • ResourceDatabasePopulator를 활용하면 SQL 스크립트를 읽어 DB 초기화 가능
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(new ClassPathResource("schema.sql"));
DatabasePopulatorUtilsexecute(populator, dataSource);

 

 

오늘도 수고하셨습니다.