2012-06-13 2 views
1

간단한 클라이언트 측 호출 형식으로 JDBC 쿼리의 ResultSet을 반환하는 편리한 메소드를 작성하는 것이 목적입니다. 나는이 같은 것을 쓴형식의 인수를 준비하는 방법 : List <Entry <? extends 클래스 <?>,? >>

이 편리한 클래스를 사용하여

public class JdbcQueryManager { 
    public static ResultSet executePreparedStatementWithParameters(
     Connection jdbcConnection, String sqlQuery, 
     Map.Entry<? extends Class<?>, ?>... sqlQueryParameters) 
     throws JdbcQueryFailureException { 
    return executePreparedStatementWithParameters(jdbcConnection, sqlQuery, 
     Arrays.asList(sqlQueryParameters), ResultSet.TYPE_FORWARD_ONLY, 
     ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT); 
    } 
    private static ResultSet executePreparedStatementWithParameters(
     Connection jdbcConnection, String sqlQuery, 
     List<Map.Entry<? extends Class<?>, ?>> sqlQueryParameters, 
     int resultSetType, int resultSetConcurrency, int resultSetHoldability) 
     throws JdbcQueryFailureException { 
    try { 
     PreparedStatement preparedStatement = 
      jdbcConnection.prepareStatement(sqlQuery, resultSetType, 
       resultSetConcurrency, resultSetHoldability); 
     for (int i = 0; i < sqlQueryParameters.size(); i++) { 
     int sqlQueryParameterIndex = i + 1; // SQL parameters are 1-based 
     Entry<? extends Class<?>, ?> sqlQueryParameter = 
      sqlQueryParameters.get(i); 
     Class<?> sqlQueryParameterClass = sqlQueryParameter.getKey(); 
     if (sqlQueryParameterClass == Integer.class) { 
      int sqlQueryParameterIntegerValue = 
       (Integer) sqlQueryParameter.getValue(); 
      preparedStatement.setInt(sqlQueryParameterIndex, 
       sqlQueryParameterIntegerValue); 
     } else if (sqlQueryParameterClass == String.class) { 
      String sqlQueryParameterStringValue = 
       (String) sqlQueryParameter.getValue(); 
      preparedStatement.setString(sqlQueryParameterIndex, 
       sqlQueryParameterStringValue); 
      // TODO: accept other types, not just String and Integer 
     } else { 
      throw new JdbcQueryFailureException(new IllegalArgumentException(
       sqlQueryParameterClass.getName())); 
     } 
     } 
     ResultSet resultSet = preparedStatement.executeQuery(); 
     return resultSet; 
    } catch (SQLException sqlException) { 
     throw new JdbcQueryFailureException(sqlException); 
    } 
    } 
} 

:

public class QueryParameter<T> extends AbstractMap.SimpleEntry<Class<T>, T> { 
    @SuppressWarnings("unchecked") 
    public QueryParameter(T parameterValue) { 
    super((Class<T>) parameterValue.getClass(), parameterValue); 
    } 
} 

이 같은 JDBC SQL 문을 수행 할 수 있도록 :

ResultSet resultSet = 
    JdbcQueryManager.executePreparedStatementWithParameters(jdbcConnection, 
     sqlQuery, new QueryParameter<String>("AnswerRequest"), 
     new QueryParameter<Integer>(42)); 

. .. 어떻게하면 좋을까요? 당신은 무엇 클래스 각 당신의 방법을 말하려고 -

List<Map.Entry<? extends Class<?>, ?>> 
+0

사이드 노트 : 포맷터는 줄당 150 자 이상을 받아 들여야합니다. 이것이 일반적으로 IMO가 된 이유입니다. – sp00m

+1

그 이유는 무엇입니까? :) 기본적으로 "한 줄에 더 많은 문자가있는 형식 코드"/ "더 넓은"을 의미합니까? – Robottinosino

+0

IMHO, 당신은 단지 전체'QueryParameter' 물건으로 당신의 삶을 복잡하게 만들고 있습니다. 왜'execute (sqlQuery, "AnswerRequest", 42)'와 같은 것을 사용하지 않습니까? 한 번 이런 식으로 썼고 그것은 작동합니다 (4 개의 다른 DB로). – maaartinus

답변

3

Map.Entry<? extends Class<?>, ?>의 목록을 전달에서 값이없는 :

특히, 내적인 혼란이 겉으로는 복잡 가능성이 불필요한 형태의 사용에 거짓말 매개 변수는입니다. 하지 마세요 !!! 통념

는 달리, 당신은 단지 preparedStatement.setObject(index, object)를 사용하고 JDBC 드라이버가 알아낼 것이다, 당신이 "기본"자바 객체 (포장 프리미티브 및 Dates)를 사용하는 경우 다양한 입력 된 preparedStatement.setXXX() 방법을 사용할 필요가 없습니다 것 할 것!

입력 된 설정자를 사용해야하는 경우는 객체가 이 아니고 "기본형"중 하나입니다. 실제로 이것을 필요로한다면 instanceof을 사용하여 각 매개 변수를 확인한 다음 사용하려는 문자열 값을 추출하기위한 코드를 작성해야하지만 여전히 해당 문자열로 preparedStatement.setObject(index, object)을 호출 할 수 있습니다.


나 자신이 뭔가를 작성하고 난 단순히 사용 :

public static ResultSet executePreparedStatementWithParameters(
    Connection jdbcConnection, String sqlQuery, Object... parameters) 

을하고 그냥 잘 작동합니다.

+0

나는 setObject (예 : Xerial의 Sqlite, PostreSQL 용 pgjdbc 등)를 구현하는 JDBC 드라이버가 거의 없으며 대부분의 경우 유형을 설정하기 전에 일련의 instanceof 검사 (Timestamp, Double, Integer, Float. java.util.Date 등)를 수행합니다. 당신은 "do not do this !!! !!!"에 많은 강조점을 두었습니다. 그 안에 약간의 해가있는 것처럼, 그것은 중복되어 불필요한 잠재적 인 버그 소스를 가져오고, 중복으로 인해 DRY를 위반하게됩니다. 비슷한 코드를 작성해도 코드를 공유 할 수 있습니까? – Robottinosino

+0

어떻게 이런 좋은 대답을 받아 들일 수 있습니까? – Robottinosino

관련 문제