DB연동, 컨넥션풀

서울IT코드정리 /kyChoi·2021년 10월 24일
0

JSP 정리❤

목록 보기
5/22

중급 mvc 는 굉장히 느린 db 연동이였어요~

jsp랑 db 연동하려면 우선사항으로 jdbc.jar 파일을

tomcat의 lib에 넣어야 합니다

자바 중급때 데이터베이스 연동은 굉장히 느린 방법을 사용했다면

jsp에서는 훨씬 빠른(미리 데이터를 메모리에 올려) 방법을 이용합니다

⇒ 풀링방법 :

미리 데이터베이스 Connection 을 여러개 만들어서 특정공간에 저장해 놓고, 필요할때 마다 하나씩 꺼내서 사용합니다. 로직은 톰캣 홈페이지에 있습니다. 직접 짤 필요없이, 얘들이

그런 역할만 하는거 알고 복사 붙여넣기 하면 됩니다.~

필요성:

Connection 클래스는 객체화 될때, 다른 일반 클라스와 달리 몇초 지연됩니다. 만약 데이터베이스가

같은 회사가 아니라 다른 도시에 있다면 네트워크의 상태에 따라 더 지연될 수 있습니다.

jsp 페이지가 빈번하게 데이터베이스 Connection 을 생성하면 시간이 더 걸려요~

그러면 jsp가 시작할때(요청받았을때 Connection을 만들면 느리다고 했죠~) 요청이 없어도 미리 만들어 놓으면 요청받았을때 더 빠르게 대응할 수 있습니다.

환경변수 설정

100명의 클라이언트가 동시 접속하면 회원데이터를 한명 씩 회원이 맞는지 확인하고 줘야 하니

시간이 오래 걸릴 수 있습니다

예를 들면

<%
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
try{
Class.forName("oracle.jdbc.OracleDriver");
String url="jdbc:oracle:thin:@//localhost:1521/xe";
String sqlid = "scott";
String sqlpw = "tiger";
conn=DriverManager.getConnection(url,sqlid,sqlpw);
stmt = conn.createStatement();
rs = stmt.executeQuery("select empno from emp"); 
while(rs.next())
	out.print(rs.getString("empno")+"<br/>");

}

이 로직이 jsp 파일에 Connection 객체를 만들어 놓는거에요~

느려요

이 상황에서 톰캣이 켜졌을때 컨넥션을 미리 만들어 두면 더 빨라요~ -> connection 객체를 메모리에
미리 올려 둔것을(여기서는 DBUtil 에 넣었습니다) db pooling 기법이라고 합니다


[localhost]http://localhost → jdbc dataSources → oracle 8i 9i &10g 


<Resource name="jdbc/myoracle" auth="Container"
              type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
              url="jdbc:oracle:thin:@127.0.0.1:1521:xe" //이 부분 xe로 고쳐요~
              username="scott" password="tiger" maxTotal="20" maxIdle="10"
              maxWaitMillis="-1"/>

이 내용을 찾을 수 있고, maxTotal 이 총 20개 데이터 받을 수 있고 평소에 10개를 돌린다라는
의미입니다~

현업에 가면 미리 세팅이 되어 있으니 걱정하지 말게요~

얘를 server.xml 에 가서

<GlobalNamingResources></GlobalNamingResources> 에 붙여넣어요~
단, 기존에 있는 resource 태그 밑에 붙여야 해요~
두번째는 **context.xml** 에 가서 
<ResourceLink global ="jdbc/myoracle" name="jdbc/myoracle" type="javax.sql.DataSource"/>
얘를 붙여넣어요~

이렇게 두 군데에 붙여 넣기 하면 이제 

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

얘를 사용 할 수 있습니다. 얘를 자바 로직이라 붙여넣기한 걸 읽을 수 있어요~

현업에서 혼자 안 짜길 바란다.

이제 톰캣을 내렸다 다시 올려요~

쌤은 DBUtil 클래스 만들어서 그곳에 넣었어요 볼게요~

