'Java/shoppingMall Project'에 해당되는 글 1건

  1. 2011.01.20 JDBC 프로그래밍 과정 _ DB와 연결하기!!!
2011. 1. 20. 16:17
JDBC개념과 역할
  * JDBC 구조
     - JDBC(Java Database Connectivity)
     - 데이터베이스 벤더와 상관없이 동일한 개발이 가능함

  * JDBC 드라이버
     - JDBC 드라이버는 사용하고자 하는 데이터베이스 벤더 별로 제공 된다.


(ojdbc14.jar)를 jar 파일로 추가



 * JDBC 프로그래밍 단계

1. JDBC 드라이버 로드
    : System.sepProperty()
2. 데이터베이스 연결
3. Statement생성
4. SQL 문 전송
    : java.sql.Statement -> [DB조회] excuteQuery(),   <-  Query를 넣어서...
                                      [DB변경]  excuteUpdate()
5. 결과 받기 [excuteQuery()의 경우]
   java.sql.ResultSet(state마다 하나씩밖에 없다.
6. 연결 해제
   java.sql.Connection -> close()   


> 코드보기(select문에 대한 sql문 처리)

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DBTest {
 public static void main(String[] args) {
  
  //DB는 전부다 1521 포드로 연결
  //jdbc:oracle:thin:@117.17.93.103:1521:orcl
  String url = "jdbc:oracle:thin:@117.17.93.103:1521:orcl";
  String username="scott";
  String passwd = "tiger";
  
  //쿼리문 하나 만듦.
  String sql = "select * from customers";
  Connection con = null;
  Statement st = null;
  ResultSet rs = null;   //finally에서 사용하기 위해 Connection ~ ResultSet까지의 객체를 try~catch문 밖에 선언
  try {
   //[1.JDDB드라이버 로드]
   Class.forName("oracle.jdbc.driver.OracleDriver"); //예외처리
   
   //[2. 데이터 베이스 연결.. 드라이버 연결(connection 얻어오는 작업)]
   con = DriverManager.getConnection(url, username, passwd); //예외처리
   
   //3. Statement 생성 
   st = con.createStatement();
   //statement객체 쿼리를 담을 수 있는 객체, 쿼리를 제공하는 메소드가 담겨져 있는 클래스
   
   
   //4.SQL문 전송
   rs = st.executeQuery(sql);
   //쿼리한 결과가 ResultSet으로 반환됨.
   
   //5. 결과 받기
   //resultset은 처음에는 컬럼명에 있음..
   //rs의 위치는  rs-> name       phone           address
   //      rs.next()이순신    010-2222-1111     서울시 노원구 중계동
   //다음줄로 넘길려면 rs.next()
   System.out.println("customers 테이블 정보");
   System.out.printf("%-10s %-16s %-30s\n", "  이름", "|     전화번호", "|       주소");
   System.out.println("-----------------------------------------------------");
   while(rs.next()){
    System.out.printf("%-10s %-16s %-30s\n",
      rs.getString("name"), rs.getString("phone"), rs.getString("address"));
    //컬럼 이름으로 준것, index로 줘서 rs.getString(1) 도 동일
    //rs.getString(2)
    //rs.getString(3)
   }
   System.out.println("-----------------------------------------------------");
      
   
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } finally{
   //6. 연결끊기(해제) (가장 마지막에 만들어진 객체 부터.. 닫아줌)
   if( rs != null) try { rs.close();} catch (SQLException e) { e.printStackTrace();}
   if( st != null) try { st.close();} catch (SQLException e) { e.printStackTrace();}
   if( con != null) try { con.close();} catch (SQLException e) { e.printStackTrace();}
   
  }
 }
}
[console]
customers 테이블 정보
  이름       |     전화번호       |       주소                   
-----------------------------------------------------
김영숙        010-1112-2222    서울시 노원구 중계동                  
홍길동        010-2222-2222    서울시 노원구 중계동                  
이순신        010-3333-2222    서울시 노원구 중계동                  
장동건        010-4444-2222    서울시 노원구 중계동                  
-----------------------------------------------------



* 데이터 베이스 연결
- Connection conn = DriverManger.getConnection(JDBC_url, "아이디", "비밀번호");
- JDBC_URL 구성 = JDBC:orcle:thin:@IP주소:포트:SID
- 엑세스 DB인 경우 = JDBC:odbc:song

*statement 생성 및 쿼리 실행
- Statement 객체 생성후 SQL 문장을 변수 처리부와 함께 문자열로 구형
- 쿼리가 복잡해 질수록 성능저하 및 관리에 어려움이 있음
 //Statement객체 : 쿼리를 담는 객체 (가장 간편히 사용) static한 string을 받아서..(변동이 없는 쿼리물을 담음)
 //PreparedStatement (satement객체 상속받음) 쿼리문이 계속 바뀌는 경우
//CallofStatement(preparedStatement 객체 상속받음) 아주~~ 성능이 좋아야 하는 경우, 쿼리문을 DB가 갖고 있음.
                                                                          (쿼리문을 db에 proceduer로 등록시킴..)
-Statement stmt = conn.createStatement();
 쿼리 - 데이터변경 : executeUpdate()
       - 데이터읽기: executeQury()

*PreparedStament생성 및 쿼리 실행(insert나 add같은 경우)
 - PreparedStatement 객체 생성시 SQL 문장을 미리 생성하고 변수 부는 별도의 메서드로 대입하는 방식으로 성능과 관리 면에서 모두 권장되는 방식임
PreparedStatement pstmt = conn.prepareStatement("insert into test values(?,?)");
pstmt.setString(1,request.getParameter("username");
pstmt.setString(2,request.getParameter("email");
pstmt.executeUpdate();


* 결과받기
 ResultSet rs = pstmt.executeQuery();
- ResultSet은 커서 개념의 연결 포인터
- 기본적으로 next()메서드를 통해 로우 이동


* 연결해제
  - Connection 을 close()해 주지 않으면 사용하지 않은 연결이 유지됨
  - DB 자원을 낭비하게 됨. conn.close();
   


>customers에 insert하고, select * from customer 한것.. (sql문을 두개 사용)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


public class DBTest {
 public static void main(String[] args) {
  
  //DB는 전부다 1521 포드로 연결
  //jdbc:oracle:thin:@117.17.93.103:1521:orcl
  String url = "jdbc:oracle:thin:@117.17.93.103:1521:orcl";
  String username="scott";
  String passwd = "tiger";
  
  String sql2 = "insert into customers values(?,?,?)";
  String sql = "select * from customers";
  Connection con = null;
  PreparedStatement st = null;
  PreparedStatement st2 = null;
  ResultSet rs = null;   //finally에서 사용하기 위해 Connection ~ ResultSet까지의 객체를 try~catch문 밖에 선언
  try {

   //[1.JDDB드라이버 로드]
   Class.forName("oracle.jdbc.driver.OracleDriver"); //예외처리
   
   //[2. 데이터 베이스 연결.. 드라이버 연결(connection 얻어오는 작업)]
   con = DriverManager.getConnection(url, username, passwd); //예외처리
   
   //3. PreparedStatement 생성
   st2 = con.prepareStatement(sql2); //sql문 넘겨받음
   st2.setString(1, "흐흐흐3"); //자바문법이기 때문에 표시를 " " 로 해 주어야
   st2.setString(2, "010-1234-5678");
   st2.setString(3, "서울시 몽땅 우리집");
   st2.executeUpdate();
   //새로운 레코드를 추가

   st = con.prepareStatement(sql); //sql문 넘겨받음
   rs = st.executeQuery(); //이미 쿼리문을 st가 갖고 있기에 (sql)할 필요 없다.
   //쿼리한 결과가 ResultSet으로 반환됨.
   
   //5. 결과 받기
   //resultset은 처음에는 컬럼명에 있음..
   //rs의 위치는  rs-> name       phone           address
   //      rs.next()이순신    010-2222-1111     서울시 노원구 중계동
   //다음줄로 넘길려면 rs.next()
   System.out.println("customers 테이블 정보");
   System.out.printf("%-10s %-16s %-30s\n", "  이름", "|     전화번호", "|       주소");
   System.out.println("-----------------------------------------------------");
   while(rs.next()){
    System.out.printf("%-10s %-16s %-30s\n",
      rs.getString("name"), rs.getString("phone"), rs.getString("address"));
    //컬럼 이름으로 준것, index로 줘서 rs.getString(1) 도 동일
    //rs.getString(2)
    //rs.getString(3)
   }
   System.out.println("-----------------------------------------------------");
      
   
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } finally{
   //6. 연결끊기 (가장 마지막에 만들어진 객체 부터.. 닫아줌)
   if( rs != null) try { rs.close();} catch (SQLException e) { e.printStackTrace();}
   if( st != null) try { st.close();} catch (SQLException e) { e.printStackTrace();}
   if( con != null) try { con.close();} catch (SQLException e) { e.printStackTrace();}
   
  }
 }
}


customers 테이블 정보
  이름       |     전화번호       |       주소                   
-----------------------------------------------------
김영숙        010-1112-2222    서울시 노원구 중계동                  
홍길동        010-2222-2222    서울시 노원구 중계동                  
이순신        010-3333-2222    서울시 노원구 중계동                  
장동건        010-4444-2222    서울시 노원구 중계동                  
kim        111-1111-1111    서울시 강북                       
하하하        010-1234-5678    서울시 몽땅 우리집                   
호호호        010-1234-5678    서울시 몽땅 우리집                   
흐흐흐        010-1234-5678    서울시 몽땅 우리집                   
흐흐흐2       010-1234-5678    서울시 몽땅 우리집                   
흐흐흐3       010-1234-5678    서울시 몽땅 우리집                   
-----------------------------------------------------
Statement 객체  //사용할 때 쿼리문을 준다.
Statement st = con.createStatement();
st.executeQuery("select * from customer");   //쿼리문은 쿼리 할 때 들어감
//st.executeUpdate("insert....   delete... update...);

PreparedStatement 객체  : 객체를 만들때 쿼리문을 줌
PreparedStatement ps = con.prepareStatment("select ~~~~ ");
ps.executeQuery();  //argument없이
ps.executeUpdate(); //처음에 con.prepareStatement(" ") 할때 insert, delete, update가 들어간 경우..

만약
PreparedStatement ps = con.prepareStatment("insert into table values(?, ?, ?)");
ps.setInt(1,100);
ps.setString(2, "kdkdkd");
ps.executeQuery();





>Prepared Statement 이용하여 데이터 추가하기 (코드)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DBTest {
 public static void main(String[] args) {
  
  //DB는 전부다 1521 포드로 연결
  //jdbc:oracle:thin:@117.17.93.103:1521:orcl
  String url = "jdbc:oracle:thin:@117.17.93.103:1521:orcl";
  String username="scott";
  String passwd = "tiger";
  
  String sql = "insert into customers values(?,?,?)";
  Connection con = null;
  PreparedStatement st = null;
 

  try {
   Class.forName("oracle.jdbc.driver.OracleDriver");
   con = DriverManager.getConnection(url, username, passwd); 

   st = con.prepareStatement(sql); // prepareStatement 객체는 만들때 argument를 받는다.
   st.setString(1, "이름1");
   st.setString(2, "전화번호111");
   st.setString(3, "주소2222");
   st.executeUpdate();   //st.execute()해도 됨... 차이는
   //excupteUpdate 하면 integer값이 반환되고,
   //excute()하면 boolean이 반환됨
   
   
   
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } finally{
   //6. 연결끊기 (가장 마지막에 만들어진 객체 부터.. 닫아줌)
   if( st != null) try { st.close();} catch (SQLException e) { e.printStackTrace();}
   if( con != null) try { con.close();} catch (SQLException e) { e.printStackTrace();}
   
  }
 }
}

Quantun DB 에 가보면 제대로 insert 된 것을 확인할 수 있다.




>이름이 홍길동인 row 검색..
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DBTest {
 
 public static void main(String[] args) {
  
  //DB는 전부다 1521 포드로 연결
  //jdbc:oracle:thin:@117.17.93.103:1521:orcl
  String url = "jdbc:oracle:thin:@117.17.93.103:1521:orcl";
  String username="scott";
  String passwd = "tiger";
  
  String sql = "select * from customers where name like ?"; //쿼리문 수행
  Connection con = null;
  PreparedStatement st = null;
  ResultSet rs = null; //쿼리문 이기에 결과를 받아야 한다.
  
  try {
   Class.forName("oracle.jdbc.driver.OracleDriver");
   con = DriverManager.getConnection(url, username, passwd); 
   st = con.prepareStatement(sql); // prepareStatement 객체는 만들때 argument를 받는다.
   st.setString(1, "홍길동%");
   st.executeUpdate();  
   rs = st.executeQuery();
   System.out.println("실행결과");
   while(rs.next()){
    System.out.println(rs.getString(1) + " : " + rs.getString(2) +
      " : " + rs.getString(3));
   }
       
   
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } finally{
   //6. 연결끊기 (가장 마지막에 만들어진 객체 부터.. 닫아줌)
   if( rs != null) try { rs.close();} catch (SQLException e) { e.printStackTrace();}
   if( st != null) try { st.close();} catch (SQLException e) { e.printStackTrace();}
   if( con != null) try { con.close();} catch (SQLException e) { e.printStackTrace();}
   
  }
 }
}


실행결과
홍길동     : 010-2222-2222    : 서울시 노원구 중계동
name은 char(10)으로 정의되어 있으므로...
like와 "홍길동%"를 써줘야 .... 검색이 가능









DB만 전담하는 object를 만들자.
DAO(Database Access Object)
1) DB를 쓰고 싶으면 DAO를 통해서 하도록 하겠다.
(뒤에오는 DB의 규모가 얼마인지에 따라서 DAO의 규모를 한개로 할건지, 다중으로 할건지...)











Posted by Triany