ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] JDBC를 사용한 데이터베이스 연동(Mysql)
    DBProgramming/JDBC 2020. 4. 9. 23:57
    728x90
    반응형

    1. JDBC API 

    Java DataBase Connectivity의 약자로 JDBC는 자바 언어로 데이터베이스 프로그래밍을 하기 위한 라이브러리이다. 

    JDBC는 DBMS에 종속되지 않는 관련 API를 제공한다. JDBC API는 JDK에서 제공하며 JDBC 프로그래밍을 위해서는 JDBC드라이버가 필요하다! JDBC 드라이버는 각 DBMS 회사에서 제공하는 라이브러리 압축파일이다. 우리는 MySQL 데이터베이스관리시스템을 사용하지만 오라클을 사용한다면 오라클용 JDBC 드라이버가 필요하다.

     

     

    2. JDBC API 클래스

    JDBC는 다양한 클래스와 인터페이스로 구성된 패키지 java.sql와 javax.sql로 구성되어 있다.

     

    • 데이터베이스를 연결하여 테이블 형태의 자료를 참조
    • SQL 문을 질의
    • SQL 문의 결과를 처리

     

    전체적인 구조는 위와 같고, 이제 각각의 인터페이스와 클래스가 어떤 역할을 하는지에 대해서 알아보자.

     

     

     

    3. JDBC를 이용한 데이터베이스 연동과정

    JDBC 드라이버 로드

    1
    Class.forName("com.mysql.Jdbc.Driver"); 
     

     

    Class.forName() 메서드를 호출하여, mysql에서 제공하는 Driver 클래스를 JVM method area에 로딩시킨다. 

     

     

    데이터베이스 연결

    1
    2
    String jdbc_url = "jdbc:mysql://localhost:3306/datebase?serverTimezone=UTC";
    Connection con = DriverManager.getConnection(URL, "user""password");
     

     

    두 번째 줄의 의미는 localhost:3306 (로컬 환경에서 MySQL의 포트번호가 3306이기 때문이다) 그리고 database는 스키마 이름을 지정하면 된다.

    이제 Connection 객체를 만들어 사용하게 되는데 방법은 DriverManager 클래스의 static 메서드인 getConnection() 메서드를 호출해서, mysql에 연결하기 위한 커넥션 정보(url, user, password)를 입력한다.

    getConnection() 메서드 수행 결과로 Connection 객체를 반환하는데, 이 객체를 통해 쿼리를 날리는 statement를 작성할 수 있다.  SELECT 쿼리에서는 createStatement() , INSERT에서는 prepareStatement()를 호출한다.

     

     

    SQL을 위한 객체생성

    1
    Statement stmt = con.createStatement(); 
     

     

    사실 Connection, Statement, DriverManager의 내부는 정확히 뜯어보지는 않았지만 대략적으로 주요 메소드의 역할만 알면서 정리하려 한다.

     

     

    SQL 문장 실행

    1
    2
    String sql = "select * from student";
    ResultSet result = stmt.executeQuery(sql);  
     

     

    select 문장은 테이블 형태의 결과를 반환한다. 그러므로 select 문장을 실행하기 위해 Statement의 메소드 executeQuery()를 사용한다. 메소드 executeQuery()는 질의 결과로 테이블 형태의 결과를 반환하는데, 이 반환형이 인터페이스 ResultSet이다. 

     

    객체 Statement의 메소드 executeUpdate()는 create 또는 drop, insert, delete, update와 같이 테이블의 내용을 변경하는 문장에 사용한다.

     

    질의결과 처리

    1
    2
    3
    4
    5
    6
    7
     
    while(result .next()){       
        String name = result .getString(1);
        String owner = result .getString(2);
        String date = result .getString(3);
    }
     
     
     

    ResultSet 인터페이스에는 질의 결과의 현재 행(row)을 가리키는 커서(cursor)라는 개념이 있으며, 이 커서를 다음 행으로 이동시키는 메소드가 next()이다.  

     

     

    예를들어 위와 같이 결과가 나온 테이블의 구조가 있다고 가정하면 처음에는 첫번 째 행을 가리킬거고 그 행이 존재한다면 true, 존재하지 않는다면 false를 리턴한다. 

     

     

     

     

    ResultSet의 메소드 getString()과 getInt() 

    ResultSet의 커서가 있는 행에서 컬럼 자료를 참조하기 위해 ResultSet이 제공하는 메소드 getString()을 이용한다. 

    getString()의 인자는 컬럼 이름을 문자열로 직접 쓰거나 또는 컬럼 번호를 이용할 수 있다. 컬럼 값의 자료유형에 따라 메소드 getString()뿐만 아니라 getInt(), getDouble(), getDate() 등 다양한 컬럼 반환 메소드를 제공한다. 

     

    SELECT 쿼리 예제

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
     
    public class Example1 {
     
       public static void main(String[] args) {
          // TODO Auto-generated method stub
          
          String jdbc_driver = "com.mysql.cj.jdbc.Driver";
          String jdbc_url = "jdbc:mysql://localhost:3306/board?serverTimezone=UTC";
          try {
              
             Class.forName(jdbc_driver).newInstance();
             Connection con = DriverManager.getConnection(jdbc_url, "root""root");
             Statement st = con.createStatement();
             
             String sql = "SELECT * FROM member";
             ResultSet rs = st.executeQuery(sql);
     
             while(rs.next()){       
                 String name = rs.getString(1);
                 String owner = rs.getString(2);
                 String date = rs.getString(3);
     
                 System.out.println(name + " " + owner + " " + date);
             }
     
          
             rs.close();
             st.close();
             con.close();    
             
          } catch (Exception e) {
             e.printStackTrace();
          } 
       }
    }
     
     

     

    INSERT 쿼리 예제

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
     
    public class InsertTest {
        public static void main(String[] args) {
            // pet 테이블에는 이름/소유자/종/성별/출생일 칼럼이 있습니다.
            insert("봄이""victolee""페르시안""m""2010-08-21"null);
        }
     
        public static void insert(String name, String owner, String species,
                                  String gender, String birth, String death){
            Connection conn = null;
            PreparedStatement pstmt = null;
     
            try{
                // 1. 드라이버 로딩
                Class.forName("com.mysql.jdbc.Driver");
     
                // 2. 연결하기
                String url = "jdbc:mysql://localhost/dev";
                conn = DriverManager.getConnection(url, "dev""dev");
     
     
                // 3. SQL 쿼리 준비
                // 추가하려는 데이터의 값은 전달된 인자를 통해 동적으로 할당되는 값이다.
                // 즉 어떤 값이 전달될지 모르므로 Select 할 때와 달리
                // stmt = conn.createStatement(); 를 작성하지 않고
                // pstmt = conn.prepareStatement(sql); 로 작성하여 데이터를 추가할 것임을 알립니다.
                // 물론 sql 쿼리 내에서 + 연산자로 한 줄로 작성할 수 있지만 가독성이 너무 떨어지게 되므로
                // 이 방법을 권합니다.
                String sql = "INSERT INTO pet VALUES (?,?,?,?,?,?)";
                pstmt = conn.prepareStatement(sql);
     
     
                // 4. 데이터 binding
                pstmt.setString(1, name);
                pstmt.setString(2, owner);
                pstmt.setString(3, species);
                pstmt.setString(4, gender);
                pstmt.setString(5, birth);
                pstmt.setString(6, death);
     
     
                // 5. 쿼리 실행 및 결과 처리
                // SELECT와 달리 INSERT는 반환되는 데이터들이 없으므로
                // ResultSet 객체가 필요 없고, 바로 pstmt.executeUpdate()메서드를 호출하면 됩니다.
                // INSERT, UPDATE, DELETE 쿼리는 이와 같이 메서드를 호출하며
                // SELECT에서는 stmt.executeQuery(sql); 메서드를 사용했었습니다.
                // @return     int - 몇 개의 row가 영향을 미쳤는지를 반환
                int count = pstmt.executeUpdate();
                if( count == 0 ){
                    System.out.println("데이터 입력 실패");
                }
                else{
                    System.out.println("데이터 입력 성공");
                }
            }
     
            catch( ClassNotFoundException e){
                System.out.println("드라이버 로딩 실패");
            }
     
            catch( SQLException e){
                System.out.println("에러 " + e);
            }
     
            finally{
                try{
                    if( conn != null && !conn.isClosed()){
                        conn.close();
                    }
                    if( pstmt != null && !pstmt.isClosed()){
                        pstmt.close();
                    }
                }
                catch( SQLException e){
                    e.printStackTrace();
                }
            }
        }
    }
     
     

     

    • Insert 쿼리를 수행할 때도 먼저 Connection 객체를 얻어야 한다.
    • INSERT는 일반적으로 동적으로 값이 할당되므로 createStatement()를 호출하지 않고, 쿼리를 준비하는 statement라는 의미로 prepareStatement() 메서드를 호출한다.
    • 그러면 PreparedStatement 를 반환하는데, pstmt.setString() 메서드를 통해 동적으로 값을 할당할 수 있다.
    • 값이 할당되면 pstmt.executeUpdate() 메서드를 실행하여 INSERT 쿼리를 실행 할 수 있다.
    • 반환 값은 영향을 미친 row의 개수이다.

     

    마무리

    • 쿼리를 수행할 때 동적으로 할당해야 하는 값이 있으면 PreparedStatement 객체를 사용하고, 동적으로 할당할 필요가 없으면 Statement 객체를 사용한다.
    • 쿼리의 결과가 있으면 executeQuery() 메서드를 호출하여 ResultSet 객체에 담고, 쿼리의 결과가 없으면 executeUpdate() 메서드를 호출하여 int형 변수에 결과 값을 할당한다.

     

    Reference

    https://victorydntmd.tistory.com/145

     

    [Java] JDBC 사용하기 ( MySQL )

    1. JDBC란? 자바에서 데이터베이스를 사용하기 위한 절차에 대한 규약입니다. DBMS에 따라 DB를 다루는 방식이 다르다면, 사용자는 알아야 할 것이 매우 많을 것입니다. 그래서 JDBC를 통해 추상화된 인터페이스를..

    victorydntmd.tistory.com

     

     

    반응형

    댓글

Designed by Tistory.