获得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,呵呵,找到了。
listpublic List 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() ) { 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 |
5. 在api文档左下角All Classes框架搜索QueryTranslator,查到后点击查看api,嗯,有料。
getSQLStringpublic String getSQLString()
|
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; /** public List find(String query, Object value, Type type) throws HibernateException { public List find(String query, Object[] values, Type[] types) throws HibernateException {
|
7.开始修改,将第4步找到的代码复制出来更改如下,然后添加回SessionImpl类
publicString[] 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 |
8.给Session接口增加一个方法
public String[] getSQLStrings(String query) throws HibernateException; |
9.编译之后大功告成,我们可以使用Session.getSQLStrings(query)获得sql语句数组 :)