JSP - 오라클 데이터베이스 연동
22 Feb 2021 | JSPJSP - 오라클 데이터베이스 연동
JSP에서 오라클 데이터베이스와 연동을 해보자
우선 실습을 위해 TEMPMEMBER 테이블을 만들었다.
이 테이블은 ID, 비번, 이름, 회원번호, 이멜, 전번, 우편, 주소, 직업 등의 필드를 가진다.
오라클 JDBC는 WebContent/WEB-INF/lib 안에 모셔둔다. 외부 라이브러리는 모두 이 곳에 위치하게 된다.
-
JDBC를 이용하여 데이터 가져오기
- 이 방법은 가장 기초적이면서도 꼭 알아야하는 방법이다
- java.sql.*을 import 시킨다
<% Class.forName("oracle.jdbc.driver.OracleDriver"); Connection conn = null; Statement stmt = null; ResultSet rs = null; String id = ""; String passwd = ""; <!-- ...생략 --> int counter = 0; try { conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521/XEPDB1", "mytest", "mytest"); stmt = conn.createStatement(); rs = stmt.executeQuery("SELECT * FROM TEMPMEMBER"); %> <!-- HTML 시작 --> <% if(rs!=null) { while(rs.next()) { id= rs.getString("id"); passwd = rs.getString("passwd"); <!-- ...생략 --> %> <tr> <td><%= id %></td> <td><%= passwd %></td> <!-- ...생략 --> </tr> <% counter++; }//end while }// end if %> </table><br> <% } catch(SQLException se) { System.out.println("sql exception"); } catch(Exception e) { System.out.println("exception"); } finally { if(rs != null) try {rs.close();}catch(SQLException e){} if(stmt != null) try {stmt.close();}catch(SQLException e){} if(conn != null) try {conn.close();}catch(Exception e){} } %>
- Java에서 연동했던 방법과 크게 다르지 않다. 다만, 표현하고자 하는 데이터를 XML 태그 안에 집어넣는다는것 뿐?
-
Connection Pool을 이용하여 데이터 가져오기
- 데이터베이스와 연결된 커넥션을 미리 만들어서 저장해두었다가 필요시 꺼내쓰고 다시 반환하는 것을 커넥션 풀이라고 한다
- 커넥션 풀을 이용하면 데이터베이스 부하를 줄이고 동시접속자를 유동적으로 처리할 수 있다는 장점이 있다
- 커넥션을 저장할 수 있는 두 개의 Vector를 생성한다. (혹은 ArrayList)
- Free 벡터는 커넥션풀 클래스의 객체가 생성될 때 미리 생성된 커넥션을 저장하는 저장소이다
- used 벡터는 실제 미들웨어에서 DBMS와 연결할 때 사용하는 커넥션 저장소이다
- Free에서 커넥션 객체를 꺼내 used에 저장하고 실제 앱과 연결 후 다시 반납하는 구조이다
//Connection Pool Class import java.sql.*; import java.util.*; public class ConnectionPool { // DB 드라이버 불러오기 static { try { Class.forName("oracle.jdbc.driver.OracleDriver"); } catch(ClassNotFoundException e) { e.printStackTrace(); } } // 초기 커넥션 저장 private ArrayList<Connection> free; private ArrayList<Connection> used; // 사용중인 커넥션 저장 private String url = "jdbc:oracle:thin:@localhost:1521/XEPDB1"; private String user = "mytest"; private String passwd = "mytest"; private int initialCons = 10; // 초기 커넥션 수 private int maxCons = 20; // 최대 커넥션 수 private int numCons = 0; // 총 커넥션 수 private static ConnectionPool cp; private ConnectionPool() throws SQLException { // 초기 커넥션 수만큼 ArrayList 생성 free = new ArrayList<Connection>(initialCons); used = new ArrayList<Connection>(initialCons); // 초기 커넥션 수만큼 커넥션 생성 while(numCons < initialCons) { addConnection(); } } // 객체 생성 후 ConnectionPool 리턴 public static ConnectionPool getInstance() { try { if(cp == null) { synchronized(ConnectionPool.class) { cp = new ConnectionPool(); } } } catch(SQLException e) { e.printStackTrace(); } return cp; } // free에 커넥션 객체를 저장 private void addConnection() throws SQLException { free.add(getNewConnection()); } // 새로운 커넥션 생성 private Connection getNewConnection() throws SQLException { Connection con = null; try { con = DriverManager.getConnection(url, user, passwd); } catch(SQLException e) { e.printStackTrace(); } System.out.println("About to connect to"+ con); ++numCons; // 커넥션 생성될 때마다 커넥선 수 증가 return con; } // free에 있는 커넥션을 used로 옮기는 작업 public synchronized Connection getConnection() throws SQLException { // free에 커넥션이 없으면 maxCons만큼 커넥션 생성 if(free.isEmpty()) { while(numCons < maxCons) { addConnection(); } } Connection _con; _con = free.get(free.size() -1); free.remove(_con); used.add(_con); return _con; } // used에 있는 커넥션을 free로 반납 public synchronized void releaseConnection(Connection _con) throws SQLException { boolean flag = false; if(used.contains(_con)) { used.remove(_con); numCons--; flag = true; } else { throw new SQLException("ConnectionPool 없음"); } try { if(flag) { free.add(_con); numCons++; } else { _con.close(); } } catch(SQLException e) { try { _con.close(); } catch(SQLException e2) { e2.printStackTrace(); } } } }
- JSP에서 ConnectionPool class 사용
<% ConnectionPool pool = ConnectionPool.getInstance(); Connection conn = null; Statement stmt = null; ResultSet rs = null; String id = ""; String passwd = ""; <!-- ...생략 --> int counter = 0; try { conn = pool.getConnection(); stmt = conn.createStatement(); rs = stmt.executeQuery("SELECT * FROM TEMPMEMBER"); %> <!-- HTML 시작 --> <% if(rs!=null) { while(rs.next()) { id= rs.getString("id"); passwd = rs.getString("passwd"); <!-- ...생략 --> %> <tr> <td><%= id %></td> <td><%= passwd %></td> <!-- ...생략 --> </tr> <% counter++; }//end while }// end if %> </table><br> <% } catch(SQLException se) { System.out.println("sql exception"); } catch(Exception e) { System.out.println("exception"); } finally { if(rs != null) try {rs.close();}catch(SQLException e){} if(stmt != null) try {stmt.close();}catch(SQLException e){} if(conn != null) try {pool.releaseConnection(conn);}catch(Exception e){} } %>
- 1번 방법과 크게 다르지 않은데, 연결과 반납을 ConnectionPool 클래스의 메소드를 이용한다는 점이 다르다.
-
JavaBeans를 이용하여 데이터 가져오기
- VO와 DAO를 만들어 JSP에서 사용하는 방법
package jdbc; public class TempMemberVO { private String id; private String passwd; //... 생략 public String getId() { return id; } public void setId(String id) { this.id = id; } public String getPasswd() { return passwd; } public void setPasswd(String passwd) { this.passwd = passwd; } //... 생략 }
public class TempMemberDAO { private final String JDBC_DRIVER = "oracle.jdbc.driver.OracleDriver"; private final String JDBC_URL = "jdbc:oracle:thin:@localhost:1521/XEPDB1"; private final String USER = "mytest"; private final String PASSWD = "mytest"; public TempMemberDAO() { try { Class.forName(JDBC_DRIVER); } catch(Exception e) { System.out.println("ERROR : JDBC 드라이버 로딩 실패"); } } // DB에서 데이터 받아서 벡터에 저장 public Vector<TempMemberVO> getMemberList() { Connection conn = null; Statement stmt = null; ResultSet rs = null; Vector<TempMemberVO> vecList = new Vector<TempMemberVO>(); try { conn = DriverManager.getConnection(JDBC_URL, USER, PASSWD); String query = "select * from tempmember"; stmt = conn.createStatement(); rs = stmt.executeQuery(query); while(rs.next()) { TempMemberVO vo = new TempMemberVO(); vo.setId(rs.getString("id")); vo.setPasswd(rs.getString("passwd")); <!-- ...생략 --> vecList.add(vo); } } catch(Exception e) { System.out.println("Exception" + e); } finally { if(rs != null) try {rs.close();}catch(SQLException e){} if(stmt != null) try {stmt.close();}catch(SQLException e){} if(conn != null) try {conn.close();}catch(Exception e){} } return vecList; } }
- JSP에서 사용
<jsp:useBean id="dao" class="jdbc.TempMemberDAO" scope="page" /> <% Vector<TempMemberVO> vlist = dao.getMemberList(); int counter = vlist.size(); for(int i=0; i<vlist.size(); i++) { TempMemberVO vo = vlist.elementAt(i); %> <tr> <td><%= vo.getId() %></td> <td><%= vo.getPasswd() %></td> <td><%= vo.getName() %></td> <td><%= vo.getMem_num1() %></td> <td><%= vo.getMem_num2() %></td> <td><%= vo.getEmail() %></td> <td><%= vo.getPhone() %></td> <td><%= vo.getZipcode() %>/<%= vo.getAddress() %></td> <td><%= vo.getJob() %></td> </tr> <% } %> </table>
-
Connection Pool과 JavaBeans 모두 적용하는 방법
- 2번과 3번의 방법을 혼용하여 사용
- 3번의 DAO에서 연결,반납하는 방법을 커넥션 풀 객체를 생성하고 커넥션 풀의 메소드를 이용
public class TempMemberDAO { private ConnectionPool pool = null; public TempMemberDAO() { try { pool = ConnectionPool.getInstance(); } catch(Exception e) { System.out.println("ERROR : 커넥션 얻어오기 실패"); } } // DB에서 데이터 받아서 벡터에 저장 public Vector<TempMemberVO> getMemberList() { Connection conn = null; Statement stmt = null; ResultSet rs = null; Vector<TempMemberVO> vecList = new Vector<TempMemberVO>(); try { conn = pool.getConnection(); String query = "select * from tempmember"; stmt = conn.createStatement(); rs = stmt.executeQuery(query); while(rs.next()) { TempMemberVO vo = new TempMemberVO(); vo.setId(rs.getString("id")); vo.setPasswd(rs.getString("passwd")); vo.setName(rs.getString("name")); vo.setMem_num1(rs.getString("mem_num1")); vo.setMem_num2(rs.getString("mem_num2")); vo.setEmail(rs.getString("e_mail")); vo.setPhone(rs.getString("phone")); vo.setZipcode(rs.getString("zipcode")); vo.setAddress(rs.getString("address")); vo.setJob(rs.getString("job")); vecList.add(vo); } } catch(Exception e) { System.out.println("Exception" + e); } finally { if(rs != null) try {rs.close();}catch(SQLException e){} if(stmt != null) try {stmt.close();}catch(SQLException e){} if(conn != null) try {pool.releaseConnection(conn);}catch(Exception e) {} } return vecList; } }
- JSP에서 사용하는 방법은 3번의 방법과 동일하다
-
WAS에서 제공하는 DBCP 이용하여 데이터 가져오기
- 아파치에서 제공하는 Connection Pool인 DBCP를 이용하여 오라클과 연동한다
- www.apache.org의 common에서 collections, dbcp, pool 라이브러리를 다운받아 jar파일을 WEB-INF/lib 폴더에 넣는다
- META-INF에 context.xml 파일을 추가하여 다음 속성을 기입한다
<?xml version="1.0" encoding="UTF-8"?> <Context> <Resource name="jdbc/myOracle" auth="Container" driverClassName="oracle.jdbc.driver.OracleDriver" type="javax.sql.DataSource" url="jdbc:oracle:thin:@localhost:1521/XEPDB1" username="mytest" password="mytest" maxTotal="8" maxIdle="10" maxWaitMillis="-1" /> </Context>
자료 출처 : https://devbox.tistory.com/entry/JSP-%EC%BB%A4%EB%84%A5%EC%85%98-%ED%92%80-1
- DD (web.xml)에 다음을 추가한다
<resource-ref> <description>ConnectionPool</description> <res-ref-name>jdbc/myOracle</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
- JSP 컨테이너에서 이 환경설정을 사용해서 드라이버에 연결한다
// import 주의 import javax.naming.*; import javax.sql.*; public class TempMemberDAO { private Connection getConnection() { Connection conn = null; try { Context init = new InitialContext(); DataSource ds = (DataSource) init.lookup("java:comp/env/jdbc/myOracle"); conn = ds.getConnection(); } catch(NamingException ne) { ne.printStackTrace(); } catch(SQLException se) { se.printStackTrace(); } return conn; } // DB에서 데이터 받아서 벡터에 저장 public Vector<TempMemberVO> getMemberList() { Connection conn = null; Statement stmt = null; ResultSet rs = null; Vector<TempMemberVO> vecList = new Vector<TempMemberVO>(); try { conn = getConnection(); String query = "select * from tempmember"; stmt = conn.createStatement(); rs = stmt.executeQuery(query); while(rs.next()) { TempMemberVO vo = new TempMemberVO(); vo.setId(rs.getString("id")); vo.setPasswd(rs.getString("passwd")); vo.setName(rs.getString("name")); vecList.add(vo); } } catch(Exception e) { System.out.println("Exception" + e); } finally { if(rs != null) try {rs.close();}catch(SQLException e){} if(stmt != null) try {stmt.close();}catch(SQLException e){} if(conn != null) try {conn.close();}catch(Exception e){} } return vecList; } }
- 커넥션 객체는 외부 API를 이용해서 생성되고 나머지 로직은 이전 예제와 같다
- 실행 모습
참고 자료
KG 아이티뱅크 강의 자료
처음해보는 JSP&Servlet 웹 프로그래밍