paging처리

sql문

--row_number() over(분석) 함수를 이용해보자
--분석절을 기준으로 행번호를 붙여주는 함수
select * from(
select row_number() over(order by idx desc) rn,
board.* from board
)where rn between 1 and 5;

BoardListServlet

package board.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import board.model.BoardDAO;
import board.model.BoardVO;
import common.controller.AbstractAction;

public class BoardListAction extends AbstractAction {

	@Override
	public void execute(HttpServletRequest req, HttpServletResponse res) throws Exception {
		String cpStr=req.getParameter("cpage");
		String psStr=req.getParameter("pageSize");
		if(cpStr==null||cpStr.trim().isEmpty()) {
			cpStr="1";
		}
		HttpSession session=req.getSession();
		if(psStr==null||psStr.trim().isEmpty()) {
			psStr=(String)session.getAttribute("pageSize");
			if(psStr==null) {				
				psStr="5";
			}
		}
		session.setAttribute("pageSize", psStr);
		int cpage=Integer.parseInt(cpStr);
		int pageSize=5;
		if(psStr!=null) {
			pageSize=Integer.parseInt(psStr);//한 페이지당 보여줄 게시글 수
		}
		
		//BoardDAO객체 생성해서 메소드 호출 listBoard()
		BoardDAO dao = new BoardDAO();
		//1. 총 게시글 수 가져오기
		int totalCount=dao.getTotalCount();
		int pageCount = (totalCount-1)/pageSize+1;
		if(cpage<1) {
			cpage=1;
		}else if(cpage>pageCount) {
			cpage=pageCount;
		}
		//DB에서 끊어오기 위한 변수 (start, end)
		int end = pageSize*cpage;
		int start = end-pageSize+1;
		
		//2. 게시목록 가져오기
		List<BoardVO> arr = dao.listBoard(start,end);
		int pagingBlock=5;//페이지를 5개 단위로 블럭 처리
		int prevBlock=0, nextBlock=1;
		prevBlock = (cpage-1)/pagingBlock * pagingBlock;
		nextBlock = prevBlock + pagingBlock + 1;
		
		//반환해주는 List<BoardVO>를 req에 저장 (key값: boardArr)
		req.setAttribute("cpage", cpage);
		req.setAttribute("pageCount", pageCount);
		req.setAttribute("totalCount", totalCount);
		req.setAttribute("boardArr", arr);
		req.setAttribute("pagingBlock", pagingBlock);
		req.setAttribute("prevBlock", prevBlock);
		req.setAttribute("nextBlock", nextBlock);
		this.setViewPage("boardList2.jsp");
		this.setRedirect(false);
	}

}

list.jsp

 

<!-- begin:시작 end:끝 step:증가치 -->
<ul class="pagination justify-content-center">
	<c:forEach var="i" begin="1" end="${pageCount}" step="1">
		<li class="page-item <c:if test="${cpage==i}">active</c:if>"><a class="page-link" href="list.do?cpage=${i}">${i}</a></li>
	</c:forEach>
</ul>

책갈피

action에 #bbs를 적어주면 list.do에 bbs를 바로 보여준다

	<form name="listF" id="listF" action="list.do#bbs">
		<input type="hidden" name="cpage" value="${cpage}">
		<select name="pageSize" class="form-control " onchange="submit()">
			<option value="5">::페이지 사이즈 선택::</option>
			<c:forEach var="ps" begin="5" end="20" step="5">
			<option value="${ps}">페이지 사이즈 ${ps}</option>
			</c:forEach>
		</select>
	</form>

페이징 블럭처리
//이전 5개 [1][2][3][4][5] 아후 5개

 * [1][2][3][4][5] | [6][7][8][9][10] | [11][12][13][14][15] | ...
 * cpage pagingBlock prevBlock nextBlock
 * 1,2,3,4,5 5 0 6
 * 6,7,8,9,10 5 5 11
 * 11,12,13,14,15 5 10 16
 * 
 * prevBlock = (cpage-1)/pagingBlock * pagingBlock 
 * nextBlock = prevBlock + pagingBlock + 1 

<c:if test="${prevBlock>0}"> <!-- 이전 5개 -->
	<li class="page-item"><a class="page-link" href="list.do?cpage=${prevBlock}#bbs">이전${pagingBlock}개</a></li>
</c:if>

