Everything has an expiration date
JDBC 20231120 [프로그래밍 소스] DBConn, DBConnBackup, Test001 ~ Test004 본문
[JDBC]/Program source (JDBC)
JDBC 20231120 [프로그래밍 소스] DBConn, DBConnBackup, Test001 ~ Test004
Jelly-fish 2023. 11. 20. 17:01JDBC01 - [Package] com.util
DBConn.java
/*============================
DBConn.java
==============================*/
// ※ 싱글톤(singleton) 디자인 패턴을 이용한 Database 연결 객체 생성 전용 클래스
// → DB 연결 과정이 부하가 매우 크기 때문에
// 한 번 연결된 객체를 계속 사용하는 것이 좋지 않을까...
// ⓒ : Class
// ⓘ : Interface
// 변수를 선언만 하고 사용하지 않았을 경우 노란색 밑줄이 그어진다.
/*
// Unhandled exception type ClassNotFoundException
// format() 메소드가 ClassNotFoundException을 throws 하고 있는데, 이를 처리하지 않았어!
// quiks : Addthrows declaration ---> [예외 던지기]
// : Surround with try/catch ---> [try~catch문으로 에러 잡기]
*/
/*
처음에 게임을 구동할 때 Database와 연결하는 과정에서
트래픽이 굉장히 많이 발생한다. (리소스 소모가 심하다!)
[ Ex) 문을 열고 화장실 가기]-------------------------------------------
미리 열쇠를 만들어 놓지 않았다면, 열쇠를 만들기 위한 광물부터 캔다...
그걸 제련하고, 두드리고, 열쇠 모양으로 만들어서 화장실 이용.
열쇠가 필요할 때마다 만들고 사용한 후 버린다면 이 과정을 계속 반복
이러면...... 안 되겠죠. 되게 비효율적일 거 아닙니까!
한번 열쇠를 만들고 문 앞에 매달아두는게 낫겠죠!
필요할 때마다 만들어진 열쇠를 계속 이용하도록.
-----------------------------------------------------------------------
*************************************************
★ 이렇게 열쇠 계속 만들지 말고
DB를 연결해주는 아이를 만들고 이를 이용하자
▶【그것이 DBConn~!!!!!!!!!!!!】
-->> 이것이 바로 Singleton 기법~!!
**************************************************
디자인 패턴 : 특정한 무늬나 색상이 규칙적으로 반복되는 것.
어떤 무늬가 교차해서 나오느냐!
★ 개발 분야의 디자인 패턴 : 시각적 무늬 X
◎【디자인 패턴】 : 내가 어떤 목적을 갖고 어떤 기능을 갖는 프로그램을 만드려 했을 때
어떤 계층구조를 갖도록 설계해야하는지가 공식처럼 만들어 진 것을 의미한다.
○ 알고리즘 (Algorithm) : '코드 레벨'에서의 설계
○ 디자인 패턴 : '계층 구조'에서의 설계를 어떻게 가져가면 좋을지에 대한 공식을 의미한다.
객체의 현재 상태에 따라
특정 동작을 시행했을 때
상태를 변환시키거나 다른 행동을 취할 수 있게 허가하는 패턴
디자인 패턴이란 기존
환경 내에서 반복적으로 일어나는 문제들을
어떻게 풀어나갈 것인가에 대한 일종의 솔루션
*/
// static : ⓐ 탄생시점, ★ⓑ『공유』
//---------------------------------------------------------------------------
// [ip 분할] Subnetting : 관리자가 편리하게 하기 위해 네트워크를 나누는 것
// ip를 나누게 되는 순간 양 끝을 쓰지 못하게 된다.
// Loop back ○■■[IP]■■○ Broadcast
// 나 자신이 나 자신을 호출해 본다. 통신이 안 될 때 내 잘못인지 알기 위해
// 내가 내 거 지칭! (local host)
// --==> 【Loop back address】 : 127.으로 시작하는 IP! (= localhost)
// 네트워크의 인원이 10명이 있다하면, 10명 모두에게 방송을 하는 것
// --==> 【Broadcast】
// 1521 : pot 번호
// 고유한 sid 부여하여 하나의 소통채널, 어떤 식별과정 통해서 접근해야 하나
// 『xe : Express Edition』
//---------------------------------------------------------------------------
// ▤▤▤▤▤[최대한 빨리 암기~!!!]▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤
package com.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
// ojdbc6.jar 파일을 연계해놨기 때문에 가능
public class DBConn
{
// 변수 선언 (연결 객체)
private static Connection dbConn; //-->> Connection type 변수 선언
// 메소드 정의 → 연결
public static Connection getConnection() throws ClassNotFoundException, SQLException
{
// 메소드 호출하면 연결 객체(Connection)를 넘겨주게끔 구성한 메소드
// * 열쇠가 만들어져 있지 않으면(dbConn == null) 새롭게 생성.
// 한 번 연결해서 얻어온 객체를 다시 쓰도록 한 것. 계속 새롭게 DB연결 안 하기 위해.
// ⓐ 기존에 만들어놓은 연결 객체가 존재하지 않을 경우에만
// ⓐ DB 연결 객체 생성
// 한 번 연결된 객체를 계속해서 사용
// 즉, 연결되지 않은 경우에만 연결을 시도하겠다는 의미
// → 싱글톤 (디자인 패턴)
if (dbConn == null)
{
// localhost : 대상 오라클 서버가 무엇인지 지정하는 코드
String url = "jdbc:oracle:thin:@localhost:1521:xe";
//-- 『localhost』는 오라클 서버의 ip 주소를 기재하는 부분
// "jdbc:oracle:thin:@211.238.142.164:1521:xe"
// "jdbc:oracle:thin:@127.0.0.164:1521:xe"
//-- 『1521』은 오라클 리스너 Port Number
//-- 『xe』는 오라클 SID (Express Edition 의 SID는 xe)
String user = "scott";
//-- 오라클 사용자 계정 이름
String pwd = "tiger";
//-- 오라클 사용자 계정 암호
// 이름으로 뭔가를 찾아주는 메소드 : forName()
// 오라클 상자 안에 jdbc 상자 안에 driver상자 안에 OrcleDriver.
// 이 이름을 갖는 클래스를 찾아달라는 명령이다.
Class.forName("oracle.jdbc.driver.OracleDriver");
//-- OracleDriver 클래스에 대한 객체 생성(클래스 찾아줘~!!!)
// Static 메소드 이므로, 인스턴스를 통해 메소드를 호출하지 않고
// 클래스 명으로 접근하는 것을 확인할 수 있다.
dbConn = DriverManager.getConnection(url, user, pwd);
//-- 오라클 서버 실제 연결
// 갖고 있는 인자값(매개변수)은 오라클주소, 계정명, 패스워드
}
// ⓑ 기존에 만들어 놓은 연결 객체가 존재하면...
// ⓑ 그거 걍 써~!!!
return dbConn;
//-- 구성된 연결 객체 반환
}
// 첫 번째 getConnection을 Overloading (매개변수 형태만 다르게 하는 것)
// 첫 번째 getConnection() 메소드는 무조건 scott으로만 로그인이 가능하기 때문에
// 매개변수로 아이디, 패스워드, url을 받아서 다른 계정으로도 로그인 할 수 있도록 getConnection을 하나 더 정의.
// 메소드 정의 → 메소드 오버로딩 → 연결
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
{
// 이미 끊어져 있는 것을 또 끊지 않도록
// 연결 되어 있는 상태에서만 종료할 수 있게 구성.
// dbConn 변수(멤버 변수)는
// Database 가 연결된 상태일 경우 Connection 을 갖는다.
// 연결되지 않은 상태라면... null 인 상태가 된다.
if (dbConn != null)
{
// Connection 클래스 내부의 isClosed()
// isClosed() : db가 닫혀 있으면 true, db가 닫히지 않았으면 false
// 연결 객체(dbConn) 의 isClosed() 메소드를 통해 연결 상태 확인
//-- 연결이 닫혀있는 경우 true 반환
//-- 연결이 닫혀있지 않은 경우 false 반환
if (!dbConn.isClosed())
{
dbConn.close();
//-- 연결 객체의 close() 메소드 호출을 통해 연결 종료~!!!
}
}
// check~!!!
// ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
// dbConn을 null 로 만들어서 초기화시켜주지 않으면
// 위에서 연결할 때 필터링이 적용되지 않기 때문에 반드시 null로 초기화 해 주어야 한다.
dbConn = null;
//-- 연결 객체 초기화
}
}
DBConnBackup.java
package com.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBConnBackup
{
private static Connection dbConn;
public static Connection getConnection()
{
if (dbConn == null)
{
try
{
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);
} catch (Exception e)
{
System.out.println(e.toString());
//-- 오라클 연결 실패 시 오류 메세지 출력 부분
}
}
return dbConn;
}
public static Connection getConnection(String url, String user, String pwd)
{
if (dbConn == null)
{
try
{
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()
{
if (dbConn != null)
{
try
{
if (!dbConn.isClosed())
{
dbConn.close();
}
} catch (Exception e)
{
System.out.println(e.toString());
}
}
dbConn = null;
}
// alt 누르고 위아래 방향키 → 원하는 위치로 구문 이동
// alt + ctrl 누르고 아래 방향키 → 아래로 무한 복사!!!!
}
[Package] com.test
Test001.java
package com.test;
public class Test001
{
// 【ctrl + space = 단축키(자동 완성)】
// "syso" + ctrl + space
// 저장을 할 때마다 컴파일을 해 준다.
// ctrl + F11 > java application 콘솔 창 등장!
public static void main(String[] args)
{
System.out.println("JAVA Test");
}
}
Test002.java
/*============================
Test002.java
==============================*/
// Run on server
//
package com.test;
import java.sql.Connection;
import com.util.DBConnBackup;
public class Test002
{
public static void main(String[] args)
{
Connection conn = DBConnBackup.getConnection();
// ※ DB 연결 과정이 매우 부하가 크기 때문에
// 한 번 연결된 객체를 계속 사용할 수 있도록 Singleton 패턴 적용~!!!
// 위의 getConnection() 메소드를 통해
// 데이터베이스와 정상적인 연결이 이루어진 상황이라면...
if (conn != null)
{
System.out.println("데이터베이스 연결 성공~!!!");
}
DBConnBackup.close();
}
}
// 실행 결과
//--==>> 데이터베이스 연결 성공~!!!
Test003.java
/*================================
Test003.java
- 데이터베이스 연결 실습
- 데이터 입력 실습
==================================*/
package com.test;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import com.util.DBConn;
public class Test003
{
public static void main(String[] args) throws ClassNotFoundException, SQLException
{
// 연결 객체 생성(구성)
Connection conn = DBConn.getConnection();
if (conn == null)
{
System.out.println("데이터베이스 연결 실패~!!!");
System.exit(0);
// 프로그램 나가기
}
// System.out.println("데이터베이스 연결 성공~!!!");
try
{
Statement stmt = conn.createStatement();
String sql = "INSERT INTO TBL_MEMBER(SID, NAME, TEL) VALUES(2, '김지민', '010-3937-6913')";
int result = stmt.executeUpdate(sql);
if (result > 0)
{
System.out.println("데이터 입력 성공~!!!");
}
else
{
System.out.println("입력 실패~ ㅠ_ㅠ");
}
} catch (Exception e)
{
System.out.println(e.toString());
}
}
}
Test004.java
/*=========================
Test004.java
===========================*/
// 실행 예)
// 번호를 입력하세요(-1 종료) : 3
// 이름을 입력하세요 : 박나영
// 전화번호를 입력하세요 : 010-3333-3333
// >> 데이터베이스 연결 성공~!!!
// >> 회원 정보가 입력되었습니다.
// 번호를 입력하세요(-1 종료) : 4
// 이름을 입력하세요 : 정현욱
// 전화번호를 입력하세요 : 010-4444-4444
// >> 데이터베이스 연결 성공~!!!
// >> 회원 정보가 입력되었습니다.
// 번호를 입력하세요(-1 종료) : 5
// 이름을 입력하세요 : 김민지
// 전화번호를 입력하세요 : 010-5555-5555
// >> 데이터베이스 연결 성공~!!!
// >> 회원 정보가 입력되었습니다.
// 번호를 입력하세요(-1 종료) : -1
// >> 데이터베이스 연결 닫힘~!!
// >> 프로그램 종료됨~!!!
package com.test;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
import com.util.DBConn;
public class Test004
{
public static void main(String[] args) throws ClassNotFoundException, SQLException
{
Scanner sc = new Scanner(System.in);
int n;
String name;
String tel;
String insertStr;
// 연결 객체 생성(구성)
Connection conn = DBConn.getConnection();
if (conn == null)
{
System.out.println("데이터베이스 연결 실패~!!!");
System.exit(0);
// 프로그램 나가기
}
// 번호 입력받기
do
{
System.out.println("번호를 입력하세요(-1 종료) : ");
n = sc.nextInt();
if (n == -1)
{
System.out.println("데이터베이스 연결 닫힘~!!");
System.out.println("프로그램 종료됨~!!!");
DBConn.close();
// 연결객체 닫기
System.exit(0);
// 프로그램 나가기
}
System.out.print("이름을 입력하세요 : ");
name = sc.next();
System.out.print("전화번호를 입력하세요 : " );
tel = sc.next();
//--------------------------------------------
try
{
Statement stmt = conn.createStatement();
insertStr = String.format("INSERT INTO TBL_MEMBER(SID, NAME, TEL) VALUES(%d, \'%s\', \'%s\')", n, name, tel);
int result = stmt.executeUpdate(insertStr);
if (result > 0)
{
System.out.println("데이터베이스 연결 성공~!!!");
System.out.println("회원 정보가 입력되었습니다.");
}
} catch (Exception e)
{
System.out.println(e.toString());
}
}
while(n != -1);
}
}