2014년 1월 12일 일요일

A. Srping Framework 게시판 만들기 (리스트,페이징,검색) , 스프링 게시판 소스, 리스트보기, 스프링공부, Spring학원


 A. Srping Framework 게시판 만들기 (리스트,페이징,검색) , 스프링 게시판 소스, 리스트보기, 스프링공부, Spring학원




1.     시작하기
 
-       이클립스 프로젝트명(Context명)은 onjboard1
-       이클립스 STS Plug-In을 설치 하였으며 MAVEN, MAVEN Plug-In도 설치하였음
-       Spring MVC Project를 작성(프로젝트 이름은 onjboard1)
-       Spring Version은 3.2.3
-       오라클에 접속하여 scott 계정에서 게시판용 테이블 및 데이터 2건 만들자
 
 -- 게시판
-- 게시글번호, 작성자, 비밀번호, 글제목, 글내용, 파일이름, 작성일, 조회수
create table board02(
  seq       varchar2(1000),
  name      varchar2(20) not null,
  passwd    varchar2(20) not null,
  title     varchar2(500)not null,
  content   clob         not null,
  filename  varchar2(100)not null,
  regdate   date         default sysdate,
  readcount number(10)   default 0,
  
  constraint b_seq_pk primary key(seq)
);

create sequence sequence_board_seq
start with 1 increment by 1;

-- 댓글
-- 댓글 입력한 게시글 번호, 댓글 깊이, 댓글 출력순서
create table reply(
  reply       varchar2(1000) not null,
  reply_step  number(10) default 0,
  reply_level number(10) default 0,
  constraint reply_seq_fk foreign key(reply) references board02(seq)
);

-- 코멘트
-- 코멘트 입력 번호, 코멘트 작성자, 코멘트 내용, 코멘트 입력된 게시글번호
create table comment_t02(
  comment_seq  varchar2(1000),
  comment_name varchar2(20)   not null,
  comment_comm varchar2(4000) not null,
  seq          varchar2(1000) not null,
  
  constraint comment_t_comment_seq_pk primary key(comment_seq),
  constraint comment_t_seq_fk foreign key(seq) references board02(seq)
);

create sequence sequence_comment_seq
start with 1 increment by 1;

INSERT ALL
       INTO board02 VALUES(sequence_board_seq.nextval,name,passwd,title,content,filename,regdate,readcount)
       INTO reply   VALUES(sequence_board_seq.currval,reply_step,reply_level)
SELECT '오엔제이' AS name, '1111' AS passwd, '질문입니다.' AS title, 'SQL을 배울 수 있느 과정이 뭐죠??'AS content, ' ' As filename, SYSDATE AS regdate, 0 AS readcount,
       0 AS reply_step, 0 AS reply_level
FROM DUAL;

INSERT ALL
       INTO board02 VALUES(sequence_board_seq.nextval,name,passwd,title,content,filename,regdate,readcount)
       INTO reply   VALUES(sequence_board_seq.currval,reply_step,reply_level)
SELECT '오엔제이2' AS name, '1111' AS passwd, 'JAVA 질문입니다.' AS title, 'JAVA을 배울 수 있느 과정이 뭐죠??'AS content, ' ' As filename, SYSDATE AS regdate, 0 AS readcount,
       0 AS reply_step, 0 AS reply_level
FROM DUAL;

commit;

2.     /WEB-INF/web.xml 만들기

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>EUC-KR</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/appServlet/servlet-context.xml 
</param-value>
</context-param>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name> 
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/appServlet/servlet-context.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet> 
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>

</web-app>

3.     /WEB-INF/spring/appServlet/servlet-context.xml 

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />

<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<beans:property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<beans:property name="url"      value="jdbc:oracle:thin:@localhost:1521:ex"/>
<beans:property name="username" value="study"/> 
<beans:property name="password" value="study"/>
</beans:bean>
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/jsp/"/>
<beans:property name="suffix" value=".jsp" /> 
</beans:bean>

<!-- 넘어오는 URL에 따라 컨트롤러에서 실행될 메소드 매핑 -->
<!-- PropertiesMethodNameResolver는 prop key로 넘어오는 url에 대해 실행할 컨트롤러의 메소드 정의 -->
<beans:bean id="userControllerMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<beans:property name="mappings">
<beans:props>
<beans:prop key="/list.html">list</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<!-- controller mapping -->
<beans:bean name="/list.html" class="com.onj.board.BoardMultiController">
<beans:property name="methodNameResolver" ref="userControllerMethodNameResolver"/>
<beans:property name="boardService" ref="boardService"/>
<beans:property name="pageHandler" ref="pageHandler"/>
</beans:bean>
</beans:beans>