<c:forEach var="i" begin="${prevBlock+1}" end="${nextBlock-1}" step="1">
<c:if test="${i<=pageCount}">
	<li class="page-item <c:if test="${cpage==i}">active</c:if>"><a class="page-link" href="list.do?cpage=${i}#bbs">${i}</a></li>
</c:if>
</c:forEach>

<c:if test="${nextBlock<=pageCount}"> <!-- 이후 5개 -->
	<li class="page-item"><a class="page-link" href="list.do?cpage=${nextBlock}#bbs">이후${pagingBlock}개</a></li>
</c:if>

</ul>
</td>
<td colspan="2" class="text-center">총게시글수: 
<span class="text-primary">${totalCount}</span>
<br>
<span class="text-danger">${cpage}</span>/<span>${pageCount}</span>
</td>

검색처리

find.Jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<jsp:include page="/top.jsp"/>
<div class="text-left p-5">
	<h1 class="text-center">MVC Board [${findKeyword}] 검색결과</h1>
	<p class="text-center">
		<a href="write.do">글쓰기</a>|
		<a href="list.do">글목록</a>
	</p>
	<p>
	<!-- pageSize관련 form 시작 -->
	<div class="row">
	<div class="col-md-3 ">
	<form name="listF" id="listF" action="find.do#bbs" class="m-2">
		<input type="hidden" name="cpage" value="${cpage}">
		<input type="hidden" name="findType" value="${findType}">
		<input type="hidden" name="findKeyword" value="${findKeyword}">
		<select name="pageSize" class="form-control " onchange="submit()">
			<option value="5">::페이지 사이즈 선택::</option>
			<c:forEach var="ps" begin="5" end="20" step="5">
			<option value="${ps}">페이지 사이즈 ${ps}</option>
			</c:forEach>
		</select>
	</form>
	</div><!-- col end -->
	<div class="col-md-9">
		<form name="findF" id="findF" action="find.do#bbs" class="form-inline">
			<select name="findType" id="findType" class="form-control m-2">
				<option value="0">::검색유형::</option>
				<option value="1">제   목</option>
				<option value="2">작성자</option>
				<option value="3">글내용</option>
			</select>
			<input type="text" name="findKeyword" id="findKeyword" placeholder="검색어를 입력하세요" class="form-control m-2" required>
			<button class="btn btn-primary">검색</button>
		</form>
	</div>
	</div><!-- row end -->
	<!-- ------------------- -->
	</p>
	<table id="bbs" class="table table-striped table-hover">
		<tr class="table-secondary">
			<th width="10%">글번호</th>
			<th width="40%">제목</th>
			<th width="20%">글쓴이</th>
			<th width="20%">날   짜</th>
			<th width="10%">조회수</th>
		</tr>
		<!-- 반복문 -->
		<c:if test="${boardArr!=null||empty boardArr}">
			<c:forEach var="board" items="${boardArr}">
				<tr>
					<td>${board.idx}</td>
					<td><a href="view.do?idx=${board.idx}">${board.subject}</a>
					<c:if test="${board.filesize>0}">
						<img src="../images/attatch.PNG" width="16px">
					</c:if>
					</td>
					<td>${board.name}</td>
					<td>
					<!-- 날짜 포맷 -->
					<fmt:formatDate value="${board.wdate}" pattern="yyyy-MM-dd"/>
					</td>
					<td>${board.readnum}</td>
				</tr>
			</c:forEach>
		</c:if>
		<c:if test="${boardArr==null&&not empty boardArr }">
			<tr><td colspan="5">데이터가 없습니다.</td></tr>
		</c:if>
		<!-- when otherwise로 if else 문을 사용할 수 있다. -->
		<c:choose>
			<c:when test="true"></c:when>
			<c:otherwise></c:otherwise>
		</c:choose>
		<!-- 반복문 -->
		<tr>
			<td colspan="3" class="text-center">
			<!-- begin:시작 end:끝 step:증가치 -->
			<ul class="pagination justify-content-center">
			<c:if test="${prevBlock>0}"> <!-- 이전 5개 -->
			<li class="page-item"><a class="page-link" href="find.do?cpage=${prevBlock}#bbs">이전${pagingBlock}개</a></li>
			</c:if>
			
			<c:forEach var="i" begin="${prevBlock+1}" end="${nextBlock-1}" step="1">
			<c:if test="${i<=pageCount}">
			<li class="page-item <c:if test="${cpage==i}">active</c:if>"><a class="page-link" href="find.do?cpage=${i}#bbs">${i}</a></li>
			</c:if>
			</c:forEach>
			
			<c:if test="${nextBlock<=pageCount}"> <!-- 이후 5개 -->
			<li class="page-item"><a class="page-link" href="find.do?cpage=${nextBlock}#bbs">이후${pagingBlock}개</a></li>
			</c:if>
			
			</ul>
			</td>
			<td colspan="2" class="text-center">총게시글수: 
			<span class="text-primary">${totalCount}</span>
			<br>
			<span class="text-danger">${cpage}</span>/<span>${pageCount}</span>
			</td>
		</tr>
	</table>
