수업 시간에는 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 |