testMapper.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="egovframework.example.test.service.TestMapper">

	<!--게시글 목록 조회 -->
	<select id="selectTest" resultType="TestVO">
		SELECT
		*
		FROM test
		<trim prefix="WHERE" prefixOverrides="AND|OR">
			<if test="searchType=='testTitle' and keyword != null and keyword != '' ">
				AND testTitle like CONCAT('%', #{keyword}, '%')
			</if>
			<if test="searchType=='testContent' and keyword != null and keyword != '' ">
				AND testContent like CONCAT('%', #{keyword}, '%')
			</if>
			<if test="searchType=='testName' and keyword != null and keyword != '' ">
				AND testName like CONCAT('%', #{keyword}, '%')
			</if>
		</trim>
		ORDER BY
		testId DESC
		LIMIT #{startList}, #{listSize}
	</select>

	<!-- 전체 글의 개수를 읽어 오는 SQL문 -->
	<select id="getBoardListCnt" resultType="int">
		SELECT
		count(*) as
		listCnt
		FROM
		test
		<trim prefix="WHERE" prefixOverrides="AND|OR">
			<if test="keyword != null and keyword != '' ">
				<if test="searchType=='testTitle'">
					AND testTitle like CONCAT('%', #{keyword}, '%')
				</if>
				<if test="searchType=='testContent'">
					AND testContent like CONCAT('%', #{keyword}, '%')
				</if>
				<if test="searchType=='testName'">
					AND testName like CONCAT('%', #{keyword}, '%')
				</if>
			</if>
		</trim>
	</select>

	<!--게시글 삽입 -->
	<insert id="insertTest" parameterType="TestVO">
		<![CDATA[
		INSERT INTO test(testTitle, testContent, testName, testDate)
		VALUES(#{testTitle}, #{testContent}, '밥샵', now())
		]]>
	</insert>

	<!--게시글 클릭시 detailView -->
	<select id="selectDetail"
		parameterType="egovframework.example.test.domain.TestVO"
		resultType="egovframework.example.test.domain.TestVO">
		<![CDATA[
			SELECT *
			FROM test
			WHERE testId = #{testId}
		]]>
	</select>

	<!--게시글 업데이트 -->
	<update id="updateTest">
		update test set
		testTitle = #{testTitle}
		,testContent =
		#{testContent}
		where
		testId = #{testId}
	</update>

	<!--게시글 삭제 -->
	<delete id="deleteTest">
		delete from test
		where
		testId = #{testId}
	</delete>
</mapper> 





Pagination과 Search 추가


Pagination

package egovframework.example.test.domain;

public class Pagination {

	private int listSize = 10; // 초기값으로 목록개수를 10으로 셋팅 한 페이지당 보여질 리스트의 개수

	private int rangeSize = 5; // 초기값으로 페이지범위를 5로 셋팅 한 페이지 범위에 보여질 페이지의 개수

	private int page; // 현재목록의 페이지 번호

	private int range; // 각 페이지 범위 시작 번호

	private int listCnt; // 전체 개시물의 개수

	private int pageCnt; // 전체 페이지 범위의 개수

	private int startPage; // 각 페이지 범위 시작 번호

	private int startList; // 게시판 시작번호

	private int endPage; // 각 페이지 범위 끝 번호

	private boolean prev; // 이전 페이지

	private boolean next; // 다음 페이지

	public int getRangeSize() {

		return rangeSize;

	}

	public int getPage() {

		return page;

	}

	public void setPage(int page) {

		this.page = page;

	}

	public int getRange() {

		return range;

	}

	public void setRange(int range) {

		this.range = range;

	}

	public int getStartPage() {

		return startPage;

	}

	public void setStartPage(int startPage) {

		this.startPage = startPage;

	}

	public int getEndPage() {

		return endPage;

	}

	public void setEndPage(int endPage) {

		this.endPage = endPage;

	}

	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 getListSize() {

		return listSize;

	}

	public void setListSize(int listSize) {

		this.listSize = listSize;

	}

	public int getListCnt() {

		return listCnt;

	}

	public void setListCnt(int listCnt) {

		this.listCnt = listCnt;

	}

	public int getStartList() {

		return startList;

	}

	// 첫번째 인자 page 는 현재 페이지 정보, 두번째 인자 range 는 현재 페이지 범위 정보, 세번째 인자 listCnt는 게시물의 총 개수
	public void pageInfo(int page, int range, int listCnt) {

		this.page = page;

		this.range = range;

		this.listCnt = listCnt;

		// 전체 페이지수
		this.pageCnt = (int) Math.ceil((double) listCnt / listSize);

		// 시작 페이지
		this.startPage = (range - 1) * rangeSize + 1;

		// 끝 페이지
		this.endPage = range * rangeSize;

		// 게시판 시작번호
		this.startList = (page - 1) * listSize;

		// 이전 버튼 상태
		this.prev = range == 1 ? false : true;

		// 다음 버튼 상태
		this.next = endPage > pageCnt ? false : true;
		if (this.endPage > this.pageCnt) {
			this.endPage = this.pageCnt;
			this.next = false;
		}
	}
}

Search

package egovframework.example.test.domain;

//Search 클래스가 Pagination 클래스를 상속 받았으므로 기존 Pagination의 특성을 그대로 사용 할 수 있다.
public class Search extends Pagination{

	private String searchType;
	private String keyword;	

	public String getSearchType() {
		return searchType;
	}

	public void setSearchType(String searchType) {
		this.searchType = searchType;
	}

	public String getKeyword() {
		return keyword;
	}

	public void setKeyword(String keyword) {
		this.keyword = keyword;
	}
}

TestController

package egovframework.example.test.web;


import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import egovframework.example.test.domain.Search;
import egovframework.example.test.domain.TestVO;
import egovframework.example.test.service.TestService;

@Controller
public class TestController {

	@Autowired
	private TestService testServiceImpl;

	// 글 목록 리스트, 페이징, 검색
	@RequestMapping(value = "/testList.do")
	public String testListDo(Model model
			,@RequestParam(required = false, defaultValue = "1") int page
			,@RequestParam(required = false, defaultValue = "1") int range
			,@RequestParam(required = false, defaultValue = "testTitle") String searchType
			,@RequestParam(required = false) String keyword,
			@ModelAttribute("search") Search search
			) throws Exception {

		//검색
		model.addAttribute("search", search);
		search.setSearchType(searchType);
		search.setKeyword(keyword);
		
		// 전체 게시글 개수를 얻어와 listCnt에 저장
		int listCnt = testServiceImpl.getBoardListCnt(search);

		//검색
		search.pageInfo(page, range, listCnt);
		//페이징
		model.addAttribute("pagination", search);
		//게시글 화면 출력
		model.addAttribute("list", testServiceImpl.selectTest(search));

		return "test/testList";
	}

	// 글 작성 클릭시 글 작성 페이지로 이동
	@RequestMapping(value = "/testRegister.do")
	public String testRegister() {
		return "test/testRegister";
	}

	// 글 작성 버튼 구현
	@RequestMapping(value = "/insertTest.do")
	public String write(@ModelAttribute("testVO") TestVO testVO, RedirectAttributes rttr) throws Exception {
		testServiceImpl.insertTest(testVO);
		return "redirect:testList.do";
	}

	// HttpServletRequest 객체안에 모든 데이터들이 들어가는데 getParameter메소드로 testId 원하는 데이터 가져옴
	// 제목 클릭 시 상세보기
	@RequestMapping(value = "/testDetail.do")
	public String viewForm(@ModelAttribute("testVO") TestVO testVO, Model model, HttpServletRequest request)
			throws Exception {

		int testId = Integer.parseInt(request.getParameter("testId"));
		testVO.setTestId(testId);

		TestVO resultVO = testServiceImpl.selectDetail(testVO);
		model.addAttribute("result", resultVO);

		return "test/testDetail";
	}

	// 수정하기
	@RequestMapping(value = "/updateTest.do")
	public String updateTest(@ModelAttribute("testVO") TestVO testVO, HttpServletRequest request) throws Exception {
		testServiceImpl.updateTest(testVO);
		return "redirect:testList.do";
	}

	// 삭제하기
	@RequestMapping(value = "/deleteTest.do")
	public String deleteTest(@ModelAttribute("testVO") TestVO testVO) throws Exception {
		testServiceImpl.deleteTest(testVO);
		return "redirect:testList.do";
	}

}

TestService

package egovframework.example.test.service;

import java.util.List;

import egovframework.example.test.domain.Search;
import egovframework.example.test.domain.TestVO;

public interface TestService {

	public List<TestVO> selectTest(Search search) throws Exception;

	public void insertTest(TestVO testVO)throws Exception;

	public TestVO selectDetail(TestVO testVO) throws Exception;

	public void updateTest(TestVO testVO) throws Exception;

	public void deleteTest(TestVO testVO) throws Exception;
	
	//총 게시글 개수 확인
	public int getBoardListCnt(Search search) throws Exception;

}

TestServiceImpl

package egovframework.example.test.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import egovframework.example.test.dao.TestDAO;
import egovframework.example.test.domain.Search;
import egovframework.example.test.domain.TestVO;
import egovframework.example.test.service.TestService;

@Service("testServiceImpl")
public class TestServiceImpl implements TestService {

	@Autowired
	private TestDAO testDAOService;

	@Override
	public List<TestVO> selectTest(Search search) throws Exception {
		return testDAOService.selectTest(search);
	}

	@Override
	public void insertTest(TestVO testVO) throws Exception {
		testDAOService.insertTest(testVO);
	}

	@Override
	public TestVO selectDetail(TestVO testVO) throws Exception {
		/*
		 * TestVO resultVO = testDAOService.selectDetail(testVO); return resultVO;
		 */
		return testDAOService.selectDetail(testVO);
	}

	@Override
	public void updateTest(TestVO testVO) throws Exception {
		testDAOService.updateTest(testVO);
	}

	@Override
	public void deleteTest(TestVO testVO) throws Exception {
		testDAOService.deleteTest(testVO);
	}
	// 총 게시글 개수 확인

	@Override
	public int getBoardListCnt(Search search) throws Exception {
		return testDAOService.getBoardListCnt(search);
	}

}

TestDAO

package egovframework.example.test.dao;

import java.util.List;

import egovframework.example.test.domain.Search;
import egovframework.example.test.domain.TestVO;

public interface TestDAO {

	List<TestVO> selectTest(Search search) throws Exception;

	void insertTest(TestVO testVO) throws Exception;
	
	TestVO selectDetail(TestVO testVO) throws Exception;

	void updateTest(TestVO testVO) throws Exception;

	void deleteTest(TestVO testVO) throws Exception;
	
	//총 게시글 개수 확인
	public int getBoardListCnt(Search search) throws Exception;

}

TestDAOService

package egovframework.example.test.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import egovframework.example.test.domain.Search;
import egovframework.example.test.domain.TestVO;
import egovframework.example.test.service.TestMapper;

@Service("testDAOService")
public class TestDAOService implements TestDAO {

	@Autowired
	private SqlSession sqlSession;

	@Override
	public List<TestVO> selectTest(Search search) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		return mapper.selectTest(search);
	}

	@Override
	public void insertTest(TestVO testVO) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		mapper.insertTest(testVO);
	}

	@Override
	public TestVO selectDetail(TestVO testVO) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		return mapper.selectDetail(testVO);
	}

	@Override
	public void updateTest(TestVO testVO) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		mapper.updateTest(testVO);
	}

	@Override
	public void deleteTest(TestVO testVO) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		mapper.deleteTest(testVO);
	}

	// 총 게시글 개수 확인
	@Override
	public int getBoardListCnt(Search search) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		return mapper.getBoardListCnt(search);
	}
}

TestMapper.java

package egovframework.example.test.service;

import java.util.List;

import egovframework.example.test.domain.Search;
import egovframework.example.test.domain.TestVO;


public interface TestMapper {

	// 게시물 리스트 조회
	public List<TestVO> selectTest(Search search) throws Exception;

	// 게시물 작성
	public void insertTest(TestVO testVO) throws Exception;

	// 게시물 조회
	public TestVO selectDetail(TestVO testVO) throws Exception;

	// 게시물 수정
	public void updateTest(TestVO testVO) throws Exception;

	// 게시물 삭제
	public void deleteTest(TestVO testVO) throws Exception;

	// 총 게시글 개수 확인
	public int getBoardListCnt(Search search) throws Exception;
}

testList.jsp

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<html>

<head>
<!-- Bootstrap CSS -->

<link rel="stylesheet"
	href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
	integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
	crossorigin="anonymous">

<link href="/css/test/test.css" rel="stylesheet" type="text/css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>

</head>

<body>

	<h1>게시판List</h1>

	<div class="testlist">
		<form id="boardForm" name="boardForm" method="post">
			<table class="list_table">
				<colgroup>
					<col width="20%" />
					<col width="50%" />
					<col width="15%" />
					<col width="15%" />
				</colgroup>
				<tbody>
				<thead>

					<tr>
						<th>번호</th>
						<th>제목</th>
						<th>작성자</th>
						<th>등록일자</th>
					</tr>
				</thead>

				<!-- jstl 데이터베이스를 검색해 넘겨 받은 list 를 result 라는 이름으로 순차적으로 실행을 시키게 됨  java의 for문같이 순차적으로 실행시킴-->

				<c:forEach items="${list}" var="result">
					<tr>
						<td><c:out value="${result.testId}" /></td>
						<td><a href='#' onClick='fn_view(${result.testId})'><c:out
									value="${result.testTitle }" /></a></td>
						<td><c:out value="${result.testName}" /></td>
						<td><c:out value="${result.testDate}" /></td>
					</tr>
				</c:forEach>
				</tbody>
			</table>
		</form>
	</div>
	<div>
		<button id="btn_write" type="button" class="btn_write">글작성</button>
	</div>
	<br>
	<!-- pagination{s} -->

	<div id="paginationBox" class="pagination1">
		<ul class="pagination">

			<c:if test="${pagination.prev}">
				<li class="page-item"><a class="page-link" href="#"
					onClick="fn_prev('${pagination.page}', '${pagination.range}', '${pagination.rangeSize}', '${pagination.listSize}'
					,'${search.searchType}', '${search.keyword}')">이전</a></li>
			</c:if>

			<c:forEach begin="${pagination.startPage}"
				end="${pagination.endPage}" var="testId">

				<li
					class="page-item <c:out value="${pagination.page == testId ? 'active' : ''}"/> "><a
					class="page-link" href="#"
					onClick="fn_pagination('${testId}', '${pagination.range}', '${pagination.rangeSize}', '${pagination.listSize}'
					 ,'${search.searchType}', '${search.keyword}')">
						${testId} </a></li>
			</c:forEach>

			<c:if test="${pagination.next}">

				<li class="page-item"><a class="page-link" href="#"
					onClick="fn_next('${pagination.range}', '${pagination.range}', '${pagination.rangeSize}', '${pagination.listSize}'
					,'${search.searchType}', '${search.keyword}')">다음</a></li>
			</c:if>
		</ul>
	</div>
	<!-- pagination{e} -->



	<!-- search{s} -->

	<div class="form-group row justify-content-center">

		<div class="w100" style="padding-right: 10px">
			<select class="form-control form-control-sm" name="searchType"
				id="searchType">
				<option value="testTitle">제목</option>
				<option value="testContent">본문</option>
				<option value="testName">작성자</option>
			</select>
		</div>

		<div class="w300" style="padding-right: 10px">
			<input type="text"
				<%-- value="${pagination.keyword}" --%> class="form-control form-control-sm"
				name="keyword" id="keyword">
		</div>

		<div>
			<button class="btn btn-sm btn-primary" name="btnSearch"
				id="btnSearch">검색</button>
		</div>

	</div>

	<!-- search{e} -->


	<!-- 페이지 목록 갯수   -->
	<div class="form-group row justify-content-center">
		<p>게시판 목록 갯수</p>
		<div class="w100" style="padding-right: 10px">
			<select class="form-control form-control-sm" name="searchType"
				id="listSize" onchange="page(1)">
				<option value="10"
					<c:if test="${pagination.getListSize() == 10 }">selected="selected"</c:if>>10개</option>
				<option value="15"
					<c:if test="${pagination.getListSize() == 15 }">selected="selected"</c:if>>15개</option>
				<option value="20"
					<c:if test="${pagination.getListSize() == 20 }">selected="selected"</c:if>>20개</option>
			</select>
		</div>

	</div>
