2012-01-10 3 views
0

문제점이 있습니다 - SQL 쿼리를 동적으로 생성하고 사용자 입력 옵션을 기반으로합니다. 따라서 사용자는 5 개의 매개 변수를 가지며 (실제로는 더 많음) 매개 변수의 일부 (원하는 경우 모두) 또는 없음을 선택하거나 쿼리에서 값을 지정할 수 있습니다. 그래서 매개 변수가 선택되었는지와 값이 제공되었는지 확인하여 쿼리 문자열 (기본 WHERE 조건)을 구성합니다. 그러나 지금은 '와 같은 특수 문자의 문제가 있습니다. replaceAll (" '", "\\")을 사용하려고 시도 할 수는 있지만 이것은 상당히 둔하며 PreparedStatement.setString()이 작업을 잘 수행한다는 것을 알고 있습니다. 그러나 나를 위해 필자는 매개 변수가 제공된 지, 이전 매개 변수가 있었는지 다시 확인하는 것보다 (독을 지정하고 올바른 매개 변수에 연결하는 것보다) 필요합니다. 이것은 많은 조합을 일으키고 우아하게 보이지 않습니다.preparedStatem.setString()에서 문자열을 가져올 수 있습니까?

내 질문은 - 어쨌든 preparedStatement.setString() 문자열을 생성 할 수 있습니까? 또는 동일한 작업을 수행하고 문자열을 수동으로 쿼리에 넣을 수있는 비슷한 기능이 있습니다.

어쩌면 소개가 너무 길었지 만 누군가가 더 좋은 아이디어를 가지고있을 수 있고 내가 왜 필요로하는지 설명하고 싶었을 것입니다.

+1

나는 확실히 당신의 질문을 이해하지 않습니다하지만 당신은 절대적으로 100 % setString 등을 이용해야한다()를 사용하는 것이 좋습니다. –

+0

코드의 해당 부분을 포함하십시오. –

+0

제공되는 매개 변수에 따라 '?'문자가 포함 된 쿼리 문자열을 구성해야한다고 생각합니다. 그런 다음 쿼리 문자열을 얻은 다음 매개 변수를 반복하여'setString()'을 호출합니다. 그게 속임수일까요? –

답변

0

매개 변수가 지정되었는지 여부에 따라 매개 변수화되지 않은 기본 SQL 쿼리를 작성한 다음 준비된 문을 사용하여 매개 변수를 채우십시오. 그것은이 (밑그림) 같은 것을 볼 수 있었다

:

Map<String, Object> parameterValues = /*from user*/; 
List<String> parameterNames = Arrays.asList("field1", "field2", "field3"); 
List<Object> valueList = new ArrayList<Object>(); 

StringBuilder statementBuilder = new StringBuilder("select * from table where "); 
for (String parameterName : parameterNames) { 
    if (parameterValues.containsKey(parameterName)) { 
     statementBuilder.append(parameterName + " = ? AND"); 
     valueList.add(parameterValues.get(parameterName)); 
    } 
} 

PreparedStatement st = conn.prepareStatement(statementBuilder.toString(), 
         valueList); 
//set each parameter here. 

그것은 단지 하드 처음을; 그러면 일반화 할 수 있습니다. 거기에는 아마도이 모든 것을 추상화 한 쿼리 빌더가있을 것입니다. QueryDSL을 사용하지만 순수한 JDBC에 대한 바인딩이 아니라 JPA와 JDO 등에 대한 바인딩이 있습니다.

+0

마크 - 예. 나는 매우 비슷합니다. 문제는 나중에 매개 변수를 설정하는 것입니다. 이것이 제 질문이었습니다. 매개 변수에 번호가 매겨지기 때문에 이전 매개 변수가 설정되었는지 확인해야합니다. 즉 parameterB에 대해 매개 변수 A가 설정되었는지 확인한 다음 setString (2, parB)을 사용하고 setString (1, parB)을 사용하지 않는지 확인해야합니다. 매개 변수 C의 경우 A 및 B가 1,2 또는 3 위치에있을 수 있으므로 확인해야합니다. 이것은 어려운 부분입니다. 그래서 setString과 같은 값을 준비하기 위해 일부 함수를 사용하여 수동으로 설정해야합니다. –

+0

@ srd.pl : 목록의 요점은 그렇게 할 필요가 없다는 것이 었습니다. for 루프를 간단하게 수행하고 인덱스를 증가시킬 수 있습니다. 값이 * 지정된 경우에만 valueList에 값을 저장하므로 목록의 요소 위치는 준비된 명령문에서의 위치입니다. –

+1

@ mark-peters Querydsl DOES는 Querydsl SQL 모듈에서 JDBC에 대한 바인딩을 가지고 있습니다. –