필요한 데이터
회원 : 조회 / 삽입 / 수정 / 삭제
MemberMgr => DAO역할
MemberBean => DTO
상품 : 조회 / 삽입 / 수정 / 삭제
ProductMg r=> DAO역할
ProductBean => DTO
주문 : 조회 / 삽입 / 수정 / 삭제
OrderMgr => DAO역할
OrderBean => DTO
장바구니 : 조회 / 삽입 / 수정 / 삭제
CartMgr => DAO역할
** 기존에 사용했던 방식(DAO,DTO 하나를 만들어서 이 안에 모든 코드를 넣는다.)대로 하게되면 코드양이 너무 길어진다. 그렇기에 각각의 클래스를 따로 만들어서 사용한다.
기존에 했던 쇼핑몰 프로젝트에 데이터베이스 연동을 시켰다.
오늘은 기존에 했던 방식(사용자 1명)과 달리 여러명의 사용자가 접속할 수 있도록 여러개의 커넥션 객체를 생성 하여 사용하는 방법으로 만들었다. => 서브 클래스를 만들어서 Connection객체와 그 객체의 사용여부를 저장
DBConnectionMgr (순서대로) -> 서브클래스를 만든다.
서브 클래스)
class ConnectionObject{
public Connection connection=null; //Connection 객체
public boolean inuse=false; // 사용여부
public ConnectionObject(Connection c, boolean useFlag) {
connection=c;
inuse=useFlag;
}
** 서브 클래스는 절대로 접근제한자를 가질 수 없다.
서브 클래스 -> Connection 객체와 그 객체의 사용여부를 저장할 수 있는 클래스 선언
.Connection / 자원해제
.Connection 객체를 미리 여러개를 만들어 놓고, 다수의 사용자가 접속했을때 사용되지 않는 Connection객체를 제공
.Connection 객체를 미리 여러개를 생성 => POOL
public class DBConnectionMgr_ {
private Vector<ConnectionObject> connections=new Vector<ConnectionObject>(10);
private String driver="oracle.jdbc.driver.OracleDriver";
private String url="jdbc:oracle:thin:@127.0.0.1:1521:XE";
private String id="dahoon226";
private String pw="ekgns00";
private boolean _traceOn=false; //사용가능 여부 확인
private boolean initialize=false; // 객체 초기화 여부 확인
private int _openConnections=50; // 최대 가능 개수
//DBConnectionMgr객체는 어플리케이션 내에서 단 하나만 존재할 수 있도록
private static DBConnectionMgr_ instance=null;
private DBConnectionMgr_() {
} //기본 생성자
여러개의 Connection 객체들을 담을 수 있도록 Vector를 생성 ( 또는 ArrayList ) 초기값 10개
불린 변수를 선언하여 Connection객체를 사용가능한지 확인하고 초기화가 되었는지 확인한다.
공유 Connection 메소드)
public static DBConnectionMgr_ getInstance() {
if(instance != null) {
instance = new DBConnectionMgr_();
}
return instance;
}
열려있는 Connection 객체 확인 메소드
/** 열려있는 Connection 객체의 수 **/
public void setOpenConnectionCount(int count) {
_openConnections=count;
}
전역변수로 최대 50개까지 열리도록 선언 되어있다.
사용가능한 Connection 객체가 있는지 확인
/** 사용가능여부 설정 **/
public void setEnablcTrace(boolean enable) {
_traceOn=enable;
}
Vector 객체 반환
/** Vector<ConnectionObject> connections를 반환 **/
public Vector<ConnectionObject> getConnections(){
return connections;
}
현재 열려있는 Connection 객체가 몇개인지 확인
/** 현재 열려있는 Connection객체 **/
public int getConnectionCount(){
return connections.size();
}
사용자 접속에 따라 새로운 Connection 객체 생성
/** 새로운 Connection 객체를 생성 **/
private Connection createConnection() {
Connection conn = null;
try {
if(id == null) {
id = "";
}
if(pw == null) {
pw = "";
}
//실무에서 자주 사용되는 방법
Properties props = new Properties();
props.put("user", id);
props.put("password", pw);
conn = DriverManager.getConnection(url,props);
} catch(SQLException e) {
System.err.println("CONNECT ERR "+e.getMessage());
}
return conn;
}
if문은 다른 사용자가 접속을 시도 할 때 null값이 아닌 ""으로 초기화 시키기 위한 조건문이다.
Properties 객체를 생성하여 계정과 비밀번호를 담아 Connection객체를 생성할 때 사용할 수 있다.
모든 Connection객체를 자원해제할 때
/** 모든 연결을 닫고(해제) 연결 pool(vector)내의 모든 내용을 삭제 **/
public void finalize() {
ConnectionObject conns = null;
for(int i=0;i<connections.size();i++) {
conns=(ConnectionObject)connections.elementAt(i);
try {
// Vector안의 ConnectionObject 내의 객체를 자원해제(close())
conns.connection.close();
} catch (SQLException e) {
System.err.println("자원해제 실패"+e.getMessage());
}
conns = null;
}
connections.removeAllElements(); // Vector안의 모든 객체를 제거
}
Vector에서 값을 꺼낼때는 Object타입으로 꺼내지기 때문에 타입 변환=>ConnectionObject
사용되지 않지만 연결이 되어있는 Connection객체 자원해제
/** 현재 사용되지 않지만 연결되어 있는 Connection 자원 해제 **/
public void releaseFreeConneciont() {
ConnectionObject conns = null;
for(int i=0;i<connections.size();i++) {
conns=(ConnectionObject)connections.elementAt(i);
if(conns.inuse) {
removeConnection(conns.connection);
}
}
}
사용되지 않는 Connection 객체 제거
/** 사용되지 않는 Connection 객체 제거 **/
public void removeConnection(Connection c) {
if(c == null) {
return;
}
ConnectionObject conns = null;
for(int i=0;i<connections.size();i++) {
conns=(ConnectionObject)connections.elementAt(i);
if(c == conns.connection) {
try {
c.close();
connections.removeElementAt(i);
}catch (SQLException e) {
System.err.println("CONNECTION REMOVE ERR "+e.getMessage());
}
break;
}
}
}
finally에 if문을 넣고 일일이 나열해서 자원해제를 하지않고 자원 해제 메소드를 따로 만들어 호출함으로써 간단하게 자원해제 시킬 수 있다.
/** PreparedStatement, Statement, ResultSet 다양한 자원 해제 메소드 (Overloading) **/
public void freeConnection(PreparedStatement pstmt, ResultSet rs) {
try {
if(rs != null) {
rs.close();
}
if(pstmt != null) {
pstmt.close();
}
}catch (SQLException e) {
System.err.println("PreparedStatement, ResultSet CLOSE ERR"+e.getMessage());
}
}
public void freeConnection(Statement stmt, ResultSet rs) {
try {
if(rs != null) {
rs.close();
}
if(stmt != null) {
stmt.close();
}
}catch (SQLException e) {
System.err.println("Statement, ResultSet CLOSE ERR"+e.getMessage());
}
}
public void freeConnection(PreparedStatement pstmt) {
try {
if(pstmt != null) {
pstmt.close();
}
}catch (SQLException e) {
System.err.println("PreparedStatement CLOSE ERR"+e.getMessage());
}
}
public void freeConnection(Statement stmt) {
try {
if(stmt != null) {
stmt.close();
}
}catch (SQLException e) {
System.err.println("Statement CLOSE ERR"+e.getMessage());
}
}
새로운(현재 사용하지 않거나) Connection 객체를 반환
public Connection getConnection() {
Connection conn=null;
ConnectionObject conns=null;
if(initialize) {
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, id,pw);
} catch (ClassNotFoundException e) {
System.err.println("NEW DRIVER ERR"+e.getMessage());
} catch(SQLException e) {
System.err.println("NEW CONN ERR"+e.getMessage());
}
//연결이 잘못되었을 경우 상태값 저장
boolean badConnection = false;
for(int i=0;i<connections.size();i++) {
conns = (ConnectionObject)connections.elementAt(i);
//연결이 유효한지 테스트
if(!conns.inuse) {
try {
badConnection=conns.connection.isClosed(); // 기존 Connection 객체가 닫혀있는지 확인
if(!badConnection) {
badConnection=(conns.connection.getWarnings() != null); //경고 발생
}
} catch(SQLException e) {
System.err.println(e.getMessage());
}
//잘못연결
if(badConnection) {
connections.removeElementAt(i);
continue;
}
conn=conns.connection;
conns.inuse=true;
break;
} // 연결이 유효한지 테스트
if(conn==null) {
conn=createConnection();
conns=new ConnectionObject(conn, true);
connections.addElement(conns);
}
}
}
return conn;
}
DB연결은 여기까지
DTO => 각 데이터 테이블에 해당하는 자바빈즈를 만들어 준다.
오늘 작업한 내용은 회원가입 부분이다.
기존에 회원가입 폼까지는 작성을 해둔 상태였고 오늘은 주소와 아이디 중복체크, 그리고 회원가입 완료시 데이터베이스에 해당 데이터가 추가되는 부분까지
회원가입 폼
아이디 체크 => idCheck 함수 호출
까지는 저번 시간에 했던 부분
우편번호에 zipCheck()함수 부분
기존 script.js에
function zipCheck(){
url="zipSearch.jsp?search=n";
window.open(url, "post", "width=500,height=300");
}
zipSearch.jsp에 search라는 파라미터명으로 값을 넘겨 준다.
zipSearch.jsp 코드가 좀 복잡하다...
회원가입 버튼을 누르게 되면 가입 하기전 입력한 데이터가 맞는지 확인하는 페이지로 이동하게 된다.
폼양식은 member.jsp (회원가입폼)을 사용하지만 값을 전달 받는 것이기 때문에 조금 달라진 부분이 있다.
회원가입 폼(member.jsp)에서 post방식으로 전달하기 때문에 먼저 인코딩을 해줘야한다.
회원가입에서 넘어온 값을 데이터베이스에 저장하기 위하여 자바빈즈를 임포트 시켜놓고
값을 넣어준다. => property="*" 사용하지않는 영역이 없기때문에 전체로 설정하여 값이 자리에 맞게 알아서 들어간다.
** 단, 데이터베이스 컬럼명, 빈즈 변수명, 파라미터명이 다 같아야 된다.
전달된 값을 꺼내기 위하여 value속성을 사용
** gender => <%=mBean.getGender().equals("1")?"cheked" : ""%>
넘어온 값에 맞게 체크
취미의 경우는 다중값선택 가능으로 배열로 선언 했기 때문에 배열로 선언
회원가입 폼에서 틀린 값이 없으면 가입이 완료되면서 데이터베이스 값이 저장되고
아니라면 다시 입력해야한다.
수업시간에 이해를 못하고 코드만 따라 쳤더니
오류가 발생했을때 해결하는데 시간이 좀 걸렸다
블로그로 한번 더 정리하면서 이해할려고 했는데 코드 양도 그렇고 페이지도 많이 나눠져서 어떻게 정리를 해야할지 모르겠다..
정리하면서 조금 이해 되긴 했지만 완전히 내걸로 만든게 아니여서 걱정이다..
기사 시험도 다음주에 있고 세미 프로젝트도 해야하는데 큼...
'Learn > KH정보교육원' 카테고리의 다른 글
[KH정보교육원 당산] 44일차 (파일 업로드) (0) | 2021.05.11 |
---|---|
[KH정보교육원 당산] 42일차 (쇼핑몰 - 주문) (0) | 2021.05.07 |
[KH정보교육원 당산] 40일차(CSS 연습) (0) | 2021.05.04 |
[KH정보교육원 당산] 39일차(UI시작-HTML,CSS) (0) | 2021.05.03 |
[KH정보교육원 당산] 38일차(휴강..) (0) | 2021.05.03 |