본문 바로가기
[ Developer ]/Spring Framework

[Spring] 스프링 기반 간단한 게시판

by 김현섭. 2016. 6. 30.
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
Spring 간단한 게시판

# 패키지 구조
  • 기존 방식
    • WEB -> Biz -> DAO
  • 바뀐 방식
    • WEB -> Service -> Biz -> DAO
    • Transaction 처리를 위해서 Service를 추가한 것
    • WEB
      • Controller
      • Session 필요 시 생성 후 Service로 넘김
      • 단순하게 URL Mapping을 통해 서비스 호출 기능
    • Service
      • Interface, Class 작성
      • Transaction 처리
      • Controller의 업무를 받아서 처리
      • 여러 개의 Biz를 가짐


우선 DB를 생성하기 위해서 Toad for Oracle에서 System 계정으로 로그인한다
Schema Browser에서 Users에서 계정을 추가한다


SPRING / spring로 계정을 생성한다

그런 후 Tablespace를 설정한다


그리고 Roles와 System privileges에서 HR 계정 권한을 복사한 후 System 계정을 끊고 SPRING으로 접속한다
Tables에서 ARTICLE이라는 테이블을 생성해본다


DESCRIPTION이 4000 CHAR를 넘을 수 있는 가능성에 대비해서 Data Type을 바꿔준다
그런 후 ARTICLE_ID_SEQ도 생성을 해준다

# 프로젝트 생성
Spring으로 돌아가서 SpringSimpleBoard로 생성한다 기본적인 세팅을 하고 URL은 board로 바꿔준다





# Spring 설정

pom.xml
pom.xml에서 build 밑에 있는 resources 부분과 repositories에서 부터
제일 밑까지를 복사해서 SpringSimpleBoard의 pom.xml에 붙여넣는다



spring view
src/main/webapp/WEB-INF/spring 과 view 폴더를 복사한다



src/main/resources 

src/main/resources의 logback.xml과 mybatis.xml을 복사한다


rootContext.xml

Connection Pool에서 DB id와 password를 수정한다


그런 후 aop:config에서 service 패키지에서 트랜잭션을 처리하기로 했으므로 web으로 되어있던 것을 service로 바꿔준다


applicationContext.xml
interceptor를 추가한 부분과 <bean으로 각각의 Controller들을 정의했던 것을 삭제한다


view 
view폴더에서 error 폴더를 제외한 필요없는 폴더를 제거한다

web.xml
기존의 web.xml에서 error-page 부터 밑에 까지 복사해서 복사하면 된다

handler
패키지를 생성한 후 handler패키지 생성해서 CUstomExceptionHandler를 복사한다



# Write Page
우선 view 폴더 내에 article 폴더를 생성하고 간단한 jsp를 만든다

write.jsp


이제는 컨트롤러를 통해서 write.jsp를 보여줄 수 있는 맵핑과 doWriterAction 맵핑을 만들어준다
그러기 위해서 패키지를 먼저 생성한다


우선 web에서 ArticleController를 생성한다
Mapping 메소드를 생성할 때 앞으로 보여주는 페이지는 view보여줄페이지Page라고 네이밍을 한다


작성 후엔 applicationContext.xml에서 articleController를 등록시켜준다


서버를 재시작하여 접속해보면 나오는 것을 볼 수 있다



# doWriteAction
/doWriteAction으로 form을 넘길 때 받으려면 service, biz, dao, vo를 생성해야 한다

vo를 먼저 생성한다


VO에서 Vaild Check를 해본다 필수적으로 입력 받을 것이 subject와 writer라면 @NotEmpty를 이용해서 체크를 한다


이제는 ArticleController에서 URL Mapping을 한다


form의 데이터를 request와 각각의 요소로 받을 수 있지만 객체로 받는게 편하므로 객체로 파라미터로 받아버린다
@Valid를 이용해서 받고 Valid가 등장하면 반드시 그 다음에 Errors가 등장해야 한다


이제 Service를 부르기 위해서 Service를 생성한다
ArticleService를 Interface로 생성한다


Service가 Controller의 기능을 하려면 Controller의 파라미터를 모두 Service가 받아야 한다
이제 구현 클래스인 Impl을 생성한다 Service 패키지 내에 impl패키지를 생성하고 정의한다


Service의 기능에서는 에러가 있다면 다시 페이지를 보낼 것이다


그래서 if 구절로 errors가 에러가 있다면 view.addObject로 보내왔던 데이터를 다시 보내줘서 입력한 양식을 그대로 보여줄 것이다
에러가 없다면 redirect:/list로 보내준다

그리고 Controller로 다시 가서 Service를 선언하고 setter만 만들어준다


그리고 나면 doWriteAction에서 맵핑을 리턴만 해주면 된다


이제 ArticleService를 Context에 추가를 시켜줘야 한다
하지만 ArticleService는 URL과 관련된 것이 아니므로 새로운 Context를 생성해준다

articleContext.xml


그런 후 applicationContext.xml에 가서 Controller에게 property로 articleService를 준다

applicationContext.xml


결과 화면은 동일하고 모두 입력하면 list로 간다

글쓴이를 입력하지 않는다면 Validation Check가 된다

 


그리고 폼안에서의 input에서는 value와 textarea에서는 중앙에 넣으면 입력했던 내용을 그대로 다시 보여준다

 



그리고 이제는 ArticleBiz Interface를 생성한다


구현 클래스를 넣을 impl 패키지 생성 후 ArticleBizImpl로 클래스를 생성한다


