티스토리 뷰
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
'Framework & Management > Spring' 카테고리의 다른 글
11월 1일 화요일 [코드로 배우는 스프링웹프로젝트] - 5day(1) (0) | 2022.11.01 |
---|---|
10월 31일 월요일 [코드로 배우는 스프링웹프로젝트] - 4day(2) (0) | 2022.10.31 |
10월 28일 금요일 [코드로 배우는 스프링웹프로젝트] -3day(3) (0) | 2022.10.28 |
10월 28일 금요일 [코드로 배우는 스프링웹프로젝트] -3day(2) (0) | 2022.10.28 |
10월 28일 금요일 [코드로 배우는 스프링웹프로젝트] -3day(1) (0) | 2022.10.28 |
- Total
- Today
- Yesterday
- Objects 클래스
- 역반복문
- 리스트연산자
- 순환할당
- FALSE
- 파이썬
- 문자열함수
- 리스트
- Format 클래스
- Arrays 클래스
- 함수
- Date 클래스
- StringTokenizer 클래스
- Calendar 클래스
- Math 클래스
- 포장 클래스
- 스레드 스케줄링
- StringBuilder 클래스
- 요소선택
- IndexError
- python
- 프로그램
- Random 클래스
- 자료형
- 기본 API 클래스
- Pattern 클래스
- StringBuffer 클래스
- not_in
- java.time.package
- 딕셔너리
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |