중복코딩방지를 위해

오라클 연결 과정 과 SQL문 실행들을 메소드로 빼서 

필요할 때 메소드 호출로 불러 올 것!

 

인터페이스

// 메소드로 상속할 인터페이스 생성(오라클 연결,sql실행문,객체닫기,사용자에게 값 받기)

public interface IConnect {
	// 멤버상수에 데이터로딩, 데이터베이스연결
    String ORACLE_DRIVER = "oracle.jdbc.OracleDriver";
    String ORACLE_URL = "jdbc:oracle:thin:@127.0.0.1:1521:xe";
    
    //추상메소드  데이터베이스연결(sqlplus로그인),쿼리문전송,닫기,사용자값받기,쿼리문입력(>SQL)
    void connect(String url,String user,String password);
    void execute() throws Exception;
    void close();
    String getValue(String message);
    String getQueryString();  
}

메소드 호출 할 부모 클래스 생성

public class IConnectImpl implements IConnect{

 		//멤버변수
		public Connection conn;
        public ResultSet rs;
        public Statement stmt;
        public PreparedStatement psmt;
        public CallableStatement csmt;
        private Scanner sc = new Scanner(System.in);

		//static 블락  여기다가 맨 처음 드라이버 로딩할 거
        static {
        	try{  //데이터로딩
                Class.forName(ORACLE_DRIVER);
             }
              catch(ClassNotFoundException e){
                System.out.println("드라이버 로딩 실패:"+e.getmessage);
                 }                        
              }
         
         //기본생성자
         public IConnectImpl(){}
         //인자생성자  --이거로 데이터베이스 연결해서 로그인해도 되고(여기서 바로 인자 넣거나 메인에서 넣거나)
         public IConnectImpl(String url, String user, String password) {
         connect(url, user, password);
            }

		@Override
		public void connect(String url, String user, String password) {		
            try {   // 이걸로 데이터베이스 연결해서 로그인해도 된다!
                conn = DriverManager.getConnection(url, user, password);
            } 
             catch (SQLException e) {
                 System.out.println("데이터베이스 연결 실패:"+e.getMessage());
		      }
	    }
        
        @Override  //부모로 사용할거라서 구현은 안해도 됨! 자식에서 구현해도 됩니다
		public void execute() throws Exception { }
        
        @Override  // 연결끊기 메소드
		public void close() {
			try {
                    if (csmt != null) csmt.close();
                    if (psmt != null) psmt.close();
                    if (stmt != null) stmt.close();
                    if (rs != null) rs.close();
                    if (conn != null) conn.close();
                   }
					catch(SQLException e){}				
	        }
        
        @Override  //사용자용 입력 메소드
		public String getValue(String message) {
				System.out.println(message + "를 입력하세요");
				String value = sc.nextLine();
				if("exit".equalsIgnoreCase(value)) {
						close();
					System.out.println("프로그램 종료");
					System.exit(0);
					}
				return value;
	         }

		@Override  
		public String getQueryString() {		
		return null;
		}	                              
}

'학원 > JDBC' 카테고리의 다른 글

10/24 27-4 (insertSQLAutoGeneratedKeys)  (0) 2022.10.24
10/24 27-3 (UpdateSQL.statement)  (0) 2022.10.24
10/24 27-1( DeleteSQL.statement )  (0) 2022.10.24
10/21 26-7( InsertSQL .statement )  (0) 2022.10.23
10/21 26-6 DBconnection(실전이닷)  (0) 2022.10.23

이젠 지워버리겠으!!  => 바로 사용자에게 값 받아서!!

 

public class DeleteSQL {

	//멤버변수
	private Connection conn;
	private Statement stmt;		
	
	public DeleteSQL() {
			
		    try {
				Class.forName("oracle.jdbc.OracleDriver");
				conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","KOSMO","KOSMO");/// ==> 이거 나중에 정식으로 할 땐 별도의 클래스꼭 빼야 함!				
			} catch (ClassNotFoundException e) {
				System.out.println("드라이버가 없어요");
			} catch(SQLException e) {
				System.out.println("데이터베이스 연결 실패");
			}		    
	}

	private void execute() {
		try {
			stmt = conn.createStatement();
            while(true){
                        try {
                            int affected = stmt.executeUpdate("DELETE member WHERE username='"+getValue("삭제할 아이디").toString()+"'");
                            System.out.println(affected+"행이 삭제 되었습니다.");
                           }
                            catch(SQLException e) {
                               System.out.println("delete 쿼리문 실행 오류:"+e.getMessage());
                             }
                         	catch(NullPointerException e){
                            	System.out.println("오라클 연결을 종료합니다.");
                               	break;
                             }
                  }///// while
                                             
             }
		  catch (SQLException e) {
			System.out.println("statement 객체 생성 실패");			
		}
		finally {
			close();
		}
		
		
	}///////////
	
	private void close() {
		try {
            if(stmt != null) stmt.close();
            if(conn != null) conn.close();
		   }
		catch(SQLException e) {}
		
	}//////////

	private static Scanner sc=new Scanner(System.in);
	
    public static String getValue(String message) {
		System.out.println(message+"를(을) 입력하세요");
		String value = sc.nextLine();
		if("exit".equalsIgnoreCase(value)) {
			return null;
		}
		return value;
	}////////

	public static void main(String[] args) {		
		new DeleteSQL().execute();		
	}////main
}////class

근데 이거 실행이 아예 안되는 거같음...... 집 컴퓨터로 한 번 실행 해 보고 결과캡쳐는 나중에.....

된다아아아앙~

 

연결을 넘어서 

이번엔 사용자에게 값을 받아서 입력하고 출력까지 해 볼 거임!

 

public class InsertSQL {
	private Connection conn;
    private Statement stmt;
    private ResultSet rs;   // 결과값도 가져올거얌
    
    public InsertSQL(){  // 생성자에서 오라클 연결
         try{
            Class.forName("oracle.jdbc.OracleDriver");
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","kosmo","kosmo");
            }
         catch(ClassNotFoundException e){
            System.out.println("드라이버 클래스가 없음");	
            }
         catch(SQLException e) {
			System.out.println("데이터베이스 연결실패");			
		    }
    }
    
    private void execute(){  // 쿼리실행 출력 메소드
    	try{
       		 stmt = conn.createStatement(); // 객체생성
               while(true){   
                      try{  
                         String sql = "INSERT INTO member VALUES('"+getvalue("아이디").toString+"',
                                                                '"+getvalue("비밀번호").toString+"',
                                                                    '"+getvalue("이름").toString+"',
                                                                     SYSDATE)";          
                         int affected = stmt.excuteUpdate(sql);
                         System.out.println(affected +"행이 입력되었습니다.");  // 여기까진 INSERT문 쿼리
                         
                         Stirng sql2 = "SELECT * FROM member";
                         rs = stmt.executeQuery(sql2);

                         while(rs.next()) { 
                                    String id = rs.getString(1);					  
                                    int pass =rs.getInt("password");
                                    String name = rs.getString("name");
                                    Date today = rs.getDate(4);
                                    System.out.println(String.format("%-5s%-11s%-10s%-10s",
                                              id,pass,name,today));
                                     }  				// 여기까진 SELECT문 쿼리
                         }
                        catch(SQLException e) {
                            System.out.println("쿼리문 실행 오류:"+e.getMessage());
                                }
                        catch(NullPointerException e) {
                           System.out.println("오라클 데이터와 연동 끊어짐");
                         break;  // 끝내기
                            }
                }
          }
        catch(SQLException e){
             System.out.println("statement 객체생성 실패");
         }
        finally{
             close();
        } 
     }
    
    private void close() {
		try {
			if (stmt != null) stmt.close();
			if (conn != null) conn.close();
			if (rs != null) rs.close();            
		}catch(SQLException e) {}			
	}/////
    
    private static Scanner sc = new Scanner(System.in);
	public static String getValue(String message) {
		System.out.println(message+"(을)를 입력하세요,종료는 exit ");
		String value = sc.nextLine();
		if("exit".equalsIgnoreCase(value)) {
			return null;
		 }
		return value;     
	 }//////
     
     	public static void main(String[] args) {
		new InsertSQL().execute();		
	}////main
}///class

