MVC 패턴(Model-View-Controller Pattern)
MVC 패턴은 여러가지 디자인 패턴 중에 하나이다. 즉, 건축으로 비유하자면 공법이며, 소프트웨어에 빗대어 말하자면 어떻게 소프트웨어를 개발할 것인지의 개발 방식을 공식화 한 패턴이다.
특히 MVC 패턴은 사용자와 상호작용을 하는 어플리케이션을 개발할 때 사용되는 방식이다. 예를 들어 웹 어플리케이션과 같이 UI(User Interface)를 통하여 사용자가 직접적으로 소통하는 부분들이 있는 어플리케이션에서 보편적으로 사용된다.
MVC(Model-View-Controller) 패턴은 이름에서도 알 수 있듯이, 어플리케이션을 기능적으로 크게 세 가지로 나눈다. 각 기능의 세부 정보는 아래와 같다.
모델(Model) : 비즈니스 영역의 로직을 처리한다.
뷰(View) : 비즈니스 영역에 대한 프레젠테이션 뷰(즉, 사용자가 보게 될 결과 화면)를 담당한다.
컨트롤러(Controller) : 사용자의 입력 처리와 흐름 제어를 담당한다.
각 부분이 어플리케이션에서 어떻게 동작하는지의 흐름도는 아래와 같다.
엄밀히 말하면 위의 디자인 패턴의 흐름도는 MVC2 패턴에 가깝지만, 이해를 돕기 위해서 사용하였다.
1. 사용자는 원하는 기능을 처리하기 위한 모든 요청을 컨트롤러에 보낸다.
2. 컨트롤러는 모델을 사용하여 알맞은 비즈니스 로직을 수행한다.
3. 사용자에게 보여줄 뷰를 선택한다.
4. 선택된 뷰는 사용자에게 알맞는 결과 화면을 보여준다. 이 때 사용자에게 보여줄 데이터는 컨트롤러를 통해서
전달받는다.
위와 같은 순서로 사용자의 요청을 처리하여 응답하기까지의 과정을 수행한다. 여기서 MVC 패턴의 핵심적인 부분을 정리하자면, 비즈니스 로직을 처리하는 모델과 결과 화면을 보여주는 뷰를 분리한다는 것과, 어플리케이션의 흐름 제어나 사용자의 처리 요청은 컨트롤러에 집중된다는 것이다.
* 비즈니스 로직(Business Logic)은 유저의 요청에 따른 결과물을 만들어내기 위한 일련의 작업들을 의미한다. 회원가입을 예로들면, 아이디 중복 체크를 할 때 유저에게는 단순하게 중복여부를 출력만 하지만, 내부적으로는 DB에 접근하여 유저가 입력한 아이디가 존재하는지 확인하는 절차가 진행된다. 다시 정리하자면, 사용자가 어떤 요청을 했을 때, 그 요청을 처리하기 위해 내부적으로 진행되는 절차를 비즈니스 로직이라고 한다.
MVC1 패턴(MVC1 Pattern)
MVC1 패턴은 JSP를 이용한 단순한 모델이다. 아래의 그림을 통해 자세히 알아보자.
1. 웹 브라우저에서 요청한다.
2. 요청을 JSP가 받아서 자바빈이나 서비스 클래스를 사용해서 웹 브라우저가 요청한 작업을 처리한다.
3. 결과를 클라이언트에게 응답한다.
따라서 JSP에서는 비즈니스 로직을 처리하기 위한 코드와 결과를 출력하는 코드가 섞이게 된다. 따라서 클라이언트의 요청을 받은 JSP에서 요청을 처리하고 출력까지 하게 된다. 그리고 글을 게시하고 삭제하는 등의 CRUD작업들은 자바빈으로 생성하여 수행하게 된다. 그런 역할을 하는 객체를 DAO라고 한다.
* DAO(Data Access Object)는 데이터 접근 객체로, DB의 CRUD를 목적으로 하는 객체이다. 하나의 커넥션을 통해서 객체를 생성하고 외부에서는 인터페이스를 통해서 접근하는 역할만하여, DB의 세부 내용을 노출시키지 않는다.
MVC2 패턴(MVC2 Pattern)
MVC2 패턴에서는 MVC1 패턴과 달리 뷰(View)와 컨트롤러(Controller)가 나뉘어 있다. 아래 그림을 통해 알아보자.
여기서 뷰는 JSP로 작성되며, 컨트롤러는 서블릿(Servlet)으로 작성되어 요청을 받아들이고 알맞게 처리한 후 그 결과를 보여줄 JSP 페이지로 포워딩한다. 하나하나 따져보자.
1. 웹 브라우저에서 요청한다.
2. 요청을 서블렛이 받아서 로직 클래스를 통해 요청을 처리한다. 여기서 비즈니스 로직에 알맞는 모델을 선택하여
처리한다.
3. 포워딩을 통해 요청 흐름을 받은 JSP 페이지는 결과 화면을 생성한다.
4. 결과를 클라이언트에게 응답한다.
MVC2 패턴의 가장 큰 특징은 웹 브라우저의 모든 요청을 단일 진입점(서블릿)에서 처리한다는 것이다. 서블릿은 웹 브라우저의 요청을 구분하여 알맞는 모델을 찾아 요청을 처리한다.
작성방법을 한 번 더 정리하자면 다음과 같다.
컨트롤러 - 서블릿(Servlet)
사용자의 요청을 받아들이는 컨트롤러는 서블릿으로 작성된다. 서블릿을 통해 요청을 받아서 그 요청을 처리하기에 알맞은 모델을 선택하여 처리하도록 흐름제어를 한다.
뷰 - JSP
사용자에게 최종적으로 보여지는 결과물을 JSP 페이지로 작성된다. 서블릿으로 부터 완벽하게 처리가 완료된 결과물을 받아서 JSP 페이지로 포워딩하여 결과물을 생성한다.
모델
모델의 경우는 비즈니스 로직을 처리할 수 있는 것이면 어떤 것이든 상관없다.
MVC1 패턴 vs MVC2 패턴
MVC1 패턴과 MVC2 패턴의 가장 큰 차이점은 뷰(View)와 컨트롤러(Controller)의 분할 여부이다. MVC1 모델은 뷰와 컨트롤러가 하나의 JSP페이지로 작성되는 형태이고, MVC2 모델은 서블릿으로 요청을 받아서 알맞게 처리한 후에 JSP 페이지로 포워딩하는 형태로 작동한다.
MVC1 패턴을 사용하는 경우
MVC1 패턴은 최근에는 거의 사용되지 않는다고 봐도 무방하다. 하지만 소규모 프로젝트를 진행할 때는 오히려 MVC2 패턴보다 구조가 단순하여 구축이 쉽다. 하지만 그 규모가 커질 수록 유지보수에 약점을 보인다.
MVC2 패턴을 사용하는 경우
MVC2 패턴은 최근 거의 표준처럼 사용되는 패턴이다. 규모가 큰 프로젝트를 하기에 적합하고, 각 기능이 확실하게 분리되어 있어서 유지보수에 상당한 이점을 보인다. 하지만 소규모 프로젝트를 진행함에 있어서 과도하게 구조가 복잡해질 수 있다는 단점이 있다. 최근에는 프래임워크를 통해 이러한 단점은 보완되었다고 할 수 있다.
MVC 패턴을 사용하는 이유
한 마디로 말하자면, 유지보수에서 상당히 유리해진다는 것이다. MVC패턴으로 잘 짜여진 웹 어플리케이션은 사용자에게 보여지는 부분(VIew)과 흐름 제어를 담당하는 부분(Controller), 비즈니스 로직을 수행하는 부분(Model)이 독립적으로 나눠지 있기 때문에 특정 부분을 수정하고자 하면, 그 부분만 열어서 수정하기에 상당히 용이하다.
만약에 하나의 JSP페이지에 비즈니스 모델과 컨트롤러, 뷰가 혼재한다면, 어떤 부분이 어떤 역할을 하는지도 정확하게 구분하기가 어려울 것이다. 이는 덩치가 큰 어플리케이션일수록 더 심각해질 것이다. 따라서 좋은 프로그래머라면 유지보수까지 고려한 MVC 패턴도 정확하게 알아두어야만 한다.
자 이제 코딩을 예를 들어서 설명해보겠다~!!!
전에 jsp/servlet을 이용한 프로젝트를 만들었는데 여기서 중요한 사실을 service대신에 서블릿의 implements를
사용하여 구성했다는 점이다~!!
- web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>12_board</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>board</servlet-name>
<servlet-class>myPkg.BoardFrontController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>board</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
web.xml의 경로를 *.do로 해주었다.
근데 이것은 상황에 따라서 *.ab이라던지 *.go라던지 등등의 경로로 바꿔주어도 된다.
여기서 사용한 command들이 많은데 저는 list를 위한 command만 일단 설명해보려고 한다.
일단 기본적으로 만들 command부터 소개해보도록 하겠다~~
- boardCommand
package myPkg;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface BoardCommand {
void execute(HttpServletRequest request, HttpServletResponse response);
}
자 그리고 list를 받아올 command도 설명해보겠다!!!
- boardListCommand(service대신)
package myPkg;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class BoardListCommand implements BoardCommand{
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) {
BoardDao dao = BoardDao.getInstance();
int page = 1;
if(request.getParameter("page")!=null){
page = Integer.parseInt(request.getParameter("page"));
}
Paging paging = new Paging();
paging.setPage(page);
paging.setTotalCount(44);
ArrayList<BoardBean> lists = dao.selectAll(page);
request.setAttribute("lists",lists);
request.setAttribute("paging", paging);
//request.setAttribute("paging",new BoardSearchVO(cri,total));
}
}
그리고 controller용 command도 사용해보겠다!!
- boardFrontController
package myPkg;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class BoardFrontController
*/
/*@WebServlet("*.do")*/
public class BoardFrontController extends HttpServlet {
private static final long serialVersionUID = 1L;
ServletContext context = null;
/**
* @see HttpServlet#HttpServlet()
*/
public BoardFrontController() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
context = config.getServletContext();
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//response.getWriter().append("Served at: ").append(request.getContextPath());
doProcess(request,response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//doGet(request, response);
doProcess(request,response);
}
public void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
request.setCharacterEncoding("UTF-8");
String uri = request.getRequestURI();
String conPath = request.getContextPath();
String command = uri.substring(conPath.length());
BoardCommand mcommand = null;
String viewPage = null;
String flag = (String)context.getAttribute("flag");
if(command.equals("/insert.do")) {
if(flag.equals("false")) {
mcommand = new BoardInsertCommand();
mcommand.execute(request, response);
context.setAttribute("flag", "true");
viewPage = "/list.do";
}
else {
viewPage = "/list.do";
}
}
else if(command.equals("/list.do")) {
mcommand = new BoardListCommand();
mcommand.execute(request, response);
viewPage = "boardList.jsp";
}
/*else if(command.equals("/paging.do")) {
mcommand = new BoardPageCommand();
mcommand.execute(request, response);
viewPage = "boardList.jsp";
}*/
else if(command.equals("/deleteProc.do")) {
mcommand = new BoardDeleteCommand();
mcommand.execute(request, response);
viewPage = "/list.do";
}
else if(command.equals("/deleteAll.do")) {
mcommand = new BoardDeleteAllCommand();
mcommand.execute(request, response);
viewPage = "/list.do";
}
else if(command.equals("/updateBoard.do")) {
mcommand = new BoardUpdateFormCommand();
mcommand.execute(request, response);
viewPage = "updateBoard.jsp";
}
else if(command.equals("/updateHit.do")) {
mcommand = new BoardUpdateHitCommand();
mcommand.execute(request, response);
viewPage = "updateView.jsp";
}
else if(command.equals("/updateProc.do")) {
mcommand = new BoardUpdateCommand();
mcommand.execute(request, response);
viewPage = "/list.do";
}
else if(command.equals("/id_check_proc.do")) {
mcommand = new BoardIdCheckCommand();
mcommand.execute(request, response);
return;
}
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);
dispatcher.forward(request, response);
}
}
그리고 boardDao, boardBean, paging처리를 한 코드도 한번 살펴보도록 한다~
기본적으로 paging이나 검색을 사용한 방법으로 게시판을 짤 수 있는데~ 저는 paging만 사용하여 프로젝트를
짜보았다~!!ㅎㅎㅎ
- boardDao.java
package myPkg;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class BoardDao {
private static BoardDao dao = null;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
DataSource ds = null;
private BoardDao(){
try {
Context context = new InitialContext();
ds = (DataSource) context.lookup("java:comp/env/jdbc/OracleDB");
conn = ds.getConnection();
} catch (SQLException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
}
public static BoardDao getInstance() {
if(dao == null) {
dao = new BoardDao();
}
return dao;
}
public void insertData(BoardBean bean) {
String sql = "insert into board(num,id,name,age,content,time,hit,memo) "
+ "values(board_seq.nextval,?,?,?,?,?,?,?)";
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, bean.getId());
pstmt.setString(2, bean.getName());
pstmt.setInt(3, bean.getAge());
pstmt.setString(4, bean.getContent());
pstmt.setString(5, bean.getTime());
pstmt.setInt(6,bean.getHit());
pstmt.setString(7, bean.getMemo());
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(pstmt!=null)
pstmt.close();
}catch(SQLException e) {
}
}
}//insertData
public int getArticleCount() {
String sql = "select count(*) as cnt from board";
int count = 0;
try {
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()) {
count = rs.getInt("cnt");
}
}catch(Exception e) {
e.printStackTrace();
}finally {
try {
if(rs!=null){
rs.close();
}
if(pstmt!=null){
pstmt.close();
}
}catch(Exception e) {
e.printStackTrace();
}
}return count;
}//getArticleCount-전체레코드 갯수 리턴
/*public ArrayList<BoardBean> getArticles(int startRow, int endRow){
ArrayList<BoardBean> lists = new ArrayList<BoardBean>();
String sql = "select num, id, name, age, content, time, hit, memo "
+ "from(select rownum as rank, num, id, name, age, content, time, hit, memo "
+ "from(select num, id, name, age, content, time, hit, memo from board order by num desc)) "
+ "where rank between ? and ?";
String sql = "select * from board order by num desc";
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, startRow);
pstmt.setInt(2, endRow);
rs = pstmt.executeQuery();
while(rs.next()) {
BoardBean bean = new BoardBean();
bean.setNum(rs.getInt("num"));
bean.setId(rs.getString("id"));
bean.setName(rs.getString("name"));
bean.setAge(rs.getInt("age"));
bean.setContent(rs.getString("content"));
bean.setTime(rs.getString("time"));
bean.setHit(rs.getInt("hit"));
bean.setMemo(rs.getString("memo"));
lists.add(bean);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
try {
if(rs!=null){
rs.close();
}
if(pstmt!=null){
pstmt.close();
}
}catch(Exception e) {
e.printStackTrace();
}
}
return lists;
}//getArticles
*/
public ArrayList<BoardBean> selectAll(int page){
ArrayList<BoardBean> lists = new ArrayList<BoardBean>();
//1번 페이지 1~10
//2번 페이지 11~20
int startNum = (page-1)*5+1;
int endNum = page*5;
System.out.println(startNum+"//"+endNum);
String sql="SELECT * FROM ("
+ "SELECT * FROM ("
+ "SELECT ROWNUM row_num, board.* FROM "
+ "board ORDER BY NUM DESC"
+ ")PAGING_BOARD WHERE row_num>=?"
+ ") WHERE row_num <=?";
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, startNum);
pstmt.setInt(2, endNum);
rs = pstmt.executeQuery();
while (rs.next()) {
int num = rs.getInt("num");
String id = rs.getString("id");
String name = rs.getString("name");
int age = rs.getInt("age");
String content = rs.getString("content");
String time = rs.getString("time");
int hit = rs.getInt("hit");
String memo = rs.getString("memo");
BoardBean dto =
new BoardBean(num, id, name, age, content, time, hit, memo);
lists.add(dto);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
return lists;
}// selectAll
public boolean nextPage (int pageNumber) {
String SQL = "SELECT * FROM board WHERE num < ? hit = 1 ORDER BY num DESC LIMIT 7";
ArrayList<BoardBean> list = new ArrayList<BoardBean>();
try {
pstmt = conn.prepareStatement(SQL);
pstmt.setInt(1, getNext() - (pageNumber -1) * 7);
rs = pstmt.executeQuery();
if (rs.next()) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
return false;
}
private int getNext() {
// TODO Auto-generated method stub
return 0;
}
public int getTotalCount(){
int total = 0;
try {
String sql = "select count(*) from board";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
if(rs.next()){
total = rs.getInt(1);
}
} catch (Exception e){
e.printStackTrace();
} finally {
try {
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
return total;
}
public void deleteData(String num){
String sql = "delete from board where num = ?";
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, Integer.parseInt(num));
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}//
public void deleteCheckData(String[] check){ // 11,13,17
PreparedStatement pstmt = null;
System.out.println("체크된 개수:"+check.length);
for(int i=0;i<check.length;i++){
System.out.println(check[i]);
}
//delete from movie where num=? or num=? or num=?;
String sql = "delete from board where num=?";
for(int i=0;i<check.length-1;i++){
sql += " or num=?";
}
try{
pstmt = conn.prepareStatement(sql);
for(int i=1;i<=check.length;i++){
pstmt.setInt(i,Integer.parseInt(check[i-1]));
}
pstmt.executeUpdate();
}catch(SQLException e){
e.printStackTrace();
}finally{
try{
if(pstmt!=null)
pstmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
} //
public BoardBean oneSelect(String num){
BoardBean dto = null;
String sql = "select * from board where num = ?";
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, Integer.parseInt(num));
rs = pstmt.executeQuery();
if(rs.next()) {
int num2 = rs.getInt("num");
String id = rs.getString("id");
String name = rs.getString("name");
int age = rs.getInt("age");
String content = rs.getString("content");
String time = rs.getString("time");
//int hit = rs.getInt("hit");
String memo = rs.getString("memo");
dto = new BoardBean(num2,id,name,age,content,time,memo);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
return dto;
} //
public BoardBean oneSelecthit(int num){
BoardBean dto = null;
String sql = "select * from board where num = ?";
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, num);
rs = pstmt.executeQuery();
if(rs.next()) {
int num2 = rs.getInt("num");
String id = rs.getString("id");
String name = rs.getString("name");
int age = rs.getInt("age");
String content = rs.getString("content");
String time = rs.getString("time");
int hit = rs.getInt("hit");
String memo = rs.getString("memo");
dto = new BoardBean(num2,id,name,age,content,time,hit,memo);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
return dto;
} //
public void updateData(BoardBean bean){
String sql =
"update board set name=?, age=?, content=?, time=?, memo=? where num = ?";
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, bean.getName());
pstmt.setInt(2, bean.getAge());
pstmt.setString(3, bean.getContent());
pstmt.setString(4, bean.getTime());
//pstmt.setInt(5, bean.getHit());
pstmt.setString(5, bean.getMemo());
pstmt.setInt(6, bean.getNum());
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}//updateData
public boolean searchID(String userid) {
//userid = kim
boolean flag = false;
String sql = "select id from board where id=?";
try {
pstmt=conn.prepareStatement(sql);
pstmt.setString(1,userid);
rs = pstmt.executeQuery();
while(rs.next()) {
flag = true; // movie table에 이미 있을 때
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
return flag;
}
public ArrayList<BoardBean> selectAllMember(int page){
//1번 페이지 1~10
//2번 페이지 11~20
int startNum = (page-1)*7+1;
int endNum = page*7;
//int startNum = (paging.getStartNum()-1)*7+1;
//int endNum = paging.getEndNum()*7;
String sql = "SELECT * FROM ("
+ "SELECT * FROM ("
+ "SELECT ROWNUM row_num, board.* FROM board"
+ ") WHERE row_num >= ?"
+ ") WHERE row_num <= ?";
ArrayList<BoardBean> list = new ArrayList<BoardBean>();
try{
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, startNum);
pstmt.setInt(2, endNum);
rs = pstmt.executeQuery();
while(rs.next()){
int num = rs.getInt("num");
String id = rs.getString("id");
String name = rs.getString("name");
int age = rs.getInt("age");
String content = rs.getString("content");
String time = rs.getString("time");
int hit = rs.getInt("hit");
String memo = rs.getString("memo");
BoardBean dto =
new BoardBean(num, id, name, age, content, time, hit, memo);
list.add(dto);
}
}catch(SQLException e){
e.printStackTrace();
}finally {
try {
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
return list;
}
public int getAllCount() {
String sql = "SELECT COUNT(*) as count FROM board";
int count = 0;
try{
pstmt = conn.prepareStatement(sql);
rs= pstmt.executeQuery(sql);
if(rs.next()){
count = rs.getInt("count");
}
}catch(SQLException e){
e.printStackTrace();
}finally {
try {
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
return count;
}
public void updateHit(int num) {
String sql = "update board set hit=hit+1 where num=?";
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, num);
pstmt.executeUpdate(); //실행 -> 조회수 1증가
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
- boardBean.java
package myPkg;
public class BoardBean {
private int num;
private String id;
private String name;
private int age;
private String content;
private String time;
private int hit;
private String memo;
public BoardBean() {
}
public BoardBean(int num, String id, String name, int age, String content, String time, int hit, String memo) {
super();
this.num = num;
this.id = id;
this.name = name;
this.age = age;
this.content = content;
this.time = time;
this.hit = hit;
this.memo = memo;
}
public BoardBean(int num, String id, String name, int age, String content, String time, String memo) {
super();
this.num = num;
this.id = id;
this.name = name;
this.age = age;
this.content = content;
this.time = time;
this.memo = memo;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public int getHit() {
return hit;
}
public void setHit(int hit) {
this.hit = hit;
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
}
- Paging.java
package myPkg;
public class Paging {
private int page=1; //현재 페이지
private int totalCount; //전체 게시글수
private int beginPage; //출력 시작
private int endPage; //출력 끝
private int displayRow = 5; //한 페이지에 몇 개 row
private int displayPage = 5; //한 페이지에 몇 개 페이지
boolean prev; //prev 버튼이 보일지/안 보일지
boolean next; //총 페이지 수가 10개 넘는 경우만 true
public void setTotalCount(int totalCount) {
//이걸 꼭 호출해야 paging이 가능하기 때문에
//이걸 호출하면 자동으로 paging() 함수 호출하도록 설정
this.totalCount = totalCount;
paging();
}
private void paging(){
//displayPage = 10(고정값)
//prev,next,beginPage,endPage 를 계산해서 만든다.
endPage = ((page+(displayPage-1))/displayPage)*displayPage;
beginPage = endPage - (displayPage-1);
//글이 32개라면 필요한 페이지는 4개
//32/10 = 3.2 올림해서 4
int totalPage = (int)Math.ceil(totalCount/(double)displayRow);
if(totalPage<endPage){
endPage = totalPage;
next=false;
}else{
next=true;
}
prev=(beginPage == 1)?false:true;
}
//나머지는 get/set 메소드는 생략
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getBeginPage() {
return beginPage;
}
public void setBeginPage(int beginPage) {
this.beginPage = beginPage;
}
public int getEndPage() {
return endPage;
}
public void setEndPage(int endPage) {
this.endPage = endPage;
}
public int getDisplayRow() {
return displayRow;
}
public void setDisplayRow(int displayRow) {
this.displayRow = displayRow;
}
public int getDisplayPage() {
return displayPage;
}
public void setDisplayPage(int displayPage) {
this.displayPage = displayPage;
}
public boolean isPrev() {
return prev;
}
public void setPrev(boolean prev) {
this.prev = prev;
}
public boolean isNext() {
return next;
}
public void setNext(boolean next) {
this.next = next;
}
public int getTotalCount() {
return totalCount;
}
}
그리고나서 jsp로 뿌려줄 코드들이 있는데,, paging.jsp랑 boardList.jsp등이 있는데 list쪽만 살펴보자~
- paging.jsp
<%@ page language="java" contentType="text/html; charSet=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!-- 1~10까지 있는 페이지의 페이징 -->
<c:url var="action" value="/list.do"/>
<c:if test="${param.prev}">
<a href="${action}?page=1">prev</a>
</c:if>
<c:forEach begin="${param.begin}" end="${param.end}" step="1" var="index">
<c:choose>
<c:when test="${param.page==index}">
${index}
</c:when>
<c:otherwise>
<a href="${action}?page=${index}">${index}</a>
</c:otherwise>
</c:choose>
</c:forEach>
<c:if test="${param.next}">
<a href="${action}?page=11">next</a>
</c:if>
- boardList.jsp
<%@page import="java.util.ArrayList"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="myPkg.BoardDao"%>
<%@page import="myPkg.BoardBean"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<style type="text/css">
table{
border: 1px solid blue;
}
tr:first-child{
background-color: yellow;
}
#paging{
text-align:center;
}
</style>
<!-- <script type="text/javascript" src="./js/jquery.js"></script> -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript">
function insert() {
location.href = "insertBoard.jsp";
}
function selectDelete() {
var flag = false;
var memberchk = document.getElementsByName("rowcheck");
for (var i = 0; i < memberchk.length; i++) {
if (memberchk[i].checked) {
flag = memberchk[i].checked;
}
}
if (!flag) {
alert("삭제할 내용을 체크하세요");
return;
}
document.userForm.submit();
}
function allDelete(obj) {
var chkobj = document.getElementsByName("rowcheck");
var rowcnt = chkobj.length - 1;
var check = obj.checked;
if (check) {
for (var i = 0; i <= rowcnt; i++) {
chkobj[i].checked = true;
}
} else {
for (var i = 0; i <= rowcnt; i++) {
chkobj[i].checked = false;
}
}
}
</script>
<%
int pageSize = 7; // 한 페이지에 표시할 게시글의 수
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
String pageNum = request.getParameter("pageNum");
if(pageNum == null){
pageNum ="1";
}
int currentPage = Integer.parseInt(pageNum);
int startRow = (currentPage-1) * pageSize +1;
int endRow = currentPage * pageSize;
int count = 0;
int number = 0;
ArrayList<BoardBean> lists = null;
BoardDao dao = BoardDao.getInstance();
count = dao.getArticleCount();
System.out.println("count:"+ count);
/* if(count > 0){
lists = dao.getArticles(startRow, endRow);
} */
int pageNumber = 1; //기본 페이지 넘버
//페이지넘버값이 있을때
if (request.getParameter("pageNumber") != null) {
pageNumber = Integer.parseInt(request.getParameter("pageNumber"));
}
number = count - (currentPage-1)*pageSize;// 1~10, 11~20 ...
/* page list
bbs = aaa;
total = 전체 게시물 수;
pageSize = 10;
pageTotal = (total-1)/pageSize;
cpage = 현재 페이지;
search = 검색키워드
전체 게시물을 페이지당게시물수로 나눈 전체페이지 수입니다.
*/
String link = "list.do?pageNum="+pageNum;
link = java.net.URLEncoder.encode(link);
%>
<b align="center">글목록(전체글 : <%= count %>)</b>
<form name="userForm" action="deleteAll.do">
<input type="button" value="삭제" onclick="selectDelete();">
<input type="button" value="추가" onclick="insert();"><br><br>
<table border="1" align="center" width="90%">
<tr align="center">
<td><input type="checkbox" name="allcheck" onclick="allDelete(this);"></td>
<td>번호</td>
<td>아이디</td>
<td>이름&제목</td>
<td>나이</td>
<td>내용</td>
<td>게시판 작업 시간대</td>
<td>조회수</td>
<td>개선사항</td>
<td>수정</td>
<td>삭제</td>
</tr>
<c:forEach var="board" items="${lists }">
<%-- <%
for(BoardBean bean : lists){ %> --%>
<tr align="center">
<!-- rowcheck:11,13 -->
<td><input name="rowcheck" type="checkbox" value="${board.num }"></td>
<td>${board.num }</td>
<td>${board.id }</td>
<td><a href="updateHit.do?num=${board.num }">${board.name }</a></td>
<td>${board.age }</td>
<td>${board.content }</td>
<td>${board.time }</td>
<td>${board.hit }</td>
<%-- <%if(movie.getMemo()==null ){
%>
<td>없음</td>
<%} else { %>
<td><%=movie.getMemo()%></td>
<%} %> --%>
<c:if test="${board.memo == null }">
<td>없음</td>
</c:if>
<c:if test="${board.memo != null }">
<td>${board.memo}</td>
</c:if>
<td><a href="updateBoard.do?num=${board.num }">수정</a></td>
<td><a href="deleteProc.do?num=${board.num }">삭제</a></td>
</tr>
</c:forEach>
<%-- <% }//확장 for %> --%>
</table>
</form>
<br>
<div id="paging">
<jsp:include page="/paging.jsp">
<jsp:param value="${paging.page}" name="page"/>
<jsp:param value="${paging.beginPage}" name="begin"/>
<jsp:param value="${paging.endPage}" name="end"/>
<jsp:param value="${paging.prev}" name="prev"/>
<jsp:param value="${paging.next}" name="next"/>
</jsp:include>
</div>
자 이렇게 하면 일단 기본적인 jsp/servlet을 이용한 mvc2패턴인 회원가입이나 게시판등을 짤 수 있다~
제가 프로젝트를 올려놓을테니 필요하시면 가지고 가셔도 될 듯 하군요~ㅋㅋ
- 참고링크
jsp mvc패턴 설명해보기 - https://hyoje420.tistory.com/36
'IT 관련,, > Java관련 언어들' 카테고리의 다른 글
[WEB/PHP]p태그를 사용한 글자타이핑효과~!! (0) | 2021.01.18 |
---|---|
[웹/eGovFrame]전자정프프레임워크 처음 설정 경로 바꾸기!! (0) | 2020.12.05 |
[웹/JSP]jsp jstl에 대해서 알아보장~!! (0) | 2020.09.13 |
[웹/JSP]jsp 커넥션풀(dbcp) DB 연결하기~!! (0) | 2020.09.06 |
[웹/JSP]jsp model1 간단한 도서관리게시판-5(delete문) (0) | 2020.08.09 |