멀티캠퍼스

[2026.06.11] - TIL 49일차 MyBatis MYBOARD 게시판 CRUD 정리

buckwheat 2026. 6. 15. 13:14

 

목차
1 MyBatis 게시판 실습 개요
2 MYBOARD 테이블
3 MyBatis 설정 파일
4 Mapper XML
5 MyBatisConfig
6 MyBoardDto
7 MyBoardDao
8 MyBoardMyBatis Controller
9 JSP 화면 구성
10 오늘 실습의 핵심 정리

1 MyBatis 게시판 실습 개요

1) 오늘 실습의 흐름

    (1) MyBatis 게시판
    오늘은 MyBatis를 이용해 MYBOARD 게시판 CRUD 기능을 구현했다.
    기존 JDBC 방식에서는 DAO 안에서 SQL을 문자열로 작성하고 PreparedStatement로 실행했지만, MyBatis에서는 SQL을 mapper XML 파일로 분리해서 관리했다.

    (2) 구현한 기능
    게시글 목록 조회, 상세 조회, 글 작성, 글 수정, 글 삭제 기능을 구현했다.
    사용자의 요청은 Servlet Controller가 받고, DAO는 MyBatis의 SqlSession을 사용해 mapper XML에 작성된 SQL을 실행했다.

    (3) 전체 구조
    MyBoardMyBatis는 Controller 역할을 한다.
    MyBoardDao는 MyBatis를 이용해 SQL을 실행하는 DAO 역할을 한다.
    MyBoardDto는 게시글 데이터를 담는 객체이다.
    myboard_mapper.xml은 실제 SQL을 작성하는 파일이다.
    JSP 파일들은 목록, 상세, 작성, 수정 화면을 보여주는 View 역할을 한다.

2 MYBOARD 테이블

1) MYBOARD 테이블 구조

    (1) MYBOARD
    MYBOARD 테이블은 게시글 정보를 저장하는 테이블이다.
    글 번호, 작성자 이름, 제목, 내용, 작성일을 저장한다.

    (2) MYNO
    MYNO는 게시글 번호이다.
    PRIMARY KEY로 설정되어 게시글 하나를 구분하는 고유한 값이다.

    (3) MYNAME
    MYNAME은 작성자 이름을 저장하는 컬럼이다.
    NOT NULL이 설정되어 있어 반드시 값이 들어가야 한다.

    (4) MYTITLE
    MYTITLE은 게시글 제목을 저장하는 컬럼이다.
    게시글 목록과 상세 화면에서 출력된다.

    (5) MYCONTENT
    MYCONTENT는 게시글 내용을 저장하는 컬럼이다.
    상세 화면과 수정 화면에서 사용된다.

    (6) MYDATE
    MYDATE는 게시글 작성일을 저장하는 컬럼이다.
    글 작성 시 SYSDATE를 사용해 현재 날짜를 저장한다.

2) SEQ_MYBOARD

    (1) 시퀀스
    SEQ_MYBOARD는 게시글 번호를 자동으로 증가시키기 위한 시퀀스이다.
    글을 작성할 때 SEQ_MYBOARD.NEXTVAL을 사용해 새로운 MYNO 값을 만든다.

3 MyBatis 설정 파일

1) db.properties

    (1) DB 접속 정보 분리
    db.properties는 DB 접속 정보를 따로 관리하는 파일이다.
    driver, url, username, password 값을 저장한다.

    (2) 사용하는 이유
    DB 접속 정보를 XML이나 Java 코드에 직접 쓰면 수정이 불편하다.
    properties 파일로 분리하면 접속 정보만 따로 관리할 수 있다.

2) myboard_config.xml

    (1) MyBatis 전체 설정 파일
    myboard_config.xml은 MyBatis의 전체 설정을 담당한다.
    DB 접속 정보, DTO 별칭, mapper 파일 등록을 설정한다.

    (2) properties
    properties 태그는 db.properties 파일을 읽어오는 역할을 한다.
    설정 파일 안에서 ${driver}, ${url}, ${username}, ${password}처럼 값을 사용할 수 있다.

    (3) typeAliases
    typeAliases는 DTO 클래스에 별칭을 붙이는 설정이다.
    com.my.dto.MyBoardDto를 MyBoardDto라는 짧은 이름으로 사용할 수 있게 했다.

    (4) environments
    environments는 DB 연결 환경을 설정하는 부분이다.
    transactionManager는 JDBC 방식으로 설정했고, dataSource는 POOLED 방식으로 설정했다.

    (5) mappers
    mappers는 SQL이 작성된 mapper XML 파일을 등록하는 부분이다.
    db/myboard_mapper.xml을 등록해서 MyBatis가 해당 SQL들을 사용할 수 있게 했다.

