【问题标题】:What is the difference between hibernate session's getNamedQuery(String name) and createNamedQuery(String name)?hibernate session 的 getNamedQuery(String name) 和 createNamedQuery(String name) 有什么区别?
【发布时间】:2017-12-22 11:05:37
【问题描述】:

我正在使用 Spring 和 Hibernate 开发一个应用程序。我想知道为什么有两个单独的方法 getNamedQuery(String name) 和 createNamedQuery(String name)。

我检查了 Javadoc here 并发现描述相似,除了 createNamedQuery 接受本机 sql(有单独的方法 createNativeQuery、getNamedNativeQuery、getNamedSQLQuery 来创建本机查询)。

我想了解是否有任何其他根本区别使我的查询更快/更慢。

获取命名查询:

查询 getNamedQuery(String queryName) 为命名查询创建一个 Query 实例。 参数: queryName - 预定义的命名查询的名称 回报: 用于操作和执行的查询实例 抛出: IllegalArgumentException - 如果未使用给定名称定义查询或发现查询字符串无效

创建命名查询:

Query createNamedQuery(String name) JPA 定义的命名查询 创作方法。此表单可以表示 HQL/JPQL 查询或原生 询问。参数: name - 预定义的命名查询的名称 返回:用于操作和执行的 Query 实例 IllegalArgumentException - 如果尚未使用 给定名称,或者如果发现查询字符串无效另请参阅: EntityManager.createNamedQuery(String)

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    TL;DR
    这两种方法执行(除了一些小事情)相同的处理:尝试使用几乎相同的逻辑执行命名的 JPQL 或 SQL 查询。


    你说的很好,这些方法的javadoc应该几乎相同,而它们不同。

    Query getNamedQuery(String queryName);

    为命名查询创建一个查询实例。

    参数:

    queryName预定义的命名查询的名称

    Query createNamedQuery(String name);

    JPA 定义的命名查询创建方法。这种形式可以代表 HQL/JPQL 查询或本机查询。

    参数

    name预定义的命名查询的名称

    它给人的感觉是getNamedQuery() 可能不会处理任何类型的查询。

    对于此类问题,了解差异的最佳方法通常是查看方法实现。

    这些方法的实现位于org.hibernate.internal.AbstractSharedSessionContract 类中。

    我们可以在这里看到 createNamedQuery() 依赖于 buildQueryFromName()

    @Override
    public QueryImplementor createNamedQuery(String name) {
        final QueryImplementor<Object> query = buildQueryFromName( name, null );
        query.getParameterMetadata().setOrdinalParametersZeroBased( false );
        return query;
    }
    
    protected  <T> QueryImplementor<T> buildQueryFromName(String name, Class<T> resultType) {
        checkOpen();
        checkTransactionSynchStatus();
        delayedAfterCompletion();
    
        // todo : apply stored setting at the JPA Query level too
    
        final NamedQueryDefinition namedQueryDefinition = getFactory().getNamedQueryRepository().getNamedQueryDefinition( name );
        if ( namedQueryDefinition != null ) {
            return createQuery( namedQueryDefinition, resultType );
        }
    
        final NamedSQLQueryDefinition nativeQueryDefinition = getFactory().getNamedQueryRepository().getNamedSQLQueryDefinition( name );
        if ( nativeQueryDefinition != null ) {
            return (QueryImplementor<T>) createNativeQuery( nativeQueryDefinition, resultType );
        }
    
        throw exceptionConverter.convert( new IllegalArgumentException( "No query defined for that name [" + name + "]" ) );
    }
    

    我们可以看到 getNamedQuery() 执行 buildQueryFromName()createNamedQuery() 所做的事情:

    @Override
    public QueryImplementor getNamedQuery(String name) {
        checkOpen();
        checkTransactionSynchStatus();
        delayedAfterCompletion();
    
        // look as HQL/JPQL first
        final NamedQueryDefinition queryDefinition = factory.getNamedQueryRepository().getNamedQueryDefinition( name );
        if ( queryDefinition != null ) {
            return createQuery( queryDefinition );
        }
    
        // then as a native query
        final NamedSQLQueryDefinition nativeQueryDefinition = factory.getNamedQueryRepository().getNamedSQLQueryDefinition( name );
        if ( nativeQueryDefinition != null ) {
            return createNativeQuery( nativeQueryDefinition, true );
        }
    
        throw exceptionConverter.convert( new IllegalArgumentException( "No query defined for that name [" + name + "]" ) );
    }
    

    要解释这两种看起来不受欢迎的重复方法的存在,您必须知道createNamedQuery() 来自 Persistence API(更具体的为EntityManager 接口),而getNamedQuery() 是 Hibernate 特定的方法(定义仅在org.hibernate.Session 界面中)。
    getNamedQuery() 方法是在很早的 Hibernate 版本中定义的。
    例如,Hibernate 3.0(2005 年发布)已经有了。
    The specification (JPA) 是在 2009 年发布的,所以在 Hibernate 之后, 不一定要保留所有 Hibernate 方法/类。
    而不受欢迎的重复方法(以及我们在其实现中看到的处理过程中)。

    【讨论】:

      猜你喜欢
      • 2013-03-14
      • 1970-01-01
      • 2023-02-02
      • 2011-01-28
      • 2014-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多