Burninghering's Blog
article thumbnail
Published 2023. 5. 11. 15:56
MaBatis로 DAO작성하기 패캠 챌린지

변환 에러를 피하기 위해 게시물 번호를 Integer를 썼다.

 

사용자가 요청한 데이터를 DTO에 담아서 서비스 계층으로

서비스 계층에서 Repository 계층으로 데이터를 전달할 필요가 있다

 

각 계층으로 분리를 해놨기 때문에 계층 간 데이터를 전달하는 객체가 DTO

 

컨트롤러의 실행 흐름 제어 : Redirect & Forward

 

 

관심사, 역할에 따라 계층을 분리해놨고 각 계층 간 데이터를 전달할 필요가 있기 때문에 그 데이터를 담을 객체를 DTO라고 한다.


xml문 작성하기

 

1.mapper > boardMapper.xml 파일 생성하기

2.xml 코드 따오기

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

<mapper namespace="com.fastcampus.ch4.dao.BoardMapper">

</mapper>

 

3.select문 만들기

<select id="select">

 

4.console로 가서, board 테이블을 검색하는 select sql문을 만들어서 복사해서 가져와서 붙여넣어주기

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

<mapper namespace="com.fastcampus.ch4.dao.BoardMapper">
    <select id="select">
        select bno,
               title,
               content,
               writer,
               view_cnt,
               comment_cnt,
               reg_date,
               up_date
        from board
        where bno=#{bno}
        ;
    </select>
</mapper>

 

where bno=#{bno}

 

게시물 번호에 해당하는 것을 읽어와야 하니까 where절에 조건이 들어가고,

그것이 input이다
그래서 parameterType을 적어주어야 한다.

 

sql 실행결과는 resultType에 지정해준다.

boardDto라고 적어주려면 "com.fastcampus.ch4.domain.BoardDto"로 적어주어야 하는데

mybatis-config에 typeAliases로 지정해주었기 때문에(Aliases는 대소문자 구별안함)

짧게 boardDto라고 적으면 된다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias alias="BoardDto" type="com.fastcampus.ch4.domain.BoardDto"/>
    </typeAliases>
</configuration>

 

결과

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

<mapper namespace="com.fastcampus.ch4.dao.BoardMapper">
    <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>
</mapper>

위를 호출하려면 boardDao를 만들어야 한다.

package com.fastcampus.ch4.dao;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;

public class BoardDao {
    
    @Autowired
    SqlSession session;
    
    BoardDto select(int bno){
        return session.selectOne("select", bno); //session객체에서 한 줄 가져오고 그 결과로 BoardDto타입으로 리턴 -> sql문 아이디와 bno를 넘겨준다.
    }
}

 

domain > BoardDto.java 를 만든다

테이블을 참고해서 만들어주면 된다.

 

생성자를 만들어준다.(title, content, writer)

그리고 기본 생성자를 만들어준다.

 

getter/setter 또한 만들어주는데,

이유는 MyBatis가 자동으로 값을 읽어오고 채워준다.

 

toString도 추가해준다.

 

equals and hashcode도 추가해준다.

package com.fastcampus.ch4.domain;

import java.util.Date;
import java.util.Objects;

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;
    }

    public Integer getBno() {
        return bno;
    }

    public void setBno(Integer bno) {
        this.bno = bno;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getWriter() {
        return writer;
    }

    public void setWriter(String writer) {
        this.writer = writer;
    }

    public int getView_cnt() {
        return view_cnt;
    }

    public void setView_cnt(int view_cnt) {
        this.view_cnt = view_cnt;
    }

    public int getComment_cnt() {
        return comment_cnt;
    }

    public void setComment_cnt(int comment_cnt) {
        this.comment_cnt = comment_cnt;
    }

    public Date getReg_date() {
        return reg_date;
    }

    public void setReg_date(Date reg_date) {
        this.reg_date = reg_date;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        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);
    }

    @Override
    public String toString() {
        return "BoardDto{" +
                "bno=" + bno +
                ", title='" + title + '\'' +
                ", content='" + content + '\'' +
                ", writer='" + writer + '\'' +
                ", view_cnt=" + view_cnt +
                ", comment_cnt=" + comment_cnt +
                ", reg_date=" + reg_date +
                '}';
    }


}

boardMapper를 강사님 깃허브에서 긁어왔다...

(sql문 공부하고 직접 채워넣어보기)

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

