리스트 페이지가 보여지지만 현재 클릭했을 때 아무 것도 보이지 않는다.

 

클릭하면 제목, 내용, 작성자, 조회수 등이 뜨게끔 수정해보겠다.

 

수정 후 리스트 페이지는 이렇게 떠야 한다.

 

1.  컨트롤러작성

아래 코드를 BController.java에 삽입해 준다.

	@RequestMapping("/contentView")
	public String contentView(HttpServletRequest request, Model model) {
		
		System.out.println("-------- contentView() 호출 ----------");
		
		model.addAttribute("request", request);
		//HttpServletRequest로 전 전 페이지 정보를 가져와 request에 저장함.
		
		cmd = new ContentCmd(); //bbsCommand에 ContentCmd를 불러와 cmd에 저장
		
		cmd.service(model);//model 파라미터를 service메소드에 넣어서 동작
		
		return "contentView";
	}

 

2. list.jsp 파일 수정

위의 ContentCmd.java를 만들어 주기 전에 리스트 페이지를 수정한다.

 

테이블 안에서 내용을 보여주는 td태그 안의 내용만 수정한다.

<table border="1" cellpadding="0" cellspacing="0" width="500">
		<tr>
			<td>번호</td>
			<td>제목</td>
			<td>작성자</td>
			<td>날짜</td>
			<td>조회수</td>
		</tr>
				<!-- 게시글 목록 가져오기 -->
		<c:forEach items="${list}" var="vo">	
		<!-- ListCmd에서 만들었던 모델 list를 컨트롤러를 통해 받아온다.-->
		<tr>
			<td>${vo.bNo}</td>
			<!-- 제목을 클릭하면 페이지가 넘어가면서 번호 정보를 가져온다. -->
			<td><a href="contentView?bNo=${vo.bNo}">${vo.bSubject}</a></td>
			<td>${vo.bName}</td>
			<td>${vo.bDate}</td>
			<td>${vo.bHit}</td>
		</tr>
		</c:forEach>
		<tr>
			<td colspan="5" align="center"><a href="writeForm">글쓰기</a></td>
		</tr>
		
	</table>

 

3. Cmd 작성

bbsCommand 패키지에 ContentCmd.java 파일을 생성

 

그 뒤 아래의 코드를 입력

 

ContentCmd.java

package com.spring.bbsCommand;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.ui.Model;

import com.spring.bbsDAO.BDAO;
import com.spring.bbsVO.BVO;

public class ContentCmd implements Bcmd {

	@Override
	public void service(Model model) {
		//모델을 받아 맵형태로 바꿔줌.
		Map<String, Object> map = model.asMap();
		
		//1번글을 클릭하면 1번, 2번글을 클릭하면 2번을 전달받아야 함. 컨트롤러의 리퀘스트가 맵안에 있다. 이것을  HttpServletRequest로 저장
		HttpServletRequest request = (HttpServletRequest)map.get("request");
		
		String bNo = request.getParameter("bNo");
		
		//dao 불러오기
		BDAO dao = new BDAO();
		
		//조회수증가와 내용가져옴
		BVO bVo = dao.contentView(bNo);
		
		//모델에 추가
		model.addAttribute("contentView", bVo);
	}

}

 

4. BDAO에 contentView 추가

위에서 dao의 contentview() 메소드를 사용하였으므로 BDAO에 그 메소드를 정의해줘야한다.

 

BDAO.java에 contentView메소드를 추가

