2017-06-07 40 views
0
class Request{ 
    private string f1; 
    private string f2; 
    private string f3; 
} 

我有以下查詢從Request是NamedParameterJdbcTemplate設置PARAMS用或操作者與檢查空

SELECT * FROM tbl WHERE f1 = 'val' OR f2 = 'val2' OR f3 = 'va3' 

字段可以null。我需要創建NamedParameterJdbcTemplate查詢並檢查每個字段的null

String query = "SELECT * FROM tbl"; 
if (request.getF1() !=null && !request.getF1().isEmpty()){ 
      query += .... 
     } 

這是一個非常糟糕的解決方案....

我能創造這樣

Map<String, Object> namedParameters = new HashMap<>(); 

檢查所有字段null,如果沒有null添加至地圖,並設置查詢?並且在jdbc-template中設置運算符OR

回答

0

您無法在框外動態查詢構建器(如果value爲null,則將其從where部分中排除)。你應該創建自己的構建器。

,如果你需要在一個,二個地方ececute動態查詢,你可以這樣做:

只是重構request.getF1() !=null && !request.getF1().isEmpty()爲可讀和可支持的,是這樣的:

String select = SqlDynamicWhereSectionWithOrHelper.getInstance(). 
       applyIfPresentValue(fieldName1 , value1). 
       applyIfPresentValue("" , null). 
       applyIfPresentValue(fieldName2 , value2) 
       .buildSqlWithWhere(GIVEN_SELECT); 



public final class SqlDynamicWhereSectionWithOrHelper { 
    private StringBuffer whereSqlQuery = new StringBuffer(); 
    public static final String WHERE = " where "; 
    public static final String OR = " or "; 
    private boolean whereNotPresent = true; 

    private SqlDynamicWhereSectionWithOrHelper() { 
    } 

    public static SqlDynamicWhereSectionWithOrHelper getInstance() { 
     return new SqlDynamicWhereSectionWithOrHelper(); 
    } 

    public SqlDynamicWhereSectionWithOrHelper applyIfPresentValue(String fieldName, String fieldValue) { 
     if (isNotEmpty(fieldValue) && isNotEmpty(fieldName)) { 
      applyWhereOrOr(fieldName + "=" + wrapValue(fieldValue)); 
     } 
     return this; 
    } 

    public String buildSqlWithWhere(String mainQueryWithoutWhere) { 
     return mainQueryWithoutWhere + whereSqlQuery.toString(); 
    } 

    //private section 
    private String wrapValue(String fieldValue) { 
     return "'" + fieldValue + "'"; 
    } 

    private void applyWhereOrOr(String predicate) { 
     String prefix = OR; 
     if (whereNotPresent) { 
      whereNotPresent = false; 
      prefix = WHERE; 
     } 
     whereSqlQuery.append(prefix); 
     whereSqlQuery.append(predicate); 
    } 

    //if you have apache common(or some other implementation) use method from lib StringUtils.isEmpty(String value) 
    private boolean isNotEmpty(String value) { 
     return value != null && value.trim().length() > 0; 
    } 

} 

並測試它

private static final String GIVEN_SELECT = "select * from table"; 

@Test 
    public void testForWithParamsWithNull(){ 
     //set-up data 
     String fieldName1 = "field1"; 
     String value1 = "value for field1"; 

     String fieldName2 = "field2"; 
     String value2 = "value for field2"; 

     StringBuffer expectedSelectBuffer = new StringBuffer(GIVEN_SELECT); 
     expectedSelectBuffer.append(SqlDynamicWhereSectionWithOrHelper.WHERE); 
     expectedSelectBuffer.append(fieldName1+"='"+value1+"'"); 
     expectedSelectBuffer.append(SqlDynamicWhereSectionWithOrHelper.OR); 
     expectedSelectBuffer.append(fieldName2+"='"+value2+"'"); 
     String expectedSelect = expectedSelectBuffer.toString(); 

     //execution 

     String resultSelect = SqlDynamicWhereSectionWithOrHelper.getInstance(). 
       applyIfPresentValue(fieldName1 , value1). 
       applyIfPresentValue("" , null). 
       applyIfPresentValue(fieldName2 , value2) 
       .buildSqlWithWhere(GIVEN_SELECT); 

     //verification 
     assertThat(resultSelect , is(notNullValue())); 
     assertThat(resultSelect ,equalTo(expectedSelect)); 
    } 

你也可以嘗試與修復它的SQL檢查空的,但如果你有很多數據要通過,這種技術會減慢你的請求。

SELECT * FROM tbl WHERE (f1 = 'val' or f1 = null) OR (f2 = 'val2' or f2 = null) OR (f3 = 'va3' or f3=null) 
相關問題