獲得hibernate的SQL(SQL Server培訓 MySQL培訓 )語句我們知道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: HibernateException3.查看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
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 Loader6.但是我們並不想處理第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
8.給Session接口增加一個方法 public String[] getSQLStrings(String query) throws HibernateException;9.編譯之後大功告成,我們可以使用Session.getSQLStrings(query)獲得sql語句數組 :)