4 Mapper XML

1) myboard_mapper.xml

    (1) Mapper XML
    myboard_mapper.xml은 실제 SQL문을 작성하는 파일이다.
    Java 코드 안에 SQL을 직접 작성하지 않고, XML 파일에서 SQL을 관리한다.

    (2) namespace
    namespace는 mapper를 구분하는 이름이다.
    이번 실습에서는 namespace를 com.my.dao.MyBoardDao로 설정했다.

    (3) namespace와 id
    DAO에서는 namespace와 SQL id를 합쳐서 mapper의 SQL을 호출한다.
    예를 들어 com.my.dao.MyBoardDao.selectAll은 namespace가 com.my.dao.MyBoardDao이고, id가 selectAll인 SQL을 의미한다.

2) resultMap

    (1) resultMap의 역할
    resultMap은 DB 컬럼명과 DTO 필드명을 연결하는 설정이다.
    MYNO, MYNAME, MYTITLE, MYCONTENT, MYDATE 컬럼을 MyBoardDto의 no, name, title, content, regDate 필드와 연결했다.

    (2) 사용하는 이유
    DB 컬럼명과 Java 필드명이 서로 다를 때 resultMap이 필요하다.
    예를 들어 DB 컬럼은 MYNO인데 Java 필드는 no이므로 둘을 직접 연결해줘야 한다.

3) select

    (1) selectAll
    selectAll은 MYBOARD 테이블의 전체 게시글을 조회한다.
    ORDER BY MYNO DESC를 사용해 최신 글이 먼저 나오도록 정렬했다.

    (2) selectOne
    selectOne은 MYNO 값을 기준으로 게시글 하나를 조회한다.
    상세 조회와 수정 화면에서 사용된다.

4) insert, update, delete

    (1) insert
    insert는 새 게시글을 MYBOARD 테이블에 추가한다.
    SEQ_MYBOARD.NEXTVAL로 글 번호를 생성하고, 작성자, 제목, 내용은 DTO에서 가져온다.

    (2) update
    update는 MYNO 값을 기준으로 작성자, 제목, 내용을 수정한다.
    수정할 게시글 번호는 #{no}로 전달받는다.

    (3) delete
    delete는 MYNO 값을 기준으로 게시글 하나를 삭제한다.
    상세 화면에서 삭제 버튼을 누르면 해당 글 번호가 전달되어 삭제된다.

5 MyBatisConfig

1) MyBatisConfig의 역할

    (1) SqlSessionFactory 생성
    MyBatisConfig는 myboard_config.xml 파일을 읽어서 SqlSessionFactory를 생성하는 클래스이다.
    SqlSessionFactory는 SqlSession을 만들기 위한 공장 역할을 한다.

    (2) static 초기화 블록
    static 블록은 클래스가 처음 로딩될 때 한 번 실행된다.
    이 안에서 설정 파일을 읽고 SqlSessionFactory를 미리 생성해둔다.

    (3) getSqlSessionFactory
    getSqlSessionFactory 메소드는 생성된 SqlSessionFactory를 반환한다.
    DAO에서는 이 메소드를 호출해 SqlSession을 열 수 있다.

2) 이전 SqlMapConfig와의 차이

    (1) static 방식
    MyBatisConfig는 SqlSessionFactory를 static 필드로 관리한다.
    그래서 객체를 계속 새로 만들지 않고 클래스 단위로 공유할 수 있다.

    (2) 설정 파일 경로
    MyBatisConfig는 db/myboard_config.xml을 읽는다.
    설정 파일 안에는 DB 접속 정보와 mapper 등록 정보가 들어 있다.

6 MyBoardDto

