[SPRING] Spring 구조 및 DTO, VO 개념
DTO와 VO는 같은 개념으로 쓰이고 있지만 자세하게는 역할이 다르다
DTO는 DB에서 검색할 조건을 넣는 Bean이고
VO는 DB로부터 반환해서 받아오는 Bean이다
하나의 Bean에 반환데이터와 검색조건을 넣고 처리하면
검색조건이 반환값에 덮어써져버려서 결과가 변하기 때문
또 다른 이유는
DTO는 DB의 검색조건을 관리하는 Bean이기 때문에
DB의 컬럼명과 일치해야하지만
Bean은 반환값을 보관하기 때문에
DB명과 일치하지 않는 경우도 있다
예를들면 DB는 슈퍼_아이스크림 인데
꺼내서 쓸땐 슈퍼_를 제외한 아이스크림이라는 이름으로 관리하는 경우가 생긴다
SELECT
SUPER_ICECREAM AS ICECREAM
FROM
TABLE
WHERE
SUPER_ICECREAM = ?
이럴 경우 조건문과 반환값을 받는 Bean을 한개의 Bean으로 관리하면
아이스크림이라는 목록이 2개가 존재하게 되므로 관리가 복잡해진다
#설명
스프링으로 설명을 하나 스트러츠에서도 동일하다
로직은 컨트롤러>서비스>매퍼>QUERY 순이다
컨트롤러
아래는 boardId가 자유게시판, 검색키워드가 "안녕" 이라는 조건에 부합하는 리스트를 가져오는 구조
DTO는 DB에 접속해 데이터를 가져오는 쓰는 조건변수가 들어 있는 Bean이다
LIst<BoardVO> boardList 의 boardVO는 DB의 결과를 받아오는 Bean
@Controller
public class BoardController {
@Autowired//객체생성을 스프링이 해줌
BoardService boardService;
@RequestMapping(value = "/boardList", method = RequestMethod.GET)//method가 GET이면서 url이 boardList
public String boardList(BoardDTO boardDTO,//인수에 Bean을 작성하면 넘어오는 데이터들이 Bean에 있는 멤버필드에 있는 변수이름에 맞게 자동으로 들어감
Model model) {
String url = "/board/board_list";
boardDTO.setBoardId("FREEBOARD");
boardDTO.setKeyword("안녕");
List<BoardVO> boardList = boardService.selectBoardList(boardDTO);//서비스에서 리스트를 받아옴
model.addAttribute("boardList", boardList);//boardList 객체를 boardList라는 이름으로 프론트에 보냄
return url;
}
}
서비스
public interface BoardService {
public List<BoardVO> selectBoardList(BoardDTO boardDTO);
}
@Service
public class BoardServiceImpl implements BoardService{
BoardMapper boardMapper;
@Override
public List<BoardVO> selectBoardList(BoardDTO boardDTO) {
return boardMapper.selectBoardList(boardDTO);
}
}
매퍼
@Mapper//mybatis or ibatis가 추가되야 사용가능
public interface BoardMapper {
public List<BoardVO> selectBoardList(BoardDTO boardDTO);
}
매퍼.xml
아래의 boardId에는 컨트롤러에서 입력한 FREEBOARD가 있고
keyword에는 "안녕" 이 있다
즉 boardId가 자유게시판이고 자유게시판 글 중에서 제목이나 본문에 안녕이 있는 글을 출력하는 쿼리다
그리고 resultType에서 지정한 BoardVO로 반환을 한다
<?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.example.demo.mapper.BoardMapper"><!-- mapper의 위치를 지정 -->
<select id="selectBoard" resultType="com.example.demo.entity.BoardVO"><!-- 리턴 타입은 BoardVO -->
SELECT
*
FROM
EXAMSITE
WHERE
BOARDID = #{boardID} <!-- boardId가 DTO의 boardID이면서 -->
AND (BOARDTITLE = '%'||#{keyword}||'%' OR BOARDCONTENT = '%'||#{keyword}||'%') <!-- 제목이나 본문에 DTO의 keyword가 있다면 -->
</select>
</mapper>
그럼 컨트롤러에 있는 List<BoardVO>에 들어가게 되는 로직
List<BoardVO> boardList = boardService.selectBoardList(boardDTO);//서비스에서 리스트를 받아옴
전체적인 설명글이지만
DTO는 프론트나 컨트롤러에서 입력된 DB에서 조건 검색을 하기위한 Bean
VO는 DB에서 쿼리를 돌리고 나온 결과를 담는 Bean이라고 이해하면 된다
아래는 스트러츠 프레임워크로 위 조건이 몇개 검색 됐는지 Count를 구하는 로직
package Study;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;
public class DAOStudy {
public static int selectListCount(DBConection DBCon, boardDTO boardDTO) throws SQLException, Exception {
/* SQL */
StringBuffer buf = new StringBuffer();
buf.append(" SELECT ");
buf.append(" COUNT(*) ");
buf.append(" FROM ");
buf.append(" EXAMSITE ");
buf.append(" WHERE ");
buf.append(" BOARDID = #{boardID} ");
buf.append(" AND (BOARDTITLE = '%'||?||'%' OR BOARDCONTENT = '%'||?||'%') ");
/* 파라메터 */
List<Object> param = new ArrayList<Object>();
param.add(boardDTO.getBoardId());
param.add(boardDTO.getKeyword());
int resultCount = 0;
try(PreparedStatement preState = DBCon.getPrepareStatement(buf.toString());){
DBCon.setPrepareParameter(param, preState);
String logSQL = StringConvertUtil.getPreparedSQL(buf.toString(), param);
resultCount += preState.executeUpdate();
}
return resultCount;
}
}