<mapper namespace="com.fastcampus.ch4.dao.BoardMapper">
    <select id="count" resultType="int">
        SELECT count(*) FROM board
    </select>

    <delete id="deleteAll">
        DELETE FROM board
    </delete>

    <delete id="delete" parameterType="map">
        DELETE FROM board WHERE bno = #{bno} and writer = #{writer}
    </delete>

    <insert id="insert" parameterType="BoardDto">
        INSERT INTO board
            (title, content, writer)
        VALUES
            (#{title}, #{content}, #{writer})
    </insert>

    <select id="selectAll" resultType="BoardDto">
        SELECT bno, title, content, writer, view_cnt, comment_cnt, reg_date
        FROM board
        ORDER BY reg_date DESC, bno DESC
    </select>

    <sql id="selectFromBoard">
        SELECT bno, title, content, writer, view_cnt, comment_cnt, reg_date
        FROM board
    </sql>

    <select id="select" parameterType="int" resultType="BoardDto">
        <include refid="selectFromBoard"/>
        WHERE bno = #{bno}
    </select>

    <select id="selectPage" parameterType="map" resultType="BoardDto">
        <include refid="selectFromBoard"/>
        ORDER BY reg_date DESC, bno DESC
        LIMIT #{offset}, #{pageSize}
    </select>

    <update id="update" parameterType="BoardDto">
        UPDATE board
        SET   title = #{title}
          , content = #{content}
          , up_date = now()
        WHERE bno = #{bno}
    </update>

    <update id="updateCommentCnt" parameterType="map">
        UPDATE board
        SET   comment_cnt = comment_cnt + #{cnt}
        WHERE bno = #{bno}
    </update>

    <update id="increaseViewCnt" parameterType="int">
        UPDATE board
        SET   view_cnt = view_cnt + 1
        WHERE bno = #{bno}
    </update>

</mapper>

sql문의 id를 적어주기에 앞서, 

namespace를 적어주어야 경로를 제대로 찾을 수 있다.

public class BoardDao {

    @Autowired
    SqlSession session;

    String namespace="com.fastcampus.ch4.dao.BoardMapper.";

    BoardDto select(int bno) throws Exception{
        return session.selectOne(namespace+"select", bno); //session객체에서 한 줄 가져오고 그 결과로 BoardDto타입으로 리턴 -> sql문 아이디와 bno를 넘겨준다.
    }
}

 

Dao 작성이 이전보다 훨씬 쉬워졌다!


Dao를 Interface로 추출해보자

클래스를 직접 써도 되지만, 인터페이스로 해놓으면 Dao가 바뀔 때 서비스 쪽에 영향을 받지 않게 

인터페이스 타입으로 주입받게 해준다

public class BoardDaoImpl implements BoardDao {

    @Autowired
    SqlSession session;

    String namespace="com.fastcampus.ch4.dao.BoardMapper.";

    @Override
    public BoardDto select(int bno) throws Exception{
        return session.selectOne(namespace+"select", bno); //session객체에서 한 줄 가져오고 그 결과로 BoardDto타입으로 리턴 -> sql문 아이디와 bno를 넘겨준다.
    }
}

위 클래스를 

BoardDaoImpl로 이름을 바꾸고

BoardDao라는 인터페이스를 만들어주었다

(사실 메소드들을 다 만들고 인터페이스를 만들어줘야 함)

package com.fastcampus.ch4.dao;

import com.fastcampus.ch4.domain.BoardDto;

public interface BoardDao {
    BoardDto select(int bno) throws Exception;
}

BoardDaoImpl을 테스트해보자

 

Test를 하려면 Application Context, Run with... 등이 필요하니까 코드를 복사한다.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/**/root-context.xml"})
package com.fastcampus.ch4.dao;

import com.fastcampus.ch4.domain.BoardDto;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.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); //null이 아닌지 test
        System.out.println("boardDao= "+boardDao);

        BoardDto boardDto = boardDao.select(2);
        System.out.println("boardDto = "+boardDto);
        assertTrue(boardDto.getBno().equals(2));
    }
}

<>을 &lt; &gt;로 해야하는데 

<![CDATA[ ]]> 태그로 감싸주면 된다. 

'패캠 챌린지' 카테고리의 다른 글

게시판 목록 만들기와 페이징 - TDD(2)  (1) 2023.05.24
게시판 목록 만들기와 페이징 - TDD(1)  (1) 2023.05.12
MyBatis  (0) 2023.04.28
서비스계층(Layer)의분리, Transactional  (0) 2023.04.05
AOP  (0) 2023.04.04
profile

Burninghering's Blog

@개발자 김혜린

안녕하세요! 반갑습니다.