티스토리 뷰

반응형

Chapter09. 비즈니스 계층

* 비즈니스 계층 = > MVC 패턴의 모델 부분에 대한 작업을 설명하는 부분

* 프레젠테이션 계층 : jsp

* 영속 계층 : mybatis 

* 비즈니스 영역에 있는 객체들은 '서비스'라는 용어를 많이 사용함

예) 쇼핑몰에서 상품을 구매한다 => 해당 쇼핑몰의 로직(물건을 구매한 회원에게 포인트를 올려줌), 영속계층(상품과 회원으로 나누어 설계), 비즈니스(상품 영역과 회원 영역을 동시에 사용해서 하나의 로직을 처리)

BoardService --- BoardServiceImpl -- BoardMapper -- BoardMapper.xml 로 메서드가 연결되므로 하나씩 따라가면서 확인

mapper는 MyBatis의 매핑XML에 기재된 SQL을 호출하기 위한 인터페이스.


 비즈니스 계층의 설정

설계를 할 때, 각 계층 간의 연결은 인터페이스를 이용해 느슨한(loose) 연결을 함 => 직접 객체를 가져오지 않음

//BoardService 인터페이스  : 전부 추상메소드

package org.zerock.service;

import java.util.List;

import org.zerock.domain.BoardVO;

public interface BoardService {
	
	public void register(BoardVO board);
	
	public BoardVO get(Long bno);
	
	public boolean modify(BoardVO board);
	
	public boolean remove(Long bno);
	
	public List<BoardVO> getList();

}

BoardService 메서드 이름은 현실적인 로직 이름을 붙이는 것이 관례.

명백하게 반환해야 할 데이터가 있는 'select'를 해야하는 메서드는 리턴 타입을 지정할 수 있음

특정한 게시물을 가져오는 get() 메서드와 전체 리스트를 구하는 getList() 경우, 처음부터 메서드 리턴 타입 결정할 수 있음

 

BoardService 인터페이스를 구현하는 구현체 : BoardServiceImpl 클래스

@AllArgsConstructor는 모든 파라미터를 이용하는 생성자를 만들기 때문에 BoardMapper를 주입받는 생성자가 만들어지게 됨

//BoardServiceImpl 클래스

package org.zerock.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zerock.domain.BoardVO;
import org.zerock.mapper.BoardMapper;

import lombok.AllArgsConstructor;
import lombok.Setter;
import lombok.extern.log4j.Log4j;

@Log4j
@Service
@AllArgsConstructor
public class BoardServiceImpl implements BoardService{
	
	@Setter(onMethod_=@Autowired)
	private BoardMapper mapper;

	@Override
	public void register(BoardVO board) {
		// TODO Auto-generated method stub
		
	}

 

@Service

계층 구조상 주로 비즈니스 영역을 담당하는 객체임을 표시하기 위해 사용. 작성된 어노테이션은 패키지를 읽어들이는 동안 처리됨

 

스프링의 서비스 객체 설정(root-context.xml)

root-context.xml에 @Service 어노테이션이 있는 org.zerock.service 패키지를 스캔하도록 추가하기

--> 우선 root-context.xml의 네임스페이스 탭에서 context 항목을 추가 (context라는 이름으로 시작하는 태그를 활용할 수 있음)

<context:component-scan base-package="org.zerock.service" /> 
<!-- @Service 어노테이션이 있는 패키지 스캔 -->

 비즈니스 계층 구현과 테스트

1) BoardService 객체가 제대로 주입이 가능한지 확인하는 작업

//테스트 환경의 BoardServiceTests 클래스 : BoardService 객체가 제대로 주입이 가능한지 확인하는 작업

package org.zerock.service;

import static org.junit.Assert.assertNotNull;

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 lombok.Setter;
import lombok.extern.log4j.Log4j;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class BoardServiceTests {
	
	@Setter(onMethod_= {@Autowired})
	private BoardService service;
	
	@Test
	public void testExist() {
		log.info(service);
		assertNotNull(service);
	}
}

 

정상적으로 BoardService 객체가 생성되고 BoardMapper가 주입되었다면 BoardService 객체와 데이터베이스 관련 로그가 같이 출력

INFO : org.zerock.service.BoardServiceTests - org.zerock.service.BoardServiceImpl@6bf13698

2) 등록 작업의 구현과 테스트

//BoardServiceImpl
@Override
public void register(BoardVO board) {
	log.info("register....." + board);
	mapper.insertSelectKey(board); //나중에 생성된 게시물의 번호를 확인할 수 있도록 작성함
}

mapper의 insertSelectKey()를 이용해 나중에 생성된 게시물의 번호를 확인할 수 있음

//BoardServiceTest 

@Test
public void testRegister() {
	BoardVO board = new BoardVO();
	board.setTitle("새로 작성하는 글");
	board.setContent("새로 작성하는 내용");
	board.setWriter("newbie");
	
	service.register(board);
	log.info("생성된 게시물의 번호: " + board.getBno());
}

결과

INFO : jdbc.sqltiming - insert into tbl_board(bno, title, content, writer) values (seq_board.nextval, '새로 작성하는 글', '새로 작성하는 내용', 'newbie') 
{executed in 5 msec}
INFO : jdbc.audit - 1. PreparedStatement.execute() returned false
INFO : jdbc.audit - 1. PreparedStatement.getUpdateCount() returned 1
INFO : jdbc.audit - 1. PreparedStatement.close() returned 
INFO : jdbc.audit - 1. Connection.clearWarnings() returned 
INFO : org.zerock.service.BoardServiceTests - 생성된 게시물의 번호: 9