</div>
<jsp:include page="/foot.jsp"/>

findServlet

package board.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import board.model.BoardDAO;
import board.model.BoardVO;
import common.base.CommonUtil;
import common.controller.AbstractAction;

public class BoardFindAction extends AbstractAction {

	@Override
	public void execute(HttpServletRequest req, HttpServletResponse res) throws Exception {
		HttpSession session=req.getSession();
		//검색유형과 검색어 받기
		String findType = req.getParameter("findType");
		String findKeyword=req.getParameter("findKeyword");
		if(findType==null||findType.equals("0")||findKeyword==null||findKeyword.trim().isEmpty()) {
			findType=(String)session.getAttribute("findType");
			findKeyword=(String)session.getAttribute("findKeyword");
			if(findType==null||findType.equals("0")||findKeyword==null||findKeyword.trim().isEmpty()) {
				this.setViewPage(CommonUtil.addMsgBack(req, "검색유형과 검색어를 입력하세요"));
				this.setRedirect(false);
				return;
			}
		}
		session.setAttribute("findType", findType);
		session.setAttribute("findKeyword", findKeyword);
		String cpStr=req.getParameter("cpage");
		String psStr=req.getParameter("pageSize");
		if(cpStr==null||cpStr.trim().isEmpty()) {
			cpStr="1";
		}
		
		if(psStr==null||psStr.trim().isEmpty()) {
			psStr=(String)session.getAttribute("pageSize");
			if(psStr==null) {				
				psStr="5";
			}
		}
		session.setAttribute("pageSize", psStr);
		int cpage=Integer.parseInt(cpStr);
		int pageSize=5;
		if(psStr!=null) {
			pageSize=Integer.parseInt(psStr);//한 페이지당 보여줄 게시글 수
		}
		
		//BoardDAO객체 생성해서 메소드 호출 listBoard()
		BoardDAO dao = new BoardDAO();
		//1. 총 게시글 수 가져오기
		int totalCount=dao.getTotalCount(findType,findKeyword);
		int pageCount = (totalCount-1)/pageSize+1;
		if(cpage<1) {
			cpage=1;
		}else if(cpage>pageCount) {
			cpage=pageCount;
		}
		//DB에서 끊어오기 위한 변수 (start, end)
		int end = pageSize*cpage;
		int start = end-pageSize+1;
		
		//2. 게시목록 가져오기
		List<BoardVO> arr = dao.findBoard(start,end,findType,findKeyword);
		int pagingBlock=5;//페이지를 5개 단위로 블럭 처리
		int prevBlock=0, nextBlock=1;
		//이전 5개 [1][2][3][4][5] 아후 5개
		/*
		 * [1][2][3][4][5] | [6][7][8][9][10] | [11][12][13][14][15] | ...
		 * cpage			pagingBlock		prevBlock	nextBlock
		 * 1,2,3,4,5		5				0			6
		 * 6,7,8,9,10		5				5			11
		 * 11,12,13,14,15	5				10			16
		 * 
		 * prevBlock = (cpage-1)/pagingBlock * pagingBlock 
		 * nextBlock = prevBlock + pagingBlock + 1 
		 * 
		 * */	
		prevBlock = (cpage-1)/pagingBlock * pagingBlock;
		nextBlock = prevBlock + pagingBlock + 1;
		
		//반환해주는 List<BoardVO>를 req에 저장 (key값: boardArr)
		req.setAttribute("cpage", cpage);
		req.setAttribute("pageCount", pageCount);
		req.setAttribute("totalCount", totalCount);
		req.setAttribute("boardArr", arr);
		req.setAttribute("pagingBlock", pagingBlock);
		req.setAttribute("prevBlock", prevBlock);
		req.setAttribute("nextBlock", nextBlock);
		req.setAttribute("findType", findType);
		req.setAttribute("findKeyword", findKeyword);
		this.setViewPage("boardFind.jsp");
		this.setRedirect(false);
	}

}

