정보를 데이터베이스에 테이블 추가 (테이블명 : 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>
실행결과
'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 |