«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

장미의 개발일기

JSP 프로그래밍: 모델1 방식의 웹 개발하기(갤러리 만들기) - 1 본문

개발일기/JSP 프로그래밍 (Java 웹프로그래밍)

JSP 프로그래밍: 모델1 방식의 웹 개발하기(갤러리 만들기) - 1

민장미 2023. 6. 27. 00:17

셋팅:  이클립스 EE,  톰캣  ,마이바티스 ,오라클 , SQL gate  

=> 마이바티스를 추가하여 ! 모델1 방식의 웹 갤러리 만들어보기 

 

* 디자인에 소질이 없는 고로... 제 포스팅에서 디자인은 버리고 백엔드 코드만 봐주시길 ㅠㅠ 

 

 

마이바티스 ( SQL  - DB작업을 수월하게 해줌 )

Mybatis 마이바티스 다운로드 및 환경 설정 (tistory.com)

 

Mybatis 마이바티스 다운로드 및 환경 설정

** 아래 포스팅의 예제 => model 1 타입의 게시판 사이트를 제작한 후, 그걸 복사해와서 마이바티스를 테스트 해보는 포스팅 입니다. ** 아래 모델1방식으로 웹 게시판 만들기 JSP 프로그래밍: 모델1

jangmicoding.tistory.com

 

 

저번에 포스팅했던 게시판 만들기 예제에 이어서 만드는 포스팅입니다. (안봐도 무관)

JSP 프로그래밍: 모델1 방식의 웹 개발하기(게시판 만들기) - 1 FBoard (tistory.com)

 

JSP 프로그래밍: 모델1 방식의 웹 개발하기(게시판 만들기) - 1 FBoard

*Model 1 방식: JSP 프로그래밍에서 Model과 View를 따로 분리하지 않고 같이 섞어서 개발하는 방식이다. => UI(디자인)와 비즈니스 로직을 함께 처리하는 방식이라 코드의 재사용성이 떨어진다 => 유지

jangmicoding.tistory.com

 

 

 

 

 

0. 기본 셋팅

-새로 다이나믹 프로젝트 생성 후, 

FBoard 예제 프로젝트에서 다 복사 해오기 (클래스, jsp 파일들 전부) + context.xml 

(context.xml  설정 관련은 위에 있는 마이바티스 다운로드 포스팅 보면 됩니당 => meta-inf 폴더에 넣기****!!)

 

*프로젝트 생성할 때, xml 옵션 반드시 체크

*마이바티스 다운받았으면  web-inf/ lib 파일에 복붙

 

 

* 파일 업로드를 위한 드라이버가 필요합니다.  아래 드라이버를 web-inf/ lib 파일에 복붙

cos.jar
0.05MB

 

*톰캣에  jdbc 드라이버도 있어야한다!

ojdbc6.jar
3.52MB

 

 

 

* 그림 저장 설정: reference 

(1회용 실습용이면 굳이 안해도 되지만, 이걸 해놓아야 시간이 지난 다음에 실행 했을 때도 엑박이 안뜹니다.

서버에 이미지를 저장하는 설정)  (캡쳐화면은 스프링 프레임워크지만 이클립스도 똑같습니다 )

 

 

- tboard  코드 복붙해오기  (전부) / 그리고 헤더 푸터 나눠서 따로 빼놨고, 각 fboard jsp파일에 삽입을 해놨다.

  webapp 폴더 안에 늘어놨던  Fboard  jsp파일들은 폴더를 만들어서 넣었고, 이번 포스팅의 갤러리 파일들도

  pororo 라는 폴더 안에 생성할 예정!  참고!

 

 

 

 

 

1. SQL => 테이블 생성 및 시퀀스 생성 

기본키는 숫자로, 상품의 수량, 가격 등등 

	CREATE TABLE PORORO(
	NUM NUMBER CONSTRAINT PORORO_NUM_PK PRIMARY KEY,
	IMGNAME VARCHAR2(200),
	COMM VARCHAR2(200),
	PDATE DATE,
	REIP VARCHAR2(34),
	PRICE NUMBER(20),
	QTY NUMBER(20)
	);

	CREATE SEQUENCE PORORO_SEQ
	START WITH 1
	INCREMENT BY 1;

 

 

 

2. 마이바티스 기본 설정 (중요)

 

config.xml 파일 생성 

<!-- src/config/config.xml -->
마이바티스 사이트 or 라이브러리 pdf 파일에서 복붙 
https://mybatis.org/mybatis-3/ko/getting-started.html

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">