public class DBUtil {
public static Connection getConnection() throws Exception {
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");// 이 이름이 샘플로직인데
//철자가 다르면 오류나요~
DataSource ds = (DataSource)envContext.lookup("jdbc/myoracle");
return ds.getConnection();

}
이제 DBUtil 의 객체를 db 연동하는 곳에서 불러오면 사용가능해요~

//Connection conn = DBUtil.getConnection();해서 객체 가져올 수 있어요~


serviceLocator는 쌤이 더 고급지게 만들고 확장성이 높에 만들어 놓은거에요~


public DataSource getDataSource(String jndiName) throws ServiceLocatorException {
		DataSource dataSource;
		try {
			if (cache.containsKey(jndiName)) {
				dataSource=cache.get(jndiName);
			} else {
				dataSource = (DataSource)envCtx.lookup("java:comp/env/"+jndiName);
				cache.put(jndiName, dataSource);
			}
		} catch (NamingException e) {
			throw new ServiceLocatorException(e.getMessage());
		}
		return dataSource;
	}

얘는 일부분인데, ServiceLocator를 보면 envCtx = new InitialContext(); 얘가 있습니다.
어디서 많이 본 로직이죠~

그럼 왜 고급지게 만들어 놓으셨나면, .lookup을 보면 jndiName 변수가 들어 있어요

즉, 수정이 필요할 경우 DBUtil 에서 하지 않고 연동 로직이 잇는 곳에서 하면 관리가 더

수월하겠죠~

부르는 객체는 memberDAO 입니다 왜냐면 db 연동할때 부르거든요~



자 그럼 우리가 평소 사용하는 db  로직을 볼께요~

db1.jsp

<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.Connection"%>
<%@page import="java.sql.DriverManager"%>
<%@ 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>
</head>
<body>
<%
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
try{
Class.forName("oracle.jdbc.OracleDriver");
String url="jdbc:oracle:thin:@//localhost:1521/xe";
String sqlid = "scott";
String sqlpw = "tiger";
conn=DriverManager.getConnection(url,sqlid,sqlpw);
stmt = conn.createStatement();
rs = stmt.executeQuery("select empno from emp"); 
while(rs.next())
	out.print(rs.getString("empno")+"<br/>");

}catch(Exception e){
	throw e;
}finally{
	try{
		if(rs!=null){ rs.close(); rs=null; }
		if(stmt!=null){ stmt.close(); stmt=null; }
		if(conn!=null){ conn.close(); conn=null; }
	}catch(Exception e){ throw e; }
}
%>
</body>
</html>

이게 보통의 방식인데 풀링 방식으로 해볼게요~(톰캣이 실행될때 메모리에 객체를 10개 미리 만들어 놓습니다 )





db2.jsp 

<%
Connection conn =null;
Statement stmt= null;
ResultSet rs = null;
try{
conn = DBUtil.getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery("select empno from emp"); 
while(rs.next())
	out.print(rs.getString("empno")+"<br/>");
}catch(Exception e){
	throw e;
}finally{
	try{
		if(rs!=null){ rs.close(); rs=null; }
		if(stmt!=null){ stmt.close(); stmt=null; }
		if(conn!=null){ conn.close(); conn=null; }
	}catch(Exception e){ throw e; }
}
%>

db1.jsp 

와 비교하면 className 이 사라진걸 볼 수 있어요 
어디 갔을까요~?

server.xml 에 붙여져 있죠~

자 그럼 가만히 두면 안되죠, 사원 번호를 날려서 이름을 출력 해 볼게요~

<%@page import="java.sql.PreparedStatement"%>
<%@page import="a.b.DBUtil"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.Connection"%>
<%@page import="java.sql.DriverManager"%>
<%@ 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>
</head>
<body>
<%
Connection conn =null;
PreparedStatement stmt= null;
ResultSet rs = null;
try{
conn = DBUtil.getConnection();
String no=request.getParameter("empno");
stmt = conn.prepareStatement("select ename from emp where empno=?");
stmt.setString(1,request.getParameter("empno"));
rs = stmt.executeQuery(); 
while(rs.next())
	out.print(rs.getString("ename")+"<br/>");
}catch(Exception e){
	throw e;
}finally{
	try{
		if(rs!=null){ rs.close(); rs=null; }
		if(stmt!=null){ stmt.close(); stmt=null; }
		if(conn!=null){ conn.close(); conn=null; }
	}catch(Exception e){ throw e; }
}
%>
</body>
</html>
로직을 길어 보이지만, 결국 연동 로직, 출력문 로직, 자원 로직 크게 3가지로 나눠볼 수 잇어요~
profile
건물주가 되는 그날까지

0개의 댓글