지난번에 영속 영역을 구현했다.
데이터베이스의 테이블을 구현한 VO 클래스
쿼리문 구현을 위한 Mapper 클래스, XML 파일을 작성했다.
이번엔 비즈니스 계층을 구현한다.
정말로 단순하게 설명하자면
클라이언트 -> 뷰 -> 컨트롤러 -> 서비스 -> DAO -> DB
그리고 다시 DB -> DAO -> 서비스 -> 컨트롤러 -> 뷰 -> 클라이언트
이다.
고객의 요구사항을 반영하는 계층이다.
프레젠테이션 계층(Controller, View) 와 영속 계층(VO, DAO, Mapper)
의 중간 다리 역할을 한다.
로직을 기준으로 해서 처리한다.
설계를 할때 각 계층 간의 연결은 인터페이스를 이용해 느슨한 결합을 한다.
RootConfig 클래스에 아래의 코드를 추가한다.
//스프링에 해당 패키지를 스캔하도록 설정
@ComponentScan(basePackages = "org.zerock.service")
BoardService 인터페이스
//Service 클래스의 메서드들은 최대한 고객의 요구사항에 일치하도록 이름을 지음
//계층간의 연결은 느슨한 결합으로 한다.
public interface BoardService {
public void register(BoardVO boardVO);
public BoardVO get(Long bno);
public boolean modify(BoardVO board);
public boolean remove(Long bno);
public List<BoardVO> getList();
}
BoardServiceImpl 클래스
@Log4j
@Service //Service 를 위한 클래스임을 명시
@AllArgsConstructor
//BoardService 인터페이스를 이용한 클래스. Mapper를 이용해 비즈니스 로직을 수행
public class BoardServiceImpl implements BoardService {
//Spring 4.3이상부터는 단일 파라미터를 받는 생성자가 있으면
//그 파라미터가 자동으로 주입됨.
@Setter(onMethod_=@Autowired)
private BoardMapper mapper;
@Override
//게시판 작성
public void register(BoardVO boardVO) {
log.info(boardVO);
mapper.insertSelectKey(boardVO);
}
@Override
//bno(PRIMARY KEY) 를 받아 게시물 하나를 얻어온다.
public BoardVO get(Long bno) {
return mapper.read(bno);
}
@Override
//게시물 수정
public boolean modify(BoardVO board) {
log.info("modify.........");
//BoardMapper 의 update 메서드는
//수정이 성공적으로 됏으면 1, 아니면 0 을 반환
//이때 이 메서드는 위의 결과에 따라 true, false를 반환
return mapper.update(board) == 1;
}
@Override
//게시물 삭제
public boolean remove(Long bno) {
// TODO Auto-generated method stub
log.info("delete........");
//modify 메서드와 마찬가지로 true, false를 반환
return mapper.delete(bno) == 1;
}
@Override
//게시물 목록 조회
public List<BoardVO> getList() {
log.info("getList............");
return mapper.getList();
}
}
BoardServiceTests 클래스
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {org.zerock.config.RootConfig.class})
@Log4j
public class BoardServiceTests {
//BoardService 객체 생성
@Setter(onMethod_=@Autowired)
BoardService service;
@Test
//BoardService 객체가 생성되고 BoardMapper 가 주입이 되는지 확인
public void testExist() {
log.info(service);
//service 가 null인지 확인
assertNotNull(service);
}
@Test
//게시물 작성
public void testRegister() {
BoardVO boardVO = new BoardVO();
boardVO.setTitle("새로 작성하는 글");
boardVO.setContent("새로 작성하는 내용");
boardVO.setWriter("user001");
//BoardVO 객체 생성, 필드 값 추가 후
//게시물 작성 메서드에 전달
//register 메서드는 mapper 의 insertSelectKey 메서드에 객체를 전달
service.register(boardVO);
//xml 의 selectKey 에서 시퀀스의 다음값을 bno에 보관한 후 insert 했으니 그 값을 확인
log.info("생성된 게시물의 번호: " + boardVO.getBno());
}
@Test
//게시물 목록 조회
public void testGetList() {
//getList() 메서드는 mapper 의 getList()의 결과를 받아옴
//그 결과를 forEach 메서드로 콘솔에 출력
service.getList().forEach(board -> log.info(board));
}
@Test
//게시물 조회
public void testGet() {
//get 메서드는 mapper의 read에 인자(파라미터)를 전달.
//read는 그 인자를 이용하여 row 를 반환
log.info(service.get(22L));
}
@Test
//게시물 삭제
public void testDelete() {
//remove 메서드는 mapper 의 delete 메서드에 인자를 전달
//delete 메서드는 쿼리문의 처리가 성공적으로 됐다면(삭제할 row가 있었고 삭제를 했다면)
//1이나 0을 반환하고 remove 메서드에서는 그 값을 boolean 타입으로 반환
log.info("REMOVE RESULT: " + service.remove(4L));
}
@Test
//게시물 수정
public void testUpdate() {
BoardVO boardVO = new BoardVO();
//get 함수를 이용해 row(객체)를 얻어온다
boardVO = service.get(1L);
if(boardVO == null) {
return;
}
//얻어온 객체의 필드(칼럼)을 수정
boardVO.setTitle("제목을 수정합니다");
//modify 메서드에 위에서 얻고 수정한 객체를 전달한다
//modify 메서드는 mapper 의 update 메서드에 이를 전달하고
//remove 메서드와 같은 방식으로 boolean 타입을 반환
log.info("MODIFY RESULT:" + service.modify(boardVO));
}
}