Java

本类阅读TOP10

·使用MyEclipse开发Struts框架的Hello World!(录像1)
·hibernate配置笔记
·AOP编程入门--Java篇
·linux下Tomcat 5.0.20 与 Apache 2 安装/集成/配置
·在win2003下整合了整合Tomcat5.5+ apache_2.0.53+ mod_jk_2.0.47.dll
·构建Linux下IDE环境--Eclipse篇
·Jsp 连接 mySQL、Oracle 数据库备忘(Windows平台)
·ASP、JSP、PHP 三种技术比较
·Tomcat5.5.9的安装配置
·AWT GUI 设计笔记(二)

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
获得hibernate的sql语句(2.1.6)

作者:未知 来源:月光软件站 加入时间:2005-5-13 月光软件站

获得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语句数组 :)




相关文章

相关软件