3) 목록(리스트) 작업의 구현과 테스트

현재 테이블에 저장된 모든 데이터를 가져오는 getList() 

//BoardServiceImpl

@Override
public List<BoardVO> getList() {
	log.info("getList.......");
	return mapper.getList();
}

테스트 실행 결과로 등록 작업을 테스트할 때, 추가된 데이터가 정상적으로 나오는지 확인함

//BoardServiceTests 클래스

@Test
public void testGetList() {
	service.getList().forEach(board -> log.info(board));
}

 

결과

INFO : jdbc.resultsettable - 

|----|---------------------|----------------------|--------|----------------------|----------------------|
|bno |title                |content               |writer  |regdate               |updatedate            |
|----|---------------------|----------------------|--------|----------------------|----------------------|
|1   |테스트 제목               |테스트 내용                |user00  |2022-10-31 08:20:42.0 |2022-10-31 08:20:42.0 |
|2   |테스트 제목               |테스트 내용                |user00  |2022-10-31 08:22:07.0 |2022-10-31 08:22:07.0 |
|3   |테스트 제목               |테스트 내용                |user00  |2022-10-31 08:22:08.0 |2022-10-31 08:22:08.0 |
|4   |테스트 제목               |테스트 내용                |user00  |2022-10-31 08:22:09.0 |2022-10-31 08:22:09.0 |
|5   |수정된 제목               |수정된 내용                |user000 |2022-10-31 08:22:10.0 |2022-10-31 11:17:41.0 |
|6   |새로 작성하는 글            |새로 작성하는 내용            |newbie  |2022-10-31 10:32:42.0 |2022-10-31 10:32:42.0 |
|8   |새로 작성하는 글 select key |새로 작성하는 내용 select key |newbie  |2022-10-31 10:37:04.0 |2022-10-31 10:37:04.0 |
|10  |새로 작성하는 글            |새로 작성하는 내용            |newbie  |2022-10-31 11:51:05.0 |2022-10-31 11:51:05.0 |
|----|---------------------|----------------------|--------|----------------------|----------------------|

4) 조회 작업의 구현과 테스트

//BoardServiceImpl 클래스

@Override
public BoardVO get(Long bno) {
	log.info("get..........." + bno);
	return mapper.read(bno); //특정 게시물 번호의 데이터 가져오기
}

조회는 게시물의 번호가 파라미터, BoardVO의 인스턴스가 리턴됨

게시글 번호가 1번에 해당하는 데이터를 가져오도록 테스트 코드 작성

//BoardServiceTests

@Test
public void testGet() {
	log.info(service.get(1L));
}

결과

INFO : jdbc.resultsettable - 

|----|-------|--------|-------|----------------------|----------------------|
|bno |title     |content|writer   |regdate                        |updatedate                  |
|----|-------|--------|-------|----------------------|----------------------|
|1   |테스트 제목 |테스트 내용  |user00 |2022-10-31 08:20:42.0 |2022-10-31 08:20:42.0 |
|----|-------|--------|-------|----------------------|----------------------|

 

5) 삭제/수정 구현과 테스트

정상적으로 수정과 삭제가 이루어지면 '1'이라는 값이 반환됨 : '==' 연산자를 이용해서 true/false를 처리할 수 있음

//BoardServiceImpl

@Override
public boolean modify(BoardVO board) {
	log.info("modify....." + board);
	return mapper.update(board) == 1; //정상적으로 수정되면 1이 반환됨
}

@Override
public boolean remove(Long bno) {
	log.info("remove......." + bno);
	return mapper.delete(bno) == 1; //정상적으로 삭제되면 1이 반환됨
}

 

testUpdate()의 경우: 특정 게시물을 먼저 조회, title 값을 수정한 후 이를 업데이트

//BoardServiceTests

@Test
public void testUpdate() {
	BoardVO board = service.get(1L);
	if(board==null) {
		return;
	}
	board.setTitle("제목을 수정합니다.");
	log.info("MODIFY RESULT: " + service.modify(board));
}
INFO : jdbc.resultsettable - 
|----|-----------|--------|-------|----------------------|----------------------|
|bno |title      |content |writer |regdate               |updatedate            |
|----|-----------|--------|-------|----------------------|----------------------|
|1   |제목을 수정합니다. |테스트 내용  |user00 |2022-10-31 08:20:42.0 |2022-10-31 12:25:03.0 |
|----|-----------|--------|-------|----------------------|----------------------|

INFO : org.zerock.service.BoardServiceImpl - modify.....BoardVO(bno=1, title=제목을 수정합니다., content=테스트 내용, writer=user00, regdate=Mon Oct 31 08:20:42 KST 2022, updateDate=Mon Oct 31 12:25:03 KST 2022)

INFO : org.zerock.service.BoardServiceTests - MODIFY RESULT: true

 

testDelete()의 경우: 해당 게시물이 존재할 때 true를 반환

//BoardServiceTests

@Test
public void testDelete() {
	//게시물 번호에 2번이 있는지 확인하고 테스트할 것
	log.info("REMOVE RESULT: " + service.remove(2L));
}
INFO : jdbc.sqltiming - delete from tbl_board where bno = 10 
 {executed in 18 msec}

INFO : org.zerock.service.BoardServiceTests - REMOVE RESULT: true
반응형
댓글