Kim VamPa

[STS][스프링 게시판][1] 게시판 등록 기능 구현 - 1 본문

스프링 프레임워크/게시판 프로젝트

[STS][스프링 게시판][1] 게시판 등록 기능 구현 - 1

Kim VamPa 2021. 2. 17. 09:40
728x90
반응형

Git 주소 : github.com/sjinjin7/Blog_BoardProject

목표

 

게시판 등록 기능 구현

 게시판에 대한 정보를 담는 DB 테이블을 생성하고 웹에서 해당 테이블에 정보를 즉, 게시판을 등록하는 기능 구현을 목표로합니다. 

 

 게시판 등록 기능 구현 뿐만 아니라 앞으로의 대부분 기능 구현 작업순서는 'VO,DTO(도메인 모델 계층)' -> 'Mapper(퍼시스턴트 계층)' -> 'Service(비즈니스 계층)' -> 'Controller(제어 계층)' -> 'JSP(프리젠티에션 계층)' 순으로 작업할 것입니다. 각 계층의 역할을 간략히 설명하면 다음과 같습니다.

 

 

그림 1

 

도메인 모델 계층

  •  도메인 모델은 각 계층간의 전달 되어야 할 정보를 담는 객체 입니다.
  •  해당 객체에 담긴 데이터들은 캡슐화해서 보관됩니다. ( 데이터의 접근자 private / getter,setter를 통해 데이터 접근)

퍼시스턴트 계층 

  •  DAO 계층이라고도 불립니다. 
  •  DB 질의를 통해서 데이터 러치를 담당하는 객체입니다.

비즈니스 계층

  •  핵심 업무 로직의 구현과 그에 관련된 데이터의 적합성 검증 외에도 다양한 부가적인 구현을 수행합니다.(ex. 트랜잭션 처리, 다른 계층들간 통신을 위한 인터페이스 제공, 해당 계층의 객체들간의 관계를 관리 등..)
  •  퍼시스턴트 계층과 제어 계층을 연결 하는 역할을 합니다.

제어 계층

  •  사용자로부터 요청을 받고 응답을 처리하는 계층입니다. 
  •  전체 시스템의 설정 상태를 유지합니다.
  •  사용자의 요청을 검증하고 필요시 비즈니스 계층에 필요 로직을 요청 후, 전달 받은 응답을 적절한 뷰에 연결합니다.

프리젠테이션 계층

  •  사용자와 애플리케이션 간 인터페이스 역할을 합니다. 
  •  사용자가 선택할 수 있는 기능이 표시되어 있어야 하며, 요청에 필요한 부가적 정보 전달을 위한 입력양식이 있어야 합니다.
  •  애플리케이션으로부터 전달 받은 데이터를 효과적으로 보여주기 위한 로직이 포함 됩니다.

 

 참고 : egloos.zum.com/mt1716/v/9291203

 

 

순서

1. 게시판 테이블 생성

2. BoardVO 클래스 작성

3. Mapper 처리 및 테스트

4. Service 처리 및 테스트

 

 

1. 게시판 테이블 생성

  게시판의 정보를 저장할 테이블을 아래의 명령문을 통해서 생성합니다.

 

Oracle

 

1
2
3
4
5
6
7
8
9
10
11
 
