Spring

[Spring] 방명록 만들기

(งᐛ)ว 2023. 11. 21. 00:06
728x90

정보를 데이터베이스에 테이블 추가 (테이블명 : VISIT) 추가방법은 이전글 JDBC_1 참고

더보기

--시퀀스
CREATE SEQUENCE SEQ_VISIT_IDX;

--테이블
CREATE TABLE VISIT(IDX NUMBER(3) PRIMARY KEY,
  NAME VARCHAR2(50), --작성자 
  CONTENT VARCHAR2(100), --내용
  PWD VARCHAR2(50), --비번
  IP VARCHAR2(20), --IP
  REGIDATE DATE --작성일
);


--샘플데이터 
INSERT INTO VISIT VALUES(SEQ_VISIT_IDX.NEXTVAL,
          '홍길동',
          '내가1등',
          '1111',
          '192.1.1.1',
          SYSDATE
);

INSERT INTO VISIT VALUES(SEQ_VISIT_IDX.NEXTVAL,
          '김길동',
          '내가2등',
          '1111',
          '192.1.1.1',
          SYSDATE
);

commit;

 

 

기존 글을 참고하여 필요한 파일을 세팅하자

 

[Spring] 부서조회하기

https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-war-plugin 해당 영역 복사하여 pom.xml의 영역 사이에 붙여넣고 해당 내용도 사이에 추가해주자 oraclexe 해당경로의 ojdbc.jar 파일을 복사하여 현재 스

studywithjw.tistory.com

 

부서조회하기에서 사용한 파일 중 복붙하기

pom.xml (Overview에서 Artifact Id와 프로젝트 Name만 수정)

resources의 5개 패키지(내용 수정 필요 / WebInitializer.java / Context_1_dataSource.java / Context_2_mybatis.java 세 파일은 동일하게 사용)

 

 

 

 

VisitVO.java

package vo;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class VisitVO {

	private int idx;
	private String name, content, pwd, ip, regidate;
	
}

 

 

 

VisitDAO.java

package dao;

import java.util.List;
import org.apache.ibatis.session.SqlSession;
import vo.VisitVO;

public class VisitDAO {
	
	SqlSession sqlSession;
	
	public VisitDAO(SqlSession sqlSession) {
		this.sqlSession = sqlSession;
	}
	
	//방명록 전체조회 
	public List<VisitVO> selectList(){
		return sqlSession.selectList("v.visit_list");
	}

}

 

 

 

dao객체만들기

Context_3_dao.java

package context;

import org.apache.ibatis.session.SqlSession;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import dao.VisitDAO;

@Configuration
public class Context_3_dao {

	@Bean
	public VisitDAO dao(SqlSession sqlSession) {
		return new VisitDAO(sqlSession);
	}
	
}

 

 

 

visit.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="v">

	<!-- 전체조회 -->
	<select id="visit_list" resultType="vo.VisitVO">
		select * from visit ORDER BY IDX DESC <!-- 최신글이 맨 위로 올라오게됨 -->
	</select>
	
</mapper>

 

 

 

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="cacheEnabled" value="false" />
		<setting name="useGeneratedKeys" value="true" />
		<setting name="defaultExecutorType" value="REUSE" />
	</settings>
	
	<mappers>
		<mapper resource="config/mybatis/mapper/visit.xml" />
	</mappers>
</configuration>

 

 

 

VisitController.java

package com.korea.visit;

import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import dao.VisitDAO;
import util.MyCommon;
import vo.VisitVO;

@Controller
public class VisitController {

	VisitDAO visit_dao;

	public VisitController(VisitDAO visit_dao) {
		this.visit_dao = visit_dao;
	}

	
 	//MyCommon.java 클래스 작성 후 작성하기 
	@RequestMapping(value = { "/", "visit_list.do" })
	public String select(Model model) {// 바인딩 포워딩을 위해 모델객체
		// dao에 접근하여 select 한 list 받기
		List<VisitVO> list = visit_dao.selectList();
		// 모델객체에 바인딩하기
		model.addAttribute("list", list);
		// jsp로 포워딩하기
		return MyCommon.VIEW_PATH + "visit_list.jsp";
	}

}

 

 

 

Servlet_Context.java

package mvc;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.korea.visit.VisitController;
import dao.VisitDAO;


@Configuration
@EnableWebMvc
//@ComponentScan("com.korea.db") 자동탐색
//어노테이션에도 상속관계가 있다
/*
 *@Component
 *	ㄴ@Controller
 *	ㄴ@Service
 *	ㄴ@Repository 
 * */
//컴포넌트의 자식객체가 들어있으면 사실 Controller가 아니어도 만들어 질 수 있다.
public class ServletContext implements WebMvcConfigurer {

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
	}
	
