MyBatis

2. MyBatis로 DAO작성하기 - 패스트캠퍼스 백엔드 부트캠프 3기

gkss2tpt 2025. 2. 27. 17:58

1. BoardDao의 작성

  • 첫째, DB테이블 생성 
create table board(
    bno INT AUTO_INCREMENT primary key not null,
    title varchar(100) not null,
    content text not null,
    writer varchar(30) not null,
    view_cnt int default 0,
    comment_cnt int default 0,
    reg_date datetime default now(),
    up_date datetime default now()
);
  • 둘째, Mapper XML & DTO작성
  • 셋째, DAO인터페이스 작성(생략가능)
  • 넷째, DAO인터페이스 구현 & 테스트

 

2. DTO란? - Data Trasfer Object

  • 계층간의 데이터를 주고 받기 위해 사용되는 객체

  • SpringMVC에서 분리된 Controller와 View에서 처리된 데이터를 Model에 담아 View로 반환했는데...

  • 클라이언트가 요청한 데이터를 DTO에 담아서 Service로 그리고 Repository로 전달
  • 각 계층을 분리해 놨기때문에 데이터를 전달하기 위해 사용하는 것이 DTO이다.
  • @Controller : 요청과 응답을 처리, 데이터 유효성 검증, 실행 흐름을 제어 - 예외처리 필수
  • @Service : 비즈니스 로직 담당, 트랜잭션 처리 - 예외처리, Controller로 넘기기, 예외되던지기
  • @Repository : 순수 Data Access 기능(DAO), 조회, 등록, 수정, 삭제 - 예외처리X

  • boardMapper.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTO Mapper 3.0/EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.fastcampus.ch4.dao.BoardMapper">
    <select id="now" resultType="String">
        SELECT now()
    </select>
    <select id="count" resultType="int">
        SELECT count(*)
    </select>
    <select id="select" parameterType="int" resultType="BoardDto">
        SELECT bno, title, content, writer, view_cnt, comment_cnt, reg_date, up_date
        FROM board
        WHERE bno=#{bno}
    </select>
    <insert id="insert" parameterType="BoardDto">
        INSERT INTO board
            (title, content, writer)
        VALUES
            (#{title}, #{content}, #{writer})
    </insert>
    <delete id="delete" parameterType="int">
        DELETE FROM board WHERE bno=${bno}
    </delete>
    <update id="update" parameterType="BoardDto">
        UPDATE board
        SET title = #{title},content = #{content}
        WHERE bno=#{bno}
    </update>

</mapper>
  • boardMapper.xml경로

  • BoardDto 클래스
@Getter
@Setter
@ToString
public class BoardDto {
    private Integer bno;
    private String title;
    private String content;
    private String writer;
    private int view_cnt;
    private int comment_cnt;
    private Date reg_date;

    public BoardDto(){}
    public BoardDto(String title, String content, String writer) {
        this.title = title;
        this.content = content;
        this.writer = writer;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null || getClass() != o.getClass()) return false;
        BoardDto boardDto = (BoardDto) o;
        return Objects.equals(bno, boardDto.bno) && Objects.equals(title, boardDto.title) && Objects.equals(content, boardDto.content) && Objects.equals(writer, boardDto.writer);
    }

    @Override
    public int hashCode() {
        return Objects.hash(bno, title, content, writer);
    }
}
  • BoardDaoImpl 클래스
@Repository
public class BoardDaoImpl implements BoardDao {

    @Autowired
    SqlSession session;
    // 마지막에 .붙여주기
    String namespace="com.fastcampus.ch4.dao.BoardMapper.";

    // select
    @Override
    public BoardDto select(int bno) throws Exception{
        return session.selectOne(namespace+"select", bno);
    }
    // insert
    @Override
    public void insert(BoardDto dto) throws Exception{
        session.insert("insert", dto);
    }

    @Override
    public void delete(int bno) throws Exception{
        session.delete(namespace+"delete", bno);
    }
    @Override
    public void update(BoardDto dto) throws Exception{
        session.update(namespace+"update", dto);
    }
    @Override
    public String now(){
        return session.selectOne(namespace+"now");
    }
    @Override
    public int count(){
        return session.selectOne(namespace+"count");
    }
}
  • Test
@RunWith(SpringRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/**/root-context.xml"})
public class BoardDaoImplTest {

    @Autowired
    BoardDao boardDao;

    @Test
    public void select() {
        assertTrue(boardDao!=null);
        System.out.println("boardDao = " + boardDao);
    }
}
  • boardDao가 Bean객체로 등록이 됬는지 확인

  • SELECT Test도 성공
@RunWith(SpringRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/**/root-context.xml"})
public class BoardDaoImplTest {

    @Autowired
    BoardDao boardDao;

    @Test
    public void select() throws Exception {
        assertTrue(boardDao!=null);
        System.out.println("boardDao = " + boardDao);
        BoardDto dto = boardDao.select(1);
        System.out.println("dto = " + dto);
        assertTrue(dto.getBno().equals(1));
    }

 

3. #{}와 ${}의 차이

  • #{} : PreparedStatement로 변환된다. -> "(?,?,?)" -> 값에만 사용가능
  • ${} : 일반 Statement로 변환된다. -> 유연하다 -> SQL Injection에 취약

 

4. XML의 특수 문자 처리

  • XML 내의 특수 문자(<,>, &, ...) 는 &lt(<); &gt(>);로 변환 필요
  • 또는 특수문자가 포함된 쿼리를<![CDATA[ ... ]]>로 감싼다