Skip to main content

Command Palette

Search for a command to run...

Jdbc와 사용예제

Updated
•4 min read•View as Markdown
Jdbc와 사용예제
  • JDBC(Java DataBase Connectivity)

    • 자바 프로그래밍 언어로 만들어진 클래스와 이루어진 API로서 SQL문을 실행할 수 있는 함수 호출 인터페이스이다

    • 데이터베이스가 달라지더라도 동일한 API를 사용하게 해준다(드라이버 및 URL은 수정해야 함)

    • 자바가 가지는 플랫폼에 독립적이라는 특성과 DBMS에 독립적인 특성을 가진다

      jdbc_architecture

  • JDBC API: java.sql package

    • Driver (interface)

      • 모든 드라이버가 반드시 구현해야 하는 인터페이스

      • 드라이버의 버전이나 연결에 대한 정보를 알 수 있는 메서드가 있다

    • Connection (interface)

      • 데이터베이스에 대한 하나의 세션을 표현한다

        • 세션은 하나의 클라이언트가 서버에 요청을 하기 위해 연결을 맺은 상태이다
        public interface Connection  extends Wrapper, AutoCloseable {
          //주요 메서드
        
          @CallerSensitive
          public static Connection getConnection(String url,
              String user, String password) throws SQLException {
              java.util.Properties info = new java.util.Properties();
        
              if (user != null) {
                  info.put("user", user);
              }
              if (password != null) {
                  info.put("password", password);
              }
        
              return (getConnection(url, info, Reflection.getCallerClass()));
          }
          //DriverManager 클래스의 getConnection() 메서드를 이용해 얻을 수 있다
        
          void setAutoCommit(boolean autoCommit) throws SQLException;
          //디폴트로 setAutoCommit(true)로 설정된다
          //개발자가 원하는 경우에 commit을 해주고 싶거나 트랜잭션이 아주 중요한 부분에 있어서 RollBack 처리를 하고자 할 경우에는 setAutoCommit(false)를 설정한다
          //단, 이경우에는 SQL문을 수행할 때마다 명시적으로 commit()을 호출해야 한다
        }
        
    • Statement (interface)

      • SQL문장을 실행하고 그것에 대한 결과 값을 가져오기 위해 사용한다

        public interface Statement extends Wrapper, AutoCloseable {
          //주요 메서드
        
          boolean execute(String sql) throws SQLException;
          //특별히 SQL문을 구분하지 않고 DML(delete, update, insert), Query(select), DDL(create, drop) 등을 수행할 수 있다
          //결과가 ResultSet이면 true이고 결과가 DML이거나 특별한 결과가 없으면 false를 리턴한다
        
          ResultSet executeQuery(String sql) throws SQLException;
          //Select를 처리할 때 사용한다
        
          int executeUpdate(String sql) throws SQLException;
          //주로 DML(delete, update, insert)등의 SQL
        
        }
        
    • PreparedStatement (interface)

      • 동일한 SQL 문장이 여러 번 반복적으로 수행될 때 사용하는 객체

      • 대용량의 문자나 바이너리 타입의 데이터(이미지나 사운드 등)를 저장하기 위해서도 사용될 수 있다

      • SQL 문장이 미리 컴파일 되어 PreparedStatement 객체에 저장된다

      • 여러 번 반복 수행 시 clearParameters() 메서드를 이용해 Statement에 남겨진 값을 초기화한다

        public interface PreparedStatement extends Statement {
          //주요 메서드
        
          ResultSet executeQuery() throws SQLException;
          //Select를 처리할 때 사용한다
        
          int executeUpdate() throws SQLException;
          //주로 DML(delete, update, insert) 등의 SQL을 수행할 때 사용한다
        
        }
        
    • Statement vs PreparedStatement

      • PreparedStatement 와 Statement의 가장 큰 차이점은 캐시(cache) 사용여부이다. Statement를 사용하면 매번 쿼리를 수행할 때마다 1)쿼리 문장 분석, 2)컴파일 3)실행 단계를 거치게 되고, PreparedStatement는 처음 한 번만 세 단계를 거친 후 캐시에 담아 재사용을 한다는 것이다. 만약 동일한 쿼리를 반복적으로 수행한다면 PreparedStatment가 DB에 훨씬 적은 부하를 주며, 성능도 좋다

      • 또한 사용자 입력값으로 쿼리를 생성하는 경우 PreparedStatement를 사용하면 "AA'AA"와 같은 사용자 입력 값을 파싱해주기 때문에 SQL Injection 등의 문제를 보완해줄 수 있다

      • 하지만 모든 쿼리를 PreparedStatement로 하면 DB에 SQL을 캐싱할 수 있는 한계가 있기 때문에 정작 성능상 캐싱되어야 할 쿼리가 캐싱이 안 될 수 있기 때문에 필요한 문장만 PreparedStatement를 쓰는 것이 좋다

      • Dynamic SQL을 사용한다면 매번 조건절이 틀려지게 됨으로 캐싱의 장점을 잃어버리니 Statement가 낫다. 코딩도 Statement가 편하다

    • CallableStatement (interface)

      • 데이터베이스에 대하여 실제 SQL문을 실행하는 것이 아니라 Stored Procedures를 호출한다

      • Stored Procedures란 연속되는 SQL문으로 데이터베이스에 저장해 두고 마치 함수의 호출처럼 사용한다

      • 데이터베이스에 Stored Procedures를 만들어 두고 자바에서 호출하여 사용할 수 있게 한다

      • Stored Procedures 사용 시 속도의 향상을 기대할 수 있고, 자바 코드에 SQL문장이 들어가지 않으므로 자바 코드가 SQL에 독립적이 된다

    • ResultSet (interface)

      • 쿼리에 대한 결과값 처리

      • ResultSet 객체의 커서는 첫번째 레코드보다 바로 이전을 가리킨다

        public interface ResultSet extends Wrapper, AutoCloseable {
          //주요 메서드
        
          boolean next() throws SQLException;
          //ResultSet 객체의 커서를 이동
        
          String getString(int columnIndex) throws SQLException;
          boolean getBoolean(int columnIndex) throws SQLException;
          int getInt(int columnIndex) throws SQLException;
          java.sql.Date getDate(int columnIndex) throws SQLException;
          //...
          //메서드를 이용하여 데이터를 얻을 수 있다
        }
        
  • JDBC Programming 개발 순서

    1. JDBC Driver Loading

      • 데이터베이스와의 접속을 오픈하기 위해 애플리케이션의 JVM안으로 특정 드라이버 클래스를 적재
    2. DBMS와 연결(Connection 생성)

      • DriverManager 클래스를 이용하여 URL형태로 주어진 데이터베이스에 대한 접속을 요청
    3. SQL 실행 준비

      • Statement, PreparedStatement 생성
    4. SQL 실행

      • DML(insert, update, delete)

      • Query(select)

    5. DBMS 연결 끊기

      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.PreparedStatement;
      import java.sql.SQLException;
      
      public class InsertTest {
      
       public InsertTest() {
           try {
               Class.forName("com.mysql.cj.jdbc.Driver");
               System.out.println("드라이버 로딩 성공!!!");
           } catch (ClassNotFoundException e) {
               e.printStackTrace();
               System.out.println("드라이버 로딩 실패!!!");
           }
       }
      
       private Connection getConnection() throws SQLException {
           return DriverManager.getConnection(
               "jdbc:mysql://localhost:3306/dbName?serverTimezone=UTC",
               "user",
               "password"
           );
       }
      
       private int register(String name, int age) {
           int cnt = 0;
           PreparedStatement pstmt = null;
           try (Connection conn = getConnection()) {
               //SQL 실행 준비
               StringBuilder sql = new StringBuilder("insert into jdbctest (name, age)");
               sql.append("values (?, ?)");
               pstmt = conn.prepareStatement((sql.toString()));
               pstmt.setString(1, name);
               pstmt.setInt(2, age);
               //SQL 실행
               cnt = pstmt.executeUpdate();
               System.out.println(cnt);
           } catch (SQLException e) {
               e.printStackTrace();
           }
           return cnt;
       }
      
       public static void main(String[] args) {
           InsertTest it = new InsertTest();
           int cnt = it.register("박주원", 29);
       }
      }
      
  • 참고 자료