//	  @Bean 
//	  public InternalResourceViewResolver resolver() {
//	  InternalResourceViewResolver resolver = new InternalResourceViewResolver();
//	  resolver.setViewClass(JstlView.class); resolver.setPrefix("/WEB-INF/views/");
//	  resolver.setSuffix(".jsp"); return resolver; }
	
	
	
	//자동탐색 아니고 수동으로작성
	@Bean
	public VisitController visitController(VisitDAO visit_dao) {
		return new VisitController(visit_dao);
	}
}

 

 

 

MyCommon.java

package util;

public class MyCommon {

	public static final String VIEW_PATH = "/WEB-INF/views/visit/";
	
}

 

 

 

visit_list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/visit.css">
<!-- ////////////////////////// -->
<!-- 수정,삭제 function 입력예정 -->
<!-- ////////////////////////// -->
</head>
<body>
	<div id="main_box">
		<h1>방명록 리스트</h1>
		<input type="button" value="글쓰기" onclick="location.href='insert_form.do'"> <!-- 컨트롤러에서 requestmapping으로 잡아줄예정 -->
		
	</div>
	<c:forEach var="vo" items="${list}">
		<div class="visit_box"> <!-- id 는 고유해야하는게 좋아서 위에서 썼으면 다른방법쓰는게 좋음  -->		
			
			<div class="type_content" style="word-break:break-all;">${vo.content}</div> <!-- break-all : 칸에 맞게 줄바꿈해줌 -->
			<div class="type_name">작성자 : ${vo.name}(${vo.ip})</div>
			<div class="type_regidate">작성일 : ${vo.regidate}</div>

			<div>
				<form>
					<input type="hidden" name="idx" value="${vo.idx}"> 
					<input type="hidden" name="ori_pwd" value="${vo.pwd}"> 
					비밀번호 <input type="password" name="pwd"> 
					<input type="button" value="수정" onclick="modify(this.form)"> 
					<input type="button" value="삭제" onclick="del(this.form)">
				</form>
			</div>			
			
		</div>
	</c:forEach>
</body>
</html>

 

 

 

webapp > resources > css폴더생성 > visit.css파일생성

@charset "UTF-8";
*{margin:0; padding:0;}

#main_box{
	width:330px;
	margin:auto;
	background-color: #ccc; /* 영역확인용 */
}

h1{
	text-align: center;
	margin-top: 10px;
	margin-bottom: 10px;
	color: #0080ff;
	text-shadow: 2px 2px 2px black;
}

.visit_box{
	margin:auto;
	width:330px;
	margin-top:30px;
	box-shadow: 2px 2px 2px black;
	border : 1px solid blue;
}

.type_content{
	min-height: 100px;
	height:auto;
	background: #FFFFCD;
}

.type_name{
	background: #cfc;
}

.type_regidate{
	background: #ccf;
}

 

 

 

실행결과

 

 

 


 

글쓰기 기능 추가하기

 

 

VisitController.java (jsp에서 jsp로 바로 넘어갈 수 없어서 컨트롤러를 거치는 것)

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서

	// 새글입력 폼
	@RequestMapping("insert_form.do")
	public String insert_form() {
		return MyCommon.VIEW_PATH + "visit_insert_form.jsp";
	}

 

 

 

visit_insert_form.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>
		<script type="text/javascript">
			function send(f){
				var name = f.name.value;
				var content = f.content.value;
				var pwd = f.pwd.value;

				
				//유효성체크 
				if(name==""){
					alert("이름을 입력하세요")
					return;
				}
				
				if(content==""){
					alert("내용을 입력하세요")
					return;
				}
				
				if(pwd==""){
					alert("비밀번호를 입력하세요")
					return;
				}
				
				
				f.action="insert.do";
				f.submit();
			}
			
		</script>
	</head>
	<body>
		<form method="POST" enctype="multipart/form-data">
			<table border="1" align="center">
				<caption>:::새 글 작성:::</caption>
				<tr>
					<th>작성자</th>
					<td><input name="name" style="width:250px;"></td> 
				</tr>
				<tr>
					<th>내용</th>
					<td>
						<textarea rows="5" cols="50" name="content" style="resize:none;"></textarea>
					</td>	
				</tr>
				<tr>
					<th>비밀번호</th>
					<td><input name="pwd" type="password"></td>
				</tr>
 				<tr>
					<td colspan="2" align="center">
					<input type="button" value="등록" onclick="send(this.form);">
					<input type="button" value="목록으로" onclick="location.href='visit_list.do'"> <!-- jsp로 바로 갈 수 없고 컨트롤러로 돌아가야함  -->
					</td>
				</tr>
			</table>
		</form>
	</body>