</body>
<script type="text/javascript">
	//글 작성 버튼 클릭 시 testRegister로 이동
	$("#btn_write").click(function javascript_onclikc() {
		$(location).attr('href', 'testRegister.do');

	});
	
	//글조회
	//	어떤 게시물을 클릭했는지 게시물의 번호(testId)를 넘겨 줘야 함 따라서 게시물 클릭 이벤트에서 게시물의 번호를 인자 값으로 받습니다.
	//  get 방식으로 데이터를 전송합니다. 따라서 ? 연산자를 사용해 testId를 주소 뒤에 붙여 줍니다
	function fn_view(testId){
    
  	  var form = document.getElementById("boardForm");
  	  var url = "<c:url value='/testDetail.do'/>";
  	  url = url + "?testId=" + testId;
    
 	   form.action = url;    
 	   form.submit(); 
	}
	//이전 버튼 이벤트
	//5개의 인자값을 가지고 이동 testList.do
	//무조건 이전페이지 범위의 가장 앞 페이지로 이동
	function fn_prev(page, range, rangeSize, listSize, searchType, keyword) {
			
		var page = ((range - 2) * rangeSize) + 1;
		var range = range - 1;
			
		var url = "/testList.do";
		url = url + "?page=" + page;
		url = url + "&range=" + range;
		url = url + "&listSize=" + listSize;
		url = url + "&searchType=" + searchType;
		url = url + "&keyword=" + keyword;
		location.href = url;
		}

	  //페이지 번호 클릭

	function fn_pagination(page, range, rangeSize, listSize, searchType, keyword) {

		var url = "/testList.do";
			url = url + "?page=" + page;
			url = url + "&range=" + range;
			url = url + "&listSize=" + listSize;
			url = url + "&searchType=" + searchType;
			url = url + "&keyword=" + keyword; 

			location.href = url;	
		}

		//다음 버튼 이벤트
		//다음 페이지 범위의 가장 앞 페이지로 이동
	function fn_next(page, range, rangeSize, listSize, searchType, keyword) {
		var page = parseInt((range * rangeSize)) + 1;
		var range = parseInt(range) + 1;			
		var url = "/testList.do";
			url = url + "?page=" + page;
			url = url + "&range=" + range;
			url = url + "&listSize=" + listSize;
			url = url + "&searchType=" + searchType;
			url = url + "&keyword=" + keyword;
			location.href = url;
		}
		
		
	/* $는 jQuery를 시작하는 명령어로
	$(DOM요소) 와 같은 명령어로 각 요소에 접근 할 수 있다.
	e.preventDefault(); 는 버튼 고유의 기능을 막는 명령어 */ 
		
		// 검색
	$(document).on('click', '#btnSearch', function(e){
		e.preventDefault();
		var url = "/testList.do";
		url = url + "?searchType=" + $('#searchType').val();
		url = url + "&keyword=" + $('#keyword').val();
		url = url + "&listSize=" + $('#listSize').val();
		location.href = url;
		console.log(url);

	});	

	/*한페이지당 게시물 */
	function page(testId){
	  var startPage = testId;
	  var listSize = $("#listSize option:selected").val();
		
	  if(listSize == 10){
		  var url="/testList.do?startPage="+startPage+"&listSize="+listSize
	  }else if(listSize == 15){
		  var url ="/testList.do?startPage="+startPage+"&listSize="+listSize
	  }else if(listSize == 20){
	      var url="/testList.do?startPage="+startPage+"&listSize="+listSize
	 
	  }
	  location.href = url;
	}
