1. 程式人生 > >spring-data-jpa原理探祕(2)-RepositoryQuery的用途和分類

spring-data-jpa原理探祕(2)-RepositoryQuery的用途和分類

本系列的第二篇文章,主要講解在spring-data-jpa中佔有重要地位的RepositoryQuery介面的用途和分類。
首先我們看看RepositoryQuery介面極其子類的類圖

上圖很清晰的說明,RepositoryQuery介面包含SimpleJpaQuery,NativeJpaQuery,PartTreeJpaQuery,NamedQuery,StoredProcedureJpaQuery等(葉子節點)子類。

JpaRepositoryFactory類在動態例項化Repository介面時,其父類RepositoryFactorySupport定義了一個私有Map類變數:
private final Map<Method, RepositoryQuery> queries = new ConcurrentHashMap<Method, RepositoryQuery>();
而動態例項化Repository介面時,將例項化一個QueryExecutorMethodInterceptor,為其增加監聽和interceptor。上篇文章提到過,QueryExecutorMethodInterceptor是RepositoryFactorySupport的內部類,實現了org.aopalliance.intercept.MethodInterceptor攔截器介面。
例項化QueryExecutorMethodInterceptor時會直接執行其構造器,我們看到,給每個方法都建立了一個RepositoryQuery例項,並put到了上面所說的ConcurrentHashMap私有Map類變數中,程式碼如下:
for (Method method : queryMethods) {
	RepositoryQuery query = lookupStrategy.resolveQuery(method, repositoryInformation, factory, namedQueries);

	invokeListeners(query);
	queries.put(method, query);
}
RepositoryQuery的直接抽象子類是AbstractJpaQuery,可以看到,一個RepositoryQuery例項持有一個JpaQueryMethod例項,JpaQueryMethod又持有一個Method例項,所以RepositoryQuery例項的用途很明顯,一個RepositoryQuery代表了Repository介面中的一個方法,根據方法頭上註解不同的形態,將每個Repository介面中的方法分別對映成相對應的RepositoryQuery例項。

下面我們就來看看spring-data-jpa對RepositoryQuery例項的具體分類:
1.SimpleJpaQuery
方法頭上@Query註解的nativeQuery屬性預設值為false,也就是使用JPQL,此時會建立SimpleJpaQuery例項,並通過兩個StringQuery類例項分別持有query jpql語句和根據query jpql計算拼接出來的countQuery jpql語句;

2.NativeJpaQuery
方法頭上@Query註解的nativeQuery屬性如果顯式的設定為nativeQuery=true,也就是使用原生SQL,此時就會建立NativeJpaQuery例項;

3.PartTreeJpaQuery
方法頭上未進行@Query註解,將使用spring-data-jpa獨創的方法名識別的方式進行sql語句拼接,此時在spring-data-jpa內部就會建立一個PartTreeJpaQuery例項;

4.NamedQuery
使用javax.persistence.NamedQuery註解訪問資料庫的形式,此時在spring-data-jpa內部就會根據此註解選擇建立一個NamedQuery例項;

5.StoredProcedureJpaQuery
顧名思義,在Repository介面的方法頭上使用org.springframework.data.jpa.repository.query.Procedure註解,也就是呼叫儲存過程的方式訪問資料庫,此時在spring-data-jpa內部就會根據@Procedure註解而選擇建立一個StoredProcedureJpaQuery例項。

未完待續。