public BVO contentView(String bbsNo) {
	//return하는 bVo가 VO에서 가져온 것이므로 BVO를 타입으로 사용함
	//String bbsNo가 	bNo임
	
		//조회수 로직으로
		addHit(bbsNo);
		
		BVO bVo = null;
		
		//많이 보던 형식 커넥션, 프리페어드, 리절트셋.  데이타소스  >> 그뒤 sql
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		
		try {
			connection = dataSource.getConnection();
			
			String sql = "select * from mvc_bbs where bNo = ?";
			preparedStatement = connection.prepareStatement(sql);
			preparedStatement.setInt(1, Integer.parseInt(bbsNo));
			resultSet = preparedStatement.executeQuery();
			
			if(resultSet.next()) {
				int bNo = resultSet.getInt("bNo");
				String bName = resultSet.getString("bName");
				String bSubject = resultSet.getString("bSubject");
				String bContent = resultSet.getString("bContent");
				Timestamp bDate = resultSet.getTimestamp("bDate");
				
				int bHit = resultSet.getInt("bHit");
				int bGroup = resultSet.getInt("bGroup");
				int bStep = resultSet.getInt("bStep");
				int bIndent = resultSet.getInt("bIndent");
				
				//값을 가져왔으니 bVo에
				
				bVo = new BVO(bNo, bName, bSubject, bContent, bDate, bHit, bGroup, bStep, bIndent);
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			//finally에 클로즈 처리
			
			try {
				if(resultSet != null) resultSet.close();
				if(preparedStatement != null) preparedStatement.close();
				if(connection != null) connection.close();
				
				
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
			
		}
		
		return bVo;
	}//contentView()

 

5. BDAO에 클릭하면 조회수가 증가 하는 메소드를 만든다.

 

BDAO.java에 아래 코드 입력

//조회수 늘어나는 로직
	private void addHit(String bNo) {
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		
		try {
			connection = dataSource.getConnection();
			String sql = "update mvc_bbs set bHit = bHit + 1 where bNo = ?";
			preparedStatement = connection.prepareStatement(sql);
			preparedStatement.setString(1, bNo); //1은 첫번째 물음표 값을 입력
			
			int n = preparedStatement.executeUpdate();
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if(preparedStatement != null) preparedStatement.close();
				if(connection != null) connection.close();
				
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}//addHit()

 

6. contentView.jsp 생성

그 뒤 view폴더에 contentView.jsp를 만들어 아래코드를 입력

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>글내용 보기</title>
</head>
<body>
		<div align="center">
			<h2>글내용 확인</h2>
			<hr width="500" color="green" />
			<table width="500" cellpadding="0" cellspacing="0" border="1">
			<form action="" method="post">
			<tr>
				<td>번호</td>
				<td>${contentView.bNo}</td>
			</tr>
			<tr>
				<td>조회수</td>
				<td>${contentView.bHit}</td>
			</tr>
						<tr>
				<td>작성자</td>
				<td><input type="text" name="bName" value="${contentView.bName }"></td>
			</tr>
						<tr>
				<td>제목</td>
				<td><input type="text" name="bSubject" value="${contentView.bSubject}"></td>
			</tr>
						<tr>
				<td>내용</td>
				<td><textarea rows = "10" name="bContent">${contenctView.bContent}</textarea></td>
			</tr>
			<tr>
				<td colspan="2" align="center"><input type="submit" value="수정하기" />
								&nbsp;&nbsp;&nbsp;<a href="list">목록보기</a>
								&nbsp;&nbsp;&nbsp;<a href="#">삭제</a>
								&nbsp;&nbsp;&nbsp;<a href="#">답변</a>
				</td>
			</tr>
			
			
			</form>
			
			
			</table>
			
			
		</div>
		</body>
</html>

 

수정하기는 아직 만들지 않았다.

클릭하면 조회수가 1씩 증가하는 것을 볼 수 있다.

 

내용 보여주는 곳 까지 파일로 저장해놨으니 아래 참조

 

springBBS 내용보여주는 곳 까지.zip
0.06MB

앞서 작성했던 게시판 페이지이다.

 

이번 포스팅에서 구현할 기능은 아래와 같다.

 

1. 글쓰기를 누르면 글쓰기 페이지로 넘어감

2. 글쓰기 페이지에서 제목과 내용 등을 입력하여 submit해주면 db에 입력이 됨

3. 리스트 페이지로 리다이렉트로 되어 업데이트된 페이지를 보여줌

 

1. 글쓰기 JSP파일 만들기

 

list.jsp와 같은 경로에 writeForm.jsp를 만들어 아래와 같이 코딩을 해준다.

 

writeForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
    
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<div align="center">
	<h2>글쓰기 페이지</h2>
	<hr width="500" />
	<table width="500" cellpadding="0" cellspacing="0" border="1">
		<form:form commandName="_BVO" action="writeOK" method="post">
			<tr>
				<td>작성자</td>
				<td><form:input path="bName" size="20" /></td>
			</tr>
			<tr>
				<td>제목</td>
				<td><form:input path="bSubject" size="50" /></td>
			</tr>
			<tr>
				<td>내용</td>
				<td><form:textarea path="bContent" cols="60" rows="8" /></td>
			</tr>
			<tr>
				<td colspan="2" align="center"><input type="submit" value="등록" /></td>
			</tr>
		</form:form>
	
	</table>
</div>

</body>
</html>

아까는 prefix="c"를 사용하였지만 여기에서는 태그라이브러리 prefix="form"을 사용하였다. 

 

<form:form> 태그안에 commandName은 modelAttribute로 바꾸어 사용해도 된다. 컨트롤러에서 BVO()를 리턴하게끔 모델을 정해주는 역할이다.

 

그리고 action은 어떤 url로 이동할지 정해주고, 이를 컨트롤러에서 받아와서 처리해준다.

method는 post이다.

 

그리고 <form:input>태그안에는 path 구문을 넣어 입력값이 어떤 객체로 들어갈 것인지 정해준다.

 

2. VO 작성

VO는 한번 작성하면 db의 항목이 변동되지 않는 이상 바꾸는 경우는 잘 없다.

아까 변수 선언 구문 아래에 주석 처리 되있었던  public BVO() { }만 주석을 해제해준다.

 

3. Controller 작성

여기서 작성해야 될 것은 2가지 메소드이다.

하나는 글쓰기 작성 jsp파일로 이동시키는 writeForm() 메소드이고, 하나는 글쓰기 form을 submit했을 때 처리되게끔 하는 writeOk()메소드이다.

 

구문에 대한 상세설명은 주석에 적어 놓았다.

 

Bcontroller.java

package com.spring.bbsController;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.spring.bbsCommand.Bcmd;
import com.spring.bbsCommand.ListCmd;
import com.spring.bbsCommand.WriteCmd;
//import com.spring.bbsCommand.WriteCmd;
import com.spring.bbsVO.BVO;

@Controller
public class BController {
	Bcmd cmd = null; //Bcmd 인터페이스를 불러와서 cmd에 저장해준다.

	
	@RequestMapping("/list")
	public String list(Model model) {
		//String으로 list 메소드를 생성했으니 리턴값도 String이다. RequestMapping의 아래는 대부분 String메소드이다.
		//파라미터형태로 모델 생성
		//모델의 역할은 뷰에게 데이터를 전달하기 위한 객체
		//여기서는 모델활용안하고 Bcmd.class에서 모델을 활용함.
		
		System.out.println("------------------list() 호출-------------");//에러날때를 대비해서 써줌
		//Model은 뷰에 데이터를 전달하기 위한 방법
		cmd = new ListCmd(); 	//Bcmd 인터페이스를 가져온 녀석에다 ListCmd()를 넣어줌
		//위에서 Bcmd cmd = null;을 안해주고 곧바로 이것을 해줘도 되지만 의존성을 낮추기 위해서 이렇게 해줌
		
		cmd.service(model);	//모델을 인자로 넘겨줌. 서비스를 시행
		
		return "list";
	}
	
	
	@RequestMapping("/writeForm")
	public String writeForm(Model model) {
		System.out.println("----------writeForm() 호출----------");
		
		return "writeForm";
	}
//	
//	//write폼 >>BController >> WriteCmd로 전달
	@RequestMapping("/writeOK")
	public String writeOk(HttpServletRequest request, Model model) {
		//데이터를 컨트롤러로 보냈을때, HttpServletRequest 객체안에 모든 데이터들이 들어가게 된다. 출처: https://hongku.tistory.com/118
		//String id = httpServletRequest.getParameter("id"); <<id를 불러옴
		
		System.out.println("----------writeOk() 호출-------------");
		
		model.addAttribute("request_ctrl", request); //이 request값에 formWrite에서 적었던 내용이 들어있음
		
		//서비스객체 불러옴
		cmd = new WriteCmd();
		cmd.service(model);
		
		return "redirect:list"; //등록한글을 리스트로 보여줌
	}
	
	//commandName="_BVO"와 관계 있음
	@ModelAttribute("_BVO") 
	public BVO formBacking() {
		
		return new BVO(); //BVO 안에 빈메소드로 연결됨
	}
}

 

/writeOK 리퀘스트 매핑에서는 HttpServletRequest라는 객체가 새로 생겼다.

 

그 이유는 /writeOK는 페이지를 보여주는 것이 아닌 form에서 submit된 데이터를 처리하는 용도이기 때문이다.

 

writeForm.jsp에서 submit하면 맨 끝 주소가 /writeForm에서 /writeOk로 주소가 변경되며, 컨트롤러에선 이를 받아온다.

이 때, 데이터들이 HttpServletRequest의 request안에 저장된다.

 

이 저장된 정보들을 꺼내오면 되는 것이다.

 

컨트롤러에서는 modelAttribute까지만 해주고, 데이터 저장 작업은 Service 클래스에서 해준다.

 

4. Service 작성

request에 모델 형태로 저장되었지만 이를 맵형태(키, 밸류)로 저장해준다.

 

위에서 모델을 잡아줄 때 왜 request_ctrl로 명했냐면, 그냥 request라고 할 경우 이것이 어디서 왔는지 헷갈린다.

 

실무에서야 그냥 쓰면 된다지만, 배우는 사람 입장에서는 이것이 어디서 왔는지 명확히 짚고 넘어가는 것이 중요하다.

 

블로그나 책에 req라고 나왔다고 그대로 req라고 쓰고 con이라고 나왔다고 con이라고 쓰는 것이 아니라 이것이 무엇을 의미하고 어느 클래스에서 왔는지, 또 내가 지정한 임의의 이름으로 넣었을 때 실행되는지 실험하면서 진행해가는 것이 실력향상에 도움이 된다.

 

WriteCmd.java

package com.spring.bbsCommand;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.ui.Model;

import com.spring.bbsDAO.BDAO;

public class WriteCmd implements Bcmd {

	@Override
	public void service(Model model) {
		
		System.out.println("model: "+model);
		//모델의 정보 model: {_BVO=com.spring.bbsVO.BVO@788ca69c, request_ctrl=org.apache.catalina.connector.RequestFacade@764b47fd}
		//아까 컨트롤러에서 정의해줬던 모델명 request_ctrl를 그대로 가져오는 것을 볼수 있다.
		
		Map<String, Object> map = model.asMap(); //모델객체를 맵으로 받음. 해쉬맵을 사용해도 무방
		//_BVO
		
		HttpServletRequest request = (HttpServletRequest)map.get("request_ctrl");		
		//map에 저장된 request_ctrl의 밸류값을 request에 저장
		//request_ctrl은 컨트롤러에서 모델어트리뷰트 해준 것임
		
		
		String bName = request.getParameter("bName");
		String bSubject = request.getParameter("bSubject");
		String bContent = request.getParameter("bContent");
		
		//db접속
		BDAO dao = new BDAO();
		dao.write(bName, bSubject, bContent);
	}
}

 

request에서 getParameter로 값을 가져와서 원하는 객체에 저장해준다.

 

그 다음 DAO클래스에서 write()메소드를 작성해준다.

 

5. DAO 작성

 

굳이 Controller > Service > DAO 순서대로 작성안하고 취향대로 작성해도 된다.

 

리스트 페이지를 만들 때는 DAO > Service > Controller 순으로 작성했지만 이번에는 반대로 한 이유는 어떤 순서로 보는 것이 이해하기 쉽고 내가 코드를 직접 작성할 때 좀 편할지 간접적으로 체험하라는 뜻도 있다.

 

점진적 구체화라는 용어가 있듯이 대개의 경우에는 VO > Controller > Service > DAO 순서가 편하다.

 

그럼 다시 돌아와서 write()메소드를 작성해본다.

 

윗코드내용은 아까 작성했던 부분이므로 write()메소드 시작부터 보면된다.

 

BDAO.java

package com.spring.bbsDAO;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;

//import javax.activation.DataSource; 액티베이션 아님
import javax.naming.Context; //JNDI
import javax.naming.InitialContext; //JNDI
import javax.naming.NamingException; //JNDI
import javax.sql.DataSource;

import com.spring.bbsVO.BVO;

public class BDAO {
	DataSource dataSource; //데이타소스를 가져오는 구문
	
	//생성자
	public BDAO() {
		//JNDI 를 사용한다. JNDI란 자바에서 객체를 네이밍 서비스에 등록, 삭제, 검색을 할 수 있는 방법
		
		try{
			
			Context ctx = new InitialContext(); //JNDI 네이밍 서비스 컴파일해줌
			dataSource = (DataSource)ctx.lookup("java:comp/env/jdbc/Oracle11g");
			//lookup으로 데이타소스의 객체를 얻어온다. java:comp/env/는 기본이며 그뒤의 이름은 톰캣서버 context.xml의 name을 참조한다.
			
	} catch(NamingException e) {
		e.printStackTrace();
	}
		
}
	//리스트 보여주기 위한 메소드 list()
	public ArrayList<BVO> list() {
		//DB에 있는 글목록들을 가져오는 역할 형식은 ArrayList이고 BVO타입. 칼럼정보가 BVO에 있다.
		
		ArrayList<BVO> bVOs = new ArrayList<BVO>(); //ArrayList형태의 bVOs 객체 생성
		
		//////연결을 위한 3구문/////
		Connection connection = null; //커넥션 javax
		PreparedStatement preparedStatement = null; //프리패어드 스테이트먼트 javax		
		ResultSet resultSet = null;  //데이터를 가져오는 기능의 리절트셋 javax
		//////////////
		
		
		try {
		connection = dataSource.getConnection();
		
		
		
		//쿼리문을 만들어줌
		String sql = "select bNo, bName, bSubject, bContent, bDate, bHit, bGroup, bStep, bIndent from mvc_bbs"
					+ " order by bGroup desc, bStep asc";
		
		
		preparedStatement = connection.prepareStatement(sql); //preparedStatement에 전송
		
		resultSet = preparedStatement.executeQuery(); //result값 데이터를 가져오는 것
		
		while(resultSet.next()) {
			//Resultset 다음행에 데이터가 있으면 while 문으로 반복 작업을 함		
			
			//vo의 9인자를 참조해서 작성
			int bNo = resultSet.getInt("bNo");
			String bName = resultSet.getString("bName");
			String bSubject = resultSet.getString("bSubject");
			String bContent = resultSet.getString("bContent");
			Timestamp bDate = resultSet.getTimestamp("bDate");
			
			int bHit = resultSet.getInt("bHit");
			int bGroup = resultSet.getInt("bgroup");
			int bStep = resultSet.getInt("bStep");
			int bIndent = resultSet.getInt("bIndent");
			///////
			
			//인자생성자
			BVO bVO = new BVO(bNo, bName, bSubject, bContent, bDate, bHit, bGroup, bStep, bIndent);
			
			bVOs.add(bVO); //bVOs라는 어레이에 bVO 추가함
		}
		

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			
			//finally 안에 있는 구문
			try {
				//null이면 구문들을 다 안쓰는 것
				if(resultSet !=null) {resultSet.close();}
				if(preparedStatement != null) {preparedStatement.close();}
				if(connection != null) {connection.close();}
				
			} catch (Exception e2) {	
				e2.printStackTrace();
			}
	
		}
		
		return bVOs;	
	}//list() 메소드 종료
	
	
	
	//write() 메소드 시작
	public void write(String bName, String bSubject, String bContent) {
		//글쓴이, 글제목, 글내용을 인자로 써줌.
		
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		
		try {
			connection = dataSource.getConnection();
			System.out.println("---------Connection 확보 -----------");
			
			String sql = "insert into mvc_bbs(bNo, bName, bSubject, bContent, bHit, bGroup, bStep, bIndent) " 
			+ "values(seq_bbs.nextval, ?, ?, ?,0,seq_bbs.currval,0,0)";
			//? 밸류는 사용자가 넣어줘야 될 것임. ?가 아닌 다른것을 쓰면 작동이 안된다. 공란도 안된다.
			
			preparedStatement = connection.prepareStatement(sql);
			
			preparedStatement.setString(1, bName); //첫번째 들어갈값 bName
			preparedStatement.setString(2, bSubject); //두번째 들어갈값 bSubject
			preparedStatement.setString(3, bContent); //세번째 들어갈값 bContent
			
			int n = preparedStatement.executeUpdate(); //select문은 executeQuery(), Update문은 executeUpdate()
			//변수n이 아닌 아무거나 써도 된다.
            
		} catch(SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if(preparedStatement != null) {preparedStatement.close();}
				if(connection != null) {connection.close();}
				
			} catch(Exception e2) {
				e2.printStackTrace();
			}	
		}
		
	}//write
	
}

 

그럼 이제 글작성 기능이 끝났다.

 

부가적으로 회원가입기능, 글에 비번넣기 기능도 추가할 수 있지만 우선은 CRUD 기본만 하도록 한다.

 

여기까지 실습한 내용은 첨부파일에 올려놓았다.

CRUD(글작성 까지).zip
0.03MB

아래는 서버폴더의 context.xml과 server.xml파일

서버와 콘텍스트 파일.zip
0.00MB

앞서 만들었던 게시판 리스트이다. (현재는 글쓰기 안됨)

 

백단의 DAO, VO, Service, Controller와 프론트단의 list.jsp가 어떻게 유기적으로 소통하는지 살펴본다.

"<-----화살표로 끊어지는 로직을 설명해놓았다.

 

여기 코딩 들은 단순 설명용 코딩이니 복붙해서 실행해도 안먹는다.

 

 

1-1. Controller // 리퀘스트 맵핑

주소창에 localhost:8080/list라고 입력하면 디스패처가 컨트롤러로 전달해준다.

Bcontroller에서 일련의 과정을 처리한다.

 

Bcontroller.java

@RequestMapping("/list")

public String list(Model model) {

cmd = new ListCmd(); <-------여기서 Service 클래스를 참조한다.

/*
cmd.service(model); 

return "list";



}
*/

 

2-1. Service //  DAO 참조

ListCmd는 Bcmd 인터페이스를 참조하지만 Bcmd 없이 ListCmd로 만들어줘도 된다. 

 

ListCmd.java

public class ListCmd implements Bcmd {

	@Override
	public void service(Model model) {
		
		BDAO dao =new BDAO(); <------------여기서 DAO클래스를 참조한다.
      	
        
/*        
        
        ArrayList<BVO> bVOs = dao.list(); 

		model.addAttribute("list", bVOs);
	}

}
*/

 

3-1. DAO // JNDI 네이밍을 이용하여 오라클 Lookup

실재로 SQL문을 데이터베이스에서 실행시키게끔 하는 클래스이다. 객체는 VO에서 참조한다.

 

BDAO.java

public class BDAO {
	DataSource dataSource; //데이타소스를 가져오는 구문
	
	//생성자
	public BDAO() {
		//JNDI 를 사용한다. JNDI란 자바에서 객체를 네이밍 서비스에 등록, 삭제, 검색을 할 수 있는 방법
		
		try{
			
			Context ctx = new InitialContext(); //JNDI 네이밍 서비스 컴파일해줌
			dataSource = (DataSource)ctx.lookup("java:comp/env/jdbc/Oracle11g");
			//lookup으로 데이타소스의 객체를 얻어온다. java:comp/env/는 기본이며 그뒤의 이름은 톰캣서버 context.xml의 name을 참조한다.
			
	} catch(NamingException e) {
		e.printStackTrace();
	}
		
}

	public ArrayList<BVO> list() {
		//DB에 있는 글목록들을 가져오는 역할 형식은 ArrayList이고 BVO타입. 칼럼정보가 BVO에 있다.
		
		ArrayList<BVO> bVOs = new ArrayList<BVO>(); <-------여기서 VO를 참조하여 ArrayList 객체를 만든다.
		
/*        
		//////연결을 위한 3구문/////
		Connection connection = null; //커넥션 javax
		PreparedStatement preparedStatement = null; //프리패어드 스테이트먼트 javax		
		ResultSet resultSet = null;  //데이터를 가져오는 기능의 리절트셋 javax
		//////////////
		
		
		try {
		connection = dataSource.getConnection();
		
		//쿼리문을 만들어줌
		String sql = "select bNo, bName, bSubject, bContent, bDate, bHit, bGroup, bStep, bIndent from mvc_bbs"
					+ " order by bGroup desc, bStep asc";
		
		preparedStatement = connection.prepareStatement(sql); //preparedStatement에 전송
		
		resultSet = preparedStatement.executeQuery(); //result값 데이터를 가져오는 것
		
		while(resultSet.next()) {
			//Resultset 다음행에 데이터가 있으면 while 문으로 반복 작업을 함		
			
			//vo의 9인자를 참조해서 작성
			int bNo = resultSet.getInt("bNo");
			String bName = resultSet.getString("bName");
			String bSubject = resultSet.getString("bSubject");
			String bContent = resultSet.getString("bContent");
			Timestamp bDate = resultSet.getTimestamp("bDate");
			
			int bHit = resultSet.getInt("bHit");
			int bGroup = resultSet.getInt("bgroup");
			int bStep = resultSet.getInt("bStep");
			int bIndent = resultSet.getInt("bIndent");
			///////
			
			//인자생성자
			BVO bVO = new BVO(bNo, bName, bSubject, bContent, bDate, bHit, bGroup, bStep, bIndent); <--여기서도 VO 참조
			
			bVOs.add(bVO); //bVOs라는 어레이에 bVO 추가함
		}
				
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			
			//finally 안에 있는 구문
			try {
				//null이면 구문들을 다 안쓰는 것
				if(resultSet !=null) resultSet.close();
				if(preparedStatement != null) preparedStatement.close();
				if(connection != null) connection.close();
				
			} catch (Exception e2) {	
				e2.printStackTrace();
			}
	
		}
		
		return bVOs;	
	}
	
}
*/

 

4-1. VO // 변수 선언

DAO에서 최초로 VO를 불러내었다. VO에서는 따로 참조하는 클래스가 없다.

VO에서는 순수하게 변수선언, 인자생성, setter/getter만 만들어준다.

따라서 코딩할때 가장 먼저 작성되어야할 클래스이기도 하다.

 

BVO.java

public class BVO {
	
	//db에서의 인덱스를 변수로 지정해준다. 각자의 형식에 맞춰서 형식을 지정해준다.
	//VO클래스는 변수선언, 인자생성자, setter getter 이렇게 3개로 나뉜다.
	
	//1.변수 선언
	int bNo;
	String bName;
	String bSubject;
	String bContent;
	Timestamp bDate;  //timestamp는 sql에서 불러오면됨
	int bHit;
	int bGroup;
	int bStep;
	int bIndent;
	
//	public BVO() {
//		
//	}
	
	
	//2.인자생성자
	public BVO(int bNo, String bName, String bSubject, String bContent, Timestamp bDate, int bHit, int bGroup, int bStep, int bIndent) {
		this.bNo = bNo;
		this.bName = bName;
		this.bSubject = bSubject;
		this.bContent = bContent;
		this.bDate = bDate;
		this.bHit = bHit;
		this.bGroup = bGroup;
		this.bStep = bStep;
		this.bIndent = bIndent;
	}
	
	
	//3.setter getter
	public int getbNo() {
		return bNo;
	}

	public void setbNo(int bNo) {
		this.bNo = bNo;
	}

	public String getbName() {
		return bName;
	}

	public void setbName(String bName) {
		this.bName = bName;
	}

	public String getbSubject() {
		return bSubject;
	}

	public void setbSubject(String bSubject) {
		this.bSubject = bSubject;
	}

	public String getbContent() {
		return bContent;
	}

	public void setbContent(String bContent) {
		this.bContent = bContent;
	}

	public Timestamp getbDate() {
		return bDate;
	}

	public void setbDate(Timestamp bDate) {
		this.bDate = bDate;
	}

	public int getbHit() {
		return bHit;
	}

	public void setbHit(int bHit) {
		this.bHit = bHit;
	}

	public int getbGroup() {
		return bGroup;
	}

	public void setbGroup(int bGroup) {
		this.bGroup = bGroup;
	}

	public int getbStep() {
		return bStep;
	}

	public void setbStep(int bStep) {
		this.bStep = bStep;
	}

	public int getbIndent() {
		return bIndent;
	}

	public void setbIndent(int bIndent) {
		this.bIndent = bIndent;
	}
	
}

 

간단히 "VO > DAO > Service > 컨트롤러"  이 순서대로 불러와진다고 보면된다.

다시 3. DAO로 거슬러 돌아간다.

 

 

3-2. DAO // 남은 부분처리

 

남은 부분을 처리 해주고 끝부분에서는 bVOs ArrayList를 리턴해준다.

 

BDAO.java

public class BDAO {
	/*DataSource dataSource; //데이타소스를 가져오는 구문
	
	//생성자
	public BDAO() {
		//JNDI 를 사용한다. JNDI란 자바에서 객체를 네이밍 서비스에 등록, 삭제, 검색을 할 수 있는 방법
		
		try{
			
			Context ctx = new InitialContext(); //JNDI 네이밍 서비스 컴파일해줌
			dataSource = (DataSource)ctx.lookup("java:comp/env/jdbc/Oracle11g");
			//lookup으로 데이타소스의 객체를 얻어온다. java:comp/env/는 기본이며 그뒤의 이름은 톰캣서버 context.xml의 name을 참조한다.
			
	} catch(NamingException e) {
		e.printStackTrace();
	}
		
}

	public ArrayList<BVO> list() {
		//DB에 있는 글목록들을 가져오는 역할 형식은 ArrayList이고 BVO타입. 칼럼정보가 BVO에 있다.
		
		ArrayList<BVO> bVOs = new ArrayList<BVO>(); <-------여기서 VO를 참조하여 ArrayList 객체를 만든다.
		*/
        
		//////연결을 위한 3구문/////
		Connection connection = null; //커넥션 javax
		PreparedStatement preparedStatement = null; //프리패어드 스테이트먼트 javax		
		ResultSet resultSet = null;  //데이터를 가져오는 기능의 리절트셋 javax
		//////////////
		
		
		try {
		connection = dataSource.getConnection();
		
		//쿼리문을 만들어줌
		String sql = "select bNo, bName, bSubject, bContent, bDate, bHit, bGroup, bStep, bIndent from mvc_bbs"
					+ " order by bGroup desc, bStep asc";
		
		preparedStatement = connection.prepareStatement(sql); //preparedStatement에 전송
		
		resultSet = preparedStatement.executeQuery(); //result값 데이터를 가져오는 것
		
		while(resultSet.next()) {
			//Resultset 다음행에 데이터가 있으면 while 문으로 반복 작업을 함		
			
			//vo의 9인자를 참조해서 작성
			int bNo = resultSet.getInt("bNo");
			String bName = resultSet.getString("bName");
			String bSubject = resultSet.getString("bSubject");
			String bContent = resultSet.getString("bContent");
			Timestamp bDate = resultSet.getTimestamp("bDate");
			
			int bHit = resultSet.getInt("bHit");
			int bGroup = resultSet.getInt("bgroup");
			int bStep = resultSet.getInt("bStep");
			int bIndent = resultSet.getInt("bIndent");
			///////
			
			//인자생성자
			BVO bVO = new BVO(bNo, bName, bSubject, bContent, bDate, bHit, bGroup, bStep, bIndent); <--여기서도 VO 참조
			
			bVOs.add(bVO); //bVOs라는 어레이에 bVO 추가함
		}
				
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			
			//finally 안에 있는 구문
			try {
				//null이면 구문들을 다 안쓰는 것
				if(resultSet !=null) resultSet.close();
				if(preparedStatement != null) preparedStatement.close();
				if(connection != null) connection.close();
				
			} catch (Exception e2) {	
				e2.printStackTrace();
			}
	
		}
		
		return bVOs; <----list()메소드 끝부분에서는 bVOs ArrayList를 리턴해준다.
	}
	
}

 

다시 2. Service로 거슬러 올아간다.

 

2-2. Service //

dao.list()에서 Return시킨 bVOs를 cmd의 bVOS에도 저장 시킨다.

그리고 이 bVOS를 "list"란 이름의 모델명에 적용시킨다.

 

ListCmd.java

public class ListCmd implements Bcmd {
/*
	@Override
	public void service(Model model) {
		
		BDAO dao =new BDAO(); <------------여기서 DAO클래스를 참조한다.
 */     	
       
        
        ArrayList<BVO> bVOs = dao.list(); <---list()에서 리턴된 bVOs를 bVOs에 저장

		model.addAttribute("list", bVOs);
	}

}

 

적용시킨 모델명 "list"는 컨트롤러를 통해서 list.jsp로 값을 보내주게된다. (또는 불러오게)

 

그리고 public void service(Model model)에서 model이 아닌 이름을 내가 아무렇게나 지정해도 된다.

한국의 주입식 교육의 폐해 중 하나가 이건 vo로 써야하고, 이건 model로 써야하고 이건 dao로 써야 하는 것으로 알고 가르치는 것이다.

 

편의상 그렇게 쓰는 것이지 소문자로 시작하는 것은 내가 정한 변수이므로 아무렇게나 지정해줘도 된다.

이른바 아래처럼

 

 ListCmd.java

public class ListCmd implements Bcmd {

	@Override
	public void service(Model abcdefg) {
		
		BDAO dddddddd=new BDAO(); <------------여기서 DAO클래스를 참조한다.
    	
       
        
        ArrayList<BVO> qwerqwer = dddddddd.list(); <---list()에서 리턴된 bVOs를 bVOs에 저장

		abcdefg.addAttribute("list", qwerqwer);
	}

}

 

극단적인 예로 이렇게 한것이다. 복사 붙혀넣기만 하지말고 이렇게 변수를 이거저거 바꾸어 적용해보고 하면 온전히 나의 것으로 만들 수 있다.

 

 

ListCmd 클래스에서는 이렇게 모델을 지정해주는 것으로 끝났고, 이제 Back단 중 마지막으로  1. Controller로 올라가보자.

 

1-2. Controller // 뷰페이지로 이동

cmd= new ListCmd()로 서비스를 가져와서 cmd에 저장해주었다.

 

하지만 거기서 끝이 아니라 cmd안의 service()메소드를 실행시켜줘야 작동한다.

service(model)의 model은 물론 변수이기 때문에 아무렇게나 지정해줘도 된다.

 

@RequestMapping("/list")
public String list(Model model) {
/*
cmd = new ListCmd(); <-------여기서 Service 클래스를 참조한다.
*/

cmd.service(model); <-------ListCmd의 service()메소드를 실행시킨다.

return "list"; <-------list.jsp를 사용자에게 보여준다.



}

list로 리턴하였으므로 list.jsp로 넘어간다.

 

5. 뷰페이지 // list.jsp

여기서는 다른 내용은 볼것없고 <Table>태그 안의 내용만 보면 된다.

태그라이브러리를 이용할 것이므로 맨 윗부분에 <%@ taglib prefix = "c" uri="http://java.sun.com/jsp/jstl/core" %>를 붙여주었다.

 

<c:forEach items="${list}" var="vo">

</c:forEach>

구문을 통하여 아까 모델로 지정해주었던 "list"를 불러온다.

 

이 list라는 모델에는 bNo, bSubject 등의 행들이 리스트형태로 저장되어 있다.

forEach라는 이름에 걸맞게 태그안에서 각각의 행들을 모두 불러와준다.

 

그리고 ${vo.bNO} 등을 통하여 그 모델값을 불러올 수 있다.

 

list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <% request.setCharacterEncoding("utf-8"); %>
<%@ taglib prefix = "c" uri="http://java.sun.com/jsp/jstl/core" %>
    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" http-equiv="Content-Type" content="text/html;">
<title>게시판 리스트</title>
</head>
<body>

<div align="center">
	<h2>게시판 글목록</h2>
	<hr width="400" color="red" />
	
	<table border="1" cellpadding="0" cellspacing="0" width="500">
		<tr>
			<td>번호</td>
			<td>제목</td>
			<td>작성자</td>
			<td>날짜</td>
			<td>조회수</td>
		</tr>
 
				<!-- 게시글 목록 가져오기 -->
		<c:forEach items="${list}" var="vo">	
		<!-- ListCmd에서 만들었던 모델 list를 컨트롤러를 통해 받아온다.-->
		<tr>
			<td>${vo.bNo}</td>
			<td>${vo.bSubject}</td>
			<td>${vo.bName}</td>
			<td>${vo.bDate}</td>
			<td>${vo.bHit}</td>
		</tr>
		</c:forEach>
		<tr>
			<td colspan="5" align="center"><a href="writeForm">글쓰기</a></td>
		</tr>
		
	</table>
    
   
</div>
<div>
</div>

</body>
</html>

 

다음 포스팅에선 글쓰기 기능을 추가해본다.

 

 

+ Recent posts