</script>
</html>

페이징과 검색 selectbox가 다 기능하는 모습입니다. 목록 갯수 변경 후 검색, 페이징 등

testMapper.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="egovframework.example.test.service.TestMapper">

	<!--게시글 목록 조회  -->
	<select id="selectTest" resultType="TestVO">
		SELECT
		*
		FROM test
		ORDER BY
		testId DESC

	</select>

	<!--게시글 삽입  -->
	<insert id="insertTest" parameterType="TestVO">
		<![CDATA[
		INSERT INTO test(testTitle, testContent, testName, testDate)
		VALUES(#{testTitle}, #{testContent}, '밥샵', now())
		]]>
	</insert>
	
	<!--게시글 클릭시 detailView  -->
	<select id="selectDetail"
		parameterType="egovframework.example.test.domain.TestVO"
		resultType="egovframework.example.test.domain.TestVO">
		<![CDATA[
			SELECT *
			FROM test
			WHERE testId = #{testId}
		]]>
	</select>

	<!--게시글 업데이트  -->
	<update id="updateTest">
		update test set
		testTitle = #{testTitle}
		,testContent = #{testContent}
		where
		testId = #{testId}
	</update>

	<!--게시글 삭제  -->
	<delete id="deleteTest">
		delete from test
		where
		testId = #{testId}
	</delete>
</mapper> 





TestController

package egovframework.example.test.web;


import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.web.servlet.mvc.support.RedirectAttributes;

import egovframework.example.test.domain.TestVO;
import egovframework.example.test.service.TestService;

@Controller
public class TestController {

	@Autowired
	private TestService testServiceImpl;

	@RequestMapping(value = "/testList.do")
	public String testListDo(@ModelAttribute TestVO testVO, Model model) throws Exception {
		model.addAttribute("list", testServiceImpl.selectTest(testVO));
		return "test/testList";
	}

	// 글 작성 클릭시 글 작성 페이지로 이동
	@RequestMapping(value = "/testRegister.do")
	public String testRegister() {
		return "test/testRegister";
	}

	// 글 작성 버튼 구현
	@RequestMapping(value = "/insertTest.do")
	public String write(@ModelAttribute("testVO") TestVO testVO, RedirectAttributes rttr) throws Exception {
		testServiceImpl.insertTest(testVO);
		return "redirect:testList.do";
	}

	// HttpServletRequest 객체안에 모든 데이터들이 들어가는데 getParameter메소드로 testId 원하는 데이터 가져옴
	// 제목 클릭 시 상세보기
	@RequestMapping(value = "/testDetail.do")
	public String viewForm(@ModelAttribute("testVO") TestVO testVO, Model model, HttpServletRequest request)
			throws Exception {

		int testId = Integer.parseInt(request.getParameter("testId"));
		testVO.setTestId(testId);

		TestVO resultVO = testServiceImpl.selectDetail(testVO);
		model.addAttribute("result", resultVO);

		return "test/testDetail";
	}

	// 수정하기
	@RequestMapping(value = "/updateTest.do")
	public String updateTest(@ModelAttribute("testVO") TestVO testVO, HttpServletRequest request) throws Exception {
		testServiceImpl.updateTest(testVO);
		return "redirect:testList.do";
	}

	// 삭제하기
	@RequestMapping(value = "/deleteTest.do")
	public String deleteTest(@ModelAttribute("testVO") TestVO testVO) throws Exception {
		testServiceImpl.deleteTest(testVO);
		return "redirect:testList.do";
	}

}

TestService

package egovframework.example.test.service;

import java.util.List;

import egovframework.example.test.domain.TestVO;

public interface TestService {

	public List<TestVO> selectTest(TestVO testVO) throws Exception;

	public void insertTest(TestVO testVO)throws Exception;

	public TestVO selectDetail(TestVO testVO) throws Exception;

	public void updateTest(TestVO testVO) throws Exception;

	public void deleteTest(TestVO testVO) throws Exception;
}

TestServiceImpl

package egovframework.example.test.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import egovframework.example.test.dao.TestDAO;
import egovframework.example.test.domain.TestVO;
import egovframework.example.test.service.TestService;

@Service("testServiceImpl")
public class TestServiceImpl implements TestService {
	
	@Autowired
	private TestDAO testDAOService;

	@Override
	public List<TestVO> selectTest(TestVO testVO) throws Exception {		
		return testDAOService.selectTest(testVO);
	}

	@Override
	public void insertTest(TestVO testVO) throws Exception {
		testDAOService.insertTest(testVO);
	}
	@Override
	public TestVO selectDetail(TestVO testVO) throws Exception {
		/*TestVO resultVO = testDAOService.selectDetail(testVO);
		return resultVO;*/
		return testDAOService.selectDetail(testVO);
	}

	@Override
	public void updateTest(TestVO testVO) throws Exception {
		testDAOService.updateTest(testVO);
	}

	@Override
	public void deleteTest(TestVO testVO) throws Exception {
		testDAOService.deleteTest(testVO);
	}
}

TestDAO

package egovframework.example.test.dao;

import java.util.List;

import egovframework.example.test.domain.TestVO;

public interface TestDAO {

	List<TestVO> selectTest(TestVO testVO) throws Exception;

	void insertTest(TestVO testVO) throws Exception;
	
	TestVO selectDetail(TestVO testVO) throws Exception;

	void updateTest(TestVO testVO) throws Exception;

	void deleteTest(TestVO testVO) throws Exception;
}

TestDAOService

package egovframework.example.test.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import egovframework.example.test.domain.TestVO;
import egovframework.example.test.service.TestMapper;

@Service("testDAOService")
public class TestDAOService implements TestDAO {

	@Autowired
	private SqlSession sqlSession;

	@Override
	public List<TestVO> selectTest(TestVO testVO) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		return mapper.selectTest(testVO);
	}

	@Override
	public void insertTest(TestVO testVO) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		mapper.insertTest(testVO);
	}

	@Override
	public TestVO selectDetail(TestVO testVO) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		return mapper.selectDetail(testVO);
	}
	
	@Override
	public void updateTest(TestVO testVO) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		mapper.updateTest(testVO);
	}
	
	@Override
	public void deleteTest(TestVO testVO) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		mapper.deleteTest(testVO);
	}

}