mapper파일 pororo.xml 생성 
<!-- src/mapper/tboard.xml -->
https://mybatis.org/mybatis-3/ko/configuration.html
마이바티스 사이트 or 라이브러리 pdf 파일에서 복붙 

+ 네임스페이스를 정해준다 (나는 테이블명과 똑같이 설정)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="pororo">

 

 

다시

config.xml 파일로 와서 mapper  부분 작성 (pororo.xml파일 )

 

<?xml version="1.0" encoding="UTF-8" ?>
<!-- src/config/config.xml -->
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <environments default="">
    <environment id="">
      <transactionManager type="JDBC"/>
      <dataSource type="JNDI">
        <property name="data_source" value="java:comp/env/jdbc/myora"/>
      </dataSource>
    </environment>
  </environments>
<!-- 작업할 매퍼는 꼭 등록 해줘야 한다!!! -->   
<mappers>
	<mapper resource="mapper/tboard.xml"/>
	<mapper resource="mapper/pororo.xml"/>
</mappers>
</configuration>

 

 

3.  VO 생성   sql에서 만든 테이블과 같이 만들고 단축키로 setter/getter 생성 

package vo;

public class PororoVO {
	private int num; //기본키 
	private String imgname; //이미지이름 
	private String comm; //글 내용 
	private String pdate; //작성날짜 
	private String reip; //ip
	private int price; //가격
	private int qty; //수량
	
	public String getReip() {
		return reip;
	}
	public void setReip(String reip) {
		this.reip = reip;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public int getQty() {
		return qty;
	}
	public void setQty(int qty) {
		this.qty = qty;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getImgname() {
		return imgname;
	}
	public void setImgname(String imgname) {
		this.imgname = imgname;
	}
	public String getComm() {
		return comm;
	}
	public void setComm(String comm) {
		this.comm = comm;
	}
	public String getPdate() {
		return pdate;
	}
	public void setPdate(String pdate) {
		this.pdate = pdate;
	}
	
	

}

 

 

 

 

4. DAO 인터페이스 및 클래스  생성 (싱글톤 처리) 

인터페이스는 생략한다.... 원래는 유지보수 등을 위해서 꼭 생성 해야함!! 

+ 싱글톤 처리 

+FBoard 예제를 복사해서쓰느라 메소드 이름에  fBoard가 들어간다 ㄷㄷ 뭐 잘 돌아가기만 하면...

package dao;


public class PororoDao {
	
	private static PororoDao dao;
	private PororoDao() { //단축키 
	}
	//싱글톤
	public synchronized static PororoDao getDao() {
		if(dao == null) {
			dao= new PororoDao();
		}
		return dao;
	}
	
	

	
}

여기서 weapapp 폴더에 간단한 jsp 파일을 생성하여 연결 테스트를 해봐도 되고, 안해도 된다. 

저번에 포스팅했던 Fboard의 헤더 메뉴에 갤러리로 가도록 연결 해뒀다. 

 

 

5.

뷰 코드들 셋팅 ( fboard에 이어서) 

파일 위치 잘 보고 셋팅하기

    -1 헤더코드

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>header2.jsp</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link
	href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
	rel="stylesheet">
<link rel="stylesheet" href="../resources/css/mystyle.css">
<script
	src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"></script>

</head>
<body>
	<%-- header시작 --%>
	<%-- p-5 : padding 5
	text-white : text 흰색
	text-center : text-align center
	 --%>
	<header class="p-5 bg-primary text-white text-center">
		<hgroup>
			<h1> WebPage!</h1>
			<p> WebPage! 입니다.]</p>
		</hgroup>
	</header>
	<%-- header끝 --%>
	<%-- 메뉴 시작 --%>
	<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
		<%-- 메뉴를 만들 때 검색까지 배치를 적용 --%>
		<div class="container-fluid">
			<%-- ul => navbar-nav --%>
		<ul class="navbar-nav">
			<li class="nav-item">
			<a href="<%=application.getContextPath() %>/main/main1.jsp"
			class="nav-link active">Home</a></li>
			<li class="nav-item"><a href="<%=application.getContextPath() %>/pororo/gallery.jsp" class="nav-link ">갤러리</a></li>
			
			<li class="nav-item">
			<a href="<%=application.getContextPath() %>/tboard/list.jsp"
			class="nav-link ">자유게시판</a></li>
			