대략적인 줄기로 정리먼저 해보자!

 

1. 오라클용 jdbc드라이버 메모리에 로딩하기

          Class.forName.("oracle.jdbc.OracleDriver")

 

2. 오라클설치주소 이용 연결시도!

        String url = "jdbc:oracle:thin:@localhost:1521:xe";

        String user = "scott";
        String password = "soctt";

        Connection conn = null;

        conn =DriverManager.getConnection(url, user, password);
        System.out.println("연결성공");

 

3.  쿼리문 전송용 statement 계열 객체 생성, 연결된 conn을 통해서 생성함

        Statement stmt = null;

        stmt  = conn.createStatement();

       

 4. statement 계열 클래스의 execute계열 메소드이용, 쿼리문 실행 후 나오는 결과값 담기!

        String sql = "SELECT * FROM emp ORDER BY hiredate DESC";

        ResultSet rs = null;

        rs = stmt.executeQuery(sql);

              CF. INSERT/UPDATE/DELETE 문의 경우 .executeUpdate( );

 

 

 5. 오라클 커서 기능이용, 이동하면서(.next) 결과 값 꺼내오기

       while(rs.next()) { 
                  int empno = rs.getInt(1);
                  String ename = rs.getString(2);
                  String job = rs.getString("job");
                  int sal = rs.getInt(6);
                  Date hiredate = rs.getDate(5);
                  System.out.println(String.format("%-5s%-11s%-10s%-6s%s",
                                                                        empno,ename,job,sal,hiredate));
                       }

 

6.데이터베이스 연결 끊기

        if(stmt != null)stmt.close();
        if(rs != null) rs.close();
        if(conn != null) conn.close();

 

++ 근데!! 저거 문제가 있음 아이디 비밀번호 연결주소가 너무 노출되어 있음 

    진짜 만들 때는 민감한 개인정보들 보관하는 파일을 따로 만들어서 거기서 꺼내와야 한다! 

그거랑 try catch등으로 이용해서 코딩하면 다음과 같이 만들 수 있다

// config.properties   민감정보들 저장 할 파일
#key=value
driver = oracle.jdbc.OracleDriver
url = jdbc:oracle:thin:@localhost:1521:xe
user = scott
password = scott
public static void main(String[] args) {
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
    try{
         Properties props = new Properties();   // 민감한 정보 담아둔 파일에 key값으로 접근해서 내용 가져올거임
         props.load(new fileReader("src/jdbc25/config.properties"));
         Class.forName(props.getProperty("driver"));   //1.오라클용 jdbc드라이버 메모리에 로딩
         
         String url = props.getProperty("url");
         String user = props.getProperty("user");
         String password = props.getProperty("passowrd");
         conn = DriverManager.getConnection(url,user,password);  //2.연결시도
         System.out.println("연결 성공!"); 
         
         try{
             stmt = conn.createStatemnet(); // 3.쿼리문 전송 준비
             try{
                 String sql = "select * from emp order by hiredate desc";  
                 rs = stmt.executeQuery(sql);  // 4.쿼리문 실행 후 결과담기
                 while(rs.next()) { //5.오라클 커서 기능이용 이동하면서(.next) 결과 값 꺼내오기			 
                            int empno = rs.getInt(1);
                            String ename = rs.getString(2);
                            String job = rs.getString("job");
                            int sal = rs.getInt(6);
                            Date hiredate = rs.getDate(5);
                            System.out.println(String.format("%-5s%-11s%-10s%-6s%s",
                                       empno,ename,job,sal,hiredate));
                             }
              }
               catch(SQLException e) {
                         System.out.println("select 쿼리실행 오류:"+e.getMessage());
                        }	
          }
          catch(SQLException e) {
			   	System.out.println("select쿼리 실행 오류:"+e.getMessage());
       }         
     }
     catch(ClassNotFoundException e) {
			System.out.println("오라클 드라이버 클래스 없음:"+e.getLocalizedMessage());
     }
     catch(SQLException e) {
			System.out.println("데이터베이스 연결 실패"+e.getMessage());
	 }
      catch(IOException e) {
			 System.out.println("파일로딩 실패:"+e.getMessage());
	 }
      finally {	
			try {   // 6. 데이베이스 연결 끊기
				if(stmt != null)stmt.close();
				if(rs != null) rs.close();
				if(conn != null) conn.close();
			    }
			catch(SQLException e) {}
		}   

 }////main

