본문 바로가기
프로젝트/selfmade Blog - V1 (deprecated)

3. 블로그 글 작성 기능 - 조회 기능 및 중복 Context 추출

by zangsu_ 2023. 8. 11.

조회 기능

이번에는 작성된 글을 인덱스를 활용해 조회해 보자.

public Posting findByIdx(int idx){  
    Posting posting = null;  
    try (Connection conn = 
    DriverManager.getConnection(url, userName, password)) {
      
        PreparedStatement ps = conn.prepareStatement(
        "select * from posting where idx = ?");  
        ps.setString(1, String.valueOf(idx));  
        ResultSet rs = ps.executeQuery();  
        if (rs.next()) {  
            posting = new Posting();  
            posting.setIdx(rs.getInt("idx"));  
            posting.setTitle(rs.getString("title"));  
            posting.setContent(rs.getString("content"));  
            posting.setUser_idx(rs.getInt("user_idx"));  
        }  
    } catch (SQLException e) {  
        e.printStackTrace();  
    }  
  
    return posting;  
}


전달받은 idx 값을 이용해 Posting 정보를 조회해 오는 기능을 구현했다.

 

중복 로직 추출

그런데, 이와 같이 DB에서 특정 객체를 조회하는 연산 역시 자주 사용할 것 같으니 추출을 해 두는 편이 좋을 것 같다.

인터페이스에 다음의 메서드를 추가하자.

public <R, I> R getObject(String sql, Function<ResultSet, R> mapper, I identifier);

리턴 값으로 <R> 타입의 객체를 리턴하는 getObject() 메서드이다.


sql 변수에 식별을 위한 값을 대입하기 위해 I identifier 변수를 사용했다.
그리고, 사용하는 sql의 형태에 따라 ResultSet에서 객체로 변환하기 위한 과정이 조금씩 다를텐데, 이를 함수형 인터페이스 Function<ResultSet, R> 타입의 mapper를 전달받아 해결하도록 했다.

DAOContext의 getObject() 메서드는 다음과 같이 구현될 것이다.

public <R, I> R getObject(String sql, 
  Function<ResultSet, R> mapper, 
  I identifier) {  
    R returnObject = null;  
    try (Connection conn = getConnect()) {  
        PreparedStatement ps = conn.prepareStatement(sql);  
        ps.setString(1, identifier.toString());  
        ResultSet rs = ps.executeQuery();  
  
        if (rs.next()) {  
            returnObject = mapper.apply(rs);  
        }  
    } catch (SQLException e) {  
        e.printStackTrace();  
    }  
  
    return returnObject;  
}

ResultSet에서 R returnObject를 얻기 위해 mapper.apply()를 사용한다.

위와 같이 작성해 주고 나면 findByIndex() 메서드는 다음과 같이 사용할 수 있게 된다.

 

public Posting findByIdx(int idx){  
    Posting posting = daoContext.getObject(
    "select * from posting where idx = ?",  
            rs -> {  
                Posting p = new Posting();  
                try {  
                    p.setIdx(rs.getInt("idx"));  
                    p.setTitle(rs.getString("title"));  
                    p.setContent(rs.getString("content"));  
                    p.setUser_idx(rs.getInt("user_idx"));  
                } catch (SQLException e) {  
                    e.printStackTrace();  
                }  
                return p;  
            },  
            idx);  
    return posting;  
}

 

mapper의 부분이 너무 길어지니, 이 부분을 따로 분리해 내자.

private Function<ResultSet, Posting> postingMapper = rs -> {  
    Posting p = new Posting();  
    try {  
        p.setIdx(rs.getInt("idx"));  
        p.setTitle(rs.getString("title"));  
        p.setContent(rs.getString("content"));  
        p.setUser_idx(rs.getInt("user_idx"));  
    } catch (SQLException e) {  
        e.printStackTrace();  
    }  
    return p;  
};

 

그러고 나면, findByIndex() 메서드를 훨씬 간결하게 작성할 수 있다.

public Posting findByIdx(int idx){  
    Posting posting = daoContext.getObject("select * from posting where idx = ?", 
    	postingMapper, 
        idx);  
    return posting;  
}

 

글 생성에 이어 조회하는 기능까지 구현했다.

게다가, JDBC를 사용하면서 자주 사용하게 될 기능들에 대해 중복적으로 사용하게 될 문맥을 분리해 두었다.

댓글