변환 에러를 피하기 위해 게시물 번호를 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));
}
}
<>을 < >로 해야하는데
<![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 |