獲得hibernate的sql語句(2.1.6)

來源:互聯網
上載者:User

獲得hibernate的sql語句

我們知道hibernate會將hql解析成sql,也許在某些時候,我們需要這些sql。
不過hibernate的介面中沒有公開的api,看來我們得自己行動了。

1.開始前的工作
  1.1 知道如何閱讀javadoc api
  1.2 知道如何使用ant編譯hibernate源碼包
  1.3 hibernate源碼包在hibernate壓縮包的src目錄,api文檔在doc目錄

2.在執行Query.list()方法時,hibernate在控制台輸出sql。從api文檔中我們知道, Query介面有個實作類別是net.sf.hibernate.impl.AbstractQueryImpl,但這個虛類中並沒有實現list方法,繼續查該類的子類net.sf.hibernate.impl.QueryImpl,呵呵,找到了。

list
public List list()          throws HibernateException
Description copied from interface: Query
Return the query results as a List. If the query contains multiple results pre row, the results are returned in an instance of Object[].

Returns:
the result list
Throws:
HibernateException

3.查看net.sf.hibernate.impl.QueryImpl原始碼,發現這裡吧實現丟給了Session介面,看來我們得去找Session介面的麻煩。

public List list() throws HibernateException {
    verifyParameters();
    Map namedParams = getNamedParams();
    return getSession().find( bindParameterLists(namedParams), getQueryParameters(namedParams) );
}

4.介面是沒有實現代碼的,因此我們直接看實作類別net.sf.hibernate.impl.SessionImple的原始碼

public List find(String query, QueryParameters queryParameters) throws HibernateException {

    if ( log.isTraceEnabled() ) {
        log.trace( "find: " + query );
        queryParameters.traceParameters(factory);
    }

    queryParameters.validateParameters();

    QueryTranslator[] q = getQueries(query, false);

    List results = Collections.EMPTY_LIST;

    dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called

    //execute the queries and return all result lists as a single list
    try {
        for ( int i=0; i<q.length; i++ ) {
            List currentResults;
            try {
                currentResults = q[i].list(this, queryParameters); // 原來list是由這個類做的
            }
            catch (SQLException sqle) {
                throw new JDBCException("Could not execute query", sqle);
            }
            currentResults.addAll(results);
            results = currentResults;
        }
    }
    finally {
        dontFlushFromFind--;
    }
    return results;
}

5. 在api文檔左下角All Classes架構搜尋QueryTranslator,查到後點擊查看api,嗯,有料。

getSQLString
public String getSQLString()
Description copied from class: Loader
The SQL query string to be called; implemented by all subclasses

Specified by:
getSQLString in class Loader

6.但是我們並不想處理第4步中找到的find方法的QueryParameters參數,怎麼辦捏?參考一下其他find方法

private static final Object[] NO_ARGS = ArrayHelper.EMPTY_STRING_ARRAY;
private static final Type[] NO_TYPES = ArrayHelper.EMPTY_TYPE_ARRAY;

/**
* Retrieve a list of persistent objects using a hibernate query
*/
public List find(String query) throws HibernateException {
    return find(query, NO_ARGS, NO_TYPES); // 他交給了三個參數的介面
}

public List find(String query, Object value, Type type) throws HibernateException {
    return find( query, new Object[] { value }, new Type[] { type } ); // 又丟給另一個介面處理
}

public List find(String query, Object[] values, Type[] types) throws HibernateException {
    return find(query, new QueryParameters(types, values) ); // 回到2參數的介面手裡了
}

 

7.開始修改,將第4步找到的代碼複製出來更改如下,然後添加回SessionImpl類

public String[] getSQLStrings(String query) throws HibernateException {

    // 採用單參數介面處理queryParameters的方法
    QueryParameters queryParameters = new QueryParameters(NO_ARGS, NO_TYPES);
    if ( log.isTraceEnabled() ) {
        log.trace( "find: " + query );
        queryParameters.traceParameters(factory);
    }

    queryParameters.validateParameters();

    QueryTranslator[] q = getQueries(query, false);

    String[] results = new String[q.length]; // 建立傳回值

    dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called

    //execute the queries and return all result lists as a single list
    try {
        for ( int i=0; i<q.length; i++ ) {
            try {
                results[i] = q[i].getSQLString(); // 獲得sql語句
            }
            catch (SQLException sqle) {
                throw new JDBCException("Could not execute query", sqle);
            }
        }
    }
    finally {
        dontFlushFromFind--;
    }
    return results;
}

8.給Session介面增加一個方法

public String[] getSQLStrings(String query) throws HibernateException;

9.編譯之後大功告成,我們可以使用Session.getSQLStrings(query)獲得sql語句數組

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.