그리고 Biz를 사용할 Service에서 선언 후 setter 정의 후 articleBiz를 에러가 발생하지 않은 상황에 추가해준다


 그리고 articleContext.xml에서 ArticleBizImpl을 정의한 후 articleService가 갖도록 property를 작성한다


이제 DAO도 위와 같은 방식으로 생성을 해준다


그러나 DAO 구현 클래스에서는 extends SqlSessionDaoSupport를 상속 시켜줘야한다


이제 DAO가 쿼리를 실행할 수 있게 Mapper를 정의해줘야한다
우선 ArticleBizImpl에서 DAO를 사용할 수 있게 정의한다


그리고 ArticleContext에서 DAO를 정의하고 Biz에 property 시키면 된다
DAO는 sqlSessionTemplate를 property 정의 시키면 된다


이제 DAO에서 정의를 해주면 된다 그러기 위해서 우선 impl 패키지 내에 sql 패키지를 만들고
xml파일을 생성한다


그리고 난 후 DAO.xml을 Mapper 시켜주고 typeAliases로 ArticleVO를 추가해놓는다 

mybatis.xml


이제는 articleDAO.xml을 이용해서 쿼리를 생성하면 된다
insert 시키는 쿼리를 생성해본다


ARTICLE_ID와 ARTICLE_NUMBER는 SEQ의 VALUE가 2번 들어가야 하는데 시퀀스는 쿼리에서 2번 사용하지 못한다
그렇기 때문에 시퀀스를 따로 빼야한다 시퀀스를 따로 가져오는 쿼리가 필요하다


이 쿼리를 통해 가져온 값을 객체에 넣고 객체가 가진 값을 INSERT ARTICLE을 시키면 된다

INSERT 시킬 때 ARTICLE_ID는 PK이며 VARCHAR2로 선언이 되었다
그러나 같은 값인 ARTICLE_NUMBER는 NUMBER 타입으로 두개가 타입이 다른데
그래서 조금 복잡한 로직이 들어가야 한다


ARTICLE_ID는 시퀀스가 계속 돌면서 반복되므로 중복 방지를 위해서 앞에 다른정보를 붙여줌으로써 PK가 중복이 나지 않게 한다
날짜를 넣기 위해서 날짜를 가져오는 쿼리를 하나 더 생성한다


그렇다면 예를 들어 20160421이란 값을 가지고 오게 될 것이다 그러면 그러한 값들을 취합해 고유의 ARTICLE_ID를 생성한다
이제 INSERT 시키는 쿼리는 다음과 같이 완성될 수 있다


이제 ArticleBizImpl로 가서 로직을 만든다
DAO는 로직을 가지면 안되기 때문에 Biz에서 시퀀스 넘버와 SYSDATE를 가져와서 객체를 DAO에 줄 수 있도록 구성한다

그러기 위해서 ArticleDAO Interface에서 몇가지의 메소드를 더 정의한다


이제 구현 클래스에 가서 메소드를 아래와 같이 오버라이딩 한다
getSqlSession()을 통해서 쿼리를 실행시키면 된다


이제 Biz의 구현 클래스에 가서 로직을 추가한다


그런데 nextArticleId는 000001이 아니라 단순히 1로 입력이 되는데 lpad 로직을 통해서 6개의 0을 만들어본다


위와 같은 로직으로 lpad의 기능을 만들 수 있다 그리고 String articleId에 정의하는 부분에 넣는다


그러면 아래와 같이 로직을 모두 완성할 수 있다


그리고 나서 홈페이지를 통해서 데이터를 넣는다면 



위와 같이 입력이 된다


# List Page

우선 view/article 폴더에 list.jsp를 생성하고 ArticleController로 온다

list를 맵핑하는 메소드를 정의한다


그리고 ArticleService Interface에서 정의하고 구현 클래스에서도 정의해준다


그리고 페이징을 위해 VO를 생성한다 ArticleListVO


ArticleSearchVO도 정의를 한다


그리고 난 후 ArticleServiceImpl에서 메소드를 정의한다
페이징을 위해서 전체 개수를 가져와서 적용시켜야 한다


그리고 아직 생성되지 않은 메소드를 Biz Interface에 정의한다 그리고 구현 클래스로 오버라이딩 시킨다


Biz에서는 그저 DAO를 실행 시키는 로직만 추가를 한다
위와 같이 DAO도 인터페이스에 추가를 하고 구현 클래스로 오버라이딩 시킨다


ArticleCount는 전체 게시글의 개수만을 가져오는 쿼리이므로 selectOne으로 사용을 하고
getAllArticle은 List를 리턴하므로 selectList를 이용해서 쿼리를 실행하고 searchVO를 파라미터로 보낸다

이제 쿼리를 작성해준다


getAllAtricle에서 ArticleSearchVO를 입력해야 하므로 mybatis.xml에서 typeAlias 를 지정해준다


그리고 나서 쿼리를 완성 시킨다


이제는 jsp에서 뿌려주기만 하면 된다


결과는 다음과 같다


# Detail Page

우선 view/article 폴더에 detail.jsp를 생성한다


그런 후 ArticleController에서 정의를 한다


ArticleServiceImpl 


ArticleBizImpl


ArticleDAOImpl


위와 같이 정의 후에 쿼리를 생성해준다


컨트롤러에서 수정


작성을 하고 list.jsp에서 제목에 <a> 태그를 걸어주어서 detail로 보내준다