			<li class="nav-item"><a href="" class="nav-link ">프로필</a></li>
			<li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
            Dropdown
          </a></li></ul>
          <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
            <li><a class="dropdown-item" href="#">Action</a></li>
            <li><a class="dropdown-item" href="#">Another action</a></li>
            <li><hr class="dropdown-divider"></li>
            <li><a class="dropdown-item" href="#">Something else here</a></li>
          </ul>
			<form class="d-flex">
				<input class="form-control me-2" type="search" placeholder="Search"
					aria-label="Search">
				<button class="btn btn-primary" type="submit">Search</button>
			</form>
		</div>
	</nav>

   -2 footer 코드

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
	<footer>Page Footer </footer>
</body>
</html>

 

 

-3 main/main 코드

<%@ page language="java" contentType="text/html; charset=EUC-KR"
	pageEncoding="EUC-KR"%>
<%@include file="../header2.jsp" %>
	<%-- 메뉴 끝 --%>
	<%-- 본문 내용 시작 --%>
	<article>
		<header>
			<h1>Article heading</h1>
			<time>2023-06-26</time>
		</header>
		<p>Bootstrap을 사용할 때 알아야 할 몇 가지 중요한 전역 스타일과 설정을 사용하고 있으며, 이 모든 기능은
			거의 크로스 브라우저 스타일의 정규화에 맞추어져 있습니다.</p>
		<section>
			<header>
				<h1>Section heading</h1>
			</header>

			<p>CSS에서 보다 간단한 크기 조절을 위해서 우리는 content-box에서 border-box까지 전역
				box-sizing 값을 사용하고 있습니다.</p>
			<footer>
				<p>여기는  웹사이트 입니다. 화면 레이아웃 초기 버전 입니다.</p>
			</footer>
		</section>
			<header>
				<h1>Section heading</h1>
			</header>
			<p>CSS에서 보다 간단한 크기 조절을 위해서 우리는 content-box에서 border-box까지 전역
				box-sizing 값을 사용하고 있습니다.</p>
			<figure>
				<img src="../resources/img/safari.png" alt="Safari">
				<img src="../resources/img/chrome.png" alt="Chrome">
				<img src="../resources/img/firefox.png" alt="FireFox">
				<img src="../resources/img/ie.png" alt="IE">
				<img src="../resources/img/opera.png" alt="Opera">
				<figcaption>FigCaption: Safari, Chrome, FireFox, IE,
					Opera</figcaption>
			</figure>
			<p>Bootstrap을 사용할 때 알아야 할 몇 가지 중요한 전역 스타일과 설정을 사용하고 있으며, 이 모든 기능은
				거의 크로스 브라우저 스타일의 정규화에 맞추어져 있습니다.</p>
	</article>
	<%-- side바 만들기 --%>
	<aside>
		<header>
			<span>Sidebar</span>
		</header>
		<ul class="list-unstyled">
			<li class="mb-1">
				<button class="bg-white btn btn-toggle" data-bs-toggle="collapse"
					data-bs-target="#home-collapse" aria-expanded="true">Home</button>
				<div id="home-collapse" class="collapse show">
					<ul class="list-unstyled">
						<li><a href="" class="link-dark text-decoration-none rounded">Overview</a></li>
						<li><a href="" class="link-dark text-decoration-none rounded">Updates</a></li>
						<li><a href="" class="link-dark text-decoration-none rounded">Reports</a></li>
					</ul>
				</div>
			</li>
			<li class="border-top"></li>
			<li class="mb-1">
				<button class="bg-white btn btn-toggle" data-bs-toggle="collapse"
					data-bs-target="#Dashboard-collapse" aria-expanded="true">Dashboard</button>
				<div id="Dashboard-collapse" class="collapse" style="background-color: orange;">
					<ul class="list-unstyled" style="padding: 10px;">
						<li><a href="" class="link-dark text-decoration-none rounded">Overview</a></li>
						<li><a href="" class="link-dark text-decoration-none rounded">Updates</a></li>
						<li><a href="" class="link-dark text-decoration-none rounded">Reports</a></li>
					</ul>
				</div>
			</li>
			<li class="border-top"></li>
			<li class="mb-1">
				<button class="bg-white btn btn-toggle" data-bs-toggle="collapse"
					data-bs-target="#Dashboard2-collapse" aria-expanded="true">Dashboard2</button>
				<div id="Dashboard2-collapse" class="collapse" style="background-color: yellow;">
					<ul class="list-unstyled" style="padding: 10px;">
						<li><a href="" class="link-dark text-decoration-none rounded">Overview</a></li>
						<li><a href="" class="link-dark text-decoration-none rounded">Updates</a></li>
						<li><a href="" class="link-dark text-decoration-none rounded">Reports</a></li>
					</ul>
				</div>
			</li>
		</ul>
	</aside>
<%@include file="../footer2.jsp" %>

 