1) MyBoardDto의 역할

    (1) DTO
    MyBoardDto는 MYBOARD 테이블의 한 행 데이터를 Java 객체로 담는 클래스이다.
    게시글 번호, 작성자 이름, 제목, 내용, 작성일을 필드로 가진다.

    (2) 사용하는 이유
    DB에서 조회한 데이터를 Controller, DAO, JSP 사이에서 주고받기 위해 사용한다.
    여러 값을 따로 전달하는 것보다 DTO 객체 하나로 묶어 전달하는 것이 편하다.

2) 필드와 getter

    (1) no
    no는 게시글 번호이다.
    MYBOARD 테이블의 MYNO 컬럼과 연결된다.

    (2) name
    name은 작성자 이름이다.
    MYBOARD 테이블의 MYNAME 컬럼과 연결된다.

    (3) title
    title은 게시글 제목이다.
    MYBOARD 테이블의 MYTITLE 컬럼과 연결된다.

    (4) content
    content는 게시글 내용이다.
    MYBOARD 테이블의 MYCONTENT 컬럼과 연결된다.

    (5) regDate
    regDate는 작성일이다.
    MYBOARD 테이블의 MYDATE 컬럼과 연결된다.

7 MyBoardDao

1) MyBoardDao의 역할

    (1) DAO
    MyBoardDao는 MyBatis의 SqlSession을 이용해 mapper XML에 작성된 SQL을 실행하는 클래스이다.
    기존 JDBC 방식처럼 PreparedStatement를 직접 작성하지 않는다.

    (2) SqlSession
    SqlSession은 MyBatis에서 SQL을 실행하는 핵심 객체이다.
    selectList, selectOne, insert, update, delete 메소드를 사용해 mapper의 SQL을 호출한다.

2) selectAll

    (1) 전체 조회
    selectAll은 전체 게시글 목록을 조회한다.
    session.selectList를 사용하고, 결과는 List<MyBoardDto>로 반환된다.

    (2) mapper 호출
    session.selectList("com.my.dao.MyBoardDao.selectAll")로 mapper의 selectAll SQL을 호출한다.
    문자열은 namespace와 id를 합친 값이다.

3) selectOne

    (1) 상세 조회
    selectOne은 글 번호 no를 기준으로 게시글 하나를 조회한다.
    session.selectOne을 사용해 하나의 MyBoardDto 객체를 반환한다.

4) insert

    (1) 글 작성
    insert는 MyBoardDto 객체를 mapper로 전달해 새 게시글을 저장한다.
    DTO에 들어 있는 name, title, content 값이 mapper의 #{name}, #{title}, #{content}에 들어간다.

    (2) commit과 rollback
    insert는 DB 내용을 변경하는 작업이다.
    성공하면 session.commit을 실행하고, 실패하면 session.rollback을 실행한다.

5) update

    (1) 글 수정
    update는 MyBoardDto 객체를 이용해 작성자, 제목, 내용을 수정한다.
    어떤 글을 수정할지는 dto의 no 값으로 판단한다.

    (2) 트랜잭션 처리
    update도 DB 내용을 변경하는 작업이므로 성공 시 commit, 실패 시 rollback을 처리한다.

6) delete

    (1) 글 삭제
    delete는 글 번호 no를 mapper로 전달해 게시글 하나를 삭제한다.
    삭제 성공 시 commit하고 실패 시 rollback한다.

7) session.close

    (1) 자원 정리
    각 메소드의 finally에서 session.close를 실행한다.
    SqlSession 사용이 끝나면 반드시 닫아 자원을 정리해야 한다.

8 MyBoardMyBatis Controller

1) Controller의 역할

    (1) MyBoardMyBatis
    MyBoardMyBatis는 Servlet Controller 역할을 하는 클래스이다.
    @WebServlet("/board")로 매핑되어 있어 board 주소로 들어오는 요청을 처리한다.

    (2) command 방식
    command 값을 기준으로 목록 조회, 상세 조회, 작성 화면 이동, 작성 처리, 수정 화면 이동, 수정 처리, 삭제 처리를 분기한다.

    (3) DAO 호출
    Controller는 command에 따라 MyBoardDao의 메소드를 호출한다.
    조회 결과가 필요한 경우 request에 데이터를 저장하고 JSP로 forward한다.

