티스토리 뷰

Spring/JPA

JDBC 사용해보기

땅속 디그다 2022. 8. 23. 11:19

JDBC 사용 이유

관계형 데이터 베이스에는 상당히 많은 종류가 존재

문제점

  • 데이터 베이스를 다른 종류의 데이터 베이스로 변경하면 애플리케이션 서버에 개발된 데이터 베이스 사용 코드도 함께 변경
  • 개발자가 각각의 데이터 베이스마다 커넥션 연결 SQL 전달 결과 응답 받는게 다 다름

❗ 해결을 위해 JDBC 표준 인터페이스의 등장


✅ JDBC 표준 인터페이스

  • 자바에서 데이터베이스에 접속할 수 있도록 하는 자바 API
  • 데이터 베이스에서 자료를 쿼리하거나 업데이트하는 방법을 제공
  • 크게 3가지 기능을 제공
    1. 연결
    2. SQL을 담은 내용
    3. SQL 요청 응답

🤔 jdbc 에서 connection 얻기

  1. JDBC가 제공하는 DriverManager.getConnection() 의 사용
  2. DataSource 상속 받은 DriverManagerDataSource 사용하기 (spring이 제공)DataSource.getConnection() 사용
  3. ✅ 1 에서 2번이 되면서 매번 url, username, password 를 입력했으나 (1번) 한번만 입력하기만 되게 바뀜
  4. 커넥션 풀 사용
    결국 커넥션 풀로 사용할 때도 DataSource.getConnection() 을 사용한다.

 

🖍 DriverManger.getConnection()

jdbc 는 인터페이스로서 각 구현체들은 관계형 DB 마다 따로 구현이 되어있다. (라이브러리에 저장)

  1. DriverManager 는 라이브러리에 등록된 드라이버 목록을 자동으로 인식한다.
  2. 드라이버들에게 순서대로 URL, user, password 정보를 넘겨 커넥션을 획득할 수 있는지 확인한다.
  3. url 의 prefix를 기준으로 확인한다.

public class DBConnectionUtil {

    public static Connection getConnection() {
        try {
            // TCP/IP 를 사용해 매번 새로운 커넥션 획득하기
            // DataSource 구현체가 아니기 때문에 Connection 을 얻기 위해 매번 정보를 넘겨야한다.
            Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            log.info("get connection={}, class={}", connection, connection.getClass());
            return connection;
        } catch (SQLException e) {
            throw new IllegalStateException(e);
        }
    }
}

지금까지의 흐름 요약

  1. jdbc에서 데이터베이스를 사용하기 위해서 커넥션을 위한 URL, USER, PASSWORD
  2. 커넥션을 얻기위해 DriverManager.getConnection 사용 (매번 설정 정보 넘겨야 함)
    커넥션을 얻을때 현재 라이브러리 정보 + URL을 통해 구현체 주입
  3. 얻은 커넥션으로 비지니스 로직 수행
  4. 결국 jdbc 의 등장 첫번째 이유는 다양한 db의 커넥션 지원이다. (인터페이스를 통해)

비지니스 로직 구현

회원 등록하기

🖥 회원 등록 Jdbc 이용

@Slf4j
public class MemberRepositoryV0 {
    public Member save(Member member) throws SQLException {
          // insert sql 준비
          String sql = "insert into member(member_id, money) values(?, ?)";
          Connection con = null;
          // 데이터 베이스에 전달할 SQL과 파라미터로 전달할 데이터 준비
          PreparedStatement pstmt = null;
          try {
              con = getConnection();
              pstmt = con.prepareStatement(sql);
              // 파라미터 할당
              pstmt.setString(1, member.getMemberId());
              pstmt.setInt(2, member.getMoney());
              // 커넥션을 통해 SQL 전달
              pstmt.executeUpdate();
              return member;
    } catch (SQLException e) {
        log.error("db error", e);
        throw e;
    } finally {
              //커넥션 닫기
              close(con, pstmt, null);
    }
}

// 리소스 정리하기
private void close(Connection con, Statement stmt, ResultSet rs) {
    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException e) {
            log.info("error", e);
} }
    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException e) {
            log.info("error", e);
        }
}
    if (con != null) {
        try {
            con.close();
        } catch (SQLException e) {
            log.info("error", e);
        }
} }
private Connection getConnection() {
    return DBConnectionUtil.getConnection();
}

 }

Jdbc 의 조회

🖥 Jdbc 에서의 조회 쿼리

public Member findById(String memberId) throws SQLException {
      String sql = "select * from member where member_id = ?";
      Connection con = null;
      PreparedStatement pstmt = null;
      ResultSet rs = null;
      try {
          con = getConnection();
          pstmt = con.prepareStatement(sql);
          pstmt.setString(1, memberId);
          // iterator 형식으로 결과 값을 받아온다.
          rs = pstmt.executeQuery();
          if (rs.next()) {
              Member member = new Member();
              member.setMemberId(rs.getString("member_id"));
              member.setMoney(rs.getInt("money"));
              return member;
          } else {
              throw new NoSuchElementException("member not found memberId=" + memberId); }
      } catch (SQLException e) {
          log.error("db error", e);
          throw e;
} finally {
           close(con, pstmt, rs);
      }
}

'Spring > JPA' 카테고리의 다른 글

트랜잭션 이해하기  (1) 2022.08.23
커넥션 풀  (0) 2022.08.23
JPA - 값 타입  (0) 2022.08.23
프록시와 연관관계 관리  (0) 2022.08.23
고급 매핑  (0) 2022.08.23
댓글
11-08 12:46
Total
Today
Yesterday
링크