 - 디자인  css 1 (main1.jsp / mystyle.css)  -webapp / resources / css  폴더 에 저장 

@charset "EUC-KR";
body{
	width: 1000px;
	margin: 0 auto;
	font-family: Arial, sens-serif;
	color: #777;
}
header{
	background: #777;
	height: 80%;
}

body header hgroup h1{
	font-size: 3.0em;
	text-transform: uppercase;
	color: #fff;
}
body header hgroup h2{
	font-size: 0.8em;
	color: #fff;
	font-style: italic;
}
/*메뉴 스타일*/
body nav{
	padding: 10px;
	background: #000;
	color: #ffffff;
	font-weight: bold;
	clear: both;
	-moz-border-radius: 20px 0px;
}
body nav ul{
	padding: 0;
	margin: 0;
	list-style: none;
}

nav ul li{
	display: block;
	margin-left: 20px;
	float: left;	
}
/*링크 스타일*/
nav ul li a{
	color: #fff;
	background: #000;
	text-decoration: none;
	padding: 5px;
	margin: 0;
}

nav ul li a:hover{
	background: #777;	
}

/* article 본문*/
article{
	width: 780px;
	padding: 10px;
	float: left;
}

article header{
	border: 1px dashed #777;
	padding: 5px;
}

article header h1{
	color: #000;
	font-size: 2em;	
}

article section footer{
	border: 1px dashed #777;
	padding: 10px;
}

/* 오른쪽 sidebar영역 잡기*/

aside{
	width: 220px;
	padding: 10px;
	float: left;
	background: #ccc;
	color: #000;
	font-size: 0.8em;
}

aside header h1{
	font-size: 1.5em; color: #000;
}

aside button {
	width: 100%;
}	

/*Footer 영역*/

footer{
	background: #000;
	padding: 10px;
	height: 100px;
	color: #fff;
	clear: both;
}

/*나머지*/
time{
	font-size: 0.7em;
	margin-top: 0px;
	margin-bottom: 0px;
	color: #fff;
}

figure{
	margin: 0 auto;	
	padding: 20px;
	width: 500px;
	text-align: center;
	border: 1px dashed #ccc;
	clear: both;
}
figure img{
	padding: 10px;
	margin: 0 auto;
}

 

 

- 디자인  css 2  (이번 갤러리 전부 /pororostyle.css) -webapp / resources / css  폴더 에 저장 

@charset "EUC-KR";
	/*가장 아래에 깔리는 부모 레이아웃을 설정 합니다.
	position: relative; 부모
	position: absolute; 자식 => 가장 가까운 위치에 있는 부모(조상)요소를 기준으로 배치
	상하좌우 지정이 가능하다.
	*/
	.container{
		/*요소를 자기자신을 기준으로 배치함*/
		position: relative;
		width: 200px;
		margin-left: 10px;
		float: left; /*이미지가 가로로옆으로 정렬되도록 */
	}

	.image{
		/*inline-> block 레벨요소로 설정*/
		display: block;
		width: 200px;
		height: 220px;
		cursor: pointer;
	}
	.overlay{
		position: absolute;
		bottom: 0;
		left: 0;
		right: 0;
		background: rgb(0,0,0);
		background: rgb(0,0,0,0.5);
		cursor: pointer;
		overflow: hidden;
		width:200px; /*200px*/
		height: 0;
		transition: .5s ease;
		margin-left: 12px;
	}
	.container:hover .overlay{
		height: 80%;
	}
	.text{
		color: white;
		font-size: 12px;
		position: absolute;
		top: 50%;
		left: 50%;
		/*translate(X,Y): X와 Y의 지정된 거리만큼 요소를 이동 시켜주는 값*/
		-webkit-transform: translate(-50%,-50%);
		-ms-transform: translate(-50%,-50%);
		transform: translate(-50%,-50%);
		text-align: center;
	}
.text ul{ list-style-type: none; width:120px; padding: 10px 10px;}
.text li{ width: 100%; margin-top: 2px; }

 

 

 

 

 

 

6  갤러리 업로드 부분 

