[Spring] MyBatis 기반 구조

hisungmi·2025년 7월 25일

Java-Spring

목록 보기
7/8
post-thumbnail

MyBatic

자바에서 사용하는 SQL Mapper 프레임워크

  • 직접 작성한 SQL문을 Java 객체와 매핑해줌
  • JPA처럼 자동 쿼리 생성 ❌
  • SQL 제어가 쉬워서 성능 튜닝이나 복잡한 쿼리 작성이 유리함

구조 예시

📦 controller
📦 service
📦 mapper      ← Mapper 인터페이스
📄 mapper.xml  ← 쿼리 정의
📄 VO.java     ← 결과를 담을 객체

❗️주의할 점

  • 컬럼명 정확하게!
  • XML 파일 경로와 namespace 정확하게!
  • resultType 매핑 정확하게!

Spring + MyBatic(XML Mapper 기반) 구조, VO + Impl 스타일

📦 controller
   └── UserController.java
📦 service
   ├── UserService.java        ← 인터페이스
   └── UserServiceImpl.java    ← 구현체 (Impl)
📦 dao
   ├── UserMapper.java         ← Mapper 인터페이스
   └── user-mapper.xml         ← XML Mapper
📦 vo
   └── UserVO.java             ← 값 객체 (DB와 매핑되는 필드 위주)

✅ 각 구성 요소 설명

📌 1. VO (Value Object)


public class UserVO {
    private String name;
    private String email;
    private int age;
    // getter, setter
}
  • DB 컬럼 그대로 대응
  • Entity가 없고, 이게 곧 DB와 연결되는 객체
  • Lombok 없이 getter/setter 수동으로 만들기도 함
  • 주로 XML Mapper의 결과를 담는 데 사용됨

📌 2. XML Mapper (user-mapper.xml)


<select id="getUserById" resultType="com.example.vo.UserVO">
    SELECT * FROM users WHERE id = #{id}
</select>
  • SQL을 직접 XML로 작성
  • resultType으로 VO에 매핑

📌 3. Mapper 인터페이스 (UserMapper.java)


@Mapper
public interface UserMapper {
    UserVO getUserById(Long id);
}
  • @Mapper를 붙여 MyBatis가 XML과 연결
  • 실제 구현은 없고, XML이 SQL 실행 담당

📌 4. Service + Impl


public interface UserService {
    UserVO getUser(Long id);
}

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public UserVO getUser(Long id) {
        return userMapper.getUserById(id);
    }
}
  • 인터페이스 + 구현체 (Impl)를 나눔
  • UserServiceImpl이 실제 로직 수행
  • Mapper를 주입 받아 SQL 실행

✅ 이 구조의 특징

장점단점
SQL이 명확하게 보이고 튜닝 쉬움XML 관리가 번거로움
VO가 단순하고 직관적VO와 DTO가 분리되지 않아 역할이 불명확
레거시 프로젝트에서 여전히 많이 사용유지보수 시 계층 분리가 부족하면 혼란 발생
성능 튜닝에 유리 (직접 쿼리)코드 중복, 테스트 어려움

VO를 사용하는 이유?

  • 에 의미를 부여하고 불변성을 보장하고 싶을 때

상황 별로 사용하는 구조 방식 요약표

구조 요소사용하는 경우사용하지 않는 경우
impl• 인터페이스 기반으로 계층을 나눌 때
• 유닛 테스트 / 확장성 고려할 때
• 간단한 프로젝트
• 임시 서비스 로직
Dto• 계층 간 데이터 전달이 많을 때
• 보안, 응답 포맷 조작이 필요할 때
• API 설계가 명확해야 할 때
• 빠르게 만들거나 CRUD 중심의 단순한 기능
• 내부에서만 사용할 때
Entity• JPA/ Hibernate로 DB와 매핑할 때 ( 기본적으로 사용)• 외부 API 연동만 있고 DB를 사용하지 않는 경우 추천 X
Vo• 값 단위로 의미를 부여할 때
• 도메인 모델이 중요할 때
• 값의 무결성과 불변성이 중요할 때
• 단순한 DTO처럼 쓰는 경우
• JPA 구조만으로 충분한 경우

➕스프링에서 DTO를 사용하는 이유?

💡스프링은 계층형 아키텍처를 따른다.
  • Controller - 클라이언트 요청 처리
  • Service - 비즈니스 로직 처리
  • Repository - DB 접근
  • Entity - DB와 매핑
  • DTO - 계층 간 데이터 전달

❌ Entity를 바로 반환하는 경우 문제점 (Entity <-> DTO)

  • 불필요한 몯느 필드가 외부에 노출됨 ➡️ 보안 문제
  • 응답 형식에 맞게 가공이 어려움
  • DB 무결성 위협이 있음

✅DTO의 역할

  • 요청 DTO
  • 응답 DTO
  • 필드 가공, 필요한 데이터만 전달

DTO + JPA + Service Interface 구조

profile
난 성미다.

0개의 댓글