TestMapper.java

package egovframework.example.test.service;

import java.util.List;

import egovframework.example.test.domain.TestVO;


public interface TestMapper {

	// 게시물 리스트 조회
	public List<TestVO> selectTest(TestVO testVO) throws Exception;

	// 게시물 작성
	public void insertTest(TestVO testVO) throws Exception;

	// 게시물 조회
	public TestVO selectDetail(TestVO testVO) throws Exception;

	// 게시물 수정
	public void updateTest(TestVO testVO) throws Exception;

	// 게시물 삭제
	public void deleteTest(TestVO testVO) throws Exception;
}

testList.jsp(게시판 목록 페이지)

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<html>

<head>
<!-- Bootstrap CSS -->

<link rel="stylesheet"
	href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
	integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
	crossorigin="anonymous">

<link href="/css/test/test.css" rel="stylesheet" type="text/css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>

</head>

<body>

	<h1>게시판List</h1>

	<div class="testlist">
		<form id="boardForm" name="boardForm" method="post">
			<table class="list_table">
				<colgroup>
					<col width="20%" />
					<col width="50%" />
					<col width="15%" />
					<col width="15%" />
				</colgroup>
				<tbody>
				<thead>

					<tr>
						<th>번호</th>
						<th>제목</th>
						<th>작성자</th>
						<th>등록일자</th>
					</tr>
				</thead>

				<!-- jstl 데이터베이스를 검색해 넘겨 받은 list 를 result 라는 이름으로 순차적으로 실행을 시키게 됨  java의 for문같이 순차적으로 실행시킴-->

				<c:forEach items="${list}" var="result">
					<tr>
						<td><c:out value="${result.testId}" /></td>
						<td><a href='#' onClick='fn_view(${result.testId})'><c:out
									value="${result.testTitle }" /></a></td>
						<td><c:out value="${result.testName}" /></td>
						<td><c:out value="${result.testDate}" /></td>
					</tr>
				</c:forEach>
				</tbody>
			</table>
		</form>
	</div>
	<div>
		<button id="btn_write" type="button" class="btn_write">글작성</button>
	</div>
	<br>
</body>
<script type="text/javascript">
	//글 작성 버튼 클릭 시 testRegister로 이동
	$("#btn_write").click(function javascript_onclikc() {
		$(location).attr('href', 'testRegister.do');

	});
	
	//글조회
	//	어떤 게시물을 클릭했는지 게시물의 번호(testId)를 넘겨 줘야 함 따라서 게시물 클릭 이벤트에서 게시물의 번호를 인자 값으로 받습니다.
	//  get 방식으로 데이터를 전송합니다. 따라서 ? 연산자를 사용해 testId를 주소 뒤에 붙여 줍니다
	function fn_view(testId){
    
  	  var form = document.getElementById("boardForm");
  	  var url = "<c:url value='/testDetail.do'/>";
  	  url = url + "?testId=" + testId;
    
 	   form.action = url;    
 	   form.submit(); 
	}
</script>
</html>

testRegister.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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
	integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
	crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
	integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"
	crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
	integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
	crossorigin="anonymous"></script>
<link href="/css/test/test.css" rel="stylesheet" type="text/css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script type="text/javascript" src="js/jquery-3.1.1.min.js"></script>
</head>
<body>
	<div class="container">
		<table class="table table-bordered">
			<thead>
				<h1>글쓰기</h1>
			</thead>
			<tbody>
				<form id="form_test" action="insertTest.do" method="post"
					encType="multiplart/form-data">
					<tr>
						<th>제목:</th>
						<td><input type="text" placeholder="제목을 입력하세요. "
							name="testTitle" class="form-control" /></td>
					</tr>
					<tr>
						<th>내용:</th>
						<td><textarea placeholder="내용을 입력하세요 . " name="testContent"
								class="form-control" style="height: 200px;"></textarea></td>
					</tr>
					<tr>
						<td colspan="2">
							<button id="btn_register" type="button" class="btn_register">등록</button>
							<button id="btn_previous" type="button" class="btn_previous">이전</button>
					</tr>

				</form>
			</tbody>
		</table>
	</div>


</body>
<script type="text/javascript">
	//글쓰기

	$(document).on('click', '#btn_register', function(e) {
		$("#form_test").submit();
	});

	//이전 클릭 시 testList로 이동
	$("#btn_previous").click(function javascript_onclikc() {
		$(location).attr('href', 'testList.do');
	});
</script>
</html>



testDetail.jsp(게시판 상세보기, 수정, 삭제 페이지)

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
	integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
	crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
	integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"
	crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
	integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
	crossorigin="anonymous"></script>
<link href="/css/test/test.css" rel="stylesheet" type="text/css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
</head>
<body>
	<div class="container">
		<table class="table table-bordered">
			<thead>
				<h1>글 상세보기 Detail</h1>
			</thead>
			<tbody>
				<form action="updateTest.do" id="viewForm" method="post"
					encType="multiplart/form-data">
				<tr>
					<th>글번호:</th>
					<td><input name="testId" type="text" value="${result.testId}"
						class="form-control" readonly /></td>

				</tr>
				<tr>
					<th>제목:</th>
					<td><input type="text" value="${result.testTitle}"
						name="testTitle" class="form-control" /></td>
				</tr>
				<tr>
					<th>내용:</th>
					<td><textarea name="testContent" class="form-control"
							style="height: 200px;">${result.testContent}</textarea></td>

				</tr>
				<tr>
					<td colspan="2">
						<button id="btn_previous" type="button" class="btn_previous">이전</button>
						<button id="btn_delete" type="button" class="btn_previous">삭제</button>
						<button id="btn_modify" type="button" class="btn_register">수정</button>
				</tr>
				</form>
			</tbody>
		</table>
	</div>

</body>
<script type="text/javascript">
	$(document).on('click', '#btn_modify', function(e) {
		if(confirm("정말 수정하시겠습니까 ?") == true){
	        $("#viewForm").submit();
	    }
	    else{
	        return ;
	    }
	});
	$(document).on('click', '#btn_delete', function(e) {
		if(confirm("정말 삭제하시겠습니까 ?") == true){
			$("#viewForm").attr("action", "deleteTest.do");
			$("#viewForm").submit();
	    }
	    else{
	        return ;
	    }
	});

	//이전 클릭 시 testList로 이동
	$("#btn_previous").click(function javascript_onclikc() {
		$(location).attr('href', 'testList.do');

	});
</script>
</html>

 


test.css

@charset "UTF-8";

.testlist {
	width: 100%;
}

.list_table {
	width: 100%;
}

.list_table thead th {
	text-align: center;
	border-top: 1px solid #e5e5e5;
	border-bottom: 1px solid #e5e5e5;
	padding: 8px 0;
	background: #faf9fa;
}

.list_table tbody td {
	text-align: center;
	border-bottom: 1px solid #e5e5e5;
	padding: 5px 0;
}

.paging {
	margin-top: 30px;
	text-align: center;
}

.btn_write, .btn_register, .btn_previous {
	float: right;
	margin-right: 10px;
}

.pagination1 {
	margin-top: 60px;
	margin-left: 750px;
}

extsdd.tistory.com/102?category=851852

 

[Spring/eGov ] #6 웹 서비스 만들기 2 / 요청 URL 파라미터 가져오기 / Debug 방법 / 디버깅 하는법 / @Model

 

extsdd.tistory.com

 

jo-coder.tistory.com/24

 

1. 게시판 만들기 환경설정 egovframework(전자정부프레임워크) springframework(스프링프레임워크)

extsdd.tistory.com/47?category=851852 [스프링/전자정부 프레임워크 입문] #1 프레임워크란? 전자정부 프레임워크를 알기 앞서 스프링 프레임 워크에 대해서 알아야 한다. 비전공자들도 쉽게 이해할 수 있

jo-coder.tistory.com


패키지 구조 


mariadb 

 

데이터베이스 egovtest에 test테이블을 만들고 

필요한 열들을 추가한다. 

키 id , 제목 , 내용, 작성자, 작성 날짜, 파일 이름 정도로 만들 것이다.

 


pom.xml

jeong-pro.tistory.com/168이 블로그에 maven과 pom.xml에 대한 설명이 잘 되어있다.

maven은 자바 프로젝트의 빌드(build)를 자동화해주는 빌드 툴이며