   -A업로드 폼 코드  pororo/upform.jsp

<%@page import="dao.PororoDao"%>
<%@page import="vo.PororoVO"%>
<%@page import="java.io.File"%>
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%
	request.setCharacterEncoding("euc-kr");
	//String comm = request.getParameter("comm");
	//enctype="multipart/form-data 안? null 
	// 업로드될 서버측 절대경로를 지정해줘야한다 - 이클립스 메모리에 사용되는 경로 지정
	String save_dir = application.getRealPath("resources/pororoimg");
	System.out.println("save_path:"+save_dir);
	//MultipartRequest multi = new MultipartRequest()
			
	//생성자의 인자값=>
	//request, save 디렉토리, 업로드용량, 인코딩, 파일 이름 변경을 위한 정책 클래스
	//폼에서 파일업로드를 했을 경우 현재 MultipartRequest 객체가 업로드를 해당 디렉토리에
	//실행해준다.
	
	MultipartRequest multi = new MultipartRequest(request,save_dir,
			5*1024*1024, "euc-kr", new DefaultFileRenamePolicy());
	
	//파라미터 이름 받아오기 : request 를 가공한 multi로 기존의 데이터를 받는 방식 *****
	String comm = multi.getParameter("comm");
	String reip = multi.getParameter("reip");
	int price = Integer.parseInt(multi.getParameter("price"));
	int qty = Integer.parseInt(multi.getParameter("qty"));
	System.out.println("comm:"+comm);
	//파일의 이름을 가져와서 출력해보기 
	// multi.getFile("폼에서 파일에 해당하는 파라미터 이름") type="file", name="upfile"
	File fn = multi.getFile("upfile");
	System.out.println("파일이름:"+fn.getName());
	
	
	//받은 파라미터를 모두 VO에 생성한 후 DAO의 인자로 전달한다.
	PororoVO vo = new PororoVO();
	vo.setImgname(fn.getName());
	vo.setComm(comm);
	vo.setReip(reip);
	vo.setPrice(price);
	vo.setQty(qty);
	PororoDao.getDao().addFBoard(vo);
	response.sendRedirect("gallery.jsp");	

	
%>
<%--<img src ="resources/img/<%=fn.getName()%>" style="width:120px;"> 이거 테스트다음에 redirect하는거 --%>

 

 

 

 -B  mpper(pororo.xml) 작업  

 

네임스페이스 밑 insert 쿼리문 작성 

* 끝에  ; 세미콜론 이거 반드시 꼭 떼라.... 

*여기에 작성하기 전에, sql 툴로 가서 더미데이터 넣고 쿼리문 테스트하고 가져올 것!!! 오류 방지를 위해 매우 중요하다. 

 