4.     /WEB-INF/spring/boardConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="boardDAO" class="com.board.dao.BoardDAOImple">
<property name="dataSource">
<ref bean="dataSource"/>
</property> 
</bean>
          
<bean id="boardService"  class="com.board.service.BoardServiceImple">
<property name="boardDAO">
<ref bean="boardDAO"/>
</property>
</bean>
<bean id="pageHandler" class="com.board.util.PageHandler">
<property name="boardDAO">
<ref bean="boardDAO"/>
</property>
</bean>
</beans>

5. [BoardDTO.java]

package com.board.model;

public class BoardDTO {
private String seq;
private String name;
private String passwd;
private String title;
private String content;
private String filename;
private String regdate;
private int    readcount;
private String reply;
private int    reply_step;
private int    reply_level;
public BoardDTO(){};
public BoardDTO(String seq, String name, String title, String regdate, int readcount,
 int reply_level) {
super();
this.seq = seq;
this.name = name;
this.title = title;
this.regdate = regdate;
this.readcount = readcount;
this.reply_level = reply_level;
}
public String getSeq() {
return seq;
}
public void setSeq(String seq) {
this.seq = seq;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
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 getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String getRegdate() {
return regdate;
}
public void setRegdate(String regdate) {
this.regdate = regdate;
}
public int getReadcount() {
return readcount;
}
public void setReadcount(int readcount) {
this.readcount = readcount;
}
public String getReply() {
return reply;
}
public void setReply(String reply) {
this.reply = reply;
}
public int getReply_step() {
return reply_step;
}
public void setReply_step(int reply_step) {
this.reply_step = reply_step;
}
public int getReply_level() {
return reply_level;
}
public void setReply_level(int reply_level) {
this.reply_level = reply_level;
}
}
6. [BoardDAO.java], [BoardDAOImple.java]

package com.board.dao;
import java.util.List;
import java.util.Map;
import org.springframework.dao.DataAccessException;
import com.board.model.BoardDTO;
public interface BoardDAO {
// 전체 게시글 수
public int boardCount(Map<String, Object>searchMap)throws  DataAccessException;
// 게시판 리스트
public List<BoardDTO> boardList(Map<String,  Object>searchMap) throws  DataAccessException;
}

------------------------------------------------------------------------------------------

package com.board.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import com.board.model.BoardDTO;
public class BoardDAOImple implements BoardDAO {
private JdbcTemplate jdbaTemplate;
public void setDataSource(DataSource dataSource){
this.jdbaTemplate = new JdbcTemplate(dataSource);
}
// 게시글 수
public int boardCount(Map<String, Object>searchMap)throws  DataAccessException{
int count = 0;
String sql = "";
if(searchMap.get("boardListSearchText") == null){
sql = "select count(*) from board02";
count = jdbaTemplate.queryForObject(sql,
  Integer.class
   );
}else{
String boardListSelect = (String)  searchMap.get("boardListSelect");
String boardListSearchText = (String)  searchMap.get("boardListSearchText");
sql = "select count(*) from board02 where "+boardListSelect+" like  '%"+boardListSearchText+"%'";
count = jdbaTemplate.queryForObject(sql,Integer.class)   
return count;
}
// 게시판 리스트
public List<BoardDTO> boardList(Map<String, Object>searchMap) throws  DataAccessException {
List<BoardDTO> boardList = null;
String sql = "";
Object[] obj;
if(searchMap.get("boardListSearchText") == null){
sql = "select * from ("
+ "select  b.seq ,b.name,b.title  ,TO_CHAR(b.regdate,'YYYY/MM/DD')as  regdate, b.readcount, "
+ "r.reply_level"
+ "from board02 b, reply r"
+ "where b.seq = r.reply"
+ "order by r.reply desc,  r.reply_step asc"
+ ")"
+ "where ROWNUM BETWEEN ? AND ?";
obj = new Object[]  {searchMap.get("startRow"),searchMap.get("endRow")};
}else{
String boardListSelect = (String)  searchMap.get("boardListSelect");
String boardListSearchText = (String)  searchMap.get("boardListSearchText");
sql = "select * from ("
+ "select  b.seq ,b.name,b.title          ,TO_CHAR(b.regdate,'YYYY/MM/DD')as  regdate, b.readcount, "
+ "r.reply_level"
+ "from board02 b, reply r"
+ "where b.seq = r.reply"
+ "and "
+boardListSelect+"like '%"+boardListSearchText+"%'" 
+ "order by r.reply desc, r.reply_step asc"
+ ")"
+ "where ROWNUM BETWEEN ? AND ?";
obj = new Object[]  {searchMap.get("startRow"),searchMap.get("endRow")};}   
boardList = jdbaTemplate.query(sql, 
          obj, 
    new RowMapper<BoardDTO>(){
    public BoardDTO mapRow(ResultSet rs, int  rowNum)throws SQLException{
   
BoardDTO boardDTO = new  BoardDTO(rs.getString("seq"),
rs.getString("name"),
rs.getString("title"),
rs.getString("regdate"),
rs.getInt("readcount"),
rs.getInt("reply_level"));
return boardDTO;
    }
});
return boardList;
}
}

7. [EncodingHandler.java], [PageHandler.java]

package com.board.util;
import java.io.UnsupportedEncodingException;
public class EncodingHandler {
public static String toKor(String str){
String s = null;
try{
s = new String(str.getBytes("8859_1"),"euc-kr");
}catch(UnsupportedEncodingException e){e.printStackTrace();}
return s;
}
}

------------------------------------------------------------------------------------------

package com.board.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.board.dao.BoardDAO;

public class PageHandler {

private BoardDAO boardDAO;
public void setBoardDAO(BoardDAO boardDAO){this.boardDAO = boardDAO;}

// 페이지 사이즈, 페이지 그룹
private final int PAGESIZE  = 3;
private final int PAGEGROUP = 5;
// 전체 게시글 수
public int boardAllNumber(Map<String, Object>searchMap)throws Exception{
int count = boardDAO.boardCount(searchMap);
return count;
}
// 페이지 갯수
public int boardPageCount(Map<String, Object>searchMap)throws Exception{
int pageCount = boardAllNumber(searchMap) / PAGESIZE;
if(boardAllNumber(searchMap) % PAGESIZE !=0){pageCount++;}
return  pageCount;
}
// startPage
public int boardStartPage(int pageNum)throws Exception{
int startPage = (pageNum - 1) / PAGEGROUP * PAGEGROUP +1;
return startPage;
}
// endPage
public int boardEndPage(int pageNum, Map<String, Object>searchMap)throws Exception{
int endPage = boardStartPage(pageNum)+ (PAGEGROUP-1);
if(endPage > boardPageCount(searchMap)){ endPage =  boardPageCount(searchMap); }
return endPage;
}
// 처음, 마지막 rowNumber
public List<Object> boardSetPageNumber(int pageNum)throws Exception{
List<Object> list = new ArrayList<Object>();
int endRow   = PAGESIZE*pageNum;
int startRow = endRow - PAGESIZE+1;
list.add(startRow);
list.add(endRow);
return list;
}
}

8. [BoardService.java],[BoardServiceImple.java]

package com.board.service;
import java.util.List;
import java.util.Map;
import com.board.model.BoardDTO;
public interface BoardService {
// 게시글 수
public int boardCount(Map<String, Object>searchMap)throws  Exception;
// 게시판 리스트
public List<BoardDTO> boardList(Map<String,  Object>searchMap)throws Exception;
}

------------------------------------------------------------------------------------------
package com.board.service;
import java.util.List;
import java.util.Map;
import com.board.dao.BoardDAO;
import com.board.model.BoardDTO;
public class BoardServiceImple implements BoardService {
private BoardDAO boardDAO;
public void setBoardDAO(BoardDAO boardDAO){
this.boardDAO = boardDAO;
}
// 게시글 수
public int boardCount(Map<String, Object> searchMap) throws  Exception {
return boardDAO.boardCount(searchMap);
}
// 게시판 리스트
public List<BoardDTO> boardList(Map<String, Object>  searchMap) throws Exception {
return boardDAO.boardList(searchMap);
}
}

9. [BoardMultiController.java]
package com.onj.board;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import com.board.model.BoardDTO;
import com.board.service.BoardService;
import com.board.util.EncodingHandler;
import com.board.util.PageHandler;

public class BoardMultiController extends MultiActionController{
private BoardService boardService;
private PageHandler  pageHandler;
public void setBoardService(BoardService boardService){this.boardService = boardService;}
public void setPageHandler(PageHandler pageHandler) {this.pageHandler = pageHandler;}
ModelAndView mav = null;

// 게시판 리스트
public ModelAndView list(HttpServletRequest request,  HttpServletResponse response)throws Exception{
mav = new ModelAndView();
 
List<BoardDTO> list = null;
// 검색select , 검색Text
String boardListSelect = request.getParameter("boardListSelect");  
String boardListSearchText =  request.getParameter("boardListSearchText");
Map<String, Object> searchMap = new HashMap<String,  Object>();  
if(boardListSearchText != null){ 
searchMap.put("boardListSearchText",  EncodingHandler.toKor(boardListSearchText));
searchMap.put("boardListSelect", boardListSelect); 
}
String pageNumber =  request.getParameter("pageNumber");
int pageNum = 1;
if(pageNumber != null){pageNum = Integer.parseInt(pageNumber);}
// 게시글 수
int totalCount =  pageHandler.boardAllNumber(searchMap);
// 페이지 갯수
int totalPageCount =  pageHandler.boardPageCount(searchMap);
// startPage , endPage
int startPage =  pageHandler.boardStartPage(pageNum);
int endPage   =  pageHandler.boardEndPage(pageNum,searchMap);
// 처음, 마지막 rowNumber
List<Object> rowNumberList = new ArrayList<Object> ();
rowNumberList =  pageHandler.boardSetPageNumber(pageNum);
searchMap.put("startRow", rowNumberList.get(0));
searchMap.put("endRow", rowNumberList.get(1));
// 글 전체 출력
list = boardService.boardList(searchMap);
mav.addObject("pageNumber",pageNum);
mav.addObject("boardCount",totalCount);
mav.addObject("totalPageCount", totalPageCount);
mav.addObject("startPage", startPage);
mav.addObject("endPage", endPage);
mav.addObject("list", list);
mav.setViewName("list");
return mav;
}
}

10. [WEB-INF/jsp/list.jsp], [/js/boardActionJs.js], [/css/boardCss.css]
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"  %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
 
<link rel="stylesheet" type="text/css" href="/board/css/boardCss.css">
<script type="text/javascript" src="/board/js/boardActionJs.js"></script>

<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Insert title here</title>
</head>
<body>
<form name="listForm" method="get">
<table class="listTable">
<tr> 
<td colspan="5" align="right" id="boardListCount">게시글 수 : ${boardCount} 건</td>
</tr>
</table>
<table class="listTable" border="1" cellpadding="0" cellspacing="0"> 
<tr>
<th>번호</th>
<th>글제목</th>
<th>작성자</th> 
<th>작성일</th>
<th>조회수</th>
</tr>
<tr> 
<c:if var="boardCountZroe" test="${boardCount == 0}">
<td colspan="5">
<font color="red">게시글이 없습니다.</font>
</td>
</c:if>
</tr>
<c:if test="${!boardCountZroe}">
<c:forEach var="list" items="${list}">
<tr>
<td>${list.seq}</td>
<td>
<a href="">${list.title}</a>
</td>
<td>${list.name}</td>
<td>${list.regdate}</td>
<td>${list.readcount}</td>
</tr>
</c:forEach> 
</c:if>
</table>
<!-- 페이지 -->
<c:if test="${!boardCountZroe}">
<table class="listTable">
<tr>
<td colspan="5" align="center">
<c:if test="${startPage > 1}">
<span>
<a href="/board/list.html?pageNumber=${startPage - 1}">이전</a>
</span>
</c:if>
<c:forEach var="i" begin="${startPage}" end="${endPage}">
<c:choose>
<c:when test="${pageNumber == i }">
<span>
<a href="/board/list.html?pageNumber=${i}" id="boardList_a">${i}</a> 
</span>
</c:when>
<c:otherwise>
<span>
<a href="/board/list.html?pageNumber=${i}">${i}</a> 
</span>
</c:otherwise>
</c:choose>
</c:forEach>
<c:if test="${endPage < totalPageCount}">
<span> 
<a href="/board/list.html?pageNumber=${endPage + 1}">다음</a>
</span> 
</c:if>
</td>
</tr>
</table>
</c:if>
<!-- 검색 -->
<table class="listTable">
<tr>
<td colspan="5" align="center">
<select name="boardListSelect">
<option value="name">작성자</option>
<option value="title">글제목</option>
<option value="seq">글번호</option>
</select> 
<input type="text" id="boardListSearchText" name="boardListSearchText" onkeydown="enterEvent();"> 
<input type="button" value="검색" onclick="boardListSearchGo();">
/
<input type="button" value="글 입력" onclick="Location.href='#'"> 
</td>
</tr>
</table>
</form>
</body>
</html>

------------------------------------------------------------------------------------------

// 검색 
function boardListSearchGo(){
document.listForm.action ="/board/list.html"; 
document.listForm.submit();
  
// 검색Text입력 후 바로 엔터 가능하게 하는 이벤트
function enterEvent(){
if(window.event.keyCode == 13){
boardListSearchGo();
}
}

------------------------------------------------------------------------------------------

@CHARSET "EUC-KR";
td{text-align: center;}
th{text-align: center;}
 
a:link{ text-decoration:none;    color: #5D5D5D;}
a:visited{ text-decoration:none; color: #5D5D5D;}
a:active{ text-decoration:none;  color: #47C83E;}
a:hover{ text-decoration:none;   color: #47C83E;}
.listTable{width:600px;}
#boardListCount{text-align: right;}
#boardList_a{font-weight: bold; color:#8041D9;}



댓글 없음:

댓글 쓰기