2017-12-22 9 views
2

저는 Spring과 Hibernate를 사용하는 어플리케이션을 개발 중입니다. 나는 두 개의 분리 된 메소드 인 getNamedQuery (String name)과 createNamedQuery (String name)이 왜 있는지 궁금하다. hibernate 세션의 getNamedQuery (String name)과 createNamedQuery (String name)의 차이점은 무엇입니까?

나는 자바 독 here를 확인하고 (createNativeQuery는 getNamedNativeQuery, getNamedSQLQuery 네이티브 쿼리를 만들 수있는 별도의 방법이있어) 네이티브 SQL을 받아 createNamedQuery 제외하고는 유사한 될 수있는 설명을 발견했다.

내 기본 쿼리가 더 빠르거나 느린 지 여부를 이해하고 싶습니다.

getNamedQuery :

쿼리 getNamedQuery (문자열 여기서 queryname) 명명 된 쿼리에 대한 쿼리 인스턴스를 만듭니다. 매개 변수 : 여기서 queryname - 사전 정의 된 명명 된 질의 반환의 이름 : 조작 및 실행 에 대한 조회 인스턴스 예외 : 는 IllegalArgumentException - 쿼리가 지정된 이름을 가지는 경우, 또는 정의되지 않은 경우 쿼리 문자열은 유효하지 않은 것으로 확인

createNamedQuery :

쿼리 createNamedQuery (문자열 이름)을 JPA 정의라는 이름의 쿼리 생성 방법. 이 양식은 HQL/JPQL 쿼리 또는 네이티브 쿼리를 나타낼 수 있습니다. 파라미터 : name - 사전 정의 된 이름 첨부 쿼리의 이름 조작 및 실행 용의 Query 인스턴스 예외 : IllegalArgumentException - 지정된 이름이 인 쿼리가 아직 정의되어 있지 않은 경우, 또는 쿼리 캐릭터 라인이 발견되었을 경우 또한 잘못된 참조 : EntityManager.createNamedQuery (문자열)

답변

1

TL; DR
두 가지 방법은 (몇 가지 사소한 것들을 제외)을 수행 동일 처리 : 거의으로 명명 된 JPQL 또는 SQL 쿼리를 실행하려고 같은 논리. 이러한 방법의 javadoc는이 다를 때 거의 동일해야합니다으로


귀하의 발언이 좋다.

Query getNamedQuery(String queryName);


명명 된 쿼리에 대한 쿼리 인스턴스를 생성합니다.

매개 변수 :

여기서 queryname 미리 정의 된 명명 된 쿼리

그리고

Query createNamedQuery(String name);

JPA에 정의라는 이름의 쿼리 작성의 이름 방법. 이 양식은 HQL/JPQL 쿼리 또는 네이티브 쿼리를 나타낼 수 있습니다. 매개 변수

:

이름 미리 정의 된 명명 된 쿼리

의 이름이 getNamedQuery() 쿼리의 모든 종류를 처리 할 수 ​​있다는 느낌을 준다.

이러한 종류의 질문에 대해 차이점을 이해하는 가장 좋은 방법은 메소드 구현을 자주 조사하는 것입니다.

이러한 방법의 구현은 org.hibernate.internal.AbstractSharedSessionContract 클래스에 있습니다.

@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 + "]")); 
} 

그리고 우리가 createNamedQuery()을 위해 무엇을 buildQueryFromName() 자체를 수행 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()이 지속성 AP에서 비롯된 것임을 알아야합니다. I (EntityManager 인터페이스를 더 구체적으로), getNamedQuery()은 Hibernate 특정 메소드 (org.hibernate.Session 인터페이스에서만 정의 됨)입니다.
getNamedQuery() 메소드는 Hibernate 초기 버전에서 정의되었다.
예를 들어 Hibernate 3.0 (2005 년에 릴리스 됨)은 이미 그랬습니다.
The specification (JPA)은 2009 년에 릴리즈되었으므로, Hibernate 이후에 은 반드시 모든 Hibernate 메소드/클래스를 유지할 필요가 없다.
반면 바람직하지 않은 중복 된 방법 (및 구현에서 볼 수있는 처리에서도).