簡體   English   中英

如何使用iBatis-Spring獲取參數化查詢

[英]How to get parameterized query with iBatis-Spring

我正在使用spring-ibatis集成的應用程序,我必須記錄一些執行的查詢。 所以我想做的,基本上是從XML配置文件中的ibatis映射語句中獲取SQL,然后以某種方式添加參數。 我已經能夠用這行代碼獲得查詢:

MappedStatement ms = (MappedStatement) ((SqlMapClientImpl) sqlMapClient)
    .getDelegate().getMappedStatement(queryId);

ms.setParameterClass(HashMap.class);
RequestScope scope = new RequestScope();
scope.setStatement(ms);

String sql = ((DynamicSql) ms.getSql()).getSql(scope, params);

所以第一行我得到MappedStatement,最后一行得到原始查詢。 問題是,即使我傳遞了帶有查詢參數的對象,SQL仍然有參數占位符'?' (在XML查詢中,它們被命名為參數,而不是位置參數)。

我試圖設置parameterClass字段而不是像這里建議的parameterMap但沒有成功。 我不確定如何使用內聯參數。

我正在使用ibatis-sqlmap 2.3.0spring-ibatis 2.0.8

你可能已經注意到我對iBatis知之甚少。 另外,請知道這是臟的,我正在使用我不應該的課程,不需要指出這一點。

感謝您的幫助。

我已經解決了這個問題,我希望與未來可能存在相同問題的讀者分享解決方案。 在此之前,請記住,這不是您應該使用iBatis的方式,而只是獲取底層SQL的一種骯臟的解決方法。

首先,我們需要在至少2組中對iBatis查詢進行分組:

  1. 靜態查詢 ,它們是沒有任何條件元素的簡單映射語句。

  2. 動態查詢 ,它們是帶有條件元素的映射語句(例如isEqualisGreaterThanisNull ...)。

一旦你完成了這個差異,這里是獲取SQL的代碼:

public static String getSQLFromDynamicQuery(SqlMapClient sqlMapClient,
        String queryId, Object paramObject) {

    // Gets the SQL and parameters.
    MappedStatement ms = ((SqlMapClientImpl) sqlMapClient).getDelegate()
            .getMappedStatement(queryId);
    RequestScope scope = new RequestScope();
    scope.setStatement(ms);
    String sql = ((DynamicSql) ms.getSql()).getSql(scope, paramObject);
    Object[] params = ms.getSql().getParameterMap(scope, paramObject)
            .getParameterObjectValues(scope, paramObject);

    // Adds params to the query.
    return bindQueryParam(sql, params);
}

public String getSQLFromStaticQuery(SqlMapClient sqlMapClient,
        String queryId, Object... params) {

    // Gets the SQL.
    String sql = ((StaticSql) ((SqlMapClientImpl) sqlMapClient)
            .getDelegate().getMappedStatement(queryId).getSql()).getSql(
            null, null);

    // Adds params to the query.
    if (params != null) {
        sql = bindQueryParam(sql, params);
    }

    return sql;
}

public static String bindQueryParam(String sql, Object... params) {
    String result = sql;
    for (Object param : params) {
        result = result.replaceFirst("\\?",
                param == null ? "null" : param.toString());
    }
    return result;
}

bindQueryParam方法用對象數組替換查詢中的問號。 對於靜態查詢,您必須同時為可以傳遞Objectjava.util.Map的動態數據傳遞該數組,具體取決於Mapped Statement的parameterClass

這兩種方法都使用顯式子廣播(我花了很多時間查看源代碼來弄清楚如何使這個工作如你所想),所以你可能要注意根據Mapped Statement調用正確的方法您正在處理或您將獲得ClassCastException

同樣,這不是推薦的方式,但如果您需要,它可以工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM