데이터 베이스의 중복을 최소화 시켜줄 수 있는 DAO/DTO/DBCP에 대해 알아보자.


◆ DAO (Data Access Object)

데이터 베이스에 접속해서 데이터 추가/삭제/수정 등의 작업을 하는 클래스.
즉, DB작업을 코드의 모듈화를 통해 사용(중복방지)
데이터의 작업은 메서드 단위로 실행하여 연결과 해제 또한 메서드 내부에서 한다.

public class MemberDAO {
	private String url = "jdbc:oracle:thin:@localhost:1521:xe";
	private String uid = "아이디";
	private String pwd = "비밀번호";
    
    // 객체 생성  class.forName()작업
	public MemberDAO() {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
    
    // select * 작업을 해주는 메서드
	public ArrayList<MemberDTO> memberSelect() {
		ArrayList<MemberDTO> dtos = new ArrayList<MemberDTO>();

		Connection con = null;
		Statement state = null;
		ResultSet rs = null;

		try {
			con = DriverManager.getConnection(url, uid, pwd);
			state = con.createStatement();
			rs = state.executeQuery("select * from member");

			while (rs.next()) {
				String id = rs.getString("id");
				String pw = rs.getString("pw");
				String name = rs.getString("name");
				String phone = rs.getString("phone");

				MemberDTO dto = new MemberDTO(id, pw, name, phone);
				dtos.add(dto);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (con != null)
					con.close();
				if (state != null)
					state.close();
				if (rs != null)
					rs.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return dtos;
	}

}


◆ DTO (Data Transfer Object)

DAO클래스를 이용하여 데이터를 일반 변수에 할당하는 것이 아닌 클래스화 하여 사용하는 객체.
( DTO를 사용하지 않고, Map객체를 사용해도 무방하다 )

public class MemberDTO {
	private String id;
	private String pw;
	private String name;
	private String phone;
	
	public MemberDTO(String id, String pw, String name, String phone) {
		super();
		this.id = id;
		this.pw = pw;
		this.name = name;
		this.phone = phone;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPw() {
		return pw;
	}

	public void setPw(String pw) {
		this.pw = pw;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}
	
}


▶ DAO/DTO 사용

위에서 만든 DAO와 DTO클래스를 활용하여 데이터베이스 작업을 해보자.

<%
	MemberDAO md = new MemberDAO();
	ArrayList<MemberDTO> dtos = md.memberSelect(); // DB와연결하여 select* 반환
	
	for(MemberDTO dt: dtos){
		String id = dt.getId();
		String pw = dt.getPw();
		String name = dt.getName();
		String phone = dt.getPhone();
		out.println("아이디: " + id + "/ 비밀번호 : " + pw + "/ 이름: " + name + "/ 번호: " + phone + "<br/>");
	}
%>


◆ 커텍션풀 (Data Base Connection Pool)

클라이언트의 다수 요청 발생 시 부하를 방지하기 위해 Connection객체를 미리 설정해 두고, 뽑아오는 방식


1. Server디렉터리에 context.xml에 아래와 같이 선언해 둔다.

프로젝트가 아닌 Server디렉터리에 미리 선언해 두는 것이다.

<Resource 
    	auth="Container"
    	driverClassName="oracle.jdbc.driver.OracleDriver"
    	url="jdbc:oracle:thin:@localhost:1521:xe"
    	username="DB계정"
    	password="비밀번호"
    	name="jdbc/Oracle11g"
    	type="javax.sql.DataSource"
    	maxActive="50"
    	maxWait="1000"
/>


2. 커넥션 객체 불러오기

2-1 new InitialContext()를 통해 Context객체를 생성

Context context = new InitialContext();


2-2 Context객체의 lookup(“java:comp/env/jdbc/Oracle11g”)를 DataSource객체로 캐스팅하여 반환

DataSource dataSource = (DataSource)context.lookup("java:comp/env/jdbc/Oralce11g");


2-3 DataSource객체의 getConnection() 메서드를 통해 커넥션 객체를 뽑아낼 수 있다.

Connection conn = dataSource.getConnection();


▶ 위에서 예시로 든 DAO객체를 DBCP를 이용한 방법으로 수정해 보자.

public class MemberDAO {
//private String url = "jdbc:oracle:thin:@localhost:1521:xe";
//private String uid = "gunbin";
//private String pwd = "1234";
	
	// 0. DataSource객체 선언
	private DataSource dataSource;

	public MemberDAO() {
//try {
//	Class.forName("oracle.jdbc.driver.OracleDriver");
//} catch (Exception e) {
//	e.printStackTrace();
//}
		
		// 1. New InitialContex() Context객체 생성
		// 2. Context객체의 lookup메서드로 DataSource객체 생성
		try {
			Context context = new InitialContext();
			dataSource = (DataSource)context.lookup("java:comp/env/jdbc/Oracle11g");
		}catch (Exception e) {
			e.printStackTrace();
		}
	}

	public ArrayList<MemberDTO> memberSelect() {
		ArrayList<MemberDTO> dtos = new ArrayList<MemberDTO>();

		Connection con = null;
		Statement state = null;
		ResultSet rs = null;

		try {
//con = DriverManager.getConnection(url, uid, pwd);
		// DataSource객체의 getConnection()메서드로 커넥션 객체 뽑기
			con = dataSource.getConnection();
			state = con.createStatement();
			rs = state.executeQuery("select * from member");

			while (rs.next()) {
				String id = rs.getString("id");
				String pw = rs.getString("pw");
				String name = rs.getString("name");
				String phone = rs.getString("phone");

				MemberDTO dto = new MemberDTO(id, pw, name, phone);
				dtos.add(dto);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (con != null)
					con.close();
				if (state != null)
					state.close();
				if (rs != null)
					rs.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return dtos;
	}

}