pom.xml은 프로젝트 내 빌드 옵션을 설정하는 부분이다.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>test2</groupId>
	<artifactId>test2</artifactId>
	<packaging>war</packaging>
	<version>1.0.0</version>
	<name>test2</name>
	<url>http://www.egovframe.go.kr</url>

	<licenses>
		<license>
			<name>The Apache Software License, Version 2.0</name>
			<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
		</license>
	</licenses>

	<properties>
		<spring.maven.artifact.version>4.3.16.RELEASE</spring.maven.artifact.version>
		<egovframework.rte.version>3.8.0</egovframework.rte.version>
	</properties>

	<repositories>
		<repository>
			<id>mvn2</id>
			<url>http://repo1.maven.org/maven2/</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
		</repository>
		<repository>
			<id>egovframe</id>
			<url>http://www.egovframe.go.kr/maven/</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
		<repository>
			<id>egovframe2</id>
			<url>http://maven.egovframe.kr:8080/maven/</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

	<dependencies>
		<!-- 표준프레임워크 실행환경 -->
		<dependency>
			<groupId>egovframework.rte</groupId>
			<artifactId>egovframework.rte.ptl.mvc</artifactId>
			<version>${egovframework.rte.version}</version>
			<exclusions>
				<exclusion>
					<artifactId>commons-logging</artifactId>
					<groupId>commons-logging</groupId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>egovframework.rte</groupId>
			<artifactId>egovframework.rte.psl.dataaccess</artifactId>
			<version>${egovframework.rte.version}</version>
		</dependency>
		<dependency>
			<groupId>egovframework.rte</groupId>
			<artifactId>egovframework.rte.fdl.idgnr</artifactId>
			<version>${egovframework.rte.version}</version>
		</dependency>
		<dependency>
			<groupId>egovframework.rte</groupId>
			<artifactId>egovframework.rte.fdl.property</artifactId>
			<version>${egovframework.rte.version}</version>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<scope>provided</scope>
			<version>2.5</version>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<dependency>
			<groupId>taglibs</groupId>
			<artifactId>standard</artifactId>
			<version>1.1.2</version>
		</dependency>

		<dependency>
			<groupId>org.antlr</groupId>
			<artifactId>antlr</artifactId>
			<version>3.5</version>
		</dependency>




		<dependency>
			<groupId>com.googlecode.log4jdbc</groupId>
			<artifactId>log4jdbc</artifactId>
			<version>1.2</version>
			<exclusions>
				<exclusion>
					<artifactId>slf4j-api</artifactId>
					<groupId>org.slf4j</groupId>
				</exclusion>
			</exclusions>
		</dependency>



		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.31</version>
		</dependency>


		<!-- MariaDB 연동을 위해 아래 dependency 추가 -->
		<dependency>
			<groupId>org.mariadb.jdbc</groupId>
			<artifactId>mariadb-java-client</artifactId>
			<version>2.4.1</version>
		</dependency>
        <!-- Apache Baisc Data Source -->
		<dependency>
    		<groupId>commons-dbcp</groupId>
    		<artifactId>commons-dbcp</artifactId>
    		<version>1.4</version>
		</dependency>


	</dependencies>

	<build>
		<defaultGoal>install</defaultGoal>
		<directory>${basedir}/target</directory>
		<finalName>${artifactId}-${version}</finalName>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.tomcat.maven</groupId>
					<artifactId>tomcat7-maven-plugin</artifactId>
					<version>2.2</version>
					<configuration>
						<port>80</port>
						<path>/</path>
						<systemProperties>
							<JAVA_OPTS>-Xms256m -Xmx768m -XX:MaxPermSize=256m</JAVA_OPTS>
						</systemProperties>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<configuration>
						<source>1.8</source>
						<target>1.8</target>
						<encoding>UTF-8</encoding>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.codehaus.mojo</groupId>
					<artifactId>hibernate3-maven-plugin</artifactId>
					<version>2.1</version>
					<configuration>
						<components>
							<component>
								<name>hbm2ddl</name>
								<implementation>annotationconfiguration</implementation>
							</component>
						</components>
					</configuration>
					<dependencies>
						<dependency>
							<groupId>org.hsqldb</groupId>
							<artifactId>hsqldb</artifactId>
							<version>2.3.2</version>
						</dependency>
					</dependencies>
				</plugin>
				<!-- EMMA -->
				<plugin>
					<groupId>org.codehaus.mojo</groupId>
					<artifactId>emma-maven-plugin</artifactId>
					<version>1.0-alpha-3</version>
				</plugin>
				<!-- PMD manven plugin -->
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-pmd-plugin</artifactId>
					<version>3.1</version>
				</plugin>
			</plugins>
		</pluginManagement>
		<plugins>
			<!-- EMMA -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<configuration>
					<skipTests>true</skipTests>
					<forkMode>once</forkMode>
					<reportFormat>xml</reportFormat>
					<excludes>
						<exclude>**/Abstract*.java</exclude>
						<exclude>**/*Suite.java</exclude>
					</excludes>
					<includes>
						<include>**/*Test.java</include>
					</includes>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>emma-maven-plugin</artifactId>
				<inherited>true</inherited>
			</plugin>
			<!-- JavaDoc -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-javadoc-plugin</artifactId>
				<version>2.9.1</version>
			</plugin>
		</plugins>
	</build>
	<reporting>
		<outputDirectory>${basedir}/target/site</outputDirectory>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-project-info-reports-plugin</artifactId>
				<version>2.7</version>
				<reportSets>
					<reportSet>
						<id>sunlink</id>
						<reports>
							<report>javadoc</report>
						</reports>
						<inherited>true</inherited>
						<configuration>
							<links>
								<link>http://docs.oracle.com/javase/6/docs/api/</link>
							</links>
						</configuration>
					</reportSet>
				</reportSets>
			</plugin>
			<!-- JUnit Test Results & EMMA Coverage Reporting -->
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>emma-maven-plugin</artifactId>
				<inherited>true</inherited>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>surefire-report-maven-plugin</artifactId>
				<inherited>true</inherited>
				<reportSets>
					<reportSet>
						<reports>
							<report>report-only</report>
						</reports>
					</reportSet>
				</reportSets>
			</plugin>
			<!-- Generating JavaDoc Report -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-javadoc-plugin</artifactId>
				<configuration>
					<minmemory>128m</minmemory>
					<maxmemory>512m</maxmemory>
					<encoding>${encoding}</encoding>
					<docencoding>${encoding}</docencoding>
					<charset>${encoding}</charset>
				</configuration>
			</plugin>
			<!-- Generating Java Source in HTML -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jxr-plugin</artifactId>
				<configuration>
					<inputEncoding>${encoding}</inputEncoding>
					<outputEncoding>${encoding}</outputEncoding>
					<linkJavadoc>true</linkJavadoc>
					<javadocDir>apidocs</javadocDir>
				</configuration>
			</plugin>
		</plugins>
	</reporting>
</project>

 MariaDB연동을 위해 dependency 추가해주기 


context-datasource.xml

JDBC는 클라이언트의 요청마다 커넥션을 생성하고 닫기 때문에 그 과정에서 시간이 소모되고 서버 자원이 낭비될 수 있다. 그래서 이런 문제를 해결하기 위해 등장한 것이 "커넥션 풀(Conntection Pool)"이다.

클라이언트가 요청할 때마다 커넥션을 연결하는 것이 아니라, 웹 컨테이너가 실행할 때 "풀" 안에 미리 커넥션들을 만들고, DB 작업 시 "풀"에서 빌려 사용 후 다시 반납하는 것이다. DataSource는 커넥션 풀을 관리하므로 DataSource를 통해 커넥션을 얻거나 반납할 수 있다.   블로그:gbsb.tistory.com/69 

--마리아 디비 연결을 위한 설정--

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/jdbc  http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd">

	<bean id="dataSource"
		class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName"
			value="org.mariadb.jdbc.Driver" />
		<property name="url"
			value="jdbc:mariadb://127.0.0.1:3306/egovtest" />
		<property name="username" value="root" />
		<property name="password" value="비밀번호" />
	</bean>


</beans>

 


context-mapper.xml

DB 쿼리 이후 VO(Value Object) 객체에 대한 맵핑을
iBatis나 MyBatis 등을 사용해서 할 수 있도록 설정하는 것

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">

	
	<bean
		class="egovframework.rte.psl.dataaccess.mapper.MapperConfigurer">
		<property name="basePackage" value="egovframework" />
	</bean>
	
	<!-- mybatis SqlSessionFactoryBean -->
	<bean id="sqlSessionFactory"
		class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- DB에 접속 하기 위해서 설정 -->
		<property name="dataSource" ref="dataSource" />
		<!-- myBatis 기본 설정 -->
		<property name="configLocation"
			value="classpath:/mybatis-config.xml" />
		<!-- query 적힌 xml 위치 -->
		<property name="mapperLocations"
			value="classpath:/egovframework/sqlmap/mappers/**/*Mapper.xml" />
	</bean>

	<bean id="sqlSession"
		class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg name="sqlSessionFactory"
			ref="sqlSessionFactory"></constructor-arg>
	</bean>