다시 돌아 온 이클립스 두둥...!!

우선 JDBC에 대해서...

Java언어로 데이타베이스에 연결해서 입력,수정,삭제 및 조회등의 작업을 할 수 있도록 해주는 기술이다

JDBC는 프로그램과 각각의 데이터베이스(Oracle,MS-SQL,DB2,MySQL등)  중간에서 각 데이타베이스의 벤더(회사)에서 제공하는 API들을 사용할 수 있도록 변환해주는 기능을 수행한다.
JDBC가 각 벤더에 맞는 API를 사용할 수 있도록 프로그래머는 각 벤더에서 제공해주는 드라이버를 다운받아 JAVA개발환경에 설정 해줘야 한다.
쉬운 예를 들면 회사가 처음엔 oracle쓰다가 나중에 재정사정이 안좋아져서 ms-sql이나 mysql로 데이터베이스를 바꿔야  할 때, 그 동안 oracle에서 작업했던 수많은 프로그램을 다시 바뀐 데이터베이스에 맞게 다 변환하려면 ..... 걍 퇴사하고 싶어지겠지..  아무튼 JDBC는 그렇게 각각 다른 데이터베이스들에 맞게 프로그램을 사용할 수 있게 변환 해주는 변환기 같은 거라고 생각 하면 된다! 오 그래 쓰면서 생각났네!! 220V짜리 제품을 110V에 꽂아서 사용할 수 있게 하는 변환기라고 생각 하자!! 

 

[환경설정하기]

1. 드라이버 다운로드 

  1] Oracle데이타베이스가 설치된 경우 : 11g인 경우 App폴더 로 가서 Administrator ->Product->버전->DbHome_1폴더->JDBC폴더->lib폴더  안에 드라이버(.jar)가 존재함

   11g인 경우:ojdbc5.jar(jdk 5버전),ojdbc6.jar(jdk 6.0버전)
  *상기에서 본인이  사용하고 있는 jdk버전에 맞는 .jar파일을 복사해서 환경설정을 하자.

2. 환경설정

 - classpath로 설정하는 경우 : 내 컴퓨터 ->마우스 우클릭 ->속성->고급->환경변수에서 classpath에 드라이버가 있는 폴더 추가 
- 혹은 드라이버를 복사 후 JDK가 설치된 폴더로 가서 jdk버전\jre\lib\ext폴더 안에 붙여 넣는다.

 

 