2) list

    (1) 목록 조회
    command가 null이거나 list이면 전체 게시글 목록을 조회한다.
    dao.selectAll을 호출하고 결과를 request에 list라는 이름으로 저장한다.

    (2) mylist.jsp 이동
    목록 데이터가 필요하므로 dispatch를 사용해 mylist.jsp로 forward한다.
    forward를 사용하면 request에 담은 list를 JSP에서 사용할 수 있다.

3) selectone

    (1) 상세 조회
    command가 selectone이면 no 값을 받아 게시글 하나를 조회한다.
    조회 결과를 dto라는 이름으로 request에 저장한다.

    (2) myselection.jsp 이동
    myselection.jsp에서는 dto 값을 EL로 출력한다.
    만약 dto가 비어 있으면 조회된 글이 없다는 메시지를 출력한다.

4) insertform과 insertres

    (1) insertform
    insertform은 글 작성 화면으로 이동하는 요청이다.
    별도로 전달할 데이터가 없기 때문에 myinsert.jsp로 redirect한다.

    (2) insertres
    insertres는 글 작성 처리 요청이다.
    form에서 전달된 name, title, content를 받아 MyBoardDto에 저장하고 dao.insert를 호출한다.

    (3) 작성 결과
    작성 성공 시 목록으로 이동하고, 실패 시 다시 작성 화면으로 이동한다.

5) updateform과 updateres

    (1) updateform
    updateform은 수정 화면으로 이동하는 요청이다.
    수정 화면에는 기존 글 정보가 필요하므로 no 값으로 게시글을 조회한 뒤 myupdate.jsp로 forward한다.

    (2) updateres
    updateres는 수정 처리 요청이다.
    no, name, title, content 값을 받아 MyBoardDto에 저장하고 dao.update를 호출한다.

    (3) 수정 결과
    수정 성공 시 다시 상세 페이지로 이동한다.
    실패 시 수정 화면으로 돌아간다.

6) delete

    (1) 삭제 처리
    command가 delete이면 no 값을 받아 dao.delete를 호출한다.
    삭제 성공 시 목록으로 이동하고, 실패 시 상세 페이지로 돌아간다.

7) dispatch 메소드

    (1) forward 공통 메소드
    dispatch 메소드는 request.getRequestDispatcher(url).forward(request, response)를 실행하는 공통 메소드이다.
    JSP로 forward하는 코드가 반복되기 때문에 별도 메소드로 분리했다.

9 JSP 화면 구성

1) mylist.jsp

    (1) 목록 화면
    mylist.jsp는 전체 게시글 목록을 출력하는 View 페이지이다.
    Controller가 request에 저장한 list를 JSTL로 반복 출력한다.

    (2) c:choose
    c:choose를 사용해 조회된 글이 없는 경우와 있는 경우를 나누었다.
    list가 비어 있으면 “조회된 글이 없습니다.”를 출력한다.

    (3) c:forEach
    list에 게시글이 있으면 c:forEach로 하나씩 반복 출력한다.
    제목을 클릭하면 board?command=selectone&no=글번호 요청이 발생한다.

2) myselection.jsp

    (1) 상세 화면
    myselection.jsp는 게시글 하나의 상세 내용을 출력하는 View 페이지이다.
    dto에 담긴 번호, 작성자, 제목, 내용을 EL로 출력한다.

    (2) 수정, 삭제, 목록 버튼
    수정 버튼은 updateform 요청을 보낸다.
    삭제 버튼은 delete 요청을 보낸다.
    목록 버튼은 list 요청을 보낸다.

3) myinsert.jsp

    (1) 작성 화면
    myinsert.jsp는 새 글을 작성하는 form 화면이다.
    작성자, 제목, 내용을 입력받는다.

    (2) hidden command
    command=insertres 값을 hidden input으로 전달한다.
    Controller는 이 값을 보고 글 작성 처리 요청임을 판단한다.

4) myupdate.jsp

    (1) 수정 화면
    myupdate.jsp는 기존 게시글을 수정하는 form 화면이다.
    기존 글 정보를 dto에서 가져와 input과 textarea에 출력한다.

    (2) hidden no
    수정할 글 번호는 hidden input으로 전달한다.
    화면에는 보이지 않지만 어떤 글을 수정할지 판단하는 기준이 된다.

