2017-12-14 17 views
0

무한 코드없이 이것을 수행하려면 좋은 디자인 패턴은 무엇입니까?Java로 PreparedStatement를 구축하기 변수가있는 데이터베이스에 데이터를 삽입하기위한 열 수

사용자가 1 ... 100 열을 입력 할 수 있다고 가정 할 때, 한 번에 23 회, 다른 인서트에 32 회, 다른 삽입에 99 개의 필드 등이 있습니다. 각 필드마다 매번 다른 필드가있을 수 있습니다.

자바에서의 PreparedStatement가 column names 먼저 입력해야할지 알 필요가

에서, INSERT 쿼리의 값 부분에 넣어 얼마나 많은 ? 's의 데이터베이스 필드 이름의 데이터 유형을 보장 할 수있는 올바른 setIntsetString 등이있다 입력되었습니다.

약 10 개 미만의 열에 대해서는 다음 논리로 이러한 문제를 해결할 수 있습니다.

1) variableEnteredForFieldName이 널이 아닌 경우, 문자열 빌더 유형 설정의 형식으로 조회의 관련 부분에 추가하십시오.

fieldName_1 

? 

2)) 모든 입력 필드 이름

3) 자연적으로 모두 field names에 존재합니다 최종 후행 ,을 스트립에 같은과 ?

4는 어떻게 만듭니 까 PreparedStatement

5) 동일한 입력 매개 변수를 다시 실행하여 variableEnteredForFieldName이 null이 아닐 경우 null이 아닌지 확인한 다음 알려진 데이터를 기반으로 setInt 또는 setString을 실행합니다. 데이터베이스에 필요한 유형을?들에 대해 올 Y 른 색인 x 호로 설정하십시오.

쿼리 작성기 논리와 쿼리 필러 논리가 파트 1과 파트 2에서 올바른 순서로 이름/값을 갖는 경우 모두 올바르게 작동합니다. 그러나 이것은 PreparedStatement를 작성할 때 사용할 SQL을 생성하고 PreparedStatement를 채우기 위해이 논리와 관련된 전체 코드를 복제하는 것을 의미합니다.

이것은 적은 수의 입력 매개 변수에 대해 관리 할 수 ​​있지만 더 많은 수의 입력 매개 변수에 대해서는 관리하기가 쉽지 않습니다.

같은 논리를 달성하기위한 더 좋은 디자인 패턴이 있습니까?

아래 코드는 위의 모든 내용을 요약 한 것입니다.

String fieldName1 = request.getParameter("fieldName1"); 
    String fieldName2 = request.getParameter("fieldName2"); 

    //Build Query 
    String fieldNames = ""; 
    String fieldQuestionMarks = ""; 

    if (fieldName1 != null) { 
     fieldNames = fieldNames + " FIELD_NAME_1 ,"; 
     fieldQuestionMarks = fieldQuestionMarks + " ? ,"; 
    } 

    if (fieldName2 != null) { 
     fieldNames = fieldNames + " FIELD_NAME_2 ,"; 
     fieldQuestionMarks = fieldQuestionMarks + " ? ,"; 
    } 

//Trim the trailing , 
    fieldNames = fieldNames.substring(1, fieldNames.length() - 1); 
    fieldQuestionMarks = fieldQuestionMarks.substring(1, fieldQuestionMarks.length() - 1); 


    try { 
     String completeCreateQuery = "INSERT INTO TABLE_NAME (" + fieldNames + ") VALUES (" + fieldQuestionMarks + ");"; 
     Connection con = DriverManager.getConnection(connectionURL, user, password); 
     PreparedStatement preparedStatement = con.prepareStatement(completeCreateQuery); 

     int parameterIndex = 1; 

     //Fill Query 
     if (fieldName1 != null) { 
      preparedStatement.setString(parameterIndex, fieldName1); 
      parameterIndex++; 
     } 

     if (fieldName2 != null) { 
      preparedStatement.setInt(parameterIndex, Integer.parseInt(fieldName2)); 
      parameterIndex++; 
     } 
    } 

여기서 알 수 있습니다. 그러나 단지 2 개의 선택적 필드가 있더라도이 코드는 매우 큽니다.

+0

모든 필드를 하드 코딩하는 대신 루프를 사용하지 않는 한 "거대한"것입니다. 이것은 필드 이름과 값을'Map' 데이터 구조에 넣는 것을 포함합니다. –

+0

수정하십시오.그러나 Map이 키/값 저장소 인 경우이 필드의 데이터 유형은 고려하지 않습니다. –

답변

0

사용자가 목록에서 임의의 열을 생략 할 수있는 경우 모든 열은 선택 사항이며 삽입 중에 NULL로 안전하게 설정할 수 있습니다. 따라서 모든 열이 나열된 "괴물"INSERT가있는 준비된 문 하나만 있으면됩니다. 실제 삽입 조작 중에 사용자가 제공 한 데이터를 반복하고 제공된 열의 값을 설정하고 생략 된 열을 setNull()으로 호출합니다. SQL 문에서 열 이름을 순서대로 매핑하는 어딘가의 구조 (DAO 클래스)를 유지해야합니다.

+0

@ 짐 주둔군 : downvote하시기 바랍니다 설명하십시오. 내가 본 방식대로, 연결된 질문은 실제적으로 실용적인 솔루션을 제안하지 않았고, 제안 된 제안도 실제로 제안 된 바가 아니었다. –

+0

나는이 답변이 왜 그렇게 빨리 투표에 실패했는지 궁금했다. 제 자신이 알렉스에게 제공해 준 완벽한 해결책입니다. 이것은 단순히 괴물 INSERT 문을 만들 수 있었고 사용자가이 매개 변수에 데이터를 입력하지 않은 경우 간단히 언급 한 setNull() 옵션을 사용할 수 있습니다. 나는 그 기능을 몰랐다. 감사. –