[JDBC 프로그래밍 절차]  -- 나는 이클립스에서 오라클 자료 불러올거얌!

    큰 줄기를 먼저 이해하자!

  1. 드라이버 로딩     
               Class의 forName()메서드를 이용 한다. JDBC 드라이버를 메모리에 로딩후 DriverManager에 등록 함                           Class.forName("oracle.jdbc.OracleDriver");   => 실행하면 오라클 드라이버가 메모리에 로딩

  2. 데이타 베이스 연결  :  콘솔창에서 sqlplust scott/scott 같은거  자바에선 new 같은거         
               DriverManager클래스의 getConnection()메서드로 연결 시도
               getConnection("드라이버종류:@서버가위치한 주소:사용포트:전역데이타베이스명","아이디","비밀번호");
                    ****오라클 주소 :127.0.0.1 (아니면 localhost) 걍 외우셈
               -오라클인 경우
               Connection con = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:xe","아이디","패스워드");

  3. 쿼리문 전송을 위한  준비         Connection 개체의 메서드 이용해서 Statement 계열 개체 얻기
             Statement > PreparedStatement > CallableStatement(상속 계층도) 
                 Statement , PreparedStatement 이거 둘은 일반적인 문을 쓸 때 사용하고(PreparedStatement주로 사용한대 )
                 CallableStatement 이건 함수,프로시져 실행 할 때 주로 사용한다

           -쿼리문이 일반 Text형태의 SQL문 인경우     
                       3-1. 파라미터 이용 하지 않을때
                                Statement st =con.createStarement();
                       3-2. 파라미터 이용시
                                 PreparedStatement st = con.prepareStatement("SELECT * FROM emp WHERE empno=?");
                                 *SQL문에는 ? 를 이용 파라미터에 값을 전달 한다
           -쿼리문이 스토어드 프로시저 인 경우
                       CallableStatement  st = con.prepareCall("{call 프로시저명(?,?....)}");
                       ※파라미터 : 쿼리문 중에 변경되는 부분 즉 값 부분을  ?로 처리하고 미리 쿼리문을 준비하자는 의미.

  4. 쿼리문 전송   : select * from emp ; 같은거!               - Statement/ PreparedStatement /CallableStatement 
                   개체를 통해 연결 된 데이터 베이스에 일반 쿼리문 혹은 스토어드 프로시저 전송
                    Statement 인터페이스는 execute계열 메서드에 직접 쿼리문을 인자로 넣어준다
                   단,PreparedStatement /CallableStatement 인터페이스는 Connection 개체의 prepare계열 메서드로 개체                      를 얻어 올때 미리(Prepare) 쿼리문을 넣어 준다   
                   
                   ***쿼리 전송시 메서드의 종류***
                    ResultSet rs= st.executeQuery(): 쿼리가 SELECT문인 경우
                    int affectedcount = st.executeUpdate():쿼리가 UPDATE/INSERT/DELETE 인 경우
                    boolean bool = st.execute(): 쿼리가 SELECT인 경우 true,  UPDATE/INSERT/DELETE인 경우 false;
                                                                   혹은 쿼리가 프로시저나 함수인 경우 사용

  5. ResultSet에서 값 꺼내 오기
                       while( rs.next() ){
                            rs.getXXX(컬럼인덱스) 혹은
                            rs.getXXX(컬럼명) 등의 메소드를 통해 데이터를 꺼내온다.
                            *인덱스로 가져오는것이 성능면에서 유리(속도가 더 빠름)
                                      }
                       [ResultSet 개체의 주요 메서드]
                             -next():다음행으로 커서를 옮김
                             -previous():이전 행으로 커서를 옮김
                             -first():첫번째 행으로 커서를 옮김
                             -last()마지막 행으로 커서를 옮김
                             -afterLast():커서를 마지막 행 바로 다음으로 옮김(EOF:END OF FILE)
                             -beforeFirst():커서를 첫번째 행 바로 앞으로 옮김(BOF:BEGIN OF FILE)
                             -getRow():현재 커서가 위한 행의 인덱스를 돌려 준다.인덱스는 첫번째 행 바로 앞이 0
                             -absolute(인덱스): 해당 인덱스 로 커서 이동, 양수-전진 ,음수-후진  

  6. 개체 자원 반납   => 끝냄! 오예!
                     close()메서드로 Connection 개체, Statement,PreparedStatement,CallableStatement 및 ResultSet 
                       개체등의 자원 반납.

+ Recent posts