boardDAO

	public int getTotalCount(String findType, String findKeyword) throws SQLException{
		String colName = getColumnName(findType);
		try {
			con=DBUtil.getCon();
			String sql="select count(idx) cnt from board where "+colName+" like ?";
			ps=con.prepareStatement(sql);
			ps.setString(1, "%"+findKeyword+"%");
			rs=ps.executeQuery();
			rs.next();
			int n = rs.getInt("cnt");
			return n;
		}finally {
			close();
		}
	}
	public List<BoardVO> findBoard(int start, int end, String findType, String findKeyword) throws SQLException{
		String colName=this.getColumnName(findType);
		try {
			con=DBUtil.getCon();
			StringBuilder buf= new StringBuilder("select * from (") 
					.append("select row_number() over(order by idx desc) rn, ") 
					.append("board.* from board ") 
					.append("where "+colName+" like ? ") 
					.append(") where rn between ? and ?");
			String sql=buf.toString();
			ps=con.prepareStatement(sql);
			ps.setString(1, "%"+findKeyword+"%");
			ps.setInt(2, start);
			ps.setInt(3, end);
			rs=ps.executeQuery();
			List<BoardVO> arr = makeList(rs);
			return arr;
		}finally {
			close();
		}
	}
	private String getColumnName(String findType) {
		String str="";
		switch(findType){
		case "1":str="subject";break;
		case "2":str="name";break;
		case "3":str="content";break;
		}
		return str;
	}

ConnectionPoolBean


Data 처리를 할 때 connection을 미리 만들어두고 pool을 만드는 것이다. 사용을 할 때는 true로 설정하고 모든 Connection이 사용 중이면
추가로 만든 후 기본 설정 개수를 만들어주는 기능과 같다.

tomcat은 ConnectionPoolBean을 자주 사용하기 때문에 dbcp.jar파일이 있다.

예시

package my.db;
import java.util.*;
import java.sql.*;

public class ConnectionPoolBean {
	private Hashtable<Connection, Boolean> ht;
	private String url, user, pwd;
	private int increment;
	
	public ConnectionPoolBean()
			throws ClassNotFoundException, 
			SQLException{
		increment=3;// 증가치: 3
		ht=new Hashtable<Connection,Boolean>(5);
		//커넥션을 저장할 자료구조
		Connection con=null;
		Class.forName("oracle.jdbc.driver.OracleDriver");
		url="jdbc:oracle:thin:@localhost:1521:orcl10";
		user="scott"; pwd="tiger";
		/*커넥션을 미리 5개 생성하여 저장해 놓는다.*/
		for(int i=0;i<5;i++){
			con=DriverManager.getConnection(url,user,pwd);
			ht.put(con,Boolean.FALSE);
			//첨에는   false로 마크한다.
		}
	System.out.println("ConnectionPoolBean Created....");
	}//생성자----------------------------------------- 
	
	public synchronized Connection getConnection()
	throws SQLException{
		Connection con=null;
		Enumeration<Connection> en=ht.keys();// key 값을 집합체 형체로 추출
		while(en.hasMoreElements()){
			con=en.nextElement();//key
			Boolean b=ht.get(con);//value
			if(b==Boolean.FALSE){
				ht.put(con, Boolean.TRUE);// 일하는 놈으로 마크
				return con;
			}                    
		}//while--------------
		// 놀고있는  con이 하나도 없다면 커넥션을 증가시키자.
		for(int i=0;i<increment;i++){
			Connection con2
			=DriverManager.getConnection(url,user,pwd);
			ht.put(con2, Boolean.FALSE);
		}
		return getConnection();// 재귀호출
	}//getConnection()--------------------------------
	
