spring-data-jpa原理过程

 

RepositoryFactoryBeanSupport

1,创建工厂,获取entitymanager   afterPropertiesSet

2,获取工厂代理,包括 查询类策略RepositoryQuery实例即@Query标签的  放到map中        initAndReturn

 

一个RepositoryQuery实例持有一个JpaQueryMethod实例,JpaQueryMethod又持有一个Method实例。一个被标注的方法就有一个JpaQueryMethod一个RepositoryQuery

 

 

initAndReturn中new  QueryExecutorMethodInterceptor:

 

Iterable<Method> queryMethods = repositoryInformation.getQueryMethods();

for (Method method : queryMethods) {

RepositoryQuery query = lookupStrategy.resolveQuery(method, repositoryInformation, namedQueries); 创建RepositoryQuery

invokeListeners(query);

queries.put(method, query);

}

 

 

JpaQueryLookupStrategy:

public final RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, NamedQueries namedQueries) {

return resolveQuery(new JpaQueryMethod(method, metadata, provider), em, namedQueries);

}

 

 

JpaQueryLookupStrategy内部类CreateIfNotFoundQueryLookupStrategy:

@Override

protected RepositoryQuery resolveQuery(JpaQueryMethod method, EntityManager em, NamedQueries namedQueries) {

 

try {

return lookupStrategy.resolveQuery(method, em, namedQueries);

} catch (IllegalStateException e) {

return createStrategy.resolveQuery(method, em, namedQueries);

}

}

 

 

 

JpaQueryLookupStrategy:private static class CreateQueryLookupStrategy extends AbstractQueryLookupStrategy {

 

@Override

protected RepositoryQuery resolveQuery(JpaQueryMethod method, EntityManager em, NamedQueries namedQueries) {

 

RepositoryQuery query = JpaQueryFactory.INSTANCE.fromQueryAnnotation(method, em, evaluationContextProvider);

 

if (null != query) {

return query;

}

 

query = JpaQueryFactory.INSTANCE.fromProcedureAnnotation(method, em);

 

if (null != query) {

return query;

}

 

String name = method.getNamedQueryName();

if (namedQueries.hasQuery(name)) {

return JpaQueryFactory.INSTANCE.fromMethodWithQueryString(method, em, namedQueries.getQuery(name),

evaluationContextProvider);

}

 

query = NamedQuery.lookupFrom(method, em);

 

if (null != query) {

return query;

}

 

throw new IllegalStateException(String.format(

"Did neither find a NamedQuery nor an annotated query for method %s!", method));

}

 

 

 

///这里决定用什么query

//SimpleJpaQuery

//NativeJpaQuery

//PartTreeJpaQuery

//NamedQuery

//StoredProcedureJpaQuery

JpaQueryFactory:

AbstractJpaQuery fromMethodWithQueryString(JpaQueryMethod method, EntityManager em, String queryString,

EvaluationContextProvider evaluationContextProvider) {

 

if (queryString == null) {

return null;

}

 

return method.isNativeQuery() ? new NativeJpaQuery(method, em, queryString, evaluationContextProvider, PARSER) : //

new SimpleJpaQuery(method, em, queryString, evaluationContextProvider, PARSER);

}

 

 

 

 

 

 

 

 

JpaQueryMethod 就是Repository接口中带有@Query注解方法的全部信息,包括注解,类名,实参等的存储类,所以Repository接口有多少个@Query注解方法,

就会包含多少个JpaQueryMethod实例被加入监听序列。实际运行时,一个RepositoryQuery实例持有一个JpaQueryMethod实例,JpaQueryMethod又持有一个Method实例。

 

 

工具类

 

Parameters是一个JpaParameters实例,存储的是参数名和参数值的键值对集合,JpaParameters还包含一个内部类JpaParameter,它extends Parameter;

 

 

 

JpaQueryExecution

 

抽象类和继承类也可以放在一个类中,继承类当作抽象类的内部类

 

spring-data-jpa使用了内部类来实现JpaQueryExecution的子类,也就是包含多个查询运行策略的(子)类。这么做其实是一种相对的封闭形式,

造成使用者只能实例化spring-data-jpa给出的这8种子类。你无法实现自己的JpaQueryExecution子类,在spring框架初始化时通过配置加载之。

 

 

 

 

AbstractJpaQuery  用来选择具体那种JpaQueryExecution子类

 

JpaQueryExecution内部类SingleEntityExecution:

static class SingleEntityExecution extends JpaQueryExecution {

 

@Override

protected Object doExecute(AbstractJpaQuery query, Object[] values) {

 

return query.createQuery(values).getSingleResult();/////这里正式使用orm联系数据库

}

}

 

SingleEntityExecution只覆盖了一个父类方法,而且实现里只有一条语句query.createQuery(values).getSingleResult();在执行这句时,

会调用底层数据库访问提供商,spring-data-jpa默认选择的是hibernate,执行数据库存取操作之后,将结果返回给这个JpaQueryExecution实例。

 

 参考:

http://blog.csdn.net/gaolu/article/details/53415420

 

 

猜你喜欢

转载自yuhuiblog6338999322098842.iteye.com/blog/2381077