 *#{   } 안의 요소는 반드시 소문자여야한다. ( 정확히는 VO 클래스에 설정해둔 이름과 일치해야하는 조건인데 자바 안에서 멤버필드명 첫자는 무조건 소문자니껜 ㅇㅇ...)

* vo.PororoVO  =>  PororoVO는 만들어둔 클래스명과 똑같이! vo는 다르게 해도 되는데, vo로 통일하는게 편함 직역하자면 PororoVO (자료형) 형인 vo 객체 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pororo">
	<insert id="add" parameterType="vo.PororoVO">
		INSERT INTO PORORO VALUES(PORORO_SEQ.NEXTVAL, #{imgname} ,#{comm}
		,SYSDATE, #{reip},#{price},#{qty})
	</insert>



</mapper>

 

 

 

 

 

 

-C Dao가서  addBoard ()  메소드를 구현  ( 저번 포스팅 코드와 비교해보기) *

 * 마이바티스가 SqlSession 이라는 객체를 제공해주는데,  보다시피 4줄이면 끝난다. 그리고 

package dao;


import java.util.List;

import org.apache.ibatis.session.SqlSession;

import factory.FactoryService;
import vo.PororoVO;

public class PororoDao {
	
	private static PororoDao dao;
	private PororoDao() { //단축키 
	}
	//싱글톤
	public synchronized static PororoDao getDao() {
		if(dao == null) {
			dao= new PororoDao();
		}
		return dao;
	}
	
	

	public void addFBoard(PororoVO vo) {
		
		SqlSession ss = FactoryService.getFactory().openSession();
		ss.insert("pororo.add",vo);
		ss.commit();
		ss.close();
	}//addfbo
	
	

	
}

 

예전에 포스팅 했던 마이바티스를 사용하지 않은 모델1 방식의  - FBoard 게시판 만들기 예제의 add 메소드다.

이번 포스팅보다 코드가 복잡하고 길다. 

	@Override
	public void addFBoard(FBoardVO vo) {
	
	
		String sql="INSERT INTO FBOARD VALUES(FBOARD_SEQ.NEXTVAL, ?,?,?,?, 0, ?,SYSDATE)";
		
		try(Connection con=MyConn.getConn();
			 PreparedStatement pstmt = con.prepareStatement(sql);
			){  
			//바인딩하기  제목, 작성자, 비번, 내용, ip ?순서임  
			pstmt.setString(1, vo.getSubject());
			pstmt.setString(2, vo.getWriter());
			pstmt.setString(3, vo.getPwd());
			pstmt.setString(4, vo.getContent());
			pstmt.setString(5, vo.getReip());
			
			pstmt.executeUpdate();
		
		}
			catch (SQLException e) {
				e.printStackTrace();
		}
				
	}//add fboard

 

 

 

-D insert.jsp 

 뷰가 아닌 비즈니스로직 (데이터처리) 부분이라 다 지워도 무방. 코드가 꽤나 어렵다...사실 나도 다 몰라..

Muli로 시작하는 객체가 cos 드라이버에서 제공해주는 거라고 짐작할 뿐 ㅠ 

 

-업로드한 이미지를 저장할 경로를 정확하게 설정해야한다! 

<%@page import="dao.PororoDao"%>
<%@page import="vo.PororoVO"%>
<%@page import="java.io.File"%>
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%
	request.setCharacterEncoding("euc-kr");
	//String comm = request.getParameter("comm");
	//enctype="multipart/form-data 안? null 
	// 업로드될 서버측 절대경로를 지정해줘야한다 - 이클립스 메모리에 사용되는 경로 지정
	String save_dir = application.getRealPath("resources/pororoimg");
	System.out.println("save_path:"+save_dir);
	//MultipartRequest multi = new MultipartRequest()
			
	//생성자의 인자값=>
	//request, save 디렉토리, 업로드용량, 인코딩, 파일 이름 변경을 위한 정책 클래스
	//폼에서 파일업로드를 했을 경우 현재 MultipartRequest 객체가 업로드를 해당 디렉토리에
	//실행해준다.
	
	MultipartRequest multi = new MultipartRequest(request,save_dir,
			5*1024*1024, "euc-kr", new DefaultFileRenamePolicy());
	
	//파라미터 이름 받아오기 : request 를 가공한 multi로 기존의 데이터를 받는 방식 *****
	String comm = multi.getParameter("comm");
	String reip = multi.getParameter("reip");
	int price = Integer.parseInt(multi.getParameter("price"));
	int qty = Integer.parseInt(multi.getParameter("qty"));
	System.out.println("comm:"+comm);
	//파일의 이름을 가져와서 출력해보기 
	// multi.getFile("폼에서 파일에 해당하는 파라미터 이름") type="file", name="upfile"
	File fn = multi.getFile("upfile");
	System.out.println("파일이름:"+fn.getName());
	
	
	//받은 파라미터를 모두 VO에 생성한 후 DAO의 인자로 전달한다.
	PororoVO vo = new PororoVO();
	vo.setImgname(fn.getName());
	vo.setComm(comm);
	vo.setReip(reip);
	vo.setPrice(price);
	vo.setQty(qty);
	PororoDao.getDao().addFBoard(vo);
	response.sendRedirect("gallery.jsp");	

	
%>
<%--<img src ="resources/img/<%=fn.getName()%>" style="width:120px;"> 이거 테스트다음에 redirect하는거 --%>

* 테스트땐 마지막줄 gallery.jsp 이거 주석 처리하고 하기. gallery.jsp 생성 전이라 오류날 수도 있음. 

 

무튼 테스트해서 창에 아무것도 안뜨지만, 오류가 안나고  insert.jsp 가 뜨면 성공 !   ---* String save_dir = application.getRealPath("resources/pororoimg");
System.out.println("save_path:"+save_dir); 

이 코드 => 자바 콘솔 창에 이미지가 저장되는 경로가 뜨게한다. 테스트때 그 폴더 안에 이미지 저장되는지 확인

 -sql 테이블가서 데이터가 삽입됐는지도 확인  

 

 

이제 list( gallery.jsp)를 구현해보자

 

 

 

7. list( gallery.jsp) 보드 리스트 ( 갤러리)

여기선 css가 중요하다... 그림 배치 때문에 ㅠㅠ 나한텐 css가 젤 어렵고 자바가 젤 쉬워 하하 

 

 A  gallery.jsp  

<%@page import="dao.PororoDao"%>
<%@page import="vo.PororoVO"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
    
<%@include file="../header2.jsp" %>
<link rel="stylesheet" href="../resources/css/pororostyle.css">

<div style="width: 800px; margin: auto">

<%
//Dao로부터 list받기
	List<PororoVO> list = PororoDao.getDao().listFBoard();
//반복하기
	for(PororoVO e: list){

%>

<div class="container">
	<a href="detail.jsp?num=<%=e.getNum() %>"><img src = "../resources/pororoimg/<%=e.getImgname() %>" class="image"></a>
	<div class="overlay">
		<div class="text">
		<ul>
		<li><%=e.getComm() %></li>
		<li><%=e.getPrice() %>원</li>
		<li><%=e.getQty() %>개</li>
		</ul>
		</div>
	</div>
</div>	

<%
	}
%>
</div>


<div style="width:800px; margin: auto; clear:both; text-align: center;">
	<a href="upform.jsp"><button>입력하기</button></a>
	<!-- <a href="detail.jsp">상세정보</a> -->
</div>


<%@include file="../footer2.jsp" %>

 

B mapper 작업 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pororo">
	<insert id="add" parameterType="vo.PororoVO">
		INSERT INTO PORORO VALUES(PORORO_SEQ.NEXTVAL, #{imgname} ,#{comm}
		,SYSDATE, #{reip},#{price},#{qty})
	</insert>


	<select id="list" resultType="vo.PororoVO">
		SELECT NUM, IMGNAME, COMM, REIP, PRICE,QTY, PDATE FROM PORORO ORDER BY 1
		DESC
	</select>



</mapper>

 

 

C dao가서 메소드 구현

package dao;


import java.util.List;

import org.apache.ibatis.session.SqlSession;

import factory.FactoryService;
import vo.PororoVO;

public class PororoDao {
	
	private static PororoDao dao;
	private PororoDao() { //단축키 
	}
	//싱글톤
	public synchronized static PororoDao getDao() {
		if(dao == null) {
			dao= new PororoDao();
		}
		return dao;
	}
	
	

	public void addFBoard(PororoVO vo) {
		
		SqlSession ss = FactoryService.getFactory().openSession();
		ss.insert("pororo.add",vo);
		ss.commit();
		ss.close();
	}//addfbo
	
	
	public List<PororoVO> listFBoard() {
		SqlSession ss = FactoryService.getFactory().openSession();
		
		List<PororoVO> volist =ss.selectList("pororo.list");
		ss.commit();
		ss.close();
		
		return volist;
	}//listbo
	


	
}

테스트하니 지정된 폴더에 이미지 저장은 잘 되는데, 리스트가 전부 엑박떠서 식겁했다 ㅠㅠㅠ 

보니까 gallery.jsp에서 파일 경로를 잘못 했었음...   아랫 부분 pororoimg 대신 다른 폴더 이름이 있었다. 수정하니 잘 된다!

테이블도 !

**실행은 늘 upform.jsp에서 하는 게 좋다. 오류때문에 

 

 

 

첫번째 데이터는 테스트를 위해 내가 직접 데이터를 집어넣은 것 그래서&nbsp; ip가 내가 쓴대로 나옴

 

 

 

7. 그림/게시물 상세보기  (detail.jsp)

 

A detail.jsp  폼   / 보통 write/upform.jsp를 복붙해와서 수정하는 방식을 추천 

 

<%@page import="dao.PororoDao"%>
<%@page import="vo.PororoVO"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
 

 
<% //테스트 
int num = Integer.parseInt(request.getParameter("num"));
//System.out.println("Detail num=>"+num);
// Dao로부터 값 받아오기 
	PororoVO v = PororoDao.getDao().detailFBoard(num);

%>    
 <%@include file="../header2.jsp" %>  
 
 

  <div id="wrap" class="container mt-5">
  	<div class="row">
  	<h2>Product Detail</h2>
	
	
	<div class="row mb-3">
    <label for="num" class="col-sm-2 col-form-label">넘버</label>
    <div class="col-sm-10">
      <input type="number" name = "num" class="form-control" id="num"
      value ="<%=v.getNum()%>"  readonly="readonly">
    </div>
  </div>
	
		
	<div class="row mb-3">
    <label for="imgname" class="col-sm-2 col-form-label">이미지이름/상품</label>
    <div class="col-sm-10">
      <input type="text" name = "imgname" class="form-control" id="imgname"
      value ="<%=v.getImgname() %>"  readonly="readonly">
    </div>
  </div>
  
    <!-- 이미지 넣기?  -->
  	<div class="row mb-3">
    <label for="img" class="col-sm-2 col-form-label">이미지</label>
    	<img src="<%=application.getContextPath() %>/resources/pororoimg/<%=v.getImgname() %>" style="width: 200px; border: dotted 1px; cursor: pointer;" id="imgn">
  	</div>
   
	
	<div class="row">
	  	<label for="comm" class="col-sm-2 col-form-label">내용</label>
    	<div class="col-sm-10">
		<textarea name="comm" rows="10" cols="50" id="comm" readonly="readonly">
		 <%=v.getComm() %></textarea>
	</div>
	</div>
	
	<div class="row mb-3">
    <label for="price" class="col-sm-2 col-form-label">가격</label>
    <div class="col-sm-10">
      <input type="number" name = "price" class="form-control" id="price"
      value = "<%=v.getPrice() %>" readonly="readonly">
    </div>
  </div>
  
  	<div class="row mb-3">
    <label for="qty" class="col-sm-2 col-form-label">수량</label>
    <div class="col-sm-10">
      <input type="number" name = "qty" class="form-control" id="qty"
      value = "<%=v.getQty()%>" readonly="readonly">
    </div>
  </div>
  
  <div class="row mb-3">
    <label for="pdate" class="col-sm-2 col-form-label">입고일</label>
    <div class="col-sm-10">
      <input type="text" name = "pdate" class="form-control" id="pdate"
      value = "<%=v.getPdate() %>" readonly="readonly">
    </div>
  </div>
  
  
  	<div class="container text-center" role="group">
  	<button class="btn btn-primary" type="button" onclick="location='chk.jsp?num=<%=v.getNum()%>&job=up'">수정</button>
  	<button class="btn btn-primary" type="button" onclick="location='chk.jsp?num=<%=v.getNum()%>&job=del'">삭제</button>
  	<button class="btn btn-danger" type="button" onclick="location='gallery.jsp'">리스트</button>
	</div>

   </div>
  </div>


<%@include file="../footer2.jsp" %>

 

 

B mapper (pororo.xml) 작업


 SELECT NUM, IMGNAME,COMM,REIP,PRICE,QTY,PDATE FROM PORORO WHERE NUM=4; 

이런식으로 숫자지정해서 sql 툴에서 테스트 후, 복사해와서 여기서 4 부분만 변경 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pororo">
	<insert id="add" parameterType="vo.PororoVO">
		INSERT INTO PORORO VALUES(PORORO_SEQ.NEXTVAL, #{imgname} ,#{comm}
		,SYSDATE, #{reip},#{price},#{qty})
	</insert>


	<select id="list" resultType="vo.PororoVO">
		SELECT NUM, IMGNAME, COMM, REIP, PRICE,QTY, PDATE FROM PORORO ORDER BY 1
		DESC
	</select>

	<select id="detail" parameterType="int" resultType="vo.PororoVO">
		SELECT NUM, IMGNAME,COMM,REIP,PRICE,QTY,PDATE FROM PORORO WHERE NUM=#{num}
	</select>



</mapper>

 

 

C dao가서 메소드 구현

package dao;


import java.util.List;

import org.apache.ibatis.session.SqlSession;

import factory.FactoryService;
import vo.PororoVO;

public class PororoDao {
	
	private static PororoDao dao;
	private PororoDao() { //단축키 
	}
	//싱글톤
	public synchronized static PororoDao getDao() {
		if(dao == null) {
			dao= new PororoDao();
		}
		return dao;
	}
	
	

	public void addFBoard(PororoVO vo) {
		
		SqlSession ss = FactoryService.getFactory().openSession();
		ss.insert("pororo.add",vo);
		ss.commit();
		ss.close();
	}//addfbo
	
	
	public List<PororoVO> listFBoard() {
		SqlSession ss = FactoryService.getFactory().openSession();
		
		List<PororoVO> volist =ss.selectList("pororo.list");
		ss.commit();
		ss.close();
		
		return volist;
	}//listbo
	

	public PororoVO detailFBoard(int num) {
		SqlSession ss = FactoryService.getFactory().openSession();
		PororoVO vo= ss.selectOne("pororo.detail",num);
		ss.commit();
		ss.close();
		return vo;
	}

	
}

 

gellry.jsp 에서 클릭해서 상세페이지 보기 테스트!

(이미지에 마우스 올리면 투명한 검은 오버레인? 창이 나오도록 되어있으니 그 부분 피해서 이미지를 클릭해야한다)

 

깨알같이 귀여운 루피 ~

 

 

 

 

수정/삭제는 다음 포스팅에서 합니다 ~