dependency를 사용하지 않고 jar파일을 사용해보았다.

 

1. mvnrepository로 들어가 Mybatis검색 후 원하는 버전의 jar파일을 다운받는다.

Maven Repository: org.mybatis » mybatis » 3.4.6 (mvnrepository.com)

2. 자신의 웹프로젝트의 WEB-INF의 lib폴더에 등록!

 

정리한 순서

1. 설정xml을 만들어서 DB의 정보(driver, url, user, password)를 기입하고 mapper들의 위치도 등록한다.

 

 

 

2.  Mapper(VO명Mapper.xml)XML을 만들어서 namespace(메모리상에서 이름을 가지고 구분할 수 있게)를 등록하고 
각 쿼리문을 입력 이때 id는 쿼리 구분id, parameteType은 파라미터의 자료형(int, VO객체), resultType은 결과타입(List를 반환하는 쿼리일지라도 해당 List안의 들어갈 객체들의 자료형을 적어주면됨, List처리는 Mybatis가 담당!!)

 

그리고, PreparedStatement에서 ?를 #{}로 대신하여 쓰고 #{}안에는 파라미터명을 적어주면 된다.. (이때, 파라미터명은 파라미터가 1개일 때는 아무거나 적어도 상관이 없지만 구분하기 쉽게 해당 컬럼명으로 써주는게 좋은거같구, VO로 넘어오는 매개변수면 해당 테이블의 컬럼명을 써줘야한다!!  그리고 가장 중요한 VO와 테이블의 컬럼명들을 일치시켜주는게 제일 중요!!)