	public void returnConnection(Connection returnCon)
	throws SQLException{
		Connection con=null;
		Enumeration<Connection> en=ht.keys();// key 값을 집합체 형체로 추출
		while(en.hasMoreElements()){
			con=en.nextElement();
			if(con==returnCon){
				//반환되는 커넥션과 주소값이 같다면...  false 로 표시해준다.
				ht.put(con,Boolean.FALSE);
				break;
			}//if--------
		}//while------------------		
		removeCon();
		//커넥션을 기본적으로 5개만 유지하도록...
	}//returnConnection()-------------------------------
	public void removeCon(){
		Connection con=null;
		Enumeration<Connection> en=ht.keys();
		int count=0;//False인 con의 개수
		try{
			while(en.hasMoreElements()){
				con=en.nextElement();
				Boolean b=ht.get(con);
				if(!b){
					count++;
					if(count>5){
						ht.remove(con);
						con.close();// false인 con이 5개 이상이라면 ht에서 제거후
						//연결 종료
					}
				}//if----
			}//while--------------		
		}catch(SQLException e){			
		}
	}//removeCon()-----------------------------------
	public void closeAll(){
		Enumeration<Connection> en=ht.keys();
		while(en.hasMoreElements()){
			Connection con=en.nextElement();
			try{
			con.close();
			}catch(SQLException e){}
		}//while---------
	}//closeAll()--------------------------------------
	
}//////////////////////////////////////////////

환경설정

Apache DBCP 설정

1.  다운로드받자. 아래 사이트에서... (지금은 Tomcat에 포함)

http://archive.apache.org/dist//commons/

https://commons.apache.org/proper/commons-dbcp/



jakarta-commons DBCP
jakarta-commons collections
jakarta-commons pool

위 6개의 jar파일을 다운로드 받아 클래스패스에 걸어준다.

ex]
변수명: classpath
값:
.;C:\Java\jdk1.8.0_03\jre\lib\ext\ojdbc14.jar;
C:\Java\jdk1.8.0_03\jre\lib\ext\servlet-api.jar;
C:\Java\jdk1.8.0_03\jre\lib\ext\jsp-api.jar;
C:\Java\jdk1.8.0_03\jre\lib\ext\cos.jar;
C:\Java\Tomcat 8.5\common\lib\commons-collections-3.2.jar;
C:\Java\Tomcat 8.5\common\lib\commons-collections-testframework-3.2.jar;
C:\Java\Tomcat 8.5\common\lib\commons-dbcp-1.2.2.jar;
C:\Java\Tomcat 8.5\common\lib\commons-pool-1.3.jar

2. 세팅

참조 url:
http://tomcat.apache.org/tomcat-8.0-doc/jndi-datasource-examples-howto.html

1) c:/Java/Tomcat8.5/conf/server.xml의
<GlobalNamingResources>태그 사이에 세팅

[주의: oracle.jdbc.driver.OracleDriver 확인]

<Resource name="jdbc/myoracle" auth="Container"
              type="javax.sql.DataSource" driverClassName="oracle.jdbc.driver.OracleDriver"
              url="jdbc:oracle:thin:@127.0.0.1:1521:xe"
              username="scott" password="tiger" maxActive="20" maxIdle="10"
              maxWait="-1"/> 

 

2)c:/Java/Tomcat 8.5/conf/context.xml의

<Context reloadable="true"> 태그 사이에 아래부분 세팅

<ResourceLink global="jdbc/myoracle" name="jdbc/myoracle"
		type="org.apache.tomcat.dbcp.dbcp2.BasicDataSource"/>

3) XX프로젝트(~Project)/WEB-INF/web.xml 의 
<web-app> 태그사이에 아래 부분 세팅
	<resource-ref> 
	<description>Oracle Datasource example</description> 
	<res-ref-name>jdbc/myoracle</res-ref-name> 
	<res-type>javax.sql.DataSource</res-type> 
	<res-auth>Container</res-auth> 
	</resource-ref> 
 </web-app>

4) Java Source 상에서 다음과 같이 참조

 
Context initContext = new InitialContext();
Context envContext  = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/myoracle");
Connection conn = ds.getConnection();

////////////////////////////////////////////////////////////////////////


Java 프로그램에서 DB 접속하는 방법은 
크게 2가지로 볼수 있습니다.
[1] JDBC를 사용하는 방법
-  우리는 ConnectionPoolBean을 만들어 사용
[2] WAS서버에서 제공해주는 Connection Pool을 
사용하는 방법


1) JDBC를 사용하는 방법 : 
   오라클(각 다른 DB)에서 제공하는 
   DB 커넥션 클래스를 이용해서  
   DB에 접속하는 방법입니다.
   사용자가 직접 소스에 아이디와 비밀번호 IP등을 
   입력하여 커넥션 객체를 생성하고
   그것(커넥션객체)을 이용하여 DB를 제어합니다.

