2023-java-study / book-study

북 스터디 기록 레포지토리
0 stars 0 forks source link

ResultSet 생성 #217

Open ssstopeun opened 8 months ago

ssstopeun commented 8 months ago
@Override
    public Optional<User> findByUserIdAndUserPassword(String userId, String userPassword) {
        //todo#11 -PreparedStatement- 아이디 , 비밀번호가 일치하는 회원조회
        try(Connection connection = DbUtils.getConnection()){
            String sql = "select * from jdbc_users where user_id= ? and user_password = ?";

            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,userId);
            preparedStatement.setString(2,userPassword);
            ResultSet resultSet = preparedStatement.executeQuery();
            //preparedStatement.close();
            if(resultSet.next()){
                User user = new User(resultSet.getString("user_id"),resultSet.getString("user_name"),resultSet.getString("user_password"));
                preparedStatement.close();
                return Optional.of(user);
            }
            return Optional.empty();
        }catch(SQLException e){
            log.info("Error findByUserIdAndUserPassword : {}",e.getMessage());
            return Optional.empty();
        }
    }

이거 preparedStatement.close() 주석된 부분에 처음 작성했을 때 user정보가 읽어와지지가 않는데 close하기 전데 ResultSet에 저장해놓고 close하는건데 왜 resutset정보가 왜 날아가는건지 아시나요..?

gmelon commented 8 months ago

java.sql.Statement 인터페이스 문서를 보면 Statement를 닫을 때 ResultSet도 같이 닫아준다고 합니다. 서로 연관되어있는 것 같아요! image

https://docs.oracle.com/en/java/javase/11/docs/api/java.sql/java/sql/Statement.html#close()

mysql 구현체의 경우 com.mysql.cj.jdbc.StatementImpl의 close() 메서드에서 resultSet을 같이 닫아주고 있네요. image

해당 클래스는 아래의 필드를 갖는데, image

ResultSet을 상속받는 인터페이스라네용 image

gmelon commented 8 months ago

@ssstopeun 두개가 서로 같이 닫히는건 첨 알았네요. try-with-resources로 PreparedStatement 를 닫아주면 안전하게 두 개를 모두 닫는게 될까요? 어떻게 생각하시나유

닫아주는 시점이 중요해보이는군요..?

ssstopeun commented 8 months ago

저 코드에서 PreparedStatement도 try-with으로 두개를 닫게 해주려고 했는데 preparedStatement가 sql문을 받아야 생성이 되는데 이 sql문을 try-with-resources안에 넣을 수 없어서 밖으로 뺐던 거였거든요..ㅠ

ssstopeun commented 8 months ago

sql문을 try밖에서 생성하고 try-with-resources에서 connection과 preparedStatement를 넣으면 되는거였어요. 왜 밖에 뺄생각을 순간 못했을까용..ㅎ...

@Override
    public Optional<User> findByUserIdAndUserPassword(String userId, String userPassword) {
        String sql = "select * from jdbc_users where user_id= ? and user_password = ?";
        //todo#11 -PreparedStatement- 아이디 , 비밀번호가 일치하는 회원조회
        try(Connection connection = DbUtils.getConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(sql)){
            preparedStatement.setString(1,userId);
            preparedStatement.setString(2,userPassword);
            ResultSet resultSet = preparedStatement.executeQuery();

            if(resultSet.next()){
                User user = new User(resultSet.getString("user_id"),resultSet.getString("user_name"),resultSet.getString("user_password"));
                return Optional.of(user);
            }
            return Optional.empty();
        }catch(SQLException e){
            log.info("Error findByUserIdAndUserPassword : {}",e.getMessage());
            return Optional.empty();
        }
    }
ssstopeun commented 8 months ago

resutSet은 생성하면 유지되는줄알았는데 같이 닫겨버리는게 신기하네용 감사합니다