More from this blog

[프론트] 노코드 툴 FlutterFlow로 개발하기

노코드 툴 사용 이유 프론트엔드에 적합하다 판단 앱을 개발하기 위해서는 사용자가 조작할 프론트와 기능 구현을 위한 백엔드가 모두 필요하다. 원하는 기능을 자세하게 구현하기 위해서는 코드를 작성해야한다. LLM이 더 발달하여 자연어만으로 구체적인 기능을 노코드로 개발하게 될 수도 있다. 하지만 아직 포트폴리오 리밸런싱 알고리즘 같은 기능은 코드로 구현하고 이해해야 한다. 반면 사용자가 조작할 화면은 노코드로 개발하기 적합하다고 판단했다. ...

May 28, 20241 min read
[프론트] 노코드 툴 FlutterFlow로 개발하기

부처님오신날 대체공휴일 쉬면서 떠오른 소소한 영감 기록

전환형 인턴 전반전이 끝나고 푹 쉬다 보니 소소하게 영감이 떠오른다. 정신 없이 개발만 집중하다가 확실히 여유로우니까 여러 생각이 떠오르는 것 같다. 보통 이동할 때 지하철 타고 가면서 코딩하는데, 오랜만에 버스 타고 바깥 풍경을 보면서 유튜브를 듣고 있다. 가만 보니 산은 경사져서 사람이 살기가 힘들다. 에너지적으로 xy축으로 같은 거리를 이동하는데 z축으로 위치 에너지가 계속 바뀌고 사람은 인체적으로 올라갈 때나 내려갈 때 모두 에너지를 소...

May 29, 20232 min read

로그인 처리2(서블릿 필터, 스프링 인터셉터, 로깅, @Login)

서블릿 필터 - 소개 공통 관심 사항 요구사항을 보면 로그인 한 사용자만 상품 관리 페이지에 들어갈 수 있어야 한다 앞에서 로그인을 하지 않은 사용자에게는 상품 관리 버튼이 보이지 않기 때문에 문제가 없어 보인다 그런데 문제는 로그인 하지 않은 사용자도 다음 URL을 직접 호출하면 상품 관리 화면에 들어갈 수 있다는 점이다 상품 관리 컨트롤러에서 로그인 여부를 체크하는 로직을 하나하나 작성하면 되겠지만, 등록, 수정, 삭제, 조회 등등 ...

Mar 24, 202312 min read
로그인 처리2(서블릿 필터, 스프링 인터셉터, 로깅, @Login)

로그인 처리1(쿠키, 세션)

로그인 처리하기 - 쿠키 사용 쿠키 서버에서 로그인에 성공하면 HTTP 응답에 쿠키를 담아서 브라우저에 전달하자 그러면 브라우저는 앞으로 해당 쿠키를 지속해서 보내준다 쿠키 종류 영속 쿠키 만료 날짜를 입력하면 해당 날짜까지 유지 세션 쿠키 만료 날짜를 생략하면 브라우저 종료시 까지만 유지 LoginController - login() @PostMapping("/login") public String l...

Mar 24, 20237 min read
로그인 처리1(쿠키, 세션)

배우고, 기록하고, 적용하기

55 posts