</html>

 

 

 

VisitController.java

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서

	// 새글등록
	@RequestMapping("insert.do")
	public String insert(VisitVO vo, HttpServletRequest request) {
		String ip = request.getRemoteAddr();
		vo.setIp(ip);
        
		int res = visit_dao.insert(vo);
		return "redirect:visit_list.do";

 

 

 

VisitDAO.java

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서

	//새글추가 
	public int insert(VisitVO vo) {
		return sqlSession.insert("v.visit_insert",vo);
	}

 

 

 

visit_insert라는 아이디를 가지는 쿼리를 만들어야함

visit.xml

<!--//////////////////////////////////////////////////////////////////////////////////////////
//이어서-->

	<!-- 새글추가 -->
	<insert id="visit_insert" parameterType="vo.VisitVO"> <!-- DAO에서 넘기는 파라미터(vo)가 있음 -->
		INSERT INTO VISIT VALUES(SEQ_VISIT_IDX.NEXTVAL,
					 #{name},
					 #{content},
					 #{pwd},
					 #{ip},
					 sysdate) <!-- 달러표시아님, 마지막은 콤마없음, 세미콜론 없음 -->
	</insert>

 

이 값들을 정수로 받아서 DAO에서 return 해주고

그 return된 값들을 컨트롤러가 받으므로 컨트롤러에서 int res = visit_dao.insert(vo); 가 되는것임

 

 

실행결과

 

 

 


 

글삭제 기능 추가하기 (ajax 사용_js파일)

 

visit_list.jsp

빗금부분 작성

<script src="${pageContext.request.contextPath}/resources/js/httpRequest.js"></script> <!--참조 -->
<script type="text/javascript">
	function del(f) {

		var pwd = f.pwd.value;
	
		if (pwd == "") {
			alert("비밀번호를 입력하세요");
			return;
		}	
	
		if (!confirm("삭제하시겠습니까?")) {
			return; /* 아니오 했을때 상태유지 */
		}

		var url = "delete.do";
		var param = "idx="+f.idx.value+"&pwd="+encodeURIComponent(pwd);

		sendRequest(url, param, resultFn, "POST"); /* resultFn이라는 콜백함수 만들예정 */

	}

 

 

 

VisitController.java

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서

	// 삭제하기
	@RequestMapping("delete.do")
	@ResponseBody // return값을 view형태, jsp로 인식하지 않고 콜백메서드로 전달해줌
	public String delete(int idx, String pwd) { // 원래는 파라미터 하나밖에 안되지만 딱 두개를 보낸다면 해쉬맵을 써보자

		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("idx", idx);
		map.put("pwd", pwd);

		int res = visit_dao.delete(map);

 

 

 

VisitDAO.java

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서

	//삭제하기
	public int delete(HashMap<String, Object> map) {
		return sqlSession.delete("v.visit_delete", map);
	}

 

 

 

visit.xml

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서

	<!-- 삭제하기 -->
	<delete id="visit_delete" parameterType="java.util.HashMap">
		DELETE FROM VISIT WHERE IDX=#{idx} AND PWD=#{pwd}
	</delete>

 

 

 

VisitController.java

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서

	// 삭제하기
	@RequestMapping("delete.do")
	@ResponseBody // return값을 view형태, jsp로 인식하지 않고 콜백메서드로 전달해줌
	public String delete(int idx, String pwd) { // 원래는 파라미터 하나밖에 안되지만 딱 두개를 보낸다면 해쉬맵을 써보자

		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("idx", idx);
		map.put("pwd", pwd);

		int res = visit_dao.delete(map);
		
        ////////이어서 추가작성///////////      		
        
        // 성공여부 확인후 리턴할것
		String result = "no";
		if (res == 1) {
			result = "yes";
		}

		String finRes = String.format("[{'res':'%s'}]", result); // 콜백함수로 돌아가야함 @ResponseBody를 써주자! 
		return finRes;

	}

 

 

 

visit_list.jsp

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서
	
    
    function resultFn() {
		if (xhr.readyState == 4 && xhr.status == 200) {
			var data = xhr.responseText;
			var json = (new Function("return"+data))(); //뉴 펑션 할때 F대문자로 써야함 
			
			//var json = eval(data);
			//eval() : 문자열로 표현된 자바스크립트 코드를 실행해주는 함수 
			//악영향을 줄 수 있는 문자열을 eval로 실행하면 악의적인 코드를 수행하는 결과를 초래할 수 있음 (보안이슈)
			
			if(json[0].res=="no"){
				alert("삭제실패");
				return;
			}
			
			alert("삭제성공")
			location.href="visit_list.do";
			
		}
	}

 

 

 

실행결과

 

 

 


 

수정 기능 추가하기

 

visit_list.jsp

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서
	
    	function modify(f){
		var ori_pwd=f.ori_pwd.value.trim(); //원본 비밀번호
		var pwd=f.pwd.value.trim(); //수정을 위해 입력한 비밀번호
		
		if (pwd == "") {
			alert("비밀번호를 입력하세요");
			return;
		}
		
		if(pwd != ori_pwd){
			alert("비밀번호가 일치하지 않습니다")
			return;
		}
		
		f.action = "modify_form.do";
		f.method = "post";
		f.submit();
		
	}

 

 

 

VisitController.java

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서

	// 수정폼으로 이동
	@RequestMapping("modify_form.do")
	public String modify_form(Model model, int idx) {// 기존입력된 값들을 수정폼으로 가져와야함
		
		// 파라미터로 넘어온 idx를 db로 보내야함
		VisitVO vo = visit_dao.selectOne(idx);

		model.addAttribute("vo", vo);
		return MyCommon.VIEW_PATH + "visit_modify_form.jsp";
	}

 

 

 

selectOne 메서드 생성위해 dao로 

VisitDAO.java

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서

	//게시글 한건 조회하기 
	public VisitVO selectOne(int idx) {//반환형이 vo! 내용을 담아서 반환해줄 수 있으니까
		return sqlSession.selectOne("v.visit_one",idx);
	}

 

 

 

visit.xml

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서

	<!-- 수정시 게시글 한 건만 조회하는 쿼리 (SelectOne) -->
	<select id="visit_one" resultType="vo.VisitVO" parameterType="int">
		SELECT * FROM VISIT WHERE IDX=#{idx}
	</select>

 

 

 

visit_modify_form.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>
		<script type="text/javascript">
			function update(f){
				var idx = f.idx.value;
				var content = f.content.value;
				var pwd = f.pwd.value;		
				
				if(content==""){
					alert("내용을 입력하세요")
					return;
				}
				
				f.method="GET"
				f.action="update.do"
				f.submit();
			}
		</script>
	</head>
	<body>
		<form>
			<input type="hidden" name="idx" value="${vo.idx}">
			<table border ="1" align="center">
				<caption>:::방명록 수정:::</caption>
				<tr>
					<th>작성자</th>
					<td>${vo.name}</td>
				</tr>
				<tr>
					<th>내용</th>
					<td><textarea rows="5" cols="50" name="content" style = "resize:none">${vo.content}</textarea></td>
				</tr>
				<tr>
					<th>비밀번호</th>
					<td><input type="password" name ="pwd" value="${vo.pwd}"></td>
				</tr>
				<tr>
					<td colspan="2" align="center">
					<input type="button" value ="수정" onclick="update(this.form)">
					<input type="button" value ="취소" onclick="location.href='visit_list.do'">
				</tr>
			</table>			
		</form>
	</body>
</html>

 

 

 

VisitController.java

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서

	//수정하기 
	@RequestMapping("update.do")
	public String modify(VisitVO vo, HttpServletRequest request) {
		String ip = request.getRemoteAddr();
		vo.setIp(ip);
		
		int res = visit_dao.update(vo);
		
		if(res>0) {
			return "redirect:visit_list.do";
		}
		return null;
	}
	
}

 

 

 

update메서드 생성위해 dao로 

VisitDAO.java

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서

	//게시글 수정(업데이트)하기 
	public int update(VisitVO vo) {
		return sqlSession.update("v.visit_update",vo);
	}

}

 

 

 

visit.xml

//////////////////////////////////////////////////////////////////////////////////////////////
//이어서

	<!-- 업데이트(수정) 쿼리 -->
	<update id="visit_update" parameterType="vo.VisitVO">
		UPDATE VISIT SET 
			CONTENT=#{content}, 
			PWD=#{pwd}, 
			IP=#{ip}, 
			REGIDATE=sysdate <!-- 여기서 레지데이트 없으면 수정해도 원글시간으로 그대로 --> 
			
			WHERE IDX=#{idx} 
	</update>

 

 

 

실행결과

 

 

 

728x90

'Spring' 카테고리의 다른 글

[Spring] JsonMaker  (1) 2023.11.23
[Spring] 파일업로드 (+방명록에 적용)  (1) 2023.11.23
[Spring] 부서조회하기  (0) 2023.11.18
[Spring] 롬복(LOMBOK)  (0) 2023.11.16
[Spring] 스프링 프레임워크 기본개념 및 설치  (0) 2023.11.09