肯利亚玫瑰

导航

从Hibernate中获取SQL语句

获得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: 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<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 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<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;Array.编译之后大功告成,我们可以使用session.getsqlstrings(query)获得sql语句数组 :)

posted on 2012-06-12 11:00  肯利亚玫瑰  阅读(1096)  评论(0)    收藏  举报