10 오늘 실습의 핵심 정리

1) MyBatis 흐름 이해

    (1) 설정 파일
    myboard_config.xml은 MyBatis의 전체 설정을 담당한다.
    DB 접속 정보, DTO 별칭, mapper 등록 정보를 가진다.

    (2) Mapper 파일
    myboard_mapper.xml은 실제 SQL문을 작성하는 파일이다.
    select, insert, update, delete SQL을 id로 구분해서 작성한다.

    (3) DAO
    MyBoardDao는 SqlSession을 열고 mapper의 SQL을 실행한다.
    Java 코드에서 SQL을 직접 작성하지 않고 namespace.id로 mapper SQL을 호출한다.

    (4) Controller
    MyBoardMyBatis는 사용자의 요청을 command 값으로 구분한다.
    필요한 DAO 메소드를 호출하고, 결과를 JSP로 전달하거나 redirect한다.

    (5) View
    JSP는 EL과 JSTL을 사용해 데이터를 화면에 출력한다.
    list, dto 같은 request 값을 받아 게시글 목록과 상세 정보를 보여준다.

2) JDBC 방식과의 차이

    (1) 기존 JDBC 방식
    기존에는 DAO 안에서 SQL문, PreparedStatement, ResultSet, commit, rollback 처리를 직접 작성했다.
    코드 양이 많고 SQL과 Java 코드가 섞여 있었다.

    (2) MyBatis 방식
    MyBatis에서는 SQL문을 mapper XML로 분리했다.
    DAO는 SqlSession으로 mapper의 SQL을 호출하는 역할에 집중한다.

    (3) 장점
    SQL 관리가 쉬워지고 Java 코드가 간결해진다.
    컬럼과 DTO 필드 매핑도 resultMap으로 명확하게 설정할 수 있다.

3) resultMap의 중요성

    (1) 컬럼명과 필드명 차이
    DB 컬럼명은 MYNO, MYNAME, MYTITLE, MYCONTENT, MYDATE이다.
    DTO 필드명은 no, name, title, content, regDate이다.

    (2) resultMap 사용
    이름이 다르기 때문에 resultMap으로 직접 매핑했다.
    resultMap이 있어야 조회 결과가 DTO 필드에 정확하게 들어간다.

4) 트랜잭션 처리

    (1) 조회
    selectAll과 selectOne은 조회 기능이므로 commit이나 rollback이 필요하지 않다.
    데이터를 읽기만 하기 때문이다.

    (2) 변경 작업
    insert, update, delete는 DB 데이터를 변경한다.
    성공하면 commit하고 실패하면 rollback해야 한다.

    (3) openSession(false)
    openSession(false)는 자동 commit을 하지 않겠다는 의미이다.
    그래서 변경 작업 후 session.commit을 직접 호출해야 DB에 반영된다.

5) 오늘 배운 점

    (1) MyBatis 설정 흐름
    db.properties, myboard_config.xml, myboard_mapper.xml, MyBatisConfig가 어떻게 연결되는지 이해했다.
    설정 파일을 읽고 SqlSessionFactory를 만든 뒤, DAO에서 SqlSession을 열어 SQL을 실행하는 구조였다.

    (2) namespace와 SQL id
    DAO에서 mapper SQL을 호출할 때는 namespace와 id를 합친 문자열을 사용했다.
    com.my.dao.MyBoardDao.selectAll처럼 작성하면 myboard_mapper.xml의 selectAll SQL이 실행된다.

    (3) Servlet MVC와 MyBatis 연결
    Servlet Controller가 요청을 받고, DAO가 MyBatis로 DB 작업을 처리하고, JSP가 결과를 출력하는 흐름을 복습했다.
    이전 JDBC 게시판보다 SQL 관리가 깔끔해졌다는 점이 인상적이었다.

    (4) 앞으로의 흐름
    MyBatis를 사용하면 게시판 CRUD뿐만 아니라 회원 관리, 로그인, 검색, 페이징 같은 기능도 더 구조적으로 구현할 수 있을 것 같다.