ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링 DB - JDBC개발 - 등록
    Data Base/스프링 DB 2023. 11. 20. 14:51

    JDBC 개발 - 등록

    이제 본격적으로 JDBC를 사용해서 애플리케이션을 개발해보자

    ex) JDBC를 사용해서 회원(`Member`)데이터를 데이터베이스에 관리하는 기능을 개발해보자.

     

    schema.sql

    -- 기존 member 테이블 삭제
    drop table member if exists cascade;
    
    -- 새로운 member 테이블 생성
    create table member(
    member_id varchar(10),
    money integer not null default 0,
    primary key (member_id)
    );

     

    Member

    package hello.jdbc.repository;
    
    import hello.jdbc.connection.DBConnectionUtil;
    import hello.jdbc.domain.Member;
    import lombok.extern.slf4j.Slf4j;
    
    import java.sql.*;
    
    /**
     * JDBC - DriverManager 사용
     */
    @Slf4j
    public class MemberRepositoryV0 {
    
        public Member save(Member member) throws SQLException{
            String sql = "insert into member(member_id, money) values(?, ?)";
    
            Connection con = null;
            //Statment - 그냥 sql
            //파라미터 바인딩 기능
            PreparedStatement pstmt = null;
    
            try {
                con = getConnection();
                pstmt = con.prepareStatement(sql);
                pstmt.setString(1,member.getMemberId());
                pstmt.setInt(2,member.getMoney());
                //영향 받은 row의 숫자를 반환
                int count = pstmt.executeUpdate();
                return  member;
            }catch (SQLException e){
                log.error("db error",e);
                e.printStackTrace();
                throw  e;
            }finally {
                //Exception이 발생할 경우 finally가 실행x
                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(); //SQLException
               } 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();
        }
    }

     

    커넥션 획득

    • getConnection() : 이전에 만들어둔 DBConnectionUtil을 통해서 데이터베이스 커넥션을 획득한다.

     

    save() - SQL 전달

    • sql : 데이터베이스에 전달할 SQL을 정의한다. 여기서는 데이터를 등록해야 하므로 insert sql을 준비한다.
    • con.prepareStatement(sql) : 데이터베이스에 전달할 SQL과 파라미터로 전달할 데이터들을 준비한다.
      • sql : "insert into member(member_id, money) values(?, ?)";
      • pstmt.setString(1, member.getMemberId()) : SQL의 첫번째 "?" 에 값을 지정한다. 문자이므로 setString()을 지정한다.
      • pstmt.setInt(2, member.getMoney()) : SQL의 두번째 "?" 에 값을 지정한다. Int형 숫자이므로 setInt()를 지정한다.
    • pstmt.executeUpdate() : Statement를 통해 준비된 SQL을 커넥션을 통해 실제 데이터베이스에 전달한다. 참고로 executeUpdate()는 int를 반환하는데 영향받은 DB row수를 반환한다. 이번 예시에서는 하나의 row를 등록했으므로 1을 반환한다.

     

     

    executeUpdate()

    int executeUpdate() throws SQLException;

     

    리소스 정리

    쿼리를 실행하고 나면 리소스를 정리해야한다. 위 예시에서는 Connection, PreparedStatemnet를 사용했다. 리소스를 정리할 때는 항상 역순으로 해야한다. Connection을 먼저 획득하고 Connection을 통해 PreparedStatement를 만들었기 때문에 리소슬르 반환할 때는 PreparedStatement를 먼저 종료하고, 그 다음에 Connection을 종료하면 된다. 참고로 여기서 사용하지 않은 ResultSet은 결과를 조회할 때(select 쿼리) 사용한다.

     

    ❗주의
    리소스 정리는 꼭! 해주어야 한다. 따라서 예외가 발생하든 , 하지 않든 항상 수행되어야 하므로 `finally` 구문에 주의해서 작성해야한다. 만약 이 부분을 놓치게 되면 커넥션이 끊어지지 않고 계속 유지되는 문제가 발생할 수 있다. 이런 것을 리소스 누수라고 하는데, 결과적으로 커넥션 부족으로 장애가 발생할 수 있다.

     

    ➕참고
    PreparedStatement 는 Statement의 자식 타입인데 "?" 를 통한 파라미터 바인딩을 가능하게 해준다. 참고로 SQL Injection 공격을 예방하려면 PreparedStatement를 통한 파라미터 바인딩 방식을 사용해야 한다.

     

     

     

    ➡️테스트 코드를 사용해서 JDBC로 회원을 데이터베이스에 등록해보자.

    MemberRepositoryV0Test-회원등록

    package hello.jdbc.repository;
    
    import hello.jdbc.domain.Member;
    import org.junit.jupiter.api.Test;
    
    import java.sql.SQLException;
    
    import static org.junit.jupiter.api.Assertions.*;
    
    class MemberRepositoryV0Test {
    
        MemberRepositoryV0 repository = new MemberRepositoryV0();
    
        @Test
        void crud() throws SQLException {
            Member member = new Member("memberV1", 10000);
            repository.save(member);
        }
    
    }

     

     

    [출저 - 스프링 DB 1편 - 데이터 접긎 핵심 원리, 김영한]

    https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-db-1

     

    스프링 DB 1편 - 데이터 접근 핵심 원리 - 인프런 | 강의

    백엔드 개발에 필요한 DB 데이터 접근 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 DB 접근 기술의 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 백엔

    www.inflearn.com

     

    댓글

Designed by Tistory.