국비학원/수업기록

국비 지원 개발자 과정_Day68

루팽 2023. 3. 7. 21:12

MyBatis sql문 xml에서 관리 → 컴파일 x, src에 관리, 오라클엔 DML만 넘어감

SqlSession → commit/rollback가능

pageMove[0] → forward/redirect → WEB-INF접근하려면 포워드때야함(else문처리)

 

<pojo step3 - ActionSupport.java>

package com.pojo.step3;

import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import com.pojo.step2.Board2Controller;

public class ActionSupport extends HttpServlet {
	Logger logger = Logger.getLogger(ActionSupport.class);

	protected void doService(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		logger.info("doService 호출");
		String uri = req.getRequestURI();
		logger.info(uri); // /board3/boardList.st3가 찍힘

		String context = req.getContextPath();
		logger.info(context); // "/" -> server.xml에 들어있음

		String command = uri.substring(context.length() + 1);
		System.out.println(command); // board3/boardList.st3

		int end = command.lastIndexOf(".");
		System.out.println(end); // 16(board3의 경우)

		command = command.substring(0, end);
		System.out.println(command); // board3/boardList

		String upmu[] = null; // upmu[0]=업무명(폴더명), upmu[1]=요청기능이름(메소드명)
		upmu = command.split("/"); // /기준으로 문자열 잘라서 upmu 배열에 담기
		logger.info(upmu[0] + ", " + upmu[1]);
		// upmu req에 담기
		req.setAttribute("upmu", upmu);
		Object obj = ""; // null이 맞지만 String이 들어온다는 전제로 ""

		try {
			obj = HandlerMapping.getController(upmu, req, res);
		} catch (Exception e) {
			logger.info("Exception: " + e.toString());
		}

		// 페이지 이동처리 공통코드
		// obj 형식 예시 -> redirect:XXX.jsp or forward:XXX.jsp
		if (obj != null) {
			String pageMove[] = null;
			ModelAndView mav = null;

			// obj가 String인 경우 -> webapp
			if (obj instanceof String) {
				// obj에 :이 포함된 경우
				if (((String) obj).contains(":")) {
					logger.info(": 포함되어 있음");
					pageMove = obj.toString().split(":");
				}
				// obj에 :이 포함되지 않은 경우
				else {
					logger.info(": 포함되어 있지 않음");
					pageMove = obj.toString().split("/");
				}
				logger.info("페이지이동 => " + pageMove[0] + ", " + pageMove[1]);
			}
			// obj가 ModelAndView인 경우 -> WEB-INF
			else if (obj instanceof ModelAndView) {
				mav = (ModelAndView) obj;
				pageMove = new String[2];
				pageMove[0] = ""; // forward가 들어있으면 안됨 -> 있으면 webapp로 향함
				pageMove[1] = mav.getViewName();
			}
			
			// pageMove가 null이 아닐 경우 각 방식으로 페이지 이동처리
			if (pageMove != null) {
				// pageMove[0] = redirect or forward or ""
				// pageMove[1] = XXX
				new ViewResolver(req, res, pageMove);
			}
		} // end of 페이지 이동처리 공통코드
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		logger.info("doGet호출");
		doService(req, res);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		logger.info("doPost호출");
		doService(req, res);
	}
}

 

<pojo step3 - HandlerMapping.java>

package com.pojo.step3;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;

public class HandlerMapping {
	static Logger logger = Logger.getLogger(HandlerMapping.class);
	
	/***************************************
	 * @param upmu[](upmu[0]=업무명,폴더명 | upmu[1]=메소드명, 기능명, 페이지이름)
	 * @param request -> 1-1, 1-2와는 다르게 인터페이스를 implements하지 않는다
	 * @param response -> HttpServlet
	 * Q. 어디서 받아오는가?
	 * @return Object
	 * 테스트 -> http://localhost:9000/board3/boardList.st3
	 ***************************************/
	
	public static Object getController(String[] upmu, HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		logger.info(upmu[0]+", "+upmu[1]);
		Controller3 controller = null;
		String path = null;
		Object obj = null;
		ModelAndView mav = null;
		
		// 게시판 구현
		if("board3".equals(upmu[0])) {
			controller = new Board3Controller();
			
			// 게시글 전체 목록 -> html 화면 출력(text/html)
			if("boardList".equals(upmu[1])) {
				obj = controller.boardList(req, res);
				// 리턴타입이 ModelAndView인 경우
				if(obj instanceof ModelAndView) {
					return (ModelAndView)obj;
				}
				// 리턴타입이 String인 경우
				else if(obj instanceof String) {
					return (String)obj;
				}
			}
			
			// json 게시글 전체 목록 -> json 화면 출력(application/json)
			else if("jsonBoardList".equals(upmu[1])) {
				obj = controller.jsonBoardList(req, res);
				// 리턴타입이 ModelAndView인 경우
				if(obj instanceof ModelAndView) {
					return (ModelAndView)obj;
				}
				// 리턴타입이 String인 경우
				else if(obj instanceof String) {
					return (String)obj;
				}
			}
			
			// 글 입력 - 새글쓰기와 댓글쓰기
			else if("boardInsert".equals(upmu[1])) {
				obj = controller.boardInsert(req, res);
				// 리턴타입이 String인 경우
				if(obj instanceof String) {
					return (String)obj;
				}
			}
			
			// 글 수정 - 첨부파일 수정 유무 고려하기
			else if("boardUpdate".equals(upmu[1])) {
				obj = controller.boardUpdate(req, res);
			// 리턴타입이 String인 경우
				if(obj instanceof String) {
					return (String)obj;
				}
			}
			
			// 글 삭제 - 첨부파일 삭제 유무 고려하기
			else if("boardDelete".equals(upmu[1])) {
				obj = controller.boardDelete(req, res);
			// 리턴타입이 String인 경우
				if(obj instanceof String) {
					return (String)obj;
				}
			}
			
			// 글 상세보기
			else if("boardDetail".equals(upmu[1])) {
				obj = controller.boardDetail(req, res);
				// 리턴타입이 ModelAndView인 경우
				if(obj instanceof ModelAndView) {
					return (ModelAndView)obj;
				}
				// 리턴타입이 String인 경우
				else if(obj instanceof String) {
					return (String)obj;
				}
			}
		} // end of 게시판 구현
		
		// 인증 관리 구현
		else if("auth".equals(upmu[0])) {
		}
		
		// 회원 관리 구현
		else if("member".equals(upmu[0])) {
		}
		
		// 주문 관리 구현
		else if("order".equals(upmu[0])) {
		}
		
		return obj;
	}
}

 

<pojo step3 - Controller3.java>