<?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">
<!-- 이름으로 메모리 영역을 구분하는 법 namespace 중복되면 안된다 -->
<mapper namespace="mybatis.config.Dept">
	<!--
	개발자는 Mybatis를 이용할 경우, 자바코드에서 쿼리문을 작성하지 않으며
	수많은 jdbc관련 코드 또한 작성할 필요가 없고, 오직 쿼리문에만 집중하면 된다!
	-->
	<!--모든글 가져오기 -->
	<!-- List는 자체적으로 만들어준뎨!!! -->
	<select id="selectAll" resultType="emp.model.Dept">
		select * from dept order by deptno asc
	</select>
	
	<!-- 한건 가져오기 -->
	<!-- paramertType : 파라미터자료형 -->
	<!-- ?대신 #{파라미터명} -->
	<select id="select" parameterType="int" resultType="emp.model.Dept">
		select * from dept where deptno=#{deptno}
	</select>
	
	<!-- 한건 등록 -->
	<insert id="insert" parameterType="emp.model.Dept">
		insert into deptno(dname, loc) values(#{dname}, #{loc})
	</insert>
	
	<!-- 한건 수정 -->
	<!-- 반드시 VO와 컬럼명이 일치해야함!! -->
	<update id="update" parameterType="emp.model.Dept" >
		update dept set dname=#{dname}, loc=#{locg} where deptno=#{deptno}
	</update>
	
	<!-- 삭제하기 -->
	<delete id="delete" parameterType="int">
		delete from deptno where deptno=#{deptno}
	</delete>
</mapper>

3. 지금까지 DAO를 JDBC에 따라 만들었지만 이제는 MyBatis의 코드기술을 따라만들어보았다.

Mapper를 사용하려면 SqlSession객체가 필요하다!! SqlSession객체는 SqlSessionFactory객체를 이용하여 .openSession()메서드를 이용한다. 그리고 Mapper에서 만든 쿼리문을 사용하려면 id가 필요한데 id앞에 해당 Mapper의 namespace의 이름이 필요!!

 

MybatisManager 클래스는 설정파일을 연결하여 SqlSessionFactory를 만들고 get메소드를 이용해 사용할 수 있게 해주는 클래스

/*
	DB 접속 정보 및 매퍼들에 대한 위치가 지정된 마이바티스의 설정파일을 읽어보자!!
*/
package db;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MybatisManager {
	private SqlSessionFactory sqlSessionFactory;
	
	public MybatisManager() {
		String resource = "mybatis/config/config.xml";
		InputStream inputStream;
		try {
			inputStream = Resources.getResourceAsStream(resource);
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
			System.out.println(sqlSessionFactory);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public SqlSessionFactory getSqlSessionFactory() {
		return sqlSessionFactory;
	}

	public static void main(String[] args) {
		new MybatisManager();
	}
}
/*
	지금까지는 DAO의 코드 기술을 JDBC로 이용하였기 때문에 쿼리문보다 그 외의 코드가 더 장황했었다..
	따라서 이번 DAO에서는 Mybatis 프레임웍을 도입하여, 코드를 보다 간결하게 작성해보겠다..
*/
package emp.model;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import db.MybatisManager;

public class DeptDAO {
	//DAO에서 SQL문이 들어있는 xml을 호출하자!!! 이떄, 어떤 쿼리수행을 원하는 지를 구분하기 위해서는
	// xml 태그에 부여한 id를 이용하면 된다!!!
	//xml 태그를 호출하기 위해서는 mybatic의 SqlSession이 필요하고, 현재는 MybatisManager 클래스의 멤버로
	//두었다...
	MybatisManager manager = new MybatisManager();
	SqlSessionFactory factory;
	
	public DeptDAO() {
		factory = manager.getSqlSessionFactory();
	}
	
	//모든 데이터가져오기
	public List<Dept> selectAll() {
		SqlSession session = factory.openSession();//쿼리문 수행객체 생성
		return session.selectList("mybatis.config.Dept.selectAll");
	}
}

실행결과

jsp파일을 만들어서 페이지로드 시 list들을 불러오도록 해보았다.

<%@page import="emp.model.Dept"%>
<%@page import="java.util.List"%>
<%@page import="emp.model.DeptDAO"%>
<%@ page contentType="text/html;charset=utf-8"%>
<%
	//DAO 이용하여 부서 정보 출력해보자!!!
	DeptDAO dao = new DeptDAO();
	List<Dept> list = dao.selectAll();
	
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
<style></style>
<script></script>
</head>
<body>
-----------------------------------------
	<%for(int i=0;i<list.size();i++){ %>
	<%Dept dept = list.get(i); %>
	<br>
		부서번호<%=dept.getDeptno()%><br>
		부서명<%=dept.getDname()%><br>
		부서위치<%=dept.getLoc()%><br>
		-----------------------------------------
	<%} %>
</body>
</html>

'프로그래밍 > JSP' 카테고리의 다른 글

JSP | session  (0) 2020.12.16
JSP | 커넥션풀(Connection Pool)  (0) 2020.12.11
JSP - 페이징 이해  (0) 2020.12.08
JSP - 이미지 업로드  (0) 2020.12.04
JSP - JSP(Java Server Page)란?  (0) 2020.12.01

테이블의 모든 레코드들을 가져와서 페이징 처리하기

 

필요한 값

1. totalRecord : 전체 레코드 수

2. pageSize : 한 페이지 당 보여줄 레코드 수

3. totalPage : 총 페이지 수

4. blockSize : 한 블럭(1~10페이지 이런 식으로 나누는?)당 보여질 페이지 수

5. currentPage : 현재 페이지

6. firstPage : 블럭의 시작 페이지

7. lastPage : 블럭의 끝 값 (firstPage와 lastPage를 이용하여 반복문을 사용해 블럭 나타낼 수 있다)

8. num : 페이지당 시작 번호

9. curPos : 페이지 당 List에서의 시작 index (List로 DB에서 레코드들을 받아올 경우)

 

구하는 방법

totalRecord : 총 레코드의 수 ex) list.size() = 26

pageSize : 10 (개발자 마음대로)

totalPage : 26개의 글을 각 페이지 당 10개의 글로 나오게 한다면?

=>(int)Math.ceil((float)totalRecord/pageSize) = 3

firstPage : currentPage-(currentPage-1)%blockSize 

lastPage : firstPage+(blockSize-1)

num : totalRecord-(pageSize*(currentPage-1))

curPos : pageSize*(currentPage-1)

 

예시 코드

<%@page import="board.model.QnA"%>
<%@page import="java.util.List"%>
<%@page import="board.model.QnADAO"%>
<%@ page contentType="text/html;charset=utf-8"%>
<%
	//DB연동
	QnADAO dao = new QnADAO();
	List<QnA> list = dao.selectAll();
	
	int totalRecord=list.size();//총 레코드 수, 실제 DB에 있는 데이터 수를 대입하면 된다!!
	int pageSize=10;//한 페이지당 보여줄 레코드 수
	//int totalPage=(totalRecord%pageSize)==0?(totalRecord/pageSize):(totalRecord/pageSize)+1;
	int totalPage = (int)Math.ceil(((float)totalRecord/pageSize)); //총 페이지 수
	int blockSize=10; //한 블럭 당 보여질 페이지 수
	int currentPage=1; //현재 페이지
	
	//아래의 코드는 아무때나 하는게 아니다!! 누군가 파라미터를 넘겼을 때만..
	if(request.getParameter("currentPage")!=null){//즉 페이지를 넘겼다면
		currentPage=Integer.parseInt(request.getParameter("currentPage"));
	}
	
	//int firstPage=((currentPage/blockSize)*blockSize)+1; 
	int firstPage=currentPage-(currentPage-1)%blockSize;//반복문의 시작값
	//int lastPage=((currentPage/blockSize)+1)*blockSize;
	int lastPage=firstPage+(blockSize-1);// 반복문의 끝값
	int num=totalRecord-(pageSize*(currentPage-1));//페이지당 시작 번호 ( 힌트: 위에 있는 모든 변수 조합)
	int curPos=pageSize*(currentPage-1);//페이지당 List에서의 시작 index 
%>
<%="totalRecord : "+ totalRecord+"<br>" %>
<%="pageSize : "+ pageSize+"<br>" %>
<%="totalPage : "+ totalPage +"<br>" %>
<%="blockSize : "+ blockSize+"<br>" %>
<%="currentPage : "+ currentPage +"<br>" %>
<%="firstPage : "+ firstPage+"<br>" %>
<%="lastPage : "+ lastPage +"<br>" %>
 <%="num : "+ num +"<br>" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>페이징 처리</title>
<style>
table {
  border-collapse: collapse;
  border-spacing: 0;
  width: 100%;
  border: 1px solid #ddd;
}

th, td {
  text-align: left;
  padding: 16px;
}

tr:nth-child(even) {
  background-color: #f2f2f2;
}

button {
  background-color: #4CAF50;
  color: white;
  padding: 12px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background-color: #45a049;
}

input[type=image]{
  width:100px;
 
}

img{
box-sizing: border-box;
}

a{
	text-decoration: none;
}

.pageNum{
	font-size:20pt;
	color:red;
	font-weight:bold;
}
</style>
<script></script>
</head>
<body>
<table>
  <tr>
    <th>No</th>
    <th>제목</th>
    <th>작성자</th>
	<th>등록일</th>
	<th>조회수</th>
  </tr>
	<%for(int i=1;i<=pageSize;i++){ %>
  		<%if(num<1) break; %>
  		<%
  		//break문을 만나지 않았다는 것은 레코드가 있다는 것이므로, break문 아래에서 데이터를 추출하자!! 
  			QnA qna = list.get(curPos++); //1page:0~9, 2page:10~19...
  		%>
		  <tr>
				<td><%=num-- %></td>
				<td>
					<%if(qna.getDepth()>0){ %>
						<img alt="" src="/images/reply.png" style="margin-left:<%=20*qna.getDepth()%>px">
					<%} %>
					<a href="/qna/detail.jsp?qna_id=<%=qna.getQna_id()%>"><%=qna.getTitle()%></a>
				</td>
				<td><%=qna.getWriter() %></td>
				<td><%=qna.getRegdate() %></td>
				<td><%=qna.getHit() %></td>
		  </tr>
  <%} %>
  <tr>
  	<td colspan="5" style="text-align:center">
  		<%if((firstPage-1)>0){ %>
  			<a href="/qna/list2.jsp?currentPage=<%=firstPage-1%>">◀</a>
  		<%}else{ %>
  			<a href="javascript:alert('처음 페이지입니다!');">◀</a>
  		<%} %>
  		<%for(int i=firstPage;i<=lastPage;i++){ %>
  			<%if(i>totalPage) break; //페이지 출력하는 i가 총 페이지 수에 도달하면 반복문 빠져나와라..%>
  			<a href="/qna/list2.jsp?currentPage=<%=i%>" <%if(currentPage==i){ %>class="pageNum" <%} %>>[<%=i%>]</a>
  		<%} %>
  		<%//if(totalPage<lastPage){ %>
  		<%if((lastPage+1)<lastPage){ %>
	  		<a href="/qna/list2.jsp?currentPage=<%=lastPage+1%>">▶</a>
  		<%}else{ %>
  			<a href="javascript:alert('마지막 페이지입니다!');">▶</a>
  		<%} %>
  	</td>
  </tr>
  	<tr>
	<td colspan="5">
		<button>글 등록</button>
	</td>
  </tr>
  <tr>
	<td colspan="5" style="text-align:center">
		<%@ include file="/inc/footer.jsp"%>
	</td>
  </tr>
</table>
</body>
</html>

'프로그래밍 > JSP' 카테고리의 다른 글

JSP | session  (0) 2020.12.16
JSP | 커넥션풀(Connection Pool)  (0) 2020.12.11
JSP | MyBatis 사용해보기  (0) 2020.12.10
JSP - 이미지 업로드  (0) 2020.12.04
JSP - JSP(Java Server Page)란?  (0) 2020.12.01

방법

1. oreilly에서 만든 라이브러리 사용하기

2. Apache에서 만든 라이브러리 사용하기

 

oreilly에서 만든 라이브러리 사용

Servlets.com | com.oreilly.servlet

 

Servlets.com | com.oreilly.servlet

 

www.servlets.com

위 사이트에 들어가서 MulitpartRequest 클래스를 사용하여 업로드할 수 있다.

 

페이지 아래 쪽에 jar파일을 다운로드받을 수 있게 제공해준다. jar파일을 라이브러리에 등록해준다.

<%@page import="java.io.File"%>
<%@page import="common.FileManager"%>
<%@page import="java.io.IOException"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@ page contentType="text/html;charset=UTF-8"%>
<%
	/*
클라이언트가 전송한 제목, 텍스트 및 바이너리 파일을 서버의 특정 디렉토리에 저장해보자
= 업로드라 한다!!
*/
request.setCharacterEncoding("utf-8");//파라미터 한글 깨지지 않게 인코딩
//String msg = request.getParameter("msg");//String 메시지 받기

//이미지는 글씨가 아닌 바이너리 파일이므로, request.getParameter로는 받을 수 없다!
//따라서 IO, 네트워크 등의 처리를 해야 하는데, 이 자체만으로도 하나의 개발 프로젝트일 것이다.
//해결책?? 누군가 만든 라이브러리를 이용해서 개발시간을 단축하자!!
//현재 우리가 선택한 라이브러리는 cos.jar라는 Oreilly라는 출판사에서 제작한 컴포넌트이다!!
String saveDirectory = "C:/workspace/javaee_workspace/BoardApp/WebContent/data";//하드디스크의 물리적 경로를 명시해야 한다!!
int maxSize = 1024 * 1024 * 2; //2MByte
String encoding = "utf-8";
//FileRenamePolicy policy : 업로드 시 , 동일한 파일을 업로드했을 때?? 자동으로 이름을 부여한다...
//예) p.jpg, 1p.png.. (파일명은 개발자가 주도하여 명명하므로, policy를 굳이 이용할 필요 없다.)
try {
	MultipartRequest multi = new MultipartRequest(request, saveDirectory, maxSize, encoding);
	//업로드 컴포넌트를 이용할 경우, 스트링 파라미터도 업로드 컴포넌트를 이용해야한다!!
	String msg = multi.getParameter("msg");
	//out.print("전송한 메시지는 " + msg);
	//업로드가 완료된 후, 즉 서버의 저장소에 파일이 존재하게 된 후 해야할 일!
	//파일명을 개발자가 정한 규칙으로 변경해야 한다..현재시간의 밀리세컨드까지 구해보자!
	long time = System.currentTimeMillis();
	//out.print(time);
	//구한 시간에 확장자를 붙이면 최종적으로 절대 중복되지않는 파일이 생성
	String filename = multi.getOriginalFileName("photo");
	//out.print("전송한 파일의 이름은 " + filename);
	String ext = FileManager.getExtend(filename);
	out.print("내가 조작한 파일명은 " + time + "." + ext);
	
	//조작한 이름으로 파일명을 바꾸어야함
	//결국 파일을 다루어야 하므로 javaSE의 File클래스를 이용하면 된다!
	File file = multi.getFile("photo");
	file.renameTo(new File("C:/workspace/javaee_workspace/BoardApp/WebContent/data/"+time+"."+ext));
	
	//클라이언트에게 전송할 응답정보를 가진 객체
	//클라이언트의 브라우저로 하여금 지정한 URL로 재접속을 시도하게 만듦
	response.sendRedirect("/gallery/send.html");
} catch (IOException e) {
	e.printStackTrace();//콘솔로그에 에러 출력
	out.print("업로드 용량이 너무 큽니다..");//사블릿 쓰레드 에러..
}
%>

위 코드에서 볼 수 있듯이  MultipartRequest와 request 객체를 이용해서 파일을 업로드할 수 있다.

다운받은 파일에 doc폴더 아래에 html파일들을 보면서 자세히 알 수 있다.

Apache에서 제공하는 라이브러리 사용

Maven Repository: commons-fileupload » commons-fileupload (mvnrepository.com)

 

Maven Repository: commons-fileupload » commons-fileupload

The Apache Commons FileUpload component provides a simple yet flexible means of adding support for multipart file upload functionality to servlets and web applications. VersionRepositoryUsagesDate1.4.x1.4Central226Dec, 20181.3.x1.3.3Central514Jun, 20171.3.

mvnrepository.com

위 사이트에서 jar파일을 다운받아 라이브러리에 등록한다.

<%@page import="org.apache.catalina.filters.SetCharacterEncodingFilter"%>
<%@page import="common.FileManager"%>
<%@page import="org.apache.commons.fileupload.FileItem"%>
<%@page import="java.util.List"%>
<%@page import="java.io.File"%>
<%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@page import="org.apache.commons.fileupload.DefaultFileItemFactory"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%
	/*
파일 업로드 컴포넌트 종류엔 여러종류가 있지만, 그 중 아파치의 공식 업로드 컴포넌트를 사용해본다.
*/
//업로드 객체를 생성해주는 팩토리 객체 : 주로 설정을 담당(서버의 저장경로, 파일의 용량제한..)
String saveDir = "C:/workspace/javaee_workspace/BoardApp/WebContent/data";
int maxSize = 1024 * 1024 * 3; // 3MB
DefaultFileItemFactory itemFactory = new DefaultFileItemFactory();
itemFactory.setRepository(new File(saveDir)); //저장될 위치!, 물리적인 저장이 아닌, 임시 디렉터리
//디렉터리도 파일의 종류 중 하나이다!!
itemFactory.setSizeThreshold(maxSize);//파일 크기 제한

//이 객체가 실제 업로드를 수행함
ServletFileUpload upload = new ServletFileUpload(itemFactory);//설정정보를 생성자의 인수로 전달!!

//FileItem은 클라이언트의 [전송 정보 하나 하나]를 의미한다!! 즉, html에서의 input, file 컴포넌트 들을..
//우리의 경우 input type="text"가 FileItem에 담기고
//우리의 경우 input type="file"도 FileItem에 담긴다.
List<FileItem> items = upload.parseRequest(request);//request를 전달하여 upload컴포넌트에게 클라이언트의 요청정보를 전달!!

for (FileItem item : items) {
	//out.print(item.getFieldName());//컴포넌트의 name추출 
	//반복문으로 처리되다보니, 파일만 따로 처리를 하려면 구분로직이 필요함..
	//out.print(item.getFieldName()+"은 텍스트 박스 여부 " + item.isFormField()+"<br>");
	
	if (!item.isFormField()) {//type이 text가 아닌 것만 업로드 처리!
		//out.print(item.getFieldName()+"의 값은 "+item.getString()+"<br>");
		//업로드 처리하자!! 메모리상의 이미지 정보를 실제 물리적 파일로 저장하자!
		//out.print( item.getName());
		String ext = FileManager.getExtend(item.getName());
		String filename = System.currentTimeMillis() + "." +ext;
		File file = new File(saveDir+"/"+filename);//비어있는 파일
		item.write(file);//저장 정보를 File클래스의 인스턴스로 전달!!
		out.print("보고서 작성<br>");
		out.print("본래 파일명 : "+item.getName()+"<br>");
		out.print("변경 파일명 : "+filename+"<br>");
		out.print("저장 위치 : "+saveDir+"<br>");
		out.print("파일 크기 : "+item.getSize()+"<br>");
	}
}
%>

아파치에서 제공하는 라이브러리는 Factory객체를 이용하여 설정을 할 수 있고 ServletFileUpload 객체를 이용하여 request내에 담긴 파라미터들을 해석하여 List로 받아 사용할 수 있다.!!

'프로그래밍 > JSP' 카테고리의 다른 글

JSP | session  (0) 2020.12.16
JSP | 커넥션풀(Connection Pool)  (0) 2020.12.11
JSP | MyBatis 사용해보기  (0) 2020.12.10
JSP - 페이징 이해  (0) 2020.12.08
JSP - JSP(Java Server Page)란?  (0) 2020.12.01

+ Recent posts