<!-- fileUpload -->
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- 위치 상관 x
file_upload setting
class multipartresolver 자동완성해서 불러온 후 id 하면 자동완성 -->
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- encoding -->
<beans:property name="defaultEncoding" value="utf-8"/>
<!-- 파일크기 설정 5000000->3mb.. 1024*1024 이런 수식 사용 불가능 -->
<beans:property name="maxUploadSize" value="5000000"/>
</beans:bean>
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- file_upload setting -->
<beans:bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
<beans:property name="defaultEncoding" value="utf-8"/>
<beans:property name="maxUploadSize" value="5000000"/> <!-- 이게 약 5MB_문자열 안먹혀서 1024*1024 이런거 불가능함. -->
</beans:bean>
// 아래는 이미지 파일 경로 지정하기
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/res/**" location="/resources/" />
<resources mapping="/photo/**" location="/resources/image/" />
<resources mapping="/upload/**" location="/WEB-INF/photo/" />
// 아래는 기본 mapping 주소 지정하기
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
// context : 기본 설정 package지정하기. *를 사용하면 일일이 지정이 아니라 겹치는 부분은 한번에 지정해줄 수 있음
<context:component-scan base-package="spring.mvc.*,board.data.controller" />
</beans:beans>
<?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="spring.mvc.friday.InfoDao">
<select id="selectTotalCountOfMyInfo" resultType="int">
select count(*) from myinfo
</select>
<insert id="insertOfMyInfo" parameterType="idto">
insert into myinfo(name,driver,addr,photo,gaipday) values(#{name},#{driver},#{addr},#{photo},now())
</insert>
<!-- <select id="selectAllOfMyInfo" resultType="idto">
select * from myinfo order by num
</select> -->
<select id="selectOneOfMyInfo" resultType="idto" parameterType="String">
select * from myinfo where num=#{num}
</select>
<update id="updateOfMyInfo" parameterType="idto">
update myinfo set name=#{name},driver=#{driver},addr=#{addr}
<!-- <if test="photo!='no'"></if> -->
<if test="photo!=null">
,photo=#{photo}
</if>
where num=#{num}
</update>
<delete id="deleteOfMyInfo" parameterType="String">
delete from myinfo where num=#{num}
</delete>
<!-- 검색 리스트 -->
<select id="selectAllOfMyInfo" resultType="idto" parameterType="Map">
<!-- parameterType의 경우 이름과 serch에서 각각 넘어와 총 2개가 넘어와야하므로 Map을 사용한다. -->
select * from myinfo
<if test="serch!=null">
where ${title} like concat('%',#{serch},'%') <!-- -->
<!-- ${title} 이 의미하는 것은 column이다. -->
<!-- like('*',?,'*') 원래는 이렇게 썼었는데..
검색은 오른쪽처럼 쓴다. where {검색기준이 될 필드명} link concat('%',?,'%')
-->
</if>
order by num asc
</select>
</mapper>
package spring.mvc.friday;
import java.util.List;
import java.util.Map;
public interface InfoInter {
public int getTotalCount();
public void insertMyInfo(InfoDto idto);
// 일반 전체 출력.. 아래 검색용으로 대체함
// public List<InfoDto> getAllDataOfMyInfo();
public InfoDto getData(String num);
public void updateMyInfo(InfoDto idto);
public void deleteInfo(String num);
// 검색용
public List<InfoDto> getAllDataOfMyInfo(Map<String, String> map);
}
package spring.mvc.friday;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class InfoDao implements InfoInter {
// sql팩토리로부터 만들어지는 sqlSession을 가지고 온다.
@Autowired
SqlSession session;
@Override
public int getTotalCount() {
// TODO Auto-generated method stub
return session.selectOne("selectTotalCountOfMyInfo");
}
@Override
public void insertMyInfo(InfoDto idto) {
// TODO Auto-generated method stub
session.insert("insertOfMyInfo", idto);
}
// @Override
// public List<InfoDto> getAllDataOfMyInfo() {
// // TODO Auto-generated method stub
// return session.selectList("selectAllOfMyInfo");
// }
@Override
public InfoDto getData(String num) {
// TODO Auto-generated method stub
return session.selectOne("selectOneOfMyInfo", num);
}
@Override
public void updateMyInfo(InfoDto idto) {
// TODO Auto-generated method stub
session.update("updateOfMyInfo", idto);
}
@Override
public void deleteInfo(String num) {
// TODO Auto-generated method stub
session.delete("deleteOfMyInfo", num);
}
// 검색용 출력..
@Override
public List<InfoDto> getAllDataOfMyInfo(Map<String, String> map) {
// TODO Auto-generated method stub
return session.selectList("selectAllOfMyInfo", map);
}
}
package spring.mvc.friday;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class InfoController {
@Autowired
InfoDao idao;
@Autowired
InfoInter inter;
@GetMapping("/info/list")
public ModelAndView list(@RequestParam(defaultValue = "name")String title, @RequestParam(required = false)String serch) {
// @RequestParam(defaultValue="name") String title : 검색기능으로 인해 초기값을 지정해주지 않으면 오류가 발생한다. 이에 초기값을 name으로 지정해 준 것이다.
// @RequestParam(Required = false) String serch : 검색기능으로 인해 초기값을 지정해주지 않으면 오류가 발생한다. 이에 초기값을 false로 지정해 준 것이다.
ModelAndView mview=new ModelAndView();
int totalCount=idao.getTotalCount();
// List<InfoDto> list=inter.getAllDataOfMyInfo();
System.out.println(title+","+serch);
Map<String, String> map=new HashMap<String, String>();
map.put("serch", serch);
map.put("title", title);
List<InfoDto> list=inter.getAllDataOfMyInfo(map);
mview.addObject("count", totalCount);
mview.addObject("list",list);
mview.setViewName("/info/infolist");
return mview;
}
@GetMapping("/info/addform")
public String addform() {
return "info/addForm";
}
@PostMapping("/info/insert")
public String insert(@ModelAttribute InfoDto idto, @RequestParam MultipartFile upload, HttpSession session) {
// HttpServletRequest 에 realPath 를 찾기 위해서 한다.
// 업로드할 실제 경로 구하기
String path=session.getServletContext().getRealPath("/resources/image/");
System.out.println(path);
// 사진 여러개 올리기 위해서 (현재 날짜와 시간 이용하여 파일명 겹치는거 방지하기)
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
String photo="";
// 사진선택을 안했을 경우 no..
if(upload.getOriginalFilename().equals("")) {
// photo=null;
photo="no";
} else {
String fName=upload.getOriginalFilename();
fName=sdf.format(new Date())+"_"+fName;
photo=fName;
// 업로드
try {
upload.transferTo(new File(path+"/"+photo));
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// dto의 Photo에 업로드 한 것을 넣어줘야 한다.
idto.setPhoto(photo);
// insert
inter.insertMyInfo(idto);
return "redirect:list";
}
@GetMapping("/info/uform")
public String uform(@RequestParam String num,Model model) {
InfoDto idto=inter.getData(num);
model.addAttribute("idto", idto);
return "info/updateform";
}
@PostMapping("/info/update")
public String update(@ModelAttribute InfoDto idto,@RequestParam MultipartFile upload,HttpSession session,String num) {
String path=session.getServletContext().getRealPath("/resources/image/");
System.out.println(path);
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
String photoname; // dto에 담을 변수
// 기존사진삭제
String photo=inter.getData(num).getPhoto();
if(!photo.equals("no")) {
File file=new File(path+"/"+photo); // 이미지중에 내가 고른 사진
file.delete();
}
// 사진 선택안할경우 null
if(upload.getOriginalFilename().equals("")) {
photoname=null;
} else {
photoname=upload.getOriginalFilename();
photoname=sdf.format(new Date())+"_"+photoname;
// 업로드
try {
upload.transferTo(new File(path+"/"+photoname));
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// dto의 Photo에 Upload한 photoname을 넣어준다.
idto.setPhoto(photoname);
//update
inter.updateMyInfo(idto);
return "redirect:list";
}
@GetMapping("/info/delete")
public String deleteInfo(@RequestParam String num,HttpSession session) {
// 파일삭제
String photo=inter.getData(num).getPhoto();
if(!photo.equals("no")) {
String path=session.getServletContext().getRealPath("/resources/image/");
File file=new File(path+"/"+photo); // 이미지중에 내가 고른 사진
file.delete();
}
// db삭제
inter.deleteInfo(num);
return "redirect:list";
}
}
<body>
<h2 class="alert alert-danger" style="margin: 20px 20px;">총 ${count }개의 정보가 있습니다.</h2>
<button type="button" class="btn btn-outline-info" onclick="location.href='addform'" style="margin: 20px 20px;">글쓰기</button>
<table class="table table-bordered" style="width: 800px;">
<tr>
<th>no.</th>
<th>이름</th>
<th>사진</th>
<th>운전면허</th>
<th>주소</th>
<th>작성일</th>
<th>편집</th>
</tr>
<c:forEach var="idto" items="${list }" varStatus="i">
<tr>
<td align="center">${i.count }</td>
<td align="center">${idto.name }</td>
<td align="center">
<c:if test="${idto.photo=='no' }">
<img alt="" src="../photo/noimage.jpg" width="50" class="img-circle">
</c:if>
<c:if test="${idto.photo!='no' }">
<img alt="" src="../photo/${idto.photo }" width="50" class="img-circle">
</c:if>
</td>
<td>${idto.driver }</td>
<td>${idto.addr }</td>
<td>
<fmt:formatDate value="${idto.gaipday }" pattern="yyyy-MM-dd HH:mm"/>
</td>
<td>
<button type="button" class="btn btn-outline-warning btn-sm" onclick="location.href='uform?num=${idto.num}'">수정</button>
<button type="button" class="btn btn-outline-danger btn-sm" onclick="location.href='delete?num=${idto.num}'">삭제</button>
</td>
</tr>
</c:forEach>
</table>
<div style="width: 900px; text-align: center;" >
<form action="list" class="d-inline-flex">
<select name="title" class="form-control" style="width: 120px;">
<option value="name" ${title=='name'?"selected":"" }>이름</option>
<option value="addr" ${title=='addr'?"selected":"" }>주소</option>
<option value="driver" ${title=='driver'?"selected":"" }>운전면허</option>
</select>
<input type="text" name="serch" class="form-control" placeholder="검색단어" style="width: 150px;" value="${serch }">
<button type="submit" class="btn btn-success">검색</button>
</form>
</div>
</body>
<body>
<form action="insert" method="post" enctype="multipart/form-data">
<table class="table table-bordered" style="width: 400px;">
<caption align="top"><b>개인정보 입력</b></caption>
<tr>
<th>이름</th>
<td>
<input type="text" name="name" class="form-control" style="width: 120px;" required="required">
</td>
</tr>
<tr>
<th>운전면허</th>
<td>
<input type="radio" name="driver" value="있음">있음
<input type="radio" name="driver" value="없음" checked="checked">없음
</td>
</tr>
<tr>
<th>주소</th>
<td>
<input type="text" name="addr" class="form-control" style="width: 250px;" required="required">
</td>
</tr>
<tr>
<th>사진</th>
<td>
<input type="file" name="upload" class="form-control" style="width: 200px;">
</td>
</tr>
<tr>
<td colspan="2" align="center">
<button type="submit" class="btn btn-outline-info">저장</button>
<button type="button" class="btn btn-outline-success" onclick="location.href='list'">목록</button>
</td>
</tr>
</table>
</form>
</body>
<body>
<form action="update" method="post" enctype="multipart/form-data">
<input type="hidden" name="num" value="${idto.num }">
<table class="table table-bordered" style="width: 400px;">
<caption align="top"><b>개인정보 수정</b></caption>
<tr>
<th>이름</th>
<td>
<input type="text" name="name" class="form-control" style="width: 120px;" required="required" value="${idto.name }">
</td>
</tr>
<tr>
<th>운전면허</th>
<td>
<input type="radio" name="driver" value="있음" ${idto.driver=='있음'?"checked":"" }>있음
<input type="radio" name="driver" value="없음" ${idto.driver=='없음'?"checked":"" }>없음
</td>
</tr>
<tr>
<th>주소</th>
<td>
<input type="text" name="addr" class="form-control" style="width: 250px;" required="required" value="${idto.addr }">
</td>
</tr>
<tr>
<th>사진</th>
<td>
<input type="file" name="upload" class="form-control" style="width: 200px;">
</td>
</tr>
<tr>
<td colspan="2" align="center">
<button type="submit" class="btn btn-outline-info">저장</button>
<button type="button" class="btn btn-outline-success" onclick="location.href='list'">목록</button>
</td>
</tr>
</table>
</form>
</body>