2) WAS가 제공하는 Connection Pool 을 사용하는 방법 : 
    사용자(프로그래머)가 소스에서 
	직접 DB에 연결하는 것이 아니라. 연결은 
	WAS(Weblogic나 제우스, 톰켓등을 말합니다)가 하고 
	사용자는 WAS가 연결한 
	커넥션을 이용하는 방법입니다.

	즉, WAS가 스타트 하면서 동시에 오라클에 
	커넥션 객체를 미리 생성합니다.
	프로그래머는 그 객체를 그냥 가져다 쓴다.
.
	DataSource를 이용한 방법이 바로 
	커넥션 풀 방법입니다.
	당연히 아이디와 비밀번호는 필요없죠 
	그런건 WAS가 다 알아서 접속합니다.
	그리기 위해서는 당연히 WAS의 설정파일에 
	DB연결 정보가 있어야 합니다.
	톰켓의 경우 톰켓/conf/server.xml  
	파일에 설정을 하시면 됩니다.

     cf>

	WAS가 만들어놓은 커낵션은 각각 커넥션 마다 
	이름이 있습니다.
	위 2개의 소스를 보시면
	GlobalVariable.DATA_SOURCE 
	= (DataSource) envCtx.lookup("jdbc/ora9");
	DATA_SOURCE = (DataSource) ctx.lookup("DS");
	라는 부분이 각각 있습니다.
	바로 이부분이 WAS에 등록된 커넥션 
	이름(정확히 말하면 커넥션과 매칭되는 이름)을 갖고 
	커넥션을 찾는 부분입니다.
	친절하게도 메소드 이름이 lookup 입니다. 
	뭔가 찾는다는 말이죠 
	여기서 그 이름은 jdbc/ora9, DS 가 됩니다. 
	정확히 말하면 이 이름들은 JNDI라고 합니다.
	공부하다 보면 알게 됩니다.

그리고 위 두 소스의 가장큰 차이점은

Context envCtx 
= (Context) initCtx.lookup("java:comp/env");
GlobalVariable.DATA_SOURCE 
= (DataSource) envCtx.lookup("jdbc/ora9");

props.put(Context.INITIAL_CONTEXT_FACTORY,"jeus.jndi.JEUSContextFactory");
props.put(Context.PROVIDER_URL,"127.0.0.1");

대충 이부분 정도인데 사실  차이가 아닙니다.

각기 WAS가 다르기 때문에 WAS마다 커넥션을 가져오는 방법이 다른겁니다.
위에 것은 톰켓에서 쓰는 방법이고 아래꺼는 제우스라는 국산 WAS 입니다.

///////////////////////////////////////////
질문을 통해서 보면 로그인을 할때 
DB를 사용하고 있습니다.
따라서 DB에 접근을 해서 DB상에 
아이디와패스워드를 체크하고, 
아이디정보를 가져오기 위한

Database Connection을 확보해야하는데요,

이 getConnection()이란 메소드가 바로 
그 역할을 하는것입니다.
Connection을 확보하는 방법은 
크게 두가지로 나누어집니다만,

여기서는 그중 WAS(Web Application Server, 
즉 Tomcat 같은..)에 설정되어 있는 
Datasource라는것을 통해서 가져오는 방법입니다.

 //

private Connection getConnection() throws Exception{
  Context initCtx=new InitialContext();   
  // WAS의 Datasource를 이용하기 위해 필요한 Context 객체를 생성합니다.
  Context envCtx=(Context)initCtx.lookup("java:comp/env"); 
  // WAS의 리소스중 JDNI라는 리소스 참조 방식을 사용해 "java:/comp/env" 카테고리 정보 
  //Context를 가져옵니다.
  DataSource ds=(DataSource)envCtx.lookup("jdbc/myoracle"); 
  // "java:/comp/env" 의 하위 Context중에 "jdbc/myoracle" 라는 항목의 리소스를 가져오면서 
  //해당 리소스가 DataSource 클래스란걸 알고 있기때문에 (DataSource) 로 캐스팅을 해서 
  //DataSource 객체 ds를 얻습니다.
  return ds.getConnection(); 
  // DataSource 객체 ds의 getConnection() 메소드를 통해 java.sql.Connection 객체를 얻어 반환합니다.
 }

 

이 소스는 이렇게도 가능. 즉 한다리 안걸치고 바로 JNDI 풀 PATH를 줘서 가져올수 있습니다.

private Connection getConnection() throws Exception{
  Context initCtx=new InitialContext();
  DataSource ds=(DataSource)envCtx.lookup("java:comp/env/jdbc/myoracle");
  return ds.getConnection();
 } 