create table vam_board(
    bno number generated always as IDENTITY,
    title varchar2(150not null,
    content varchar2(2000not null,
    writer varchar2(50not null,
    regdate date default sysdate,
    updatedate date default sysdate,
    constraint pk_board PRIMARY key(bno)
);
 

 

 

 

MySQL

 

1
2
3
4
5
6
7
8
9
10
11
 
create table vam_board(
    bno int auto_increment,
    title varchar(150),
    content varchar(2000),
    writer varchar(50),
    regdate timestamp default now(),
    updatedate timestamp default now(),
    constraint pk_board PRIMARY key(bno)
);
 

 

 

 - 게시판 테이블(vam_board)에 등록할 정본는 'bno(게시판 번호)', 'title(게시판 제목)', 'content(게시판 내용)', 'writer(게시판 작성자)', 'regdate(등록날짜)', 'updatedate(수정날짜)' 입니다.

 

 - 'bno' 경우 새로운 행을 작성할 때마다 자동으로 +1 증가된 값으 입력되도록 설정하였습니다.

(자동값 증가(Oracle, MySQL)(IDENTITY, AUTO_INCREMENT) 참고)

 

 - 각 게시물을 고유하게 구분해주기 위해 'bno' 열에 PRIMARY KEY 속성을 추가하였습니다. ( 제약조건명을꼭 부여할 필요는 없지만 추 후 '데이터베이스 페이징 처리'에 사용하기 위해 pk_board로 부여하였습니다.)

 

 - 등록날짜(regdate), 수정날짜(updatedate) 값은 자동으로 현재의 시간정보가 입력되도록 설정하였습니다.

 

 

 

 'bno', 'regdate', 'updatedate' 값이 자동으로 잘 입력되는지 확인하기 위해서 INSERT문을 통해 3개의 행을 추가합니다. 삽입 후 정상적으로 데이터가 삽입되었는지 SELECT문을 통해서 확인합니다. 

 

Oracle 경우 데이터가 정상적으로 삽입되었는지 확인 했다면 "commit ;" 명령을 실행합니다.

 

1
2
3
4
5
6
7
 
insert into vam_board(title, content, writer) values ('테스트 제목''테스트 내용''작가');
insert into vam_board(title, content, writer) values ('테스트 제목''테스트 내용''작가');
insert into vam_board(title, content, writer) values ('테스트 제목''테스트 내용''작가');
 
select * from vam_board;
 

 

그림 2 Oracle 결과

 

그림 3 MySQL 결과

 

 

2. BoardVO 클래스 작성

 vam_board 테이블의 컬럼 구조를 반영하는 VO(Value Object) 클래스를 생성하겠습니다. 

 

 com.vam.model 패키지에 BoardVO 클래스를 생성 합니다.

 

그림 4

 

 

 BoardVO 클래스에 아래의 코드를 작성한 후 "Getter/Setter" 메서드와 "toString"메서드를 추가합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
    /* 게시판 번호 */
    private int bno;
    
    /* 게시판 제목 */
    private String title;
    
    /* 게시판 내용 */
    private String content;
    
    /* 게시판 작가 */
    private String writer;
    
    /* 등록 날짜 */
    private Date regdate;
    
    /* 수정 날짜 */
    private Date updateDate;
 

 

그림 5

 

그림 6

 

BoardVO 전체 코드

더보기
package com.vam.model;

import java.util.Date;

public class BoardVO {
	
	/*
    bno number generated always as IDENTITY,
    title varchar2(150) not null,
    content varchar2(2000) not null,
    writer varchar2(50) not null,
    regdate date default sysdate,
    updatedate date default sysdate
	*/

	/* 게시판 번호 */
	private int bno;
	
	/* 게시판 제목 */
	private String title;
	
	/* 게시판 내용 */
	private String content;
	
	/* 게시판 작가 */
	private String writer;
	
	/* 등록 날짜 */
	private Date regdate;
	
	/* 수정 날짜 */
	private Date updateDate;

	public int getBno() {
		return bno;
	}

	public void setBno(int bno) {
		this.bno = bno;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getWriter() {
		return writer;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}

	public Date getRegdate() {
		return regdate;
	}

	public void setRegdate(Date regdate) {
		this.regdate = regdate;
	}

	public Date getUpdateDate() {
		return updateDate;
	}

	public void setUpdateDate(Date updateDate) {
		this.updateDate = updateDate;
	}

	@Override
	public String toString() {
		return "BoardVO [bno=" + bno + ", title=" + title + ", content=" + content + ", writer=" + writer + ", regdate="
				+ regdate + ", updateDate=" + updateDate + "]";
	}


	
}

 

 

3. Mapper 처리 및 테스트

Mapper 작성(인터페이스, xml)

 com.vam.mapper 패키지에 BoardMapper.java 인터페이스를 생성합니다.

 

그림 7

 

 게시판 등록 쿼리를 요청하는 enroll() 메서드 코드를 작성합니다. 파라미터로는 BoardVO 

 

1
2
3
4
 
    /* 작가 등록 */
    public void enroll(BoardVO board);
 

 

그림 8

 

src/main/resources 경로에 있는 com/vam/mapper 폴더에 BoardMapper.xml 파일을 생성합니다. 

 

그림 9

 

 xml 파일을 mapper로서의 기능을 하도록 만들기 위해 아래와 같이 작성합니다.  가중 중요한 것은 namespace 속성 값을 앞에서 생성하고 작성한 Mapper 인터페이스의 경로를 포함하는 인터페이스의 이름을 작성해야한다는 점입니다. 

 

 namespace 속성 값이 중요한 이유는 MyBatis가 Mapper 인터페이스와 XML을 인터페이스 이름 과 namespace 속성 값을 가지고 판단하기 때문입니다. 인터페이스 이름과 namespace 속성 값이 동일한 이름이면 이를 병합해서 처리하는데, 이러한 경우에는 메서드 선언은 인터페이스에 존재하고 SQL에 대한 처리는 XML을 이용하게 됩니다. 'MyBatis 작동원리' 키워드로 구글링 하시면 작동 방식에 대한 정보를 얻을 수 잇습니다.(MyBatis에 대한 사용방법은 공식 홈페이지를 참고해주세요.)

 

1
2
3
4
5
6
7
8
9
10
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  <mapper namespace="com.vam.mapper.BoardMapper">
 
 
  </mapper>
 

 

그림 10

 

 

 Mapper 인터페이스에서 선언한 enroll 메서드 호출될 시에 실행될 SQL문을 아래와 같이 작성합니다. <insert>태그에 id 속성 값을 메서드 이름과 동일하게 작성합니다.

 

 insert문 경우 앞서 직접 수행하여 실행이되는것을 확인하였기 때문에 바로 사용하였습니다.

 

 값이 들어가야 할 구문에는 Mapper 인터페이스에서 선언한 enroll() 메서드의 파라미터 BoardVO 클래스의 멤버변수명을  #{}을 붙여서 작성합니다. "#{title}"의 경우 getTitle()/setTtile()을 의미 합니다. 따라서 BoardVO 멤버 변수인 title, content, writer에 값이 담긴 경우 그 값들이 각각 #{title}, #{content}, #{writer} 대체하여 SQL문이 실행됩니다.

 

1
2
3
4
5
6
7
8
 
    <!-- 게시판 등록 -->
    <insert id="enroll">
        
        insert into vam_board(title, content, writer) values (#{title}, #{content}, #{writer})
        
    </insert>
 

 

그림 11

 

 

Mapper 테스트

 작성한 Mapper 메서드를 정상적으로 작동하는지 Junit을 통해 테스트 하겠습니다.

 

 src/test/java 경로에 com/vam/mapper 패키지를 만든 후 BoardMapperTests.java 클래스를 생성합니다.

 

그림 12

 

 클래스에 다음과 같이 작성 후 Junit 테스트를 진행합니다. 정상적으로 처리가 되었다는 표시가 뜬다면 값이 삽입되었는지 select문을 통해 데이터베이스를 직접 확인 합니다.

 

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
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
public class BoardMapperTests {
 
     private static final Logger log = LoggerFactory.getLogger(BoardMapperTests.class);
     
     @Autowired
     private BoardMapper mapper;
 
     @Test
     public void testEnroll() {
         
         BoardVO vo = new BoardVO();
         
         vo.setTitle("mapper test");
         vo.setContent("mapper test");
         vo.setWriter("mapper test");
         
         mapper.enroll(vo);
         
     }
     
 
}
 

 

그림 13

 

그림 14

 

그림 15

 

그림 16

 

 

3. Service 처리 및 테스트

Service 작성

 com.vam.service 패키지에 BoardService.java 인터페이스를 생성합니다.

 

그림 17

 

 BoardService.java 인터페이스에 게시판 등록을 수행하는 메서드를 작성합니다.

 

1
2
3
4
 
    /* 게시판 등록 */
    public void enroll(BoardVO board);
 

 

그림 18

 

 인터페이스를 생성한 패키지에 작성한 메서드를 구현할  BoardServiceImpl.java 클래스를 생성합니다.

 

그림 19

 

 해당 클래스가 BoardService 인터페이스를 구현한다는 의미의 키워드를 작성합니다.

 

1
2
3
 
implements BoardService
 

 

그림 20

 

 스프링에서 해당클래스가 Service역할을 한다는 것을 인식 할 수 있도록 @Service 어노테이션을 추가합니다.

 

그림 21

 

 BoardMapper 인터페이스를 주입 해주는 코드를 작성합니다.

 

그림 22

 

 BoardService 인터페이스에서 선언한 메서드를 오버라이딩하여 메서드의 구현부를 작성합니다. 구현부에는 BoardMapper의 enroll() 메서드를 호출 하는 코드를 작성합니다.

 

1
2
3
4
5
6
7
8
 
    @Override
    public void enroll(BoardVO board) {
        
        mapper.enroll(board);
        
    }
 

 

그림 23

 

 

Service 테스트

 Service 클래스에 작성한 메서드가 정상적으로 동작하는지 확인하기 위해 테스트를 합니다.

 

 src/test/java 경로에 com/vam/service 패키지를 생성후 BoardServiceTests.java 클래스를 생성합니다.

 

그림 24

 

 생성한 클래스에 아래와같이 코드를 작성한 후 Junit 테스트를 진행합니다. 정상적으로 동작하였다는 표시가 보인다면 데이터베이스에도 정상적으로 값이 삽입되었는지 확인합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
public class BoardServiceTests {
    
    @Autowired
    private BoardService service;
    
    @Test
    public void testEnroll() {
        
        BoardVO vo = new BoardVO();
        
        vo.setTitle("service test");
        vo.setContent("service test");
        vo.setWriter("service test");
        
        service.enroll(vo);
        
    }
 
}
 

 

그림 25

 

그림 26

 

그림 27 Oracle 결과

 

그림 28 MySQL 결과

 

 

REFERENCE

  •  

DATE

  • 2020.02.17
728x90
반응형
Comments