-
003. Singleton(싱글톤) 패턴으로 DB연결 + DAO/DTO 클래스로 문제 해결SsY/Class 2023. 4. 24. 17:50728x90
JDBC02
- DBConn
- 싱글톤 패턴 적용하여 계속 사용할 접속 객체 만들기
/*======================= DBConn.java - 예외 처리 throws ========================*/ package com.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class DBConn { private static Connection dbConn; // 주소, 계정, 비번 고정 연결 메소드 public static Connection getConnection() throws ClassNotFoundException, SQLException { if (dbConn == null) { String url = "jdbc:oracle:thin:@localhost:1521:xe"; String user = "scott"; String pwd = "tiger"; Class.forName("oracle.jdbc.driver.OracleDriver"); dbConn = DriverManager.getConnection(url, user, pwd); } return dbConn; } // 메소드 오버로딩 - 주소, 계정, 비번 받아와서 연결하게 함 public static Connection getConnection(String url, String user, String pwd) throws ClassNotFoundException, SQLException { if (dbConn == null) { Class.forName("oracle.jdbc.driver.OracleDriver"); dbConn = DriverManager.getConnection(url, user, pwd); } return dbConn; } public static void close() throws SQLException { if (dbConn != null) { // 쓰레드 처리 등으로 혹시라도 Connection 이 남아있거나 할 수 있는 상황을 한 번 더 확인 // 닫혀있으면 -> true , 열려있으면 -> false // 그래서 앞에 ! (not)을 붙여주어 닫혀있지 않으면 close 하라는 것 if (!dbConn.isClosed()) dbConn.close(); } dbConn = null; // 해당 메소드에서 가장 중요 } }
- Test005
- DBConn 연결 테스트
package com.test; import java.sql.Connection; import com.util.DBConn; public class Test005 { public static void main(String[] args) { try { Connection conn = DBConn.getConnection(); if (conn == null) { System.out.println("데이터베이스 연결 실패~!!!"); } else { System.out.println("데이터베이스 연결 성공~!!!"); } } catch (Exception e) { System.out.println(e.toString()); } finally { try { DBConn.close();; } catch (Exception e) { System.out.println(e.toString()); } } } }
SQL DEVELOPER
SELECT USER FROM DUAL; --==>> SCOTT --○ 실습 테이블 생성(TBL_MEMBER) CREATE TABLE TBL_MEMBER ( SID NUMBER , NAME VARCHAR2(30) , TEL VARCHAR2(40) , CONSTRAINT MEMBER_SID_PK PRIMARY KEY(SID) ); --==>> Table TBL_MEMBER이(가) 생성되었습니다. --○ 데이터 입력 쿼리문 구성 INSERT INTO TBL_MEMBER(SID,NAME,TEL) VALUES(1,'별희강','010-1111-1111') ; --==>> 1 행 이(가) 삽입되었습니다. --○ 확인 SELECT * FROM TBL_MEMBER; --==>> 1 별희강 010-1111-1111 --○ 커밋 COMMIT; --==>> 커밋 완료. --○ 리스트 조회 쿼리문 구성 SELECT SID, NAME, TEL FROM TBL_MEMBER ORDER BY 1; --> 한 줄 구성 SELECT SID, NAME, TEL FROM TBL_MEMBER ORDER BY 1 ; --==>> /* 1 별희강 010-1111-1111 2 수인주 010-2222-2222 3 기배리 010-3333-3333 4 하경최 010-4444-4444 */ --○ 인원 수 확인 쿼리문 구성 SELECT COUNT(*) AS COUNT FROM TBL_MEMBER; --> 한 줄 구성 SELECT COUNT(*) AS COUNT FROM TBL_MEMBER ; --==>> 4 SELECT MAX(SID) AS MAXSID FROM TBL_MEMBER; --○ 시퀀스 생성 CREATE SEQUENCE MEMBERSEQ NOCACHE; --==>> Sequence MEMBERSEQ이(가) 생성되었습니다. --○ 테이블 잘라내기 TRUNCATE TABLE TBL_MEMBER; --==>> Table TBL_MEMBER이(가) 잘렸습니다. --○ 확인 SELECT * FROM TBL_MEMBER; --==>> 조회 결과 없음 --○ 시퀀스를 활용한 데이터 입력 쿼리문 구성 INSERT INTO TBL_MEMBER(SID,NAME,TEL) VALUES(MEMBERSEQ.NEXTVAL, '별희강', '010-1111-1111'); --> 한 줄 구성 INSERT INTO TBL_MEMBER(SID,NAME,TEL) VALUES(MEMBERSEQ.NEXTVAL, '별희강', '010-1111-1111') ; --==>> 1 행 이(가) 삽입되었습니다. SELECT * FROM TBL_MEMBER; --==>> 1 별희강 010-1111-1111 COMMIT; --==>> 커밋 완료.
Eclipse
- MemberDTO
- getter / setter 구성
더보기수동으로 구성한 것
/*=================== MemberDTO.java =================== */ // DTO : 계란 한 판을 옮기기 위해서 쓰는 계란판(30구) 틀 같은 느낌 package com.test; public class MemberDTO { // 주요 속성 구성 private String sid, name, tel; public String getSid() { return sid; } public void setSid(String sid) { this.sid = sid; } }
/*=================== MemberDTO.java =================== */ // DTO : 계란 한 판을 옮기기 위해서 쓰는 계란판(30구) 틀 같은 느낌 package com.test; public class MemberDTO { // 주요 속성 구성 private String sid, name, tel; public String getSid() { return sid; } public void setSid(String sid) { this.sid = sid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getTel() { return tel; } public void setTel(String tel) { this.tel = tel; } }
- MemberDAO
/*============================= MemberDAO.java - DB 액션 처리 전담 객체 ==============================*/ // 데이터베이스에 엑세스 하는 기능 // → DBConn 활용(전담 계층) // 데이터를 입력하는 기능 → insert // 인원 수 확인하는 기능 // 즉, 대상 테이블(TBL_MEMBER)의 레코드 카운팅 기능 → select // 전체 리스트 조회하는 기능 // 즉, 대상 테이블(TBL_MEMBER)의 데이터를 조회하는 기능 → select package com.test; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import com.util.DBConn; public class MemberDAO { // 주요 속성 구성 private Connection conn; // 생성자 정의 (사용자 정의 생성자) public MemberDAO() throws ClassNotFoundException, SQLException // getConnection 의 예외처리 { conn = DBConn.getConnection(); } // 메소드 정의 → 데이터를 입력하는 기능 → insert public int add(MemberDTO dto) throws SQLException { /*====================================================================================================== // 반환할 결과값을 담아낼 변수(적용된 행의 갯수) int result = 0; // 작업 객체 생성 Statement stmt = conn.createStatement(); // 쿼리문 준비(→insert 쿼리문 구성) String sql = String.format("INSERT INTO TBL_MEMBER(SID,NAME,TEL)" + "VALUES(MEMBERSEQ.NEXTVAL, '%s', '%s')", dto.getName(), dto.getTel()); // 작업 객체를 활용하여 쿼리문 실행(전달) result = stmt.executeUpdate(sql); // 사용한 리소스 반납 stmt.close(); // 최종 결과값 반환 return result; ======================================================================================================*/ int result = 0; Statement stmt = conn.createStatement(); String sql = String.format("INSERT INTO TBL_MEMBER(SID,NAME,TEL)" + "VALUES(MEMBERSEQ.NEXTVAL, '%s', '%s')", dto.getName(), dto.getTel()); result = stmt.executeUpdate(sql); stmt.close(); return result; } // 메소드 정의 → 전체 인원 수를 확인하는 기능 → select public int count() throws SQLException { /*====================================================================================================================================== // 결과값으로 반환하게 될 변수 선언 및 초기화 int result = 0; // 작업 객체 생성 Statement stmt = conn.createStatement(); // 쿼리문 준비(→select 쿼리문 구성) String sql = "SELECT COUNT(*) AS COUNT FROM TBL_MEMBER"; // 생성된 작업 객체를 활용하여 쿼리문 실행 → select → executeQuery() → ResultSet 반환 → 일반적으로 반복문 구성을 통한 ResultSet 처리 ResultSet rs = stmt.excuteQuery(sql); // ResultSet 처리 → 반복문 구성 → 결과값 수신 while( rs.next()) // if(rs.next()) -- 단일 값이기 때문에 대체 가능 { result = rs.getInt("COUNT"); // rs.getInt(1); // ※ 컬럼 인덱스는 1 부터... } // 사용한 리소스 반납 //-- 반납 순서 주의 (분해는 조립의 역순) rs.close(); stmt.close(); // 최종 결과값 반환 return result; =======================================================================================================================================*/ int result = 0; Statement stmt = conn.createStatement(); String sql = "SELECT COUNT(*) AS COUNT FROM TBL_MEMBER"; ResultSet rs = stmt.executeQuery(sql); while( rs.next()) { result = rs.getInt("COUNT"); } rs.close(); stmt.close(); return result; } // 메소드 정의 → 전체 리스트를 조회하는 기능 → select public ArrayList<MemberDTO> lists() throws SQLException // ★ 자료구조 파악 ★ { /*========================================================================================= // 결과값으로 반환할 변수 선언 및 초기화 ArrayList<MemberDTO> result = new ArrayList<MemberDTO>(); // 작업 객체 생성 Statement stmt = conn.createStatement(); // 쿼리문 준비(→select 쿼리문 구성) String sql = "SELECT SID, NAME, TEL FROM TBL_MEMBER ORDER BY SID"; // 생성된 작업 객체를 활용하여 쿼리문 실행 → select → executeQuery() → ResultSet 반환 ResultSet rs = stmt.excuteQuery(sql); //-- MemberDTO들 을 반환해야한다!! // ResultSet 처리 → 일반적 반복문 활용 while( rs.next()) { // MemberDTO 인스턴스 생성 MemberDTO dto = new MemberDTO(); dto.setSid(rs.getString("SID")); dto.setName(rs.getString("NAME")); dto.setTel(rs.getString("TEL")); result.add(dto); } // 사용한 리소스 반납 rs.close(); stmt.close(); // 최종 결과값 반환 return result; =============================================================================================*/ ArrayList<MemberDTO> result = new ArrayList<MemberDTO>(); Statement stmt = conn.createStatement(); String sql = "SELECT SID, NAME, TEL FROM TBL_MEMBER ORDER BY 1"; ResultSet rs = stmt.executeQuery(sql); while( rs.next()) { MemberDTO dto = new MemberDTO(); dto.setSid(rs.getString("SID")); dto.setName(rs.getString("NAME")); dto.setTel(rs.getString("TEL")); result.add(dto); } rs.close(); stmt.close(); return result; }// end lists() }// end class MemberDAO
- MemberMain
/*======================= MemberMain.java ========================*/ /* ○ TBL_MEMBER 테이블을 활용하여 이름과 전화번호를 여러 건 입력받고, 전체 출력하는 프로그램을 구현한다. 단, 데이터베이스 연동이 이루어져야 하고, MemberDAO, MemberDTO 클래스를 활용해야 한다. 실행 예) 이름 전화번호 입력(5) : 이서최 010-5555-5555 >> 회원 정보 입력 완료~!!! 이름 전화번호 입력(6) : 희정권 010-6666-6666 >> 회원 정보 입력 완료~!!! 이름 전화번호 입력(7) : . ---------------------------------- 전체 회원 수 : 6명 ---------------------------------- 번호 이름 전화번호 1 별희강 010-1111-1111 2 수인주 010-2222-2222 3 기배리 010-3333-3333 4 하경최 010-4444-4444 5 이서최 010-5555-5555 6 희정권 010-6666-6666 ---------------------------------- */ package com.test; //import java.sql.SQLException; import java.util.ArrayList; import java.util.Scanner; import com.util.DBConn; public class MemberMain { public static void main(String[] args) //throws SQLException, ClassNotFoundException { Scanner sc = new Scanner(System.in); try { // count() 사용 위해서 인스턴스 생성 MemberDAO dao = new MemberDAO(); // count 값 변수에 담기 int count = dao.count(); // 테스트 // System.out.println("count : " + count); do { System.out.printf("이름 전화번호 입력(%d) : ", ++count); // 수인주 010-2222-2222 String name = sc.next(); // 수인주 // 반복의 조건을 무너뜨리는 코드 구성 if (name.equals(".")) break; String tel = sc.next(); // 010-2222-2222 // 테스트 //System.out.println("name : " + name + " & tel : " + tel); // ※ 여기까지의 과정을 통해 사용자로부터 이름과 전화번호를 입력 받은 이유는 // 입력받은 데이터를 데이터베이스의 TBL_MEMBER 테이블에 저장하기 위함 // 데이터 입력을 위해서는 MemberDAO(dao) 의 add() 메소드 호출 필요 // add() 메소드를 호출하기 위해서는 MemberDTO 를 넘겨주는 과정이 필요 // MemberDTO 를 넘겨주기 위해서는 이 객체의 속성값 구성 필요 // MemberDTO 객체 생성 MemberDTO dto = new MemberDTO(); // 속성값 구성 dto.setName(name); dto.setTel(tel); // 데이터베이스 TBL_MEMBER 테이블에 데이터를 입력하는 메소드 호출 → add() int result = dao.add(dto); if (result>0) System.out.println(">> 회원 정보 입력 완료~!!!"); } while (true); System.out.println(); System.out.println("-------------------------------------"); System.out.printf("전체 회원 수 : %d명\n", dao.count()); System.out.println("-------------------------------------"); System.out.println("번호 이름 전화번호"); // 리스트 가져와서 출력 // dao.lists(); -- 자료구조이기 때문에 바로 출력은 불가~ for (MemberDTO obj : dao.lists()) { System.out.printf("%3s %7s %12s\n", obj.getSid(), obj.getName(), obj.getTel()); } System.out.println("-------------------------------------"); } catch (Exception e) { System.out.println(e.toString()); } finally { try { DBConn.close(); System.out.println(">> 데이터베이스 연결 닫힘~!!!"); System.out.println(">> 프로그램 종료 됨~!!!"); } catch (Exception e) { System.out.println(e.toString()); } } } } // 실행결과 /* 이름 전화번호 입력(2) : 수인주 010-2222-2222 >> 회원 정보 입력 완료~!!! 이름 전화번호 입력(3) : 기배리 010-3333-3333 >> 회원 정보 입력 완료~!!! 이름 전화번호 입력(4) : 하경최 010-4444-4444 >> 회원 정보 입력 완료~!!! 이름 전화번호 입력(5) : . ------------------------------------- 전체 회원 수 : 4명 ------------------------------------- 번호 이름 전화번호 1 별희강 010-1111-1111 2 수인주 010-2222-2222 3 기배리 010-3333-3333 4 하경최 010-4444-4444 ------------------------------------- >> 데이터베이스 연결 닫힘~!!! >> 프로그램 종료 됨~!!! */
복사하고자 하는 줄에서 Ctrl + Alt + 방향키(↓) 로 아래로 똑같은 줄 복사 가능
JDBC03
SQL DEVELOPER
- 실습 테이블 , 시퀀스 생성
SELECT USER FROM DUAL; --==>> SCOTT --○ 실습 테이블 생성 CREATE TABLE TBL_SCORE ( SID NUMBER , NAME VARCHAR2(30) , KOR NUMBER(3) , ENG NUMBER(3) , MAT NUMBER(3) ); --==>> Table TBL_SCORE이(가) 생성되었습니다. --○ 제약조건 추가(SID 컬럼에 PK 제약조건 추가) ALTER TABLE TBL_SCORE ADD CONSTRAINT SCORE_SID_PK PRIMARY KEY(SID); --==>> Table TBL_SCORE이(가) 변경되었습니다. --○ 제약조건 추가(KOR,ENG,MAT 컬럼에 CK 제약조건 추가) ALTER TABLE TBL_SCORE ADD (CONSTRAINT SCORE_KOR_CK CHECK (KOR BETWEEN 0 AND 100) ,CONSTRAINT SCORE_ENG_CK CHECK (ENG BETWEEN 0 AND 100) ,CONSTRAINT SCORE_MAT_CK CHECK (MAT BETWEEN 0 AND 100)); --==>> Table TBL_SCORE이(가) 변경되었습니다. --○ 시퀀스 생성 CREATE SEQUENCE SCORESEQ NOCACHE; --==>> Sequence SCORESEQ이(가) 생성되었습니다.
Eclipse
- DBConn
/*======================= DBConn.java - try ~ catch ========================*/ package com.util; import java.sql.Connection; import java.sql.DriverManager; public class DBConn { private static Connection dbConn; public static Connection getConnection() { try { if (dbConn == null) { String url = "jdbc:oracle:thin:@localhost:1521:xe"; String user = "scott"; String pwd = "tiger"; Class.forName("oracle.jdbc.driver.OracleDriver"); dbConn = DriverManager.getConnection(url, user, pwd); } return dbConn; } catch (Exception e) { System.out.println(e.toString()); } return dbConn; } public static Connection getConnection(String url, String user, String pwd) { try { if (dbConn == null) { Class.forName("oracle.jdbc.driver.OracleDriver"); dbConn = DriverManager.getConnection(url, user, pwd); } } catch (Exception e) { System.out.println(e.toString()); } return dbConn; } public static void close() { try { if (dbConn != null) { if (!dbConn.isClosed()) dbConn.close(); } } catch (Exception e) { System.out.println(e.toString()); } dbConn = null; } }
/* ○ 성적 처리 프로그램 구현 → 데이터베이스 연동 → ScoreDTO, ScoreDAO 클래스 활용 여러 명의 이름, 국어점수, 영어점수, 수학점수를 입력받아 총점, 평균을 연산하여 내용을 출력하는 프로그램을 구현한다. 출력 시 번호 오름차순 정렬하여 출력한다. 실행 예) 1번 학생 성적 입력(이름 국어 영어 수학) : 수현양 90 75 80 2번 학생 성적 입력(이름 국어 영어 수학) : 준복이 100 90 80 3번 학생 성적 입력(이름 국어 영어 수학) : 상훈문 80 65 70 4번 학생 성적 입력(이름 국어 영어 수학) : . ---------------------------------------------------------- 번호 이름 국어 영어 수학 총점 평균 ---------------------------------------------------------- 1 수현양 90 75 80 xxx xx.x 2 준복이 100 90 80 xxx xx.x 3 상훈문 80 65 70 xxx xx.x ---------------------------------------------------------- */
- ScoreMain
/*======================= ScoreMain.java ========================*/ package com.test; import java.util.Scanner; import com.util.DBConn; public class ScoreMain { public static void main(String[] args) { // ScoreDAO 인스턴스 생성 ScoreDAO dao = new ScoreDAO(); // Scanner 인스턴스 생성 Scanner sc = new Scanner(System.in); int count = dao.count(); do { System.out.printf("%d번 학생 성적 입력(이름 국어 영어 수학) : ", ++count); String name = sc.next(); if (name.equals(".")) // 입력된 값이 "." 일 때 반복문 빠져나감 break; String kor = sc.next(); String eng = sc.next(); String mat = sc.next(); // ScoreDTO 새 객체 생성 ScoreDTO dto = new ScoreDTO(); // dto 에 속성 값 담아주기 dto.setName(name); dto.setKor(kor); dto.setEng(eng); dto.setMat(mat); // 담은 값 add 해주는 메소드 dao.add(dto); } while (true); System.out.println(); System.out.println("----------------------------------------------------------"); System.out.println("번호 이름 국어 영어 수학 총점 평균"); System.out.println("----------------------------------------------------------"); // list 출력 for (ScoreDTO obj : dao.lists()) { System.out.printf("%-8s%-6s%4s%8s%8s%8s%8s\n" ,obj.getSid(),obj.getName(),obj.getKor(),obj.getEng(),obj.getMat(),obj.getTot(),obj.getAvg()); } System.out.println("----------------------------------------------------------"); // DB 연결 종료 DBConn.close(); System.out.println("프로그램이 종료됩니다."); }// end main() } // 실행 결과 /* ---------------------------------------------------------- 번호 이름 국어 영어 수학 총점 평균 ---------------------------------------------------------- 1 수현양 90 75 80 245 81.6 2 준복이 100 90 80 270 90 3 상훈문 80 65 70 215 71.6 4 인수주 100 100 100 300 100 ---------------------------------------------------------- 프로그램이 종료됩니다. */
- ScoreDTO
- Getter / Setter 구성
더보기package com.test; public class ScoreDTO { private String sid, name, kor, eng, mat, tot, avg; public String getSid() { return sid; } public void setSid(String sid) { this.sid = sid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getKor() { return kor; } public void setKor(String kor) { this.kor = kor; } public String getEng() { return eng; } public void setEng(String eng) { this.eng = eng; } public String getMat() { return mat; } public void setMat(String mat) { this.mat = mat; } public String getTot() { return tot; } public void setTot(String tot) { this.tot = tot; } public String getAvg() { return avg; } public void setAvg(String avg) { this.avg = avg; } }
- ScoreDAO
- DB 객체 연결 전담
package com.test; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.util.ArrayList; import com.util.DBConn; public class ScoreDAO { private Connection conn; // 생성자 정의 → DB 연결 public ScoreDAO() { conn = DBConn.getConnection(); } // 메소드 정의 → 데이터를 입력하는 기능 public void add(ScoreDTO dto) { // 변수 선언 try { // 작업 객체 생성 Statement stmt = conn.createStatement(); // 쿼리문 준비 String sql = String.format("INSERT INTO TBL_SCORE(SID, NAME, KOR, ENG, MAT) VALUES(SCORESEQ.NEXTVAL, '%s', %s, %s, %s)" , dto.getName(), dto.getKor(), dto.getEng(), dto.getMat()); // 쿼리문 실행 stmt.executeUpdate(sql); // 객체 반납 stmt.close(); } catch (Exception e) { System.out.println(e.toString()); } } // end add() // 메소드 정의 → 전체 인원 수를 확인하는 기능 public int count() { // 변수 선언 int result = 0; try { // 작업 객체 생성 Statement stmt = conn.createStatement(); // 쿼리문 준비 String sql = "SELECT COUNT(*) FROM TBL_SCORE"; // 쿼리문 실행 ResultSet rs = stmt.executeQuery(sql); // 쿼리문 결과 ResultSet 반복문 처리 while (rs.next()) { result = rs.getInt("COUNT(*)"); } // 객체 반납 rs.close(); stmt.close(); } catch (Exception e) { System.out.println(e.toString()); } // 최종 결과 반환 return result; }// end count() // 메소드 정의 → 전체 리스트를 조회/확인하는 기능 public ArrayList<ScoreDTO> lists() { //변수 선언 및 초기화 ArrayList<ScoreDTO> result = new ArrayList<ScoreDTO>(); try { // 작업 객체 생성 Statement stmt = conn.createStatement(); // 쿼리문 준비 String sql = "SELECT SID, NAME , KOR, ENG, MAT, (KOR+ENG+MAT) AS TOT, TRUNC((KOR+ENG+MAT)/3,1) AS AVG FROM TBL_SCORE"; // 쿼리문 실행 ResultSet rs = stmt.executeQuery(sql); // 쿼리문 결과 ResultSet 반복문 처리 while(rs.next()) { ScoreDTO dto = new ScoreDTO(); dto.setSid(rs.getString("SID")); dto.setName(rs.getString("NAME")); dto.setKor(rs.getString("KOR")); dto.setEng(rs.getString("ENG")); dto.setMat(rs.getString("MAT")); dto.setTot(rs.getString("TOT")); dto.setAvg(rs.getString("AVG")); result.add(dto); } // 객체 반납 rs.close(); stmt.close(); } catch (Exception e) { System.out.println(e.toString()); } return result; // 최종 결과 반환 }// end lists() }//end Class ScoreDAO
728x90'SsY > Class' 카테고리의 다른 글
005. DB 연동 직원 관리 프로그램 구현 (DTO, DAO, PROCESS, MAIN) (0) 2023.04.27 004. DAO/DTO/VO 개념, 성적 처리 → 데이터베이스 연동(데이터베이스 연결 및 액션 처리) (0) 2023.04.25 002. JDBC 사전 설정, JDBC 프로그래밍 절차, Eclipse 사용법 (0) 2023.04.21 001. Eclipse 설치 및 JDBC 개념 (2) 2023.04.20 016. [PL/SQL] TRIGGER(트리거)_(:OLD/:NEW), PACKAGE(패키지) (0) 2023.04.12 - DBConn