다만 이렇게 DataSource를 사용하기 위해선 
WAS에 DataSource가 
저런 카테고리로 등록이 되어있어야합니다.
WAS에 따라서 DataSource를 등록하는법은 다르기때문에 
자세한 DataSource 등록법은 WAS별 메뉴얼을 참고.

////////////////////////////////////////////////////

cf] 
1. Naming Service란? <참고: 알기쉽게 풀어쓴 
웹로직과 EJB>

[1] 대표적인 예로 도메인명을 ip로 바꿔주는 서비스
     즉, 211.123.111.11 등의 ip를 www.a.co.kr 등의
	 이름을 이용해 접근
	 이것은 운영체제에 등록된 네임 서버를 이용해
	 해당 도메인이 어떤 아이피인지 알아낼 수 있기 때문에
	 가능.
	 이 떄 서버의 아이피가 변경되도 클라이언트는 동일한
	 이름으로 접근할 수 있는 장점이 있다.

[2] 이렇게 도메인 네임 서비스와 같이 분산된 객체를 찾기
     위해 자바 진영에서는 자바 표준 네이밍 서비스를 JNDI
	 로 정의하였다. 
	 JNDI는 특정한 이름으로 객체를 등록해서 관리할 수 있게 
	 도와준다.

2. JNDI란?  <Head First EJB 참고 : 116,602 p>

[1] Java Naming and Directory Interface의 약자
[2] 명명 및 디렉토리 서비스에 접근하기 위한 API
[3] 많은 기능이 있지만 우리는 등록(bind, rebind)하고,
     찾아쓰는(lookup) 방법만 알면 된다.
[4] 서버에 JNDI Driver(service provider라고 부름)
	 만 있으면 명명/디렉토리 서비스를 이용할 수 있다.
	 jndi 드라이버는 우리가 호출한 이름을 Naming 서비스에
	 서 이해할 수 있는 것으로 바꿔주는 역할을 한다.
[5] JNDI트리를 들어갈 때는 우선 InitialContext 에서 시작함
     ...javax.naming패키지에 있음-->1.4부터 j2se에 포함되었음
[6] InitialContext에서 시작하지만 빈에는 자기만의 JNDI컨텍스트가
     있다. 바로 이 빈에서 찾고자 하는 검색작업은 java:comp/env라는
	  서브 컨텍스트에서 시작된다.


확인

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="javax.naming.*,java.sql.*,javax.sql.*"%>
<jsp:include page="/top.jsp"/>
<div class="text-left p-5">
	<h1>DBCP Test</h1>
<%
Context initContext = new InitialContext();
Context envContext  = (Context)initContext.lookup("java:/comp/env");
//톰캣을 찾을 때는 java:comp/env
DataSource ds = (DataSource)envContext.lookup("jdbc/myshop");
Connection conn = ds.getConnection();

out.println("<h1>데이터 소스 룩업 성공: "+ds+"</h1>");
out.println("<h2>con: "+conn+"</h2>");
if(conn!=null) conn.close();
//커넥션 연결을 끊는 것이 아니라 커넥션풀레 반남을 함
%>
</div>
<jsp:include page="/foot.jsp"/>

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

Ajax

목록수정

   var goEditEnd=function(){
      //alert('a');
      //폼객체 serialize() 함수를 이용하여 파라미터 데이터를 만든다.
      var paramData=$('#editF').serialize();
      //alert(paramData);
      $.ajax({
    	  type:'POST',
    	  url:"bookUpdate.jsp",
    	  data:paramData,
    	  dataType:'xml',
    	  cache: false,
    	  success:function(res){
    		  var str = $(res).find('result').text();
    		  if(parseInt(str)>0){			  
	    		  getAllBook();
	    		  alert("성공");
    		  }else{
    			  alset("실패");
    		  }
    	  },
    	  error:function(err){
    		  alert("err: "+err.status);
    	  }
      })
      
   }//------------------------

update.jsp

<%@ page language="java" contentType="text/xml; charset=UTF-8"
    pageEncoding="UTF-8"%>
<jsp:useBean id="book" class="ajax.book.BookDTO" scope="page"/>
<jsp:setProperty property="*" name="book"/>
<jsp:useBean id="dao" class="ajax.book.BookDAO" scope="session"/>
<%
	int n = dao.updateBook(book);
%>
<result>
	<%=n %>
</result>

+ Recent posts