day1 class06 비즈니스 컴포넌트 실습1
일반적으로 프로젝트에서 사용하는 구조로 비즈니스 컴포넌트 구현 후 dependency를 점검한다.
1. BoardService 컴포넌트 구조
- 일반적으로 비즈니스 컴포넌트는 네 개의 자바 파일로 구성된다.
2. VO(Value Object) 클래스 작성
- 레이어와 레이어 사이에서 관련된 데이터를 한꺼번에 주고받을 목적으로 사용하는 클래스
- DTO(Data Transfer Object)라 하기도 함
- 테이블의 구조를 확인 하고 VO 클래스 작성
- 이름 형식 : [테이블명]VO.java 혹은 [테이블명]DTO.java
- private 접근제한자로 멤버변수를 선언하고 [alt][shift][[s] 키를 눌러 getter/setter을 생성한다.
- [alt][shift][[s] 키를 눌러 toString()함수도 생성한다. 이 메소드는 나중에 VO 객체의 값을 출력할 때 요긴하게 사용할 수 있다.
3. DAO(Data Access Object) 클래스 작성
- 데이터 베이스 연동을 담당하는 클래스
- CRUD(Create, Read, Update, Delete) 기능의 메소드가 구현 됨
- 현재 프로젝트에선 H2 데이터베이스에서 제공하는 jdbc 드라이버 필요
3.1 jdbc 드라이버 받기
- 아래와 같이 소스를 추가하면 잠시 후 Maven Denpendencies 폴더에 h2-1.4.191.jar 드라이버가 생성된다.
- h2 드라이버 버전은 h2 구동 시 브라우저상에서 왼쪽에서 확인 가능하다.
1 2 3 4 5 6 7 8 9 10 11 | <!-- pom.xml --> <dependencies> <!-- H2 데이터베이스 --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.196</version> </dependency> <!-- 생략 --> </dependencies> | cs |
3.2 jdbc utility 클래스
- mybatis 같은 프레임워크 사용 전까지는 데이터베이스 연동 처리를 JDBC로 한다.
- 드라이버를 연결해주는 getConnection메소드와 연결을 종료시켜주는 close메소드를 생성한다.
3.3 DAO 클래스 작성
- BoardVO 객체를 배개변수와 리턴타입으로 사용하면서 board 테이블과 CRUD 기능을 처리할 클래스를 작성한다.
- 데이터베이스 연동을 처리하는 @Repository 어노테이션을 추가한다.
- 이름형식 : [테이블명]DAO.java
등록 : insert[테이블명]
수정 : update[테이블명]
삭제 : delete[테이블명]
상세조회 : get[테이블명 / select[테이블명]
목록검색 : get[테이블명]LIst / select[테이블명]List
***
select nvl(max(seq), 0)+1 from board
NVL 함수는 NULL 값을 다른 값으로 바꿀 때 사용하며, 모든 데이터 타입에 적용이 가능하다.
>> board 테이블에서 seq의 최댓값을 찾아 1을 더한다. 만약 null일 경우 0을 반환하고 1을 더한다.
***
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | package com.springbook.biz.board.impl; import org.springframework.stereotype.Repository; // DAO(Data Access Object @Repository("boardDAO") public class BoardDAO { // JDBC 관련 변수 private Connection conn = null; private PreparedStatement stmt = null; private ResultSet rs = null; // SQL 명령어들 private final String BOARD_INSERT = "insert into board(seq, title, writer, content) values((select nvl(max(seq), 0)+1 from board),?,?,?)"; private final String BOARD_UPDATE = "update board set title=?, content=? where seq=?"; private final String BOARD_DELETE = "delete board where seq=?"; private final String BOARD_GET = "select * from board where seq=?"; private final String BOARD_LIST = "select * from board order by seq desc"; // CRUD 기능의 메소드 구현 // 글 등록 public void insertBoard(BoardVO vo) { System.out.println("===> JDBC로 insertBoard() 기능 처리"); try { conn = JDBCUtil.getConnection(); stmt = conn.prepareStatement(BOARD_INSERT); stmt.setString(1, vo.getTitle()); stmt.setString(2, vo.getWriter()); stmt.setString(3, vo.getContent()); stmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtil.close(stmt, conn); } } // 글 수정 // 글 삭제 // 글 상세 조회 // 글 목록 조회 public List<BoardVO> getBoardList(BoardVO vo) { System.out.println("===> JDBC로 getBoardList() 기능 처리"); List<BoardVO> boardList = new ArrayList<BoardVO>(); try { conn = JDBCUtil.getConnection(); stmt = conn.prepareStatement(BOARD_LIST); rs = stmt.executeQuery(); while (rs.next()) { BoardVO board = new BoardVO(); board.setSeq(rs.getInt("SEQ")); board.setTitle(rs.getString("TITLE")); board.setWriter(rs.getString("WRITER")); board.setContent(rs.getString("CONTENT")); board.setRegDate(rs.getDate("REGDATE")); board.setCnt(rs.getInt("CNT")); boardList.add(board); } } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtil.close(rs, stmt, conn); } return boardList; } } | cs |
4. Service 인터페이스 작성
- DAO클래스에서 <alt> + <shift> + <T>를 눌러 인터페이스를 생성한다.
- BoardDAO에서 implements 코드는 삭제한다.
- BoardService 인터페이스는 BoardServiceImpl 클래스가 구현해야 하고, BoardDAO 클래스는 독립된 클래스로 구현되어야 한다.
5. Service 구현 클래스 작성
- 비즈니스 로직을 처리하는 @Service 어노테이션을 추가하고 BoardService 인터페이스의 추상메소드를 재정의(Overriding)하여 구현한다.
- @Autowired 어노테이션을 추가하여 BoardDAO 타입의 객체를 의존성 주입하도록 설정한다.
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 31 | package com.springbook.biz.board.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service("boardService") public class BoardServiceImpl implements BoardService { @Autowired private BoardDAO boardDAO; public void insertBoard(BoardVO vo) { boardDAO.insertBoard(vo); } public void updateBoard(BoardVO vo) { boardDAO.updateBoard(vo); } public void deleteBoard(BoardVO vo) { boardDAO.deleteBoard(vo); } public BoardVO getBoard(BoardVO vo) { return boardDAO.getBoard(vo); } public List<BoardVO> getBoardList(BoardVO vo) { return boardDAO.getBoardList(vo); } } | cs |
1 2 3 | <!-- applicationContext.xml --> <context:component-scan base-package="com.springbook.biz"></context:component-scan> | cs |
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 31 32 33 34 35 36 37 | // BoardServiceClient.java package com.springbook.biz.board; import java.util.List; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; public class BoardServiceClient { public static void main(String[] args) { // 1. Spring 컨테이너를 구동한다. AbstractApplicationContext container = new GenericXmlApplicationContext("applicationContext.xml"); // 2. Spring 컨테이너로부터 BoardServiceImpl 객체를 Lookup한다. BoardService boardService = (BoardService)container.getBean("boardService"); // 3. 글 등록 기능 테스트 BoardVO vo = new BoardVO(); vo.setTitle("임시 제목"); vo.setWriter("홍길동"); vo.setContent("임시 내용.............."); boardService.insertBoard(vo); // 4. 글 목록 검색 기능 테스트 List<BoardVO> boardList = boardService.getBoardList(vo); for(BoardVO board : boardList) { System.out.println("---> " + board.toString()); } // 5. Spring 컨테이너 종료 container.close(); } } | cs |