</beans>

mybatis-config.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	
	<settings>
		<!-- 자동으로 카멜케이스 규칙으로 변환 -->
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>
	
	<typeAliases>
		<package name="egovframework.example.test.domain"/>
	</typeAliases>
	
</configuration>

 처음에 DB에 test_id 해놨다가 VO에도 test_id 해서 연결이 안 됬었다...  카멜케이스  test_id는 testId로 변환해줌 

나중에 귀찮아져서 DB도 카멜케이스로 바꿔줬음

 


testMappers.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="egovframework.example.test.service.TestMapper">

	<select id="selectTest" resultType="TestVO">
		SELECT
		*
		FROM test
		ORDER BY
		testId DESC

	</select>


</mapper> 

1)parameterType

 

Mapper 파일에 등록된 sql을 실행하려면 sql실행에 필요한 데이터를 외부로부터 받아야 한다. 이때 사용하는 속성이 parameterType속성이다.

 

이때 mybatis 메인 설정 파일에 등록된 <typeAlias>의 Alias를 사용하면 설정을 더 간결하게 처리할 수 있다.

pafameterType으로 지정된 클래스에는 사용자가 입력한 값들을 저장할 여러 변수가 있다. 변수들을 이용하여 sql 구문에 사용자 입력값들을 설정하는데, 이때 #{변수명}으로 사용한다. 

중요한 건 parameterType속성은 생략할 수 있으며 대부분 생략한다.

 

이 쿼리를 실행하기전에 파라미터타입에 객체를 집어 넣을 수 있다. 넣을 수 없다면, 저 쿼리를 봤을때 만약 Where 절에 testId가 1일때, 2일때, 3일때 똑같은 쿼리를 여러번 만들어 줘야하는데 파라미터로 가져온 TestVO안에 있는 저 변수명을 가지고 올 수 있는 것이다. 이 쿼리를 요청할때 함수 구문에 VO를 넣어주는 것이 보일텐데, 여기서 그 VO에 넣어져 있는 값을 사용할 수 있는 것이다. 쿼리문은 하나인데 들어오는 값들에 의해서 쿼리가 동적으로 변화하면서 아주 유연한 쿼링이 가능케하는 것이다. 이게 바로 MyBatis의 강점이라고 할 수 있다.

 

2)resultType 속성

 

검색 관련 sql문이 실행되면 ResultSet이 리턴되며, ResultSet에 저장된 검색 결과를 어떤 자바 객체에 매핑할지 지정해야 하는데, 이때 resultType속성을 사용한다

resultType 속성값으로도 Alias를 사용할 수 있다.

<select> 엘리먼트에서는 생략할 수 없는 필수 속성이다. 다만 resultMap 속성으로 대신 사용할 수 있다.

 

조회하고나서 어떤 데이터 형으로 뱉어줄지다. 머 String이라고 하면 문자열로 나가는등, 원하는 타입으로 선언하면 된다. 하지만, DB특성상 조회하면 여러 컬럼의 형태로 조회되기 때문에 Map형태로 뽑아줘야한다. 이 전자정부프레임워크에는 egovMap이라는 데이터형이 만들어져 있는데 Map을 쓰는게 가장 사용하기 좋다.

 

3)mapper namespace

 namespace는 DAO 구현체 쪽에서 원하는 mapper를 찾기 위해 사용 DAOimpl에서 직접 namespace 사용하는 방법이 있는데 나는 Mapper namespace와 ID를 연결할 TestMapperInterface를 두어서 interface를 호출하는 방법을 사용하였다.


public class TestVO {

	private static final long serialVersionUID = 1L;

	private int testId;
	private String testTitle;
	private String testContent;
	private String testName;
	private String testDate;
    }
    //getter setter

TestVO 

  • 자바와 같은 객체 지향 프로그램에서는 데이터 자체는 외부에서 접근을 할 수 없도록 하고, 메소드만 공개해서 이 중 유효한 값들을 데이터로 저장한다
    • 즉,  객체들이 데이터(필드)를 외부에서 직접적으로 접근하는 것을 막아놓음
  • 필드들은 private 접근 제한자로 막아두고, 각 필드의 Getter, Setter로 접근하는 방식을 취함
    • Getter, Setter는 클래스의 특성중 정보 은닉(Hiding information)을 잘보여줌
  • 이렇게 프로그래밍을 하는 이유는 객체의 무결성을 보장하기 위함

generate Getters  and Setter 하자


package egovframework.example.test.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import egovframework.example.test.domain.TestVO;
import egovframework.example.test.service.TestService;

@Controller
public class TestController {

	@Autowired
	private TestService testServiceImpl;

	@RequestMapping(value = "/testList.do")
	public String testListDo(TestVO testVO, Model model) throws Exception {

		model.addAttribute("list", testServiceImpl.selectTest(testVO));
		return "test/testList";
	}
}

TestController

 

@Autowired가 적용된 의존 주입 대상에 대해서는
<property> 태그나 <constructor-arg> 태그를 사용하지 않아도 스프링이 알맞게 의존 객체를 주입해준다. 

의존관계를 자동으로 연결해주는 기능을 가진 어노테이션

@Autowired의 경우에는 스프링에서 등장한 어노테이션입니다. 따라서 스프링 이외에서는 사용 할 수 없습니다

@Autowired, @Resource, @Inject의 차이blog.naver.com/PostView.nhn?blogId=platinasnow&logNo=220053030295

 

testList.do에 매핑되게 하였고 

함수 이름은 TestListDo이며

TestVO와 Model을 매개변수로 전달받는다.

매개변수로 전달받은 model.addAttribute("key", "value"); 메소드를 이용하여 view 전달할 데이터를 key, value쌍으로 전달할 수 있다.

 

요청이 오면 TestVo에 담아서 testVO라는 이름으로 이 함수를 내부에서 사용할 것이고 

model을 만들어놓고 로직에 처하면서 여기에 사용자가 볼 화면으로 보내줄 데이터를 모아놓을것 이라 해석하면 되겠다.

 

throws Exception 구문은 만약 에러가 발생할시 작동하는 함수인데 보통 서버 Log에 해당 사항을 기록한다.

 

 

Spring Model, ModelMap, ModelAndView 차이점 >>>  javaoop.tistory.com/56


package egovframework.example.test.service;

import java.util.List;

import egovframework.example.test.domain.TestVO;

public interface TestService {

	public List<TestVO> selectTest(TestVO testVO) throws Exception;
    }

TestService


package egovframework.example.test.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import egovframework.example.test.dao.TestDAO;
import egovframework.example.test.domain.TestVO;
import egovframework.example.test.service.TestService;

@Service("testServiceImpl")
public class TestServiceImpl implements TestService {


	
	@Autowired
	private TestDAO testDAOService;
	
	@Override
	public List<TestVO> selectTest(TestVO testVO) throws Exception {		
		return testDAOService.selectTest(testVO);
	}
}

TestServiceImpl

 

 * extends
부모에서 선언 / 정의를 모두하며 자식은 메소드 / 변수를 그대로 사용할 수 있음
 * implements (interface 구현)
부모 객체는 선언만 하며 정의(내용)은 자식에서 오버라이딩 (재정의) 해서 사용해야함


package egovframework.example.test.dao;

import java.util.List;

import egovframework.example.test.domain.TestVO;

public interface TestDAO {

	List<TestVO> selectTest(TestVO testVO) throws Exception;

}

TestDAO

Data Access Object의 약어로 실질적으로 DB에 접근하여 데이터를 조회하거나 조작하는 기능을 전담하는 객체를 말한다.
DAO의 사용 이유는 효율적인 커넥션 관리와 보안성 때문이다. 
DAO는 저수준의 Logic과 고급 비즈니스 Logic을 분리하고 domain logic으로부터 DB관련 mechanism을 숨기기 위해 사용한다.


package egovframework.example.test.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import egovframework.example.test.domain.TestVO;
import egovframework.example.test.service.TestMapper;

@Service("testDAOService")
public class TestDAOService implements TestDAO {

	@Autowired
	private SqlSession sqlSession;
	
	public List<TestVO> selectTest(TestVO testVO) throws Exception {
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		return mapper.selectTest(testVO);
	}
}

TestDAOService

