sha*_*ulk 5 java hibernate jpa
我正在使用 Spring 和 Hibernate 开发应用程序。我想知道为什么有两个单独的方法 getNamedQuery(String name) 和 createNamedQuery(String name)。
我在这里检查了 Javadoc ,发现除了 createNamedQuery 接受本机 sql 之外,描述是相似的(有单独的方法 createNativeQuery、getNamedNativeQuery、getNamedSQLQuery 来创建本机查询)。
我想了解是否有任何其他根本区别使我的查询更快/更慢。
获取命名查询:
Query getNamedQuery(String queryName) 为命名查询创建一个 Query 实例。参数: queryName - 预定义的命名查询的名称返回: 用于操作和执行的查询实例抛出: IllegalArgumentException - 如果未使用给定名称定义查询或发现查询字符串无效
创建命名查询:
Query createNamedQuery(String name) JPA 定义的命名查询创建方法。这种形式可以表示 HQL/JPQL 查询或本机查询。参数: name - 预定义的命名查询的名称返回: 用于操作和执行的查询实例抛出: IllegalArgumentException - 如果未使用给定名称定义查询或发现查询字符串无效另请参见: EntityManager.createNamedQuery(String)
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 + "]" ) );
}
Run Code Online (Sandbox Code Playgroud)
我们可以看到getNamedQuery()
它的表现与buildQueryFromName()
for 的作用相同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 + "]" ) );
}
Run Code Online (Sandbox Code Playgroud)
为了解释这两个看起来不合需要的重复方法的存在,您必须意识到它们createNamedQuery()
来自 Persistence API(EntityManager
更具体地说是接口),而getNamedQuery()
是 Hibernate 特定方法(仅在org.hibernate.Session
接口中定义)。
方法getNamedQuery()
是在非常早期的 Hibernate 版本中定义的。
例如 Hibernate 3.0(2005 年发布)就已经具备了这一点。
该规范(JPA
)于 2009 年发布,因此在 Hibernate 之后,不一定保留所有 Hibernate 方法/类。
而不受欢迎的重复方法(以及我们在其实现中看到的处理过程中)。
归档时间: |
|
查看次数: |
1606 次 |
最近记录: |