package com.pojo.step3;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// javascript기반의 UI API
// 리액트는 바닐라스크립트 + ES6(주요이슈-spread, module, arrow),ES7 + html 섞어쓰기
public interface Controller3 {
	public Object jsonBoardList(HttpServletRequest req, HttpServletResponse res);
	public Object boardList(HttpServletRequest req, HttpServletResponse res);
	public Object boardDetail(HttpServletRequest req, HttpServletResponse res);
	public Object boardInsert(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException;
	public Object boardUpdate(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException;
	public Object boardDelete(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException;
}

 

<pojo step3 - ModelAndView.java>

package com.pojo.step3;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;

/*
 * spring4에서 제공되던 ModelAndView 흉내내기
 * ModelAndView
 * 1) scope가 request이다
 * 2) 화면 이름을 정해준다
 */
public class ModelAndView {
	Logger logger = Logger.getLogger(ModelAndView.class);
	HttpServletRequest req = null;
	// 캡슐화 코드는 반드시 getter/setter가 필요하다 -> 스프링부트는 Lombok대체
	private String viewName = null;
	List<Map<String, Object>> reqList = new ArrayList<>();
	
	public ModelAndView() {
	}

	public ModelAndView(HttpServletRequest req) {
		this.req = req;
	}

	public void addObject(String name, Object obj) {
		req.setAttribute(name, obj);
		Map<String, Object> pMap = new HashMap<>();
		pMap.put(name, obj);
		reqList.add(pMap);
	}
	
	public String getViewName() {
		return viewName;
	}

	public void setViewName(String viewName) {
		this.viewName = viewName;
	}
}

 

<pojo step3 - HashMapBinder.java>

package com.util;

import java.util.Enumeration;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;

// 스프링부트에선 RequestParam이 대신해줌, Model, ModelMap
// 사용자가 입력한 값을 Map에 담아준다
// 담을 Map은 컨트롤계층에서 bind메소드호출시 파라미터를 이용해서 원본 주소번지를 받아온다
// 그리고 그 안에 담는다
public class HashMapBinder {
	HttpServletRequest req = null; // 전역변수
	
	public HashMapBinder() {
	}

	// 생성자 파라미터(지역변수)에 요청객체가 필요한 이유는?
	// ->  생성자의 1역할: 전역변수의 초기화
	public HashMapBinder(HttpServletRequest req) {
		this.req = req;
	}
	
	// 어떤 페이지 어떤 상황에서 공통코드를 재사용 가능하게 할 것인가?
	// 각 업무별 요청 클래스에서 주입받을 객체를 정해서 메소드의 파라미터로 전달받음
	// 전달받은 주소번지 원본에 값을 담아준다
	public void bind(Map<String, Object>pMap) {
		pMap.clear();
		Enumeration<String> en = req.getParameterNames();
		while(en.hasMoreElements()) {
			String key = en.nextElement();
			pMap.put(key, req.getParameter(key));
		}
	}
}

 

<pojo step3 - Board3Controller.java>

package com.pojo.step3;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import com.util.HashMapBinder;

public class Board3Controller implements Controller3 {
	Logger logger = Logger.getLogger(Board3Controller.class);
	Board3Logic boardLogic = new Board3Logic();
	
	//메소드
		@Override
		public ModelAndView boardList(HttpServletRequest req, HttpServletResponse res) {
			logger.info("boardList 호출");
			List<Map<String, Object>> bList = null;
			//사용자가 조건 검색을 원하는 경우 - 조건 값을 전달할 객체 생성함
			//MyBatis에서는 동적쿼리를 지원하므로 하나로 2가지 경우 사용 가능함
			Map<String, Object> pMap = new HashMap<>();
			HashMapBinder hmb = new HashMapBinder(req);
			hmb.bind(pMap);
			bList =boardLogic.boardList(pMap);
			ModelAndView mav = new ModelAndView(req);
			mav.setViewName("board3/boardList");
			mav.addObject("bList", bList);				
			return mav; // 리턴이 mav면 webapp/WEB-INF/views/board3 아래의 jsp
		}
		
		@Override
		public Object jsonBoardList(HttpServletRequest req, HttpServletResponse res) {
			logger.info("jsonBoardList호출");
			List<Map<String, Object>> bList = null;
			Map<String, Object> pMap = new HashMap<>();
			bList =boardLogic.boardList(pMap);
			req.setAttribute("bList", bList);
			return "forward:jsonBoardList.jsp"; // 리턴이 String이면 webapp/board3 아래의 jsp
		}
		
		@Override
		public Object boardDetail(HttpServletRequest req, HttpServletResponse res) {
			logger.info("boardDetail호출");
			List<Map<String, Object>> bList = null;
			//전체 조회에 대한 sql문 재사용 가능함 - 1건 조회 경우
			Map<String, Object> pMap = new HashMap<>();
			HashMapBinder hmb = new HashMapBinder(req);
			hmb.bind(pMap);
			bList =boardLogic.boardList(pMap);
			logger.info(bList);
			req.setAttribute("bList", bList);
			return "forward:board3/boardDetail";
		}
		
		/*
		 * INSERT INTO board_master_t(bm_no, bm_title, bm_writer, bm_content, bm_reg,
		 * bm_hit) VALUES(seq_board_no.nextval, #{bm_title},
		 * #{bm_writer}, to_char(sysdate, 'YYYY-MM-DD') , 0)
		 * 
		 * 화면에서 받아올 값 - bm_title, bm_writer, bm_content
		 * 그렇지 않은 경우 - bm_reg
		 */
		@Override
		public Object boardInsert(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
			logger.info("boardInsert호출");
			int result = 0;
			// 폼태그 안에 사용자가 입력한 정보(bm_writer, bm_title, bm_content...)를 받아온다
			// req.getParameter("bm_writer")
			// req.getParameter("bm_title")
			// req.getParameter("bm_content")
			// -> 계속 반복해야하기에 HashMapBinder클래스 공통코드 생성
			Map<String, Object> pMap = new HashMap<>();
			HashMapBinder hmb = new HashMapBinder(req);
			hmb.bind(pMap);
			result = boardLogic.boardInsert(pMap);
			String path = "";
			 if(result==1) {
				 path = "redirect:/board3/boardList.st3";
			} else {
				path = "redirect:/board3/boardInsertFail.jsp";
				res.sendRedirect(path);
			}
			return path;
		}
	
		@Override
		public Object boardUpdate(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
			logger.info("boardUpdate호출");
			int result = 0;
			Map<String, Object> pMap = new HashMap<>();
			HashMapBinder hmb = new HashMapBinder(req);
			hmb.bind(pMap);
			logger.info(pMap);
			// result값의 변화를 주는 코드(0->1)
			result = boardLogic.boardUpdate(pMap);
			String path = "";
			if(result==1) {
				 path = "redirect:/board3/boardList.st3";
			} else {
				path = "redirect:/board3/boardUpdateFail.jsp";
				res.sendRedirect(path);
			}
			return path;
		}
		
	@Override
	public Object boardDelete(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		logger.info("boardDelete호출");
		int result = 0;		
		Map<String, Object> pMap = new HashMap<>();
		HashMapBinder hmb = new HashMapBinder(req);
		hmb.bind(pMap);
		result = boardLogic.boardDelete(pMap);
		String path = "";
		if(result==1) {
			 path = "redirect:/board3/boardList.st3";
		} else {
			path = "redirect:/board3/boardUpdateFail.jsp";
			res.sendRedirect(path);
		}
		return path;
	}
}

 

<pojo step3 - Board3Logic.java>

package com.pojo.step3;

import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;

public class Board3Logic {
	Logger logger = Logger.getLogger(Board3Logic.class);
	Board3Dao boardDao = new Board3Dao();
	
	/**
	 * 글 목록 출력
	 * @param pMap
	 * @return
	 */
	public List<Map<String, Object>> boardList(Map<String, Object> pMap) {
		logger.info("boardList 호출" + pMap);
		List<Map<String, Object>> bList = null;
		bList = boardDao.boardList(pMap);
		return bList;
	}

	/**
	 * 새 글쓰기
	 * @param pMap
	 * @return
	 */
	public int boardInsert(Map<String, Object> pMap) {
		logger.info("boardInsert 호출" + pMap);
		int result = 0;
		int bm_no = 0;
		int bm_group = 0;
		bm_no = boardDao.getBNo();
		pMap.put("bm_no", bm_no);
		
		// Map안에서 꺼낸다는 건 화면에서 넘어온 값이라는 뜻
		if(pMap.get("bm_group")!=null) {
			bm_group = Integer.parseInt(pMap.get("bm_group").toString());
		}
		
		// 댓글쓰기인 경우
		/*
		 * UPDATE board_master_t
		 * SET bm_step = bm_step + 1
		 * WHERE bm_group =:g
		 * AND bm_step >:s;
		 */
		if(bm_group > 0) {
			logger.info("댓글쓰기 로직 호출");
			boardDao.bStepUpdate(pMap);
			pMap.put("bm_pos", Integer.parseInt(pMap.get("bm_pos").toString())+1);
			pMap.put("bm_step", Integer.parseInt(pMap.get("bm_step").toString())+1);
		}
		
		// 새글쓰기인 경우 -> 그룹번호 채번 포함
		else {
			logger.info("새글쓰기 로직 호출 => " + bm_group);
			bm_group = boardDao.getBGroup();
			pMap.put("bm_group", bm_group);
			pMap.put("bm_pos", 0);
			pMap.put("bm_step", 0);
		}
		
		result = boardDao.boardInsert(pMap);
		return result;
	}
	
	/**
	 * 글 수정
	 * @param pMap
	 * @return
	 */
	public int boardUpdate(Map<String, Object> pMap) {
		logger.info("boardUpdate 호출" + pMap);
		int result = 0;
		result = boardDao.boardMUpdate(pMap);
		return result;
	}
	
	/**
	 * 글 삭제
	 * @param pMap
	 * @return
	 */
	public int boardDelete(Map<String, Object> pMap) {
		logger.info("boardDelete 호출" + pMap);
		int result = 0;
		result = boardDao.boardMDelete(pMap);
		return result;
	}
}

 

<pojo step3 - Board3Dao.java>

package com.pojo.step3;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.log4j.Logger;
import com.util.MyBatisCommonFactory;

public class Board3Dao {
	Logger logger = Logger.getLogger(Board3Dao.class);
	MyBatisCommonFactory mcf = new MyBatisCommonFactory();

	/**
	 * 게시글 목록 출력
	 * @param pMap
	 * @return
	 */
	public List<Map<String, Object>> boardList(Map<String, Object> pMap) {
		logger.info("boardList 호출");
		List<Map<String, Object>> bList = null;
		SqlSessionFactory sqlSessionFactory = null;
		SqlSession sqlSession = null;
		try {
			sqlSessionFactory = mcf.getSqlSessionFactory();
			sqlSession = sqlSessionFactory.openSession();
			bList = sqlSession.selectList("boardList", pMap);
			logger.info(bList);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bList;
	}

	/**
	 * 새 게시글 쓰기
	 * @param pMap
	 * @return
	 */
	public int boardInsert(Map<String, Object> pMap) {
		logger.info("boardInsert 호출");
		int result = 0;
		SqlSessionFactory sqlSessionFactory = null;
		SqlSession sqlSession = null;
		try {
			sqlSessionFactory = mcf.getSqlSessionFactory();
			sqlSession = sqlSessionFactory.openSession();
			// insert이지만 update로 하는 이유는 리턴타입이 Object이기 때문이다
			// 메소드 이름은 상관없이 해당 쿼리문을 id로 찾기 때문이다
			result = sqlSession.update("boardMInsert", pMap);
			if(result == 1) {
				sqlSession.commit();
			}
			logger.info(result);
		} catch (Exception e) {
			e.printStackTrace();
		}		
		return result;
	}
	
	/**
	 * 글 group 채번
	 * @return
	 */
	public int getBGroup() {
		int result = 0;
		logger.info("getBGroup 호출");
		SqlSessionFactory sqlSessionFactory = null;
		SqlSession sqlSession = null;
		try {
			sqlSessionFactory = mcf.getSqlSessionFactory();
			sqlSession = sqlSessionFactory.openSession();
			result = sqlSession.selectOne("getBGroup", "");
			logger.info(result); // 채번한 글그룹번호
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 글 no 채번
	 * @return
	 */
	public int getBNo() {
		int result = 0;
		logger.info("getBNo 호출");
		SqlSessionFactory sqlSessionFactory = null;
		SqlSession sqlSession = null;
		try {
			sqlSessionFactory = mcf.getSqlSessionFactory();
			sqlSession = sqlSessionFactory.openSession();
			result = sqlSession.selectOne("getBNo", "");
			logger.info(result); // 채번한 글번호
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 글 step 업데이트
	 * @param pMap
	 */
	public void bStepUpdate(Map<String, Object> pMap) {
		logger.info("bStepUpdate 호출");
		int result = 0;
		SqlSessionFactory sqlSessionFactory = null;
		SqlSession sqlSession = null;
		try {
			sqlSessionFactory = mcf.getSqlSessionFactory();
			sqlSession = sqlSessionFactory.openSession();
			result = sqlSession.update("bStepUpdate", pMap);
			if(result == 1) {
				sqlSession.commit();
			}
			logger.info(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
	} // end of bStepUpdate
	
	/**
	 * 글 수정하기
	 * @param pMap - 사용자가 입력한 값 받아옴
	 */
	public int boardMUpdate(Map<String, Object> pMap) {
		logger.info("boardMUpdate 호출");
		int result = 0;
		SqlSessionFactory sqlSessionFactory = null;
		SqlSession sqlSession = null;
		try {
			sqlSessionFactory = mcf.getSqlSessionFactory();
			sqlSession = sqlSessionFactory.openSession();
			result = sqlSession.update("boardMUpdate", pMap);
			if(result == 1) {
				sqlSession.commit();
			}
			logger.info(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	} // end of boardMUpdate
	
	/**
	 * 글 삭제하기
	 * @param pMap
	 * @return
	 */
	public int boardMDelete(Map<String, Object> pMap) {
		logger.info("boardMDelete 호출");
		int result = 0;
		SqlSessionFactory sqlSessionFactory = null;
		SqlSession sqlSession = null;
		try {
			sqlSessionFactory = mcf.getSqlSessionFactory();
			sqlSession = sqlSessionFactory.openSession();
			int bm_no = 0;
			if(pMap.get("bm_no")!=null) {
				bm_no = Integer.parseInt(pMap.get("bm_no").toString());
			}
			result = sqlSession.update("boardMDelete", bm_no);
			if(result == 1) {
				sqlSession.commit();
			}
			logger.info(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	} // end of boardMDelete
}

 

<pojo step3 - ViewResolver.java>

package com.pojo.step3;

import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;

public class ViewResolver {
	Logger logger = Logger.getLogger(ViewResolver.class);
	
	public ViewResolver() {
	}

	public ViewResolver(HttpServletRequest req, HttpServletResponse res, String[] pageMove) throws ServletException, IOException{
		String path = pageMove[1];
		// pageMove[0]이 redirect -> webapp
		if ("redirect".equals(pageMove[0])) {
			res.sendRedirect(path);
		}
		// pageMove[0]이 forward -> webapp
		else if ("forward".equals(pageMove[0])) {
			RequestDispatcher view = req.getRequestDispatcher("/" + path + ".jsp");
			view.forward(req, res);
		}
		// 그외 forward 처리 -> WEB-INF
		// setViewName(XXX);
		// WEB-INF/views/XXX.jsp
		else {
			path = pageMove[0] + "/" + pageMove[1];
			RequestDispatcher view = req.getRequestDispatcher("/WEB-INF/views" + path + ".jsp");
			view.forward(req, res);
		}
	} // end of ViewResolver(req, res, pageMove)
}

 

<pojo step3 - board.xml>

<?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.mybatis.mapper.BoardMapper">
	<!-- 게시글 삭제 -->
	<delete id="boardMDelete" parameterType="int">
		DELETE FROM board_master_t
			WHERE bm_no = #{value}
	</delete>
	
	<!-- 게시글목록 가져오는 쿼리문 -->
	<select id="boardList" parameterType="java.util.HashMap"
		resultType="map">
		SELECT bm.bm_no,
		       bm.bm_title,
		       bm.bm_writer,
		       bm.bm_content,
		       bm.bm_pw,
		       bs.bs_file,
		       bm.bm_hit,
		       bm.bm_group,		       
		       bm.bm_pos,
		       bm.bm_step,
		       bm.bm_reg
		       FROM board_master_t bm, board_sub_t bs
		       WHERE bm.bm_no =
		       bs.bm_no(+)
		<!-- 글번호로 검색 -->
		<if test= 'bm_no  > 0' >
		 		AND bm.bm_no = #{bm_no}
		</if>
		<!-- 글날짜로 검색 -->
		<if test= 'bm_reg!=null and bm_reg.length()!=0 and bm_reg!="undefined"' >
		 		AND bm_reg LIKE  '%'||#{bm_reg}||'%'
		 </if>
	  <!-- 글제목으로 검색 -->
		<if test= 'cb_search!=null and cb_search.length()>0 and cb_search.equals("bm_title")' >
		 		AND bm_title LIKE '%'||#{tb_search}||'%'
		</if>
	  <!-- 글내용으로 검색 -->
		<if test= 'cb_search!=null and cb_search.equals("bm_content")' >
		 		AND bm_content LIKE '%'||#{tb_search}||'%'
		</if>
	  <!-- 작성자로 검색 -->
		<if test= 'cb_search!=null and cb_search.equals("bm_writer")' >
		 		AND bm_writer LIKE '%'||#{tb_search}||'%'
		</if>
		ORDER BY bm.bm_group DESC, bm.bm_step ASC
	</select>
  
	<!-- board Master에 인서트 -->
	<!-- pos와 step은 원글이면 0, 댓글이면 read.jsp에서 가진 값에 1을 더한 값으로 결정됨
			 조회수는 0(새글이니까), 날짜는 시스템 날짜정보로 등록 -->
	<insert id="boardMInsert" parameterType="map">
		INSERT INTO board_master_t (bm_no,
                            bm_title,
                            bm_writer,
                            bm_content,
                            bm_pw,
                            bm_reg,
                            bm_hit,
                            bm_group,
                            bm_pos,
                            bm_step)
     VALUES (#{bm_no}, #{bm_title}, #{bm_writer},
     #{bm_content}, #{bm_pw}, to_char(sysdate, 'YYYY-MM-DD'), 0,
     #{bm_group}, #{bm_pos}, #{bm_step})
	</insert>
	
		<!-- board Sub에 인서트 -->
		<!-- 첨부파일을 추가하는 경우에만 실행됨, 없으면 해당없음
				 글번호는 새글쓰기에서 결정된 값이 대입되어야함, 새로채번하면 안됨! -->
	<insert id="boardSInsert" parameterType="map">
		INSERT INTO
		board_sub_t(bm_no, bs_seq, bs_file, bs_size)
		VALUES(#{bm_no}, 1, #{bs_file}, #{bs_size})
	</insert>
		
		<!-- board Master에 Step 업데이트 -->
		<!-- 내가 쓰는 댓글 뒤에 댓글이 존재하는 경우만 실행됨
				 조건절에 들어오는 그룹번호와 step은 상세보기 화면에서 가져온 값이 대입됨 -->
	<update id="bStepUpdate" parameterType="map">
		UPDATE board_master_t
		SET bm_step = bm_step + 1
		WHERE bm_group = #{bm_group}
		AND bm_step > #{bm_step}
	</update>
	
	<!-- board Master 내용 수정하기 -->
	<update id="boardMUpdate" parameterType="map">
		UPDATE board_master_t
		SET bm_title = #{bm_title}
		<if test="bm_writer != null">
		    ,bm_writer = #{bm_writer}
		</if>
		<if test="bm_content != null">
		    ,bm_content = #{bm_content}
		</if>
		<if test="bm_pw != null">
		    ,bm_pw = #{bm_pw}
		</if>
				,bm_reg = TO_CHAR(sysdate, 'YYYY-MM-DD')
		WHERE bm_no = #{bm_no}
	</update>
	
	<!-- bm_no 채번 -->
	<select id="getBNo" parameterType="string" resultType="int">
	SELECT
    NVL ( (SELECT /*+index_desc(board_master_t BOARD_BM_NO_PK) */ bm_no
        FROM board_master_t
        WHERE ROWNUM = 1), 0)+1 bm_no
  FROM DUAL
	</select>
	
	<!-- bm_group 채번 -->
	<select id="getBGroup" parameterType="string" resultType="int">
	SELECT
	    NVL ( (SELECT /*+index_desc(board_master_t i_board_group) */ bm_group
	        FROM board_master_t
	        WHERE ROWNUM = 1
	        AND bm_group > 0), 0)+1 bm_group
	  FROM DUAL
	</select>
</mapper>

 

<pojo step3 - boardList.jsp → WEB-INF위치>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>    
<%
// jsp에서 자바코드(스크립틀릿)와 html코드의 작성 위치는 문제가 되지 않는다.
// 왜냐하면 어차피 jsp는 서버에서 실행되고 그 결과가 text로 출력되는 것이므로 
// html과 처리 시점이 완전 다르니까...
	List<Map<String,Object>> boardList = 
			(List<Map<String,Object>>)request.getAttribute("bList");
	int size = 0;
	if(boardList!=null){
		size = boardList.size();
	}		
%>    
<!DOCTYPE html>
<html>
<head>
<!-- <meta charset="UTF-8"> 이것때문에 한글깨짐.-->
<title>MVC기반의 계층형 게시판 구현하기[WEB-INF]</title>
<%@ include file="../common/easyUI_common.jsp" %>
<script type="text/javascript">
	let g_no=0;//그리드에서 선택이 바뀔때 마다 변경된 값이 저장됨.
	let tb_value;//사용자가 입력한 문자열 담기
	let isOk = false;
	function dlgIns_save(){
		//폼 전송 처리함.
		$("#f_boardIns").submit();
	}
	function dlgIns_close(){
		$("#dlg_boardIns").dialog('close');
	}
	function getBoardList(){
		//alert("getBoardList호출");
		//사용자가 선택한 콤보박스에 value가 담김 - b_title, or b_content or b_writer
		cb_value = user_combo;
		tb_value = $("#tb_search").val();//사용자가 입력한 조건 검색 문자열
		console.log("콤보박스 값: "+ cb_value+", 사용자가 입력한 키워드: "+tb_value);
		location.href = "./boardList.st3?cb_search="+cb_value+"&tb_search="+tb_value+"&bm_reg="+v_date;
	}	
	function boardDetail(bm_no){
		console.log(bm_no)
		location.href = "./boardDetail.st3?bm_no="+bm_no;
	}
    function fileDown(fname){
		location.href="downLoad.jsp?bs_file="+fname;
    }	
</script>
</head>
<body>
<script type="text/javascript">
	let user_combo="bm_title";//제목|내용|작성자
	//전변 - javascript에서는 선언만 하고 선택을 하지 않았거나 값이 할당되지 않으면 
	//그냥 null비교만 해서는 안된다.
	let v_date;//사용자가 선택한 날짜 정보 담기
//기본 날짜포맷을 재정의
	$.fn.datebox.defaults.formatter = function(date){
		var y = date.getFullYear();
		var m = date.getMonth()+1;
		var d = date.getDate();
		return y+'-'+(m<10? "0"+m:m)+'-'+(d<10? "0"+d:d);
	}
//날짜 포맷을 적용	
	$.fn.datebox.defaults.parser = function(s){
		var t = Date.parse(s);
		if (!isNaN(t)){
			return new Date(t);
		} else {
			return new Date();
		}
	}	
	$(document).ready(function(){//DOM구성이 완료된 시점-자바스크립트로 태그접근,설정변경,이미지
		$("#dg_board").datagrid({
			onSelect:function(index,row){
				g_no = row.B_NO;
				console.log("g_no:"+g_no);
			},
			onDblClickCell: function(index, field, value){
				if("B_TITLE" == field){
					location.href="./boardDetail.pj?b_no="+g_no;
					g_no = 0;
					$("#dg_board").datagrid('clearSelections')
				}
			}
		});
	
		//등록 날짜 정보를 선택했을 때
		$('#db_date').datebox({
			//왜? undefinded이었나?
			onSelect: function(date){
				//alert(date.getFullYear()+":"+(date.getMonth()+1)+":"+date.getDate());
				const y = date.getFullYear();
				const m = date.getMonth()+1;
				const d = date.getDate();
				v_date = y+"-"+(m<10? "0"+m:m)+"-"+(d<10? "0"+d:d);
				//console.log("사용자가 선택한 날짜 ==> "+v_date);
			}
		});
		
		//검색 조건 콤보에 변경이 일어났을 때
		$('#cb_search').combobox({
			onChange:function(){
				user_combo = $("#cb_search").combobox('getValue');//b_title or b_content or b_writer
				console.log(user_combo)
			}
		});

		$('#tb_search').textbox({
			icons: [{
				iconCls:'icon-search',
				handler: function(e){
					console.log("검색");
					//$(e.data.target).textbox('setValue', 'Something added!');
					$("#dg_board").datagrid({

					});
				}
			}]
		});

	    /*===================== CRUD버튼 시작 ====================*/	    
		//조회버튼 클릭했을 때
	    $('#crudBtnSel').bind('click', function(){
	    	getBoardList();
	    });
		$('#crudBtnIns').bind('click', function(){
	        //alert('입력 버튼');
	        $("#dlg_boardIns").dialog('open');
	    });	
		$('#crudBtnUpd').bind('click', function(){
	        alert('수정 버튼');
	    });	
		$('#crudBtnDel').bind('click', function(){
	        alert('삭제 버튼');
	    });			
	    /*===================== CRUD버튼 끝 ====================*/	    

	});///////////////// end of ready
</script>
<center>
    <table id="dg_board" class="easyui-datagrid" title="계층형 게시판 목록" style="width:800px;height:550px"
            data-options="rownumbers:true,singleSelect:true,toolbar:'#tb',footer:'#pn_board'">
        <thead>
            <tr>
                <th data-options="field:'BM_NO',width:60, align:'center', hidden:'true'">글번호</th>
                <th data-options="field:'BM_TITLE',width:350">제목</th>
                <th data-options="field:'BM_WRITER',width:80,align:'center'">작성자</th>
                <th data-options="field:'BM_REG',width:100,align:'center'">작성일</th>
                <th data-options="field:'BS_FILE',width:170">첨부파일</th>
                <th data-options="field:'BM_HIT',width:60,align:'center'">조회수</th>
            </tr>
        </thead>
        <tbody>
<%
	if(size==0){
%> 	
<script>
	$.messager.alert('Info','조회결과가 없습니다.');
</script>
<%
	}
	else if(size>0){
		for(int i=0;i<size;i++){
			if(size == i) break;
			Map<String,Object> rMap = boardList.get(i);
%>	      
        	<tr>
        		<td><%=1%></td>
        		<td>
<!-- 너 댓글이니? -->
<%
	String imgPath = path + "..\\images\\";
	if(Integer.parseInt(rMap.get("BM_POS").toString()) > 0){
		for(int j=0; j<Integer.parseInt(rMap.get("BM_POS").toString()); j++){
			out.print("&nbsp;&nbsp;&nbsp;");
		}
%>
	<img src="<%=imgPath%>reply.gif" />
<%
	}
%>	
<a href="javascript:boardDetail('<%=rMap.get("BM_NO") %>')" style="text-decoration:none;color:#000000">        		
        		<%=rMap.get("BM_TITLE")%>
</a>        		
        		</td>
        		<td><%=rMap.get("BM_WRITER")%></td>
        		<td><%=rMap.get("BM_REG")%></td>
        		<td>
        		<%="첨부파일 없음"%>	
        		</td>
        		<td><%=rMap.get("BM_HIT")%></td>
        	</tr>
<%
		}// end of for
	}// end of else if
%>        	
        </tbody>
    </table>
<!-- 툴바 추가 중 조건검색 화면 시작 -->    
    <div id="tb" style="padding:2px 5px;">
                                    <!-- 
                                    req.getParameter("cb_search"):String
                                    SELECT * FROM board_master_t
                                    WHERE ?(컬럼) LIKE %||?||%
                                     -->
        <select class="easyui-combobox" id="cb_search" name="cb_search" panelHeight="auto" style="width:100px">
            <option selected>선택</option>
            <option value="bm_title">제목</option>
            <option value="bm_content">내용</option>
            <option value="bm_writer">작성자</option>
        </select>
        <input id="tb_search" name="tb_search" class="easyui-textbox" style="width:320px">
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                작성일: <input id="db_date" class="easyui-datebox" name="bm_date" style="width:110px">
	<!-- 버튼 추가 화면 시작 --> 
	    <div id="ft" style="padding:2px 5px;">
	        <a id="crudBtnSel" href="#" class="easyui-linkbutton" iconCls="icon-search" plain="true">조회</a>
	        <a id="crudBtnIns" href="#" class="easyui-linkbutton" iconCls="icon-edit" plain="true">입력</a>
	        <a id="crudBtnUpd" href="#" class="easyui-linkbutton" iconCls="icon-reload" plain="true">수정</a>
	        <a id="crudBtnDel" href="#" class="easyui-linkbutton" iconCls="icon-cut" plain="true">삭제</a>
	    </div>
	<!-- 버튼 추가 화면 끝 -->     
    </div>
<!-- 툴바 추가 중 조건검색 화면 끝 -->
   
<!-- 페이지 네이션 추가 시작 -->
	<div style="display:table-cell;vertical-align:middle; width:800px; background:#efefef; height:30; border:1px solid #ccc;">
		1 2 3 4 5 6 7 8 9 10
	</div>
<!-- 페이지 네이션 추가   끝  -->
<%
	String gubun = request.getParameter("gubun");
	if("list".equals(gubun)){
%>	
<script type="text/javascript">
		getBoardList();
</script>	
<%		
	}
%>
<!-- 글입력 화면 추가 시작 -->
    <div id="dlg_boardIns" footer="#tb_boardIns" class="easyui-dialog" title="글쓰기" data-options="modal:true,closed:true" style="width:600px;height:400px;padding:10px">
        <!-- <form id="f_boardIns" method="post" enctype="multipart/form-data" action="./boardInsert.pj"> -->
        <form id="f_boardIns" method="get" action="./boardInsert.st3">
        <!-- 
        	hidden속성은 화면에 보이지 않음 - 개발자가 필요로하는 값
        	등록 부분과 수정 부분이 동시에 발생할 수도 있다 - 트랜젝션 처리가 필요함
        	트랜잭션 처리가 필요한 경우의 메소드 설계
         -->
	    <input type="hidden" id="bm_no" name="bm_no" value="0">
	    <input type="hidden" id="bm_group" name="bm_group" value="0">
	    <input type="hidden" id="bm_pos" name="bm_pos" value="0">
	    <input type="hidden" id="bm_step" name="bm_step" value="0">
        	<table>
        		<tr>
        			<td width="100px">제&nbsp;&nbsp;&nbsp;목</td>
        			<td width="500px"><input id="bm_title" name="bm_title" class="easyui-textbox" data-options="width:'250px'" required></td>
        		</tr>
        		<tr>
        			<td width="100px">작&nbsp;성&nbsp;자</td>
        			<td width="500px"><input id="bm_writer" name="bm_writer" class="easyui-textbox" data-options="width:'150px'" required></td>
        		</tr>
        		<tr>
        			<td width="100px">내&nbsp;&nbsp;&nbsp;용</td>
        			<td width="500px"><input id="bm_content" name="bm_content" class="easyui-textbox" data-options="multiline:'true',width:'350px', height:'90px'" required></td>
        		</tr>
        		<tr>
        			<td width="100px">비&nbsp;&nbsp;&nbsp;번</td>
        			<td width="500px"><input id="bm_pw" name="bm_pw" class="easyui-textbox" data-options="width:'100px'" required></td>
        		</tr>
        		<tr>
        			<td width="100px">첨부파일</td>
        			<td width="500px"><input id="bs_file" name="bs_file" class="easyui-filebox" data-options="width:'350px'"></td>
        		</tr>
        	</table>
        </form>
    </div>
    <!-- 다이얼로그 화면 버튼 추가 시작 -->
	<div id="tb_boardIns">
	<a href="javascript:dlgIns_save()" class="easyui-linkbutton">저장</a>
	<a href="javascript:dlgIns_close()" class="easyui-linkbutton">닫기</a>
	</div>    
    <!-- 다이얼로그 화면 버튼 추가  끝   -->
<!-- 글입력 화면 추가  끝   -->
</center>
</body>
</html>

 

<pojo step3 - boardDetail.jsp>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.List, java.util.Map"%>    
<%
	List<Map<String,Object>> getBoardList = 
		(List<Map<String,Object>>)request.getAttribute("bList");
	String bm_title = null;
	String bm_writer = null;
	String bm_content = null;
	String bm_pw = null;
	String bm_no = null;
	String bm_group = null;
	String bm_pos = null;
	String bm_step = null;
	if(getBoardList!=null && getBoardList.size()>0){
		bm_title = getBoardList.get(0).get("BM_TITLE").toString();
		bm_writer = getBoardList.get(0).get("BM_WRITER").toString();
		bm_content = getBoardList.get(0).get("BM_CONTENT").toString();
		bm_pw = getBoardList.get(0).get("BM_PW").toString();
		bm_no = getBoardList.get(0).get("BM_NO").toString();
		bm_group = getBoardList.get(0).get("BM_GROUP").toString();
		bm_pos = getBoardList.get(0).get("BM_POS").toString();
		bm_step = getBoardList.get(0).get("BM_STEP").toString();
	}
	out.print(getBoardList);
%>    
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>글상세보기</title>
<!-- 공통 코드 include처리 -->
<%@ include file="../common/easyUI_common.jsp" %>
<script type="text/javascript">
	function addAction(){
		$("#f_boardAdd").attr("action","/board3/boardInsert.st3");
		$("#f_boardAdd").submit();
		//부모창에 함수를 호출할때 opener.함수명();
		//opener.boardList();
		//self.close();
	}
	function updateForm(){
		//alert("updateForm 호출 성공");
		$('#d_boardUpd').dialog({
			title:'글수정'
		  ,width:720
		  ,height:450
		  ,closed:false
		  ,cache:false
		 ,modal:true	  
		});
		//$('#d_boardUpd').dialog('open');	
		//$('#d_boardUpd').dialog('refresh', '');
	}
	// 수정창 확인버튼
	boardUpd = () => {
		$("#uf_board").attr("action","/board3/boardUpdate.st3");
		$("#uf_board").submit();
	}
	//댓글쓰기
	function repleForm(){
		$("#dlg_boardAdd").dialog('open');
	}
	//글삭제하기 이벤트 처리
	function boardDelView(){
		console.log("boardDelView호출 성공");
		  $('#d_boardDel').dialog({
			    title: '글삭제',
			    buttons: btn_boardDel,
			    width: 420,
			    height: 250,
			    closed: true,
			    cache: false,
			    href: 'boardDelForm.jsp?bm_no=<%=bm_no%>&bm_pw=<%=bm_pw%>',
			    modal: true
	   }); 
	   $('#d_boardDel').dialog('open');		
	}
	//글삭제 화면에서 확인 버튼을 클릭했을 때
	function boardDel(){
		const db_pw = '<%=bm_pw%>'
		const u_pw = $("#u_pw").textbox('getValue');
		//alert("db_pw:"+db_pw+", u_pw:"+u_pw);
		//alert("사용자가 입력한 비번:"+$("#db_pw").textbox('getValue'));
		//사용자가 입력한 비번과 DB에서 읽어온 비번을 비교하여
		//일치하면 삭제 처리 진행하고
		//불일치하면 비번을 다시 입력받도록 해주세요.
		if(u_pw==db_pw){
			//alert("같다");
			$.messager.confirm('Confirm','정말 삭제하시겠습니까?',function(r){
			 //r:true-ok, false-cancel
				if (r){//자바스크립트는 0이면 false 나머지 true
			    	location.href="./boardDelete.st3?bm_no=<%=bm_no%>";    
			    }
			});
		}else{
			console.log('비밀번호가 다릅니다.')
			$("#db_pw").textbox('setValue','');
		}
	}
	function boardDelClose(){
		 $('#d_boardDel').dialog('close');
	}
	function boardList(){
		location.href="/board3/boardList.st3";
	}
</script>
</head>
<body>
<script type="text/javascript">
	$(document).ready(function(){
		
	});
</script>
    <table align="center" id="p" class="easyui-panel" title="글상세보기" data-options="footer:'#tb_read'"
        style="width:670px;height:380px;padding:10px;background:#fafafa;">
	    	<tr>
	    	<td>제목</td>
	    	<td><input id="bm_title" value="<%=bm_title %>" name="bm_title" data-options="width:'450px'" class="easyui-textbox"></td>
	    	</tr>
	    	<tr>
	    	<td>작성자</td>
	    	<td><input id="bm_writer" value="<%=bm_writer %>" name="bm_writer" class="easyui-textbox"></td>
	    	</tr>
	    	<tr>
	    	<td>내용</td>
	    	<td><input id="bm_content" value="<%=bm_content %>" name="bm_content" data-options="multiline:'true', width:'570px', height:'90px'" class="easyui-textbox"></td>
	    	</tr>
	    	<tr>
	    	<td>비밀번호</td>
	    	<td><input id="bm_pw" value="<%=bm_pw %>" name="bm_pw" class="easyui-passwordbox"></td>
	    	</tr>	    	
	   </table>
	 <div id="tb_read" style="padding:2px 5px;" align="center">
	    <a href="javascript:repleForm()" class="easyui-linkbutton" iconCls="icon-edit" plain="true">댓글쓰기</a>
	    <a href="javascript:updateForm()" class="easyui-linkbutton" iconCls="icon-add" plain="true">수정</a>
	    <a href="javascript:boardDelView()" class="easyui-linkbutton" iconCls="icon-remove" plain="true">삭제</a>
	    <a href="javascript:boardList()" class="easyui-linkbutton" iconCls="icon-search" plain="true">목록</a>
	</div>
		<!-- 글삭제 시작 -->
		<div id="d_boardDel" closed="true" class="easyui-dialog" style="padding:20px 50px">
			<div id="btn_boardDel" align="right">
			<a href="javascript:boardDel()" class="easyui-linkbutton" iconCls="icon-ok" style="width:90px">확인</a>
			<a href="javascript:boardDelClose()" class="easyui-linkbutton" iconCls="icon-cancel" style="width:90px">닫기</a>
			</div>
		</div>
		<!-- 글삭제  끝   -->
		<!-- 글수정 시작 -->
		<div id="d_boardUpd" closed="true" class="easyui-dialog" style="padding:20px 50px">
<form id="uf_board" method="get">
<!-- <form id="uf_board" method="post" enctype="multipart/form-data"> -->
<input type="hidden" id="bm_no" name="bm_no" value="<%=bm_no %>">
<input type="hidden" id="bs_seq" name="bs_seq" value="<%=1 %>">
<input type="hidden" id="old_file" name="old_file" value="이전파일명">
<table align="center" width="650px" height="280px">
	<tr>
		<td width="120px">글제목</td>
		<td width="580px">
			<input id="bm_title" value="<%=bm_title %>" name="bm_title" class="easyui-textbox">
		</td>
	</tr>
	<tr>
		<td width="120px">작성자</td>
		<td width="580px">
			<input id="bm_writer" value="<%=bm_writer %>" name="bm_writer" class="easyui-textbox">
		</td>
	</tr>	
	<tr>
		<td width="120px">내용</td>
		<td width="580px">
			<input id="bm_content" multiline="true" value="<%=bm_content %>" name="bm_content" class="easyui-textbox" style="width:100%;height:100px">
		</td>
	</tr>	
	<tr>
		<td width="120px">첨부파일</td>
		<td width="580px">
			<input id="b_file" name="b_file" class="easyui-filebox" style="width:100%">
		</td>
	</tr>	
	<tr>
		<td width="120px">비번</td>
		<td width="580px">
			<input id="bm_pw" name="bm_pw" class="easyui-textbox" style="width:100px">
		</td>
	</tr>	
</table>
</form>		
			<div id="btn_boardUpd" align="right">
			<a href="javascript:boardUpd()" class="easyui-linkbutton" iconCls="icon-ok" style="width:90px">등록</a>
			<a href="javascript:boardUpdClose()" class="easyui-linkbutton" iconCls="icon-cancel" style="width:90px">닫기</a>
			</div>
		</div>
		<!-- 글수정  끝  -->
		<!-- 댓글쓰기 시작 -->
<!--================== [[댓글쓰기 화면]] ==================-->
<div id="dlg_boardAdd" title="댓글쓰기" class="easyui-dialog" style="width:600px;height:400px;padding:10px" data-options="closed:'true',modal:'true',footer:'#tbar_boardAdd'">	
<!-- 
form전송시 encType옵션이 추가되면 request객체로 사용자가 입력한 값을 꺼낼 수 없다.
MultipartRequest  => cos.jar
 -->	
	<!-- <form id="f_boardAdd" method="post" enctype="multipart/form-data"> -->
	<form id="f_boardAdd" method="get">
	<input type="hidden" name="bm_no" value="<%=bm_no%>">
	<input type="hidden" name="bm_group" value="<%=bm_group%>">
	<input type="hidden" name="bm_pos" value="<%=bm_pos%>">
	<input type="hidden" name="bm_step" value="<%=bm_step%>">
	<!-- <form id="f_boardAdd"> -->
	<table>
		<tr>
			<td width="100px">제목</td>
			<td width="500px">
				<input class="easyui-textbox" data-options="width:'350px'" id="bm_title" name="bm_title" required>
			</td>
		</tr>
		<tr>	
			<td width="100px">작성자</td>
			<td width="500px">
				<input class="easyui-textbox" data-options="width:'150px'" id="bm_writer" name="bm_writer" required>
			</td>
		</tr>
		<tr>			
			<td width="100px">내용</td>
			<td width="500px">
				<input class="easyui-textbox" id="bm_content" name="bm_content" data-options="multiline:'true',width:'400px',height:'90px'" required>
			</td>
		</tr>
		<tr>			
			<td width="100px">비번</td>
			<td width="500px">
				<input class="easyui-textbox" data-options="width:'100px'" id="bm_pw" name="bm_pw" required>
			</td>
		</tr>
	</table>
	</form>
</div>
<!-- 입력 화면 버튼 추가 -->
<div id="tbar_boardAdd" align="right">
	<a href="javascript:addAction()" class="easyui-linkbutton" iconCls="icon-save">저장</a>
	<a href="javascript:$('#dlg_boardAdd').dialog('close')" 
	   class="easyui-linkbutton" iconCls="icon-cancel">닫기</a>
</div>
		<!-- 댓글쓰기  끝  -->	    
</body>
</html>

 

<pojo step3 - boardDelForm.jsp>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="../common/easyUI_common.jsp" %>   
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>글삭제</title>
</head>
<body>    
 <div style="margin-bottom:20px">
 	<input id="u_pw" name="u_pw" class="easyui-textbox" label="비밀번호:" style="width:200px;height:25px">
 </div>
</body>
</html>

 

foward 요청은 scope1으로 받고 응답은 move1으로 함

(scope1에 out.print한 출력결과는 볼 수 없다)

<scope예제 - Sonata.java>

package com.book.scope;

public class Sonata {
	public int speed = 10;
	public String carName = "2023형 소나타";
	public int wheelNum = 4;
	
	public Sonata() {
		// 전역변수 10, 2023형 소나타, 4
		System.out.println("디폴트 생성자 - 파라미터가 없는 생성자");
	}

	public Sonata(int speed) {
		// 전역변수 speed치환, 2023형 소나타, 4
		this.speed = speed;
	}
	
	public Sonata(int speed, String carName) {
		// 전역변수 speed치환, carName치환, 4
		this.speed = speed;
		this.carName = carName;
	}
	
	public Sonata(int speed, String carName, int wheelNum) {
		// 전역변수 speed치환, carName치환, wheelNum
		this.speed = speed;
		this.carName = carName;
		this.wheelNum = wheelNum;
	}
}

 

<scope예제 - scope1.jsp>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<!-- id는 인스턴스 변수로 생각해야함 -->
	<jsp:useBean id="myCar" scope="request" class="com.book.scope.Sonata" />
	<jsp:useBean id="herCar" scope="page" class="com.book.scope.Sonata" />
	<jsp:useBean id="yourCar" scope="session" class="com.book.scope.Sonata" />
	<%
	// 위의 id와 같은 이름 사용불가
	// 유지의 문제 -> request, session+cookie
		com.book.scope.Sonata himCar = new com.book.scope.Sonata(); // 별도 인스턴스화하면 scope를 가질 수 없음
		out.print("<h3>"+myCar.toString()+"</h3>"); // request
		out.print("<h3>"+herCar.toString()+"</h3>"); // page
		out.print("<h3>"+yourCar.toString()+"</h3>"); // scope를 session으로하면 주소번지 바뀌지 않음
		out.print("<h3>"+himCar.toString()+"</h3>");
		request.setAttribute("myCar", myCar);
		pageContext.setAttribute("herCar", herCar);
		session.setAttribute("yourCar", yourCar);
	%>
	<jsp:forward page="./move1.jsp">
		<jsp:param name="oMyCar" value="<%=myCar.toString() %>" />
		<jsp:param name="oHerCar" value="<%=herCar.toString() %>" />
		<jsp:param name="oYourCar" value="<%=yourCar.toString() %>" />
	</jsp:forward>
</body>
</html>

 

<scope예제 - move1.jsp>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="com.book.scope.Sonata" %>
<%
	// getAttribute는 Object
	Sonata myCar = (Sonata)request.getAttribute("myCar");
	Sonata herCar = (Sonata)pageContext.getAttribute("herCar");
	Sonata yourCar = (Sonata)session.getAttribute("yourCar");
	// getParameter는 String
	String oMyCar = request.getParameter("oMyCar");
	String oHerCar = request.getParameter("oHerCar");
	String oYourCar = request.getParameter("oYourCar");
	
	out.print("scope1.jsp에서 생성된 객체가 유지되는가?");

	out.print("<hr>");
	out.print(myCar); // request -> 주소번지가 계속 바뀜(주소번지 원본)
	out.print("<br>");
	out.print(oMyCar); // 그냥 문자열
	out.print("<br>");
	//out.print(oMyCar.carName); // 문자열이기에 주소번지 필요한 carName사용불가
	out.print(oMyCar.concat("1")+"자동차".concat("1"));
	out.print("<br>");
	out.print(oMyCar.indexOf(3)+"소나타".concat("1"));
	out.print("<br>");
	out.print(oMyCar.charAt(2)+new Boolean(true).toString());
	
	out.print("<hr>");
	out.print(herCar); // page -> url바뀌면 유지되지 않음
	out.print("<br>");
	out.print(oHerCar);
	
	out.print("<hr>");
	out.print(yourCar); // session -> 주소번지 고정
	out.print("<br>");
	out.print(oYourCar);
%>

 

<jdbc 테스트 - JDBCTemplate.java>

package com.util;

import java.io.*;
import java.sql.*;
import java.util.Properties;

public class JDBCTemplate {
	public JDBCTemplate() {
	}

	public static Connection getConnection() {
		Connection con = null;
		Properties prop = new Properties();
		try {
			String currentPath = JDBCTemplate.class.getResource("./").getPath();
			prop.load(new BufferedReader(new FileReader(currentPath + "driver.properties")));
			Class.forName(prop.getProperty("driver"));
			con = DriverManager.getConnection(prop.getProperty("url"), prop.getProperty("user"), prop.getProperty("pwd"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return con;
	}

	public static void close(Connection con) {
		try {
			if (con != null && !con.isClosed()) {
				con.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void close(Statement stmt) {
		try {
			if (stmt != null && !stmt.isClosed()) {
				stmt.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void close(ResultSet rset) {
		try {
			if (rset != null && !rset.isClosed()) {
				rset.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void commit(Connection con) {
	 try {
	 if (con != null && !con.isClosed()) { con.commit(); } 
	} catch (SQLException e) { e.printStackTrace(); }
	 }

	public static void rollback(Connection con) {
		try {
			if (con != null && !con.isClosed()) {
				con.rollback();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String args[]) {
		Connection con = getConnection();
		System.out.println(con);
	}
}