수업 복습

BoardDAO를 MyBatis로 리팩토링 실습 과제

_김영인 2026. 2. 9. 12:45

 

수업 시간에는 Member (회원) 파트를 MyBatis로 전환했고 과제에서는 Board (게시판) 파트를 동일한 방식으로 전환하는 것이 요구사항이었다.


 

1. 기존 Board DAO 구조의 문제점 (Before)

 

기존 Board DAO는 전형적인 JDBC 방식이었다.

  • DAO 클래스 내부에 SQL 문자열이 직접 들어가 있음
  • Java 코드와 SQL이 한 파일 안에 섞여 있음
  • SQL 수정이 곧 Java 코드 수정으로 이어짐

이 구조의 문제를 정리하면 다음과 같다.

① 응집도가 낮다

DAO는 원래 “DB 접근 로직”만 담당해야 하는데 SQL 문자열 관리까지 떠안으면서 책임이 과도하게 커진다.

② 결합도가 높다

SQL이 Java 코드에 직접 포함되어 있기 때문에 SQL 변경 → Java 코드 수정 → 재컴파일 → 재배포로 이어진다.

③ 협업에 불리하다

실무에서는 Java 개발자와 SQL을 다루는 역할이 분리되는 경우도 많은데, 이 구조에서는 SQL을 수정하려면 반드시 Java 코드를 건드려야 한다.


 

2. 해결 전략: MyBatis를 사용하는 이유

 

MyBatis는 흔히 ORM으로 분류되지만 엄밀히 말하면 SQL Mapper 성격이 강한 프레임워크다.

핵심 아이디어는 단순하다.

SQL을 Java 코드에서 완전히 분리한다.

  • SQL → Mapper XML 파일에서 관리
  • Java 코드 → “어떤 SQL을 실행할지”만 지정
  • 두 영역은 namespace + id로 연결

이렇게 하면 DAO는 더 이상 SQL 문자열을 몰라도 된다.


 

3. 전체 구조 설계 (After)

 

이번 과제에서 최종적으로 만든 구조는 다음과 같다.

BoardServiceImpl
        ↓
MybatisBoardDAO
        ↓
SqlSession
        ↓
Board.xml (Mapper)
        ↓
Database

 

핵심 포인트는 DAO가 SQL을 직접 실행하지 않는다는 점이다.


 

4. 1단계: Board SQL을 Mapper XML로 분리

 

먼저 기존 Board DAO에 들어 있던 SQL을 전부 분리해 Board.xml이라는 Mapper 파일로 옮겼다.

Board.xml의 역할

  • SQL만 담당하는 파일
  • Java 코드는 전혀 없음
  • 각 SQL은 id로 식별됨
 
<mapper namespace="Board">

  <insert id="insert">
    INSERT INTO BOARD (TITLE, WRITER, CONTENT)
    VALUES (#{title}, #{writer}, #{content})
  </insert>

  <select id="getList" resultType="BoardDTO">
    SELECT * FROM BOARD
    ORDER BY BID DESC
  </select>

</mapper>

 

여기서 중요한 개념이 namespace + id다.

  • Board.insert
  • Board.getList

이 문자열이 Java 코드에서 SQL을 찾는 주소 역할을 한다.


 

5. 2단계: JDBC DAO → MybatisBoardDAO로 교체

 

기존 JDBC 기반 BoardDAO 대신 MybatisBoardDAO를 새로 만들어 SqlSession을 사용하도록 변경했다.

 
@Repository
public class MybatisBoardDAO {

    @Autowired
    private SqlSession sqlSession;

    public List<BoardDTO> getBoardList() {
        return sqlSession.selectList("Board.getList");
    }
}

 

이 코드에서 확인할 수 있는 변화는 명확하다.

  • SQL 문자열 없음
  • PreparedStatement, ResultSet 없음
  • 어떤 SQL을 실행할지만 명시

DAO의 역할이 극도로 단순해졌다.


 

6. 3단계: Service 계층 연결

 

Service 계층에서는 DAO 구현체만 교체했다.

 
@Service
public class BoardServiceImpl implements BoardService {

    @Autowired
    private MybatisBoardDAO boardDAO;

    @Override
    public List<BoardDTO> getBoardList() {
        return boardDAO.getBoardList();
    }
}

Service와 Controller 로직은 거의 수정하지 않아도 됐다.
이 점이 결합도가 낮아졌다는 증거다.


 

7. 실행 결과 및 로그 확인

 

애플리케이션 실행 결과:

  • Spring Boot 정상 기동
  • HikariCP를 통한 DB 연결 성공
  • getBoardList, getBoard, insertBoard 등 비즈니스 메서드 정상 호출
  • AOP 로그를 통해 수행 시간 측정 확인

JDBC → MyBatis 전환 후에도 기능은 그대로 유지되면서 구조만 개선된 상태가 되었다.


 

8. 이번 과제의 핵심 정리 (실무 관점)

 

✔ 응집도 향상

  • DAO는 “DB 접근 요청”만 담당
  • SQL은 Mapper XML이 전담

 

✔ 결합도 감소

  • SQL 변경 시 Java 코드 수정 불필요
  • SQL과 Java의 책임 분리

 

✔ 유지보수성과 협업성 개선

  • SQL 수정 작업이 독립적으로 가능
  • 코드 가독성 및 변경 영향 범위 감소

 

이번 과제는 단순히 MyBatis 문법을 익히는 것이 아니라 “왜 SQL을 분리해야 하는가”를 구조적으로 이해하는 과정이었다.

  • Before: SQL과 Java가 섞인 DAO
  • After: 역할이 명확히 분리된 MyBatis 구조

이 경험을 통해 프레임워크를 쓰는 이유는 편의성이 아니라 ‘구조 개선’이라는 점을 명확히 체감할 수 있었다.

'수업 복습' 카테고리의 다른 글

Python 기초 복습  (0) 2026.03.11
게시글 삭제 프로세스 정리  (0) 2026.02.10
JDBC DAO에서 MyBatis로 리팩토링  (0) 2026.02.09
JDBCTemplate + RowMapper  (0) 2026.01.28
스프링에서의 JDBC 정리  (0) 2026.01.28