이 글은 코드로 배우는 스프링 웹 프로젝트(남가람북스, 구멍가게 코딩단)을 읽고 공부한 내용을 바탕으로 정리한 글입니다.
비즈니스 계층은 고객의 요구사항을 반영하는 계층으로 프레젠테이션 계층과 영속(persistence) 계층의 중간다리 역할을 합니다. 영속 계층은 데이터베이스를 기준으로 해서 설계를 나눠 구현하지만, 비즈니스 계층은 로직을 기준으로 해서 처리합니다.
예를 들어 persistence 계층이 데이터베이스를 기준으로 상품 처리 객체와 회원 처리 객체를 나누어 처리한다고 하면, business 계층은 로직에 따라 구매 서비스 하나의 객체로 처리합니다. (상품 처리 객체 / 회원 처리 객체와 상호작용)
1. Service 인터페이스
일반적으로 비즈니스 영역에 있는 객체들은 Service라는 용어를 써서 만듭니다. 비즈니스 계층을 위해서 프로젝트에서 service 패키지 아래에 BoardService
인터페이스와 이를 구현할 BoardServcieImpl
클래스를 만들겠습니다.
우선, BoardService
인터페이스는 다음과 같이 작성합니다. 일반적으로 Service 인터페이스를 설계할 때, 메서드 이름은 현실적인 로직의 이름을 붙이는 것이 관례입니다.
public interface BoardService {
public void register(BoardVO boardVO);
public BoardVO get(int bno);
public boolean modify(BoardVO boardVO);
public boolean remove(int bno);
public List<BoardVO> getList();
}
2. 스프링의 서비스 객체 설정
비즈니스 계층의 인터페이스와 구현 클래스가 작성되었다면(이후에 작성), 이를 스프링의 빈으로 등록하기 이해서 applicaionContext.xml
에 @Service
어노테이션(구현 클래스에서 사용)이 있는 service
패키지를 스캔하도록 추가합니다.
<context:component-scan base-package="com.hellomygreenworld.ex02.service"/>
3. Service 구현 클래스
본격적으로 Service 인터페이스를 구현하는 클래스를 작성해보겠습니다. 우선, BoardServiceImpl
를 생성하고 실제 구현부를 제외한 뼈대만 작성하겠습니다.
@Log4j
@Service
@AllArgsConstructor
public class BoardServiceImpl implements BoardService {
@Setter(onMethod_ = {@Autowired})
private BoardMapper mapper;
@Override
public void register(BoardVO boardVO) {
}
@Override
public BoardVO get(int bno) {
return null;
}
@Override
public boolean modify(BoardVO boardVO) {
return false;
}
@Override
public boolean remove(int bno) {
return false;
}
@Override
public List<BoardVO> getList() {
return null;
}
}
@Service
어노테이션은 계층 구조상 비즈니스 영역을 담당한느 객체임을 표시하기 위해 사용합니다.BoardServiceImple
가 동작하기 위해서는BoardMapper
객체가 필요합니다.@Setter
어노테이션으로 처리해주었습니다.@AllArgsConstructor
어노테이션은 모든 파라미터를 이용하는 생성자를 만듭니다. 따라서 아래와 같이BoardMapper
를 주입받는 생성자가 만들어집니다.
구조 설정이 완료되었으니, BoardService
객체가 정상적으로 생성되고 BoardMapper
가 제대로 주입되는지 확인하는 테스트를 해보겠습니다.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring-config/applicationContext.xml")
@Log4j
public class BoardServiceTests {
@Setter(onMethod_ = {@Autowired})
private BoardService service;
@Test
public void testExist() {
log.info(service);
assertNotNull(service);
}
}
정상적으로 객체가 만들어졌다면 아래와 같이 객체를 확인할 수 있습니다.
4. 등록 작업 구현 (register)
이제 본격적으로 실제 구현부를 작성해보겠습니다. 우선 등록 작업을 구현하겠습니다. 등록 작업은 BoardServiceImple
에서 파라미터로 전단되는 BoardVO
타입의 객체를 BoardMapper
를 통해 처리합니다. 구현된느 코드는 아래와 같습니다.
@Log4j
@Service
@AllArgsConstructor
public class BoardServiceImpl implements BoardService {
@Setter(onMethod_ = {@Autowired})
private BoardMapper mapper;
@Override
public void register(BoardVO boardVO) {
log.info("register - " + boardVO);
mapper.insertSelectKey(boardVO);
}
}
mapper.insertSelectKey()
메서드는 int를 반환하지만 현재 register()
메서드는 void 타입으로 선언되어있습니다. 반환값을 이용하려면 int 타입으로 선언할 수도 있습니다.
5. 목록(리스트) 작업 구현 (getList)
현재 테이블에 저장된 모든 데이터를 가져옵니다.
@Override
public List<BoardVO> getList() {
log.info("get list");
return mapper.getList();
}
6. 조회 작업 구현 (get)
@Override
public BoardVO get(int bno) {
log.info("get - " + bno);
return mapper.read(bno);
}
7. 수정 작업 구현 (modify)
수정 작업이 제대로 처리되었는지 확인하기 위해 boolean 리턴 타입을 갖도록 합니다.
@Override
public boolean modify(BoardVO boardVO) {
log.info("modify - " + boardVO);
return mapper.update(boardVO) == 1;
}
8. 삭제 작업 구현 (remove)
삭제 작업 또한 boolean을 리턴합니다.
@Override
public boolean remove(int bno) {
log.info("remove - " + bno);
return mapper.delete(bno) == 1;
}
9. 테스트
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring-config/applicationContext.xml")
@Log4j
public class BoardServiceTests {
@Setter(onMethod_ = {@Autowired})
private BoardService service;
@Test
public void testExist() {
log.info(service);
assertNotNull(service);
}
@Test
public void testRegister() {
BoardVO boardVO = new BoardVO();
boardVO.setTitle("new board title");
boardVO.setContent("new board content");
boardVO.setWriter("new board writer");
service.register(boardVO);
log.info("=== testRegister ===");
log.info("\tBno of created board: " + boardVO.getBno());
}
@Test
public void testGetList() {
log.info("=== testGetList ===");
service.getList().forEach(boardVO -> log.info(boardVO));
}
@Test
public void testGet() {
log.info("=== testGet ===");
log.info(service.get(1));
}
@Test
public void testModify() {
BoardVO boardVO = service.get(1);
boardVO.setTitle("modified title");
log.info("=== testModify ===");
log.info("\t Modify result: " + service.modify(boardVO));
}
@Test
public void testRemove() {
log.info("=== testRemove === ");
log.info("\t Delete result: " + service.remove(2));
}
}
모든 동작이 정상적으로 실행되며, 특히 modify()
와 remove()
는 boolean으로 선언하여 모두 true를 반환하는 것을 확인할 수 있습니다.
데이터베이스를 확인해보면 다음과 같습니다.
'Java > Spring' 카테고리의 다른 글
REST API란? (0) | 2023.01.23 |
---|---|
[Spring MVC] Presentation Tier 구현 (0) | 2023.01.12 |
[Spring MVC] Persistence Tier CRUD 구현 (0) | 2023.01.11 |
[Spring boot] Maria DB 설정 (0) | 2023.01.06 |
[Spring MVC] 컨트롤러의 Exception 처리 (0) | 2023.01.03 |
댓글