영속계층(CRUD연산을 수행하는 계층)은 데이터 생성/수정/삭제/조회를 수행한다.
여기선 영속계층의 CRUD구현을 다룬다.
영속계층의 작업은 항상 아래 순서를 따른다
@Data
public class BoardVO {
private Long bno;
private String title;
private String content;
private String writer;
private Date regdate;
private Date updateDate;
}
mapper인터페이스를 사용하기 위해선, mapper패키지를 조사해야하므로 root-context에 component-scan을 추가하도록한다.
그리고 Mapper 인터페이스를 작성한다.
public interface BoardMapper {
@Select("select * from tbl_board where bno > 0")
public List<BoardVO> getList();
}
그리고 테스트코드를 작성한 후 출력문을 보면 정상적으로 연결됨을 확인할 수 있다.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class BoardMapperTests {
@Setter(onMethod_ = @Autowired)
private BoardMapper mapper;//BoardMapperTest는 BoardMapper인터페이스의 구현체를 주입 받는다.
@Test
public void testGetList() {
mapper.getList().forEach(board -> log.info(board));
}
}
확인이 완료되었으면 src/main/resources내에 패키지와 동일한 org/zerock/mapper 단계의 폴더 생성 후 BoardMapper.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="org.zerock.mapper.BoardMapper">
<select id="getList" resultType="org.zerock.domain.BoardVO">
<![CDATA[
select * from tbl_board where bno > 0
]]>
</select>
</mapper>
주의해야할 사항은
그리고 BoardMapper 인터페이스의 SQL문을 제거하고 다시 실행하면 동일한 결과를 얻을 수 있다.
현재 예제는 bno을 PK로 이용하고, 시퀀스를 통해 자동으로 번호가 생성된다. 이럴 때 2가지 방식으로 처리할 수 있다.
이를 고려해서 작성한다. (BoardMapper.java)인터페이스
public void insert(BoardVO board);
public void insertSelectKey(BoardVO board);
BoardMapper.xml
<insert id="insert">
insert into tbl_board (bno, title, content, writer)
values (seq_board.nextval, #{title}, #{content}, #{writer})
</insert>
<insert id="insertSelectKey">
<selectKey keyProperty="bno" order="BEFORE" resultType="long">
select seq_board.nextval from dual
</selectKey>
insert into tbl_board(bno, title, content, writer)
values(seq_board.nextval, #{title},#{content} ,#{writer})
</insert>
</mapper
insert는 bno의 값을 삽입할 때 nextval을 이용하므로, 값을 알 수 없지만
SelectKet는 nextval에서 받아온 시퀀스 값을 bno에 저장하기 때문에 출력할 수 있다. 이때 출력되는 값은 시퀀스값(중복X)은 환경마다 다를 수 있다.
@Test
public void testInsert() {
BoardVO board = new BoardVO();
board.setTitle("새로 작성하는 글");
board.setContent("새로 작성 내용");
board.setWriter("newbie");
mapper.insert(board);
log.info(board); // bno가 null로 출력된다.
}
@Test
public void testInsertSelectKey() {
BoardVO board = new BoardVO();
board.setTitle("새로 작성하는 글");
board.setContent("새로 작성 내용");
board.setWriter("newbie");
mapper.insertSelectKey(board);
log.info(board); // bno=25가 결과로 나온다. 이는 시퀀스 값으로 환경마다 다른 값이 나옴(중복 없는 값을 위함)
}
}
인터페이스를 작성한다.
public BoardVO read(long bno);
mapper.xml을 작성한다
<select id="read" resultType="org.zerock.domain.BoardVO">
select * from tbl_board where bno = #{bno}
</select>
테스트코드를 작성한다.
@Test
public void readTest(){
BoardVO board = mapper.read(5L);
log.info(board);
}
5번 게시물이 출력되는 것을 볼 수 있다.
인터페이스를 작성한다.
public int delete(long bno);
XML을 작성한다.
<delete id="delete">
delete from tbl_board where bno = #{bno}
</delete>
테스트코드를 작성한다.
@Test
public void testDelete(){
log.info("DELETE COUNT: "+ mapper.delete(3L));
}
정상적으로 삭제되었으면 다음과 같은 출력문이 나온다.
INFO : org.zerock.persistence.BoardMapperTests - DELETE COUNT: 1
카운트는 몇개의 데이터가 삭제되었는지를 알려준다.
제목, 내용, 작성자를 수정한다. delete와 마찬가지로, 몇개의 데이터가 수정되었는지 처리할 수 있으므로 int형으로 작성한다.
인터페이스를 작성한다.
public int update(BoardVO board);
xml을 작성한다.
<update id="update">
update tbl_board
set title = #{title},
content = #{content},
writer = #{writer},
updatedate = sysdate
where bno = #{bno}
</update>
테스트코드를 작성한다.
@Test
public void testUpdate(){
BoardVO board = new BoardVO();
board.setBno(1L);
board.setTitle("수정된 제목");
board.setContent("수정된 내용");
board.setWriter("user01");
int count = mapper.update(board);
log.info("UPDATE COUNT: " + count);
}
수정이 완료되었으면, COUNT가 갯수에 맞춰 출력된다.