SqlSession 객체를 통해 interface TestMapper에 접근, testMapper 에 작성해 놓은 SQL문을 실행 할 수 있음
DB 접근에 필요한 connection을 관리를 DAO가 처리하게 됨.
(DAO에서 간단하게 SqlSession 을 주입받아 처리 했는데, 이것이 바로 DB Connection을 알아서 관리해 주는 객체 입니다.

 


package egovframework.example.test.service;
//매퍼의 namespace와는 경로를 맞추어야 한다. 
import java.util.List;

import egovframework.example.test.domain.TestVO;
//query 적힌 xml 위치 
//	<property name="mapperLocations"
//	value="classpath:/egovframework/sqlmap/mappers/**/*Mapper.xml" />
//</bean>
//Mapper namespace 와 ID를 연결할 Interface 를 두어서 interface를 호출하는 방법.
//Mybatis 매핑XML에 기재된 SQL을 호출하기 위한 인터페이스이다. Mybatis3.0부터 생겼다.
//SQL id는 인터페이스에 정의된 메서드명과 동일하게 작성한다
public interface TestMapper {

	// 게시물 리스트 조회
	public List<TestVO> selectTest(TestVO testVO) throws Exception;
}

TestMapper


<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<html>

<head>
<!-- Bootstrap CSS -->

<link rel="stylesheet"
	href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
	integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
	crossorigin="anonymous">

<link href="/css/test/test.css" rel="stylesheet" type="text/css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>

</head>

<body>

	<h1>게시판List</h1>

	<div class="testlist">
		<form id="boardForm" name="boardForm" method="post">
			<table class="list_table">
				<colgroup>
					<col width="20%" />
					<col width="50%" />
					<col width="15%" />
					<col width="15%" />
				</colgroup>
				<tbody>
				<thead>

					<tr>
						<th>번호</th>
						<th>제목</th>
						<th>작성자</th>
						<th>등록일자</th>
					</tr>
				</thead>

<!-- jstl 데이터베이스를 검색해 넘겨 받은 list 를 result 라는 이름으로 순차적으로 실행을 시키게 됨  java의 for문같이 순차적으로 실행시킴-->

				<c:forEach items="${list }" var="result">
					<tr>
						<td><c:out value="${result.testId}" /></td>
						<td><c:out value="${result.testTitle}" /></td>
						<td><c:out value="${result.testName}" /></td>
						<td><c:out value="${result.testDate}" /></td>
					</tr>
				</c:forEach>
				</tbody>
			</table>
		</form>
	</div>
	<br>
</body>

</html>

testList.jsp


 


이까지 마리아디비의 연결과 게시물 조회까지 되었다.

 

연습한 게시판 코드에서 코드를 지워서 넣다 보니 이상한 부분이 많은데 다음에 참고할 때 고쳐가며 참고해야 한다.

 

그래서 이미 데이터도 아주 많이 들어가 있다...ㅎㅎ 

 

extsdd.tistory.com/47?category=851852

 

[스프링/전자정부 프레임워크 입문] #1 프레임워크란?

전자정부 프레임워크를 알기 앞서 스프링 프레임 워크에 대해서 알아야 한다. 비전공자들도 쉽게 이해할 수 있도록 예시와 비유를 들어 설명하도록 하겠다. 먼저 프레임워크에 대해서 이해해야

extsdd.tistory.com

이 블로그에 정리가 참 잘 되어있다.

 

 

 

요약하자면

 

springframework는 JAVA플랫폼 기반 프레임워크 (웹서버, 어플리케이션 개발에 특화)

 

전자정부 프레임워크 = springframework + 기업/기관에 특화

 


이제 게시판을 만들기 위한 각종 환경들을 설치하자

 

1. JDK 설치 ( JDK란? Java Development Kit, JDK = JAVA코드를 프로그램으로 바꿔줌

    jo-coder.tistory.com/6?category=413574 (JDK 설치 방법)

 

2. 전자정부프레임워크 설치 

 

3. 톰캣 설치 (톰캣이란?  extsdd.tistory.com/79?category=853192(톰캣에 대한 설명)) 

  jo-coder.tistory.com/7?category=413574 (톰켓 설치 방법)

 

4. 혹시나 maven settings.xml의 경로가 맞는지 확인해주자 (처음 만들 때 경로 잘못되어있어서 에러남)


이번엔 egovframework에서 제공하는 만들어진 게시판을 띄워보자 

(그 이유는 미리 세팅되어있는 환경에서 필요없는 파일들은 지우고 그 위에 내가 다시 게시판을 만들 거임)

 

1. 오른쪽 egovframework 클릭

 

2. File - new -  egovFrame Web Project 클릭 

 

3. Project_name : 본인의 프로젝트 이름 써주고 

  Target Runtime : 톰캣 연결하고 

  Dynamic Web Module Version : 디폴트 값 2.5로 했는데  http://tomcat.apache.org/whichversion.html

 

Apache Tomcat® - Which Version Do I Want?

Apache Tomcat® is an open source software implementation of a subset of the Jakarta EE (formally Java EE) technologies. Different versions of Apache Tomcat are available for different versions of the specifications. The mapping between the specifications

tomcat.apache.org

여기서  Servlet Spec과 톰캣 버전 등을 보며 알맞게 설정해줘야 한다 (샘플 예제를 사용하려면 2.5를 사용해야 한다.)

 

 

Group id : com. 회사 이름으로 보통 명명한다. 나는 그냥 Project_name이랑 똑같이 설정함 

Artifact id : 프로그램 이름이다. Project_name이랑 똑같음

Version : 최초 생성이기 때문에 1.0.0부터 시작한다.

 

4. 다 설정했으면 next를 눌러 Generate Example을 체크 후 finish

 

5. 이제 서버 돌리면 샘플 게시판 예제가 나올 것이다.

 


이제 필요 없는 sample 파일들과 경로들을 수정하자 

 

haenny.tistory.com/67

 

[eGovFramework] Spring 기반 웹 프로젝트 만들기(2) : sample 삭제

[eGovFramework] Spring 기반 웹 프로젝트 만들기(2) : sample 삭제 Spring 기반 웹 프로젝트 만들기(1) [eGovFramework] Spring 기반 웹 프로젝트 만들기(1) : 프로젝트 생성 [eGovFramework] Spring 기..

haenny.tistory.com

이 블로그에 정리가 잘 되어있다. 수정할 부분은 수정하자.


마지막으로 테스트로 jsp 페이지 연결이다 

 

패키지명(참고로 나는 위의 블로그를 그대로 하지 않고 샘플의 패키지명을 사용하였다.)

egovframework.example.test.web    _TestController.java

package egovframework.example.test.web;

@Controller
public class TestController {

	@RequestMapping(value = "/testList.do")
	public String testListDo() {
    
		return "test/testList";
	}

 

WEB-INF/jsp/egovframework/example/test/testList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
hi
</body>
</html>

 

 

톰캣 서버 더블클릭 후 Path설정을 /로 해주고 

 

Window - Preferences - General - Web Browser - 크롬으로 

 

 

서버 스타트하고 

크롬 url에  http://localhost:8080

 

hi가 나오면 성공 

 

혹시나 에러 난다면 Project Clean도 해주자(404가 많이 떴는데 클린 하니까 돌아갈 때가 많았다. )

이클립스가 사용하고 있던 정보나 class를 전부 삭제하고 다시 만드는 것인데이렇게 함으로써 이클립스가 빌드 중에 꼬인걸 다시 새로 정리한다고 한다.

 


 

 

egovframework를 사용한다는 것은 

 

1. /WEB-INF/lib 폴더 아래에 egovframework.rte로 시작하는. jar 파일 존재 여부

2. import egovframework.rt 라는 구문이 검색되는 소스코드가 있는지

3. 상기 소스코드 중 EgovAbstractDAO(EgovMapperDAO) 또는 EgovAbstractServiceImpl(또는

    AbstractServiceImpl1)) 클래스를 상속한 구문이 존재하는지 확인

4. ibatis / Mybatis를 활용하는지

MyBatis나 iBatis를 사용한다면 

DAO 클래스(@Repository) EgovAbstractDAO(iBatis) 또는 EgovAbstractMapper(MyBatis)를 상속해야 한다.

 

 

이게 적용되지 않으면 전자정부 프레임워크 요건에 어긋난다는데... 

 

연습용으로 만들고 보니 그냥 egovframework에 덮어쓴 springframework였다.....   

echarts.apache.org/en/index.html

 

Apache ECharts (incubating)

ECharts: A Declarative Framework for Rapid Construction of Web-based Visualization Please cite the following paper whenever you use ECharts in your R&D projects, products, research papers, technical reports, news reports, books, presentations, teaching, pa

echarts.apache.org

 

 

 

 

echarts로 그린 간단한 그래프

                                                                

 

 

 

maria DB 데이터 

 

<!-- prepare a DOM container with width and height -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<div class="">
	<div id="chart" style="width: 600px; height: 400px;"></div>
</div>

<script language="javascript" type="text/javascript">
	g_cttPage = (function() {

		// 초기 설정 정의
		$(document).ready(function() {
			fn_initSetting();
		});

		// 이벤트 정의

		function fn_initSetting() {

			var params = {};

			params["fn_success"] = function(data, params) {
				fn_sourceGenSuccess(data, params);

				console.log(data);
			}
			fn_ajax("/echart/inEchart.do", params);
		}
		;
		function fn_sourceGenSuccess(data, params) {

			var a = [];
			var b = [];
			var c = [];
			var d = [];
			var e = [];

			for (var i = 15; i >= 0; i--) {
				if (data.result[i].ex_chart == 1) {
					d.push(data.result[i].ex_week);
				}
			}

			for (var i = 15; i >= 0; i--) {
				if (data.result[i].ex_chart == 1) {
					a.push(data.result[i].ex_value);
				} else if (data.result[i].ex_chart == 2) {
					b.push(data.result[i].ex_value);
				} else if (data.result[i].ex_chart == 3) {
					c.push(data.result[i].ex_value);
					//c.push(data.result[i].ex_week);
				}
			}
			for (var i = 15; i >= 0; i--) {
				if (data.result[i].ex_chart == 3) {
					e.push(data.result[i].ex_week);
				}
			}

			console.log('a', a);
			console.log('b', b);
			console.log('c', c[1]);
			console.log('e', e[0]);

			// based on prepared DOM, initialize echarts instance
			var myChart = echarts.init(document.getElementById('chart'));

			// specify chart configuration item and data
			var option = {
				title : {
					text : 'ECharts entry example'
				},
				tooltip : {},
				legend : {
					data : [ 'Sales' ]
				},
				xAxis : {
					type : 'category',
					data : d
				},
				yAxis : {
					type : 'value'
				},
				series : [ {
					data : a,
					type : 'line'
				}, {
					data : b,
					type : 'line'
				}, {
					data : [ [ e[0], c[0] ], [ e[1], c[1] ] ],
					type : 'line'
				} ]
			};
			// use configuration item and data specified to show chart
			myChart.setOption(option);

		}
	})();
</script>

 

위의 초기설정과 이벤트정의 부분은 미리 정의된 함수가 있으니 fn_sourceGenSuccess부분만 참고해야한다.

'플러그인' 카테고리의 다른 글

dataTable 플러그인  (0) 2021.05.02
owlCarousel  (0) 2021.05.02
지도에 화살표와 팝업 띄우기 open layers (https://openlayers.org/)  (0) 2020.09.13

openlayers.org/

 

OpenLayers - Welcome

A high-performance, feature-packed library for all your mapping needs.

openlayers.org

오픈레이어스에서 example과 api 보며 만들 수 있다. 

비주얼 스튜디오로 서버켜서 확인 가능

 

 

 

<!DOCTYPE html>
<html>
  <head>
    <title>Accessible Map</title>
    <link rel="stylesheet" href="https://openlayers.org/en/v3.20.1/css/ol.css" type="text/css">
    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
    <script src="https://openlayers.org/en/v3.20.1/build/ol.js"></script>
    <script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    <link href="https://openlayers.org/en/v4.6.5/css/ol.css" rel="stylesheet" />
    <script src="https://openlayers.org/en/v4.6.5/build/ol-debug.js"></script>

    <style>
      #popup{
        width: 150px;
      }
    </style>
  </head>
  <body>
    
    <div id="map" class="map" tabindex="0"><div id="popup"></div></div>
  
    <script>
      //아이콘들 
      var iconFeature = new ol.Feature({
        geometry: new ol.geom.Point([-0.1277583,51.5073509]).transform('EPSG:4326', 'EPSG:3857'),
        name: '런던<br>위도51.5073509<br>경도-0.1277583',
      
      });
      var iconFeature1 = new ol.Feature({
        geometry: new ol.geom.Point([2.3522219,48.856614]).transform('EPSG:4326', 'EPSG:3857'),
        name: '파리<br>위도48.856614<br>경도2.3522219',
        
      });
      var iconFeature2 = new ol.Feature({
        geometry: new ol.geom.Point([ 13.4081,52.5186]).transform('EPSG:4326', 'EPSG:3857'),
        name: '베를린<br>위도52.5186<br>경도13.4081',
       
      });
      var iconStyle = new ol.style.Style({
        image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
          anchor: [0.5, 46],
          anchorXUnits: 'fraction',
          anchorYUnits: 'pixels',
          src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png'
        }))
      });

      iconFeature.setStyle(iconStyle);
      iconFeature1.setStyle(iconStyle);
      iconFeature2.setStyle(iconStyle);
      



      // 화살표 
      var points = [
         [-0.1277583,51.5073509],
         [2.3522219,48.856614],
         [13.4081,52.5186],
         [-0.1277583,51.5073509]
      ];
      var route = new ol.geom.LineString(points);
      route.transform('EPSG:4326', 'EPSG:3857');

      var routeFeature = new ol.Feature({
        type: 'route',
        geometry: route
      });

      var stylesMap = {
        'route': function(feature) {
          var geometry = feature.getGeometry();
          var styles = [
            // linestring
            new ol.style.Style({
              stroke: new ol.style.Stroke({
                color: '#ffcc33',
                width: 2
              })
            })
          ];

          geometry.forEachSegment(function(start, end) {
            var dx = end[0] - start[0];
            var dy = end[1] - start[1];
            var rotation = Math.atan2(dy, dx);
            
            // arrows
            styles.push(new ol.style.Style({
              geometry: new ol.geom.Point(end),
              image: new ol.style.Icon({
                src: 'https://openlayers.org/en/v4.6.5/examples/data/arrow.png',
                anchor: [0.75, 0.5],
                rotateWithView: true,
                rotation: -rotation
              })
            }));
          });

          return styles;
        }
      };

      var vectorLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
          features: [routeFeature]
        }),
        style: function(feature) {
          const myStyle = stylesMap[feature.get('type')];
          if (myStyle instanceof Function) {
            return myStyle(feature);
          }
          return myStyle;
        }
      });


      // 지도 설정 
      var map = new ol.Map({
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          }),
          new ol.layer.Vector({
            style: function(feature) {
              return feature.get('style');
            },
          source: new ol.source.Vector({features: [iconFeature, iconFeature1, iconFeature2]})
          }),         
          vectorLayer
        ],      
        target: document.getElementById('map'),
        controls: ol.control.defaults({
          attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
            collapsible: false
          })
        }),
        view: new ol.View({
          center: ol.proj.transform([-0.1277583,51.5073509], 'EPSG:4326', 'EPSG:3857'),
          zoom: 4
        })
      });





      // 팝업 설정
      var element = document.getElementById('popup');

      var popup = new ol.Overlay({
        element: element,
        positioning: 'bottom-center',
        stopEvent: false,
        offset: [0, -50]
      });
      map.addOverlay(popup);




      // 팝업 클릭 
      map.on('click', function(evt) {
        var feature = map.forEachFeatureAtPixel(evt.pixel,
            function(feature) {
              return feature;
            });
        if (feature) {
          var coordinates = feature.getGeometry().getCoordinates();
          popup.setPosition(coordinates);
          $(element).attr('data-placement', 'top');
          $(element).attr('data-html', true);
          $(element).attr('data-content', feature.get('name'));
          $(element).popover('show');
        } else {
          $(element).popover('destroy');
        }
      });

  //    매개 변수를 사용하여 popover 함수를 호출하는 대신
  //    사용자 정의하려는 팝 오버의 각 속성에 대해 
  //    html 데이터 속성을 설정 한 다음 popover()매개 변수없이 호출
  //   $(element).popover({
  //   'placement': 'top',
  //   'html': true,
  //   'content': feature.get('information')
  // });



      // change mouse cursor when over marker
      map.on('pointermove', function(e) {
        var pixel = map.getEventPixel(e.originalEvent);
        var hit = map.hasFeatureAtPixel(pixel);
        map.getTarget().style.cursor = hit ? 'pointer' : '';
      });


      
    </script>
  </body>
</html>

 

 

 

 

'플러그인' 카테고리의 다른 글

dataTable 플러그인  (0) 2021.05.02
owlCarousel  (0) 2021.05.02
echarts 차트 그리기  (0) 2020.09.19

 

이 에러의 이유가 

1. web.xml에 맵핑을 안 해놓았을 경우

2. servlet.xml에 맵핑을 안 해놓았을 경우

3. 컨트롤러에 정의하지 않은 경우

가 있다고 한다.

 

그래서 다 확인 해봤는데 안되었었는데 

 

Project clean하니까 해결.............................................      ...  재컴파일되면서 꼬인게 되었나보다  

'에러' 카테고리의 다른 글

unknown error: cannot find Chrome binary  (0) 2020.12.22
Eclipse Project에 x 표시  (0) 2020.10.19

+ Recent posts