一、在application.yml在配置datasource的参数,hibernate,jpa的参数。
spring:
datasource:
url: jdbc:mysql://**
username: ***
password: ***
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 1
minIdle: 3
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 30000
validationQuery: select 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
filters: stat,wall,slf4j
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
useGlobalDataSourceStat: true
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
jpa:
show-sql: true
hibernate:
ddl-auto: none
在启动类上或者配置类上加上@EnableJpaRepositories注解,就会自动初始化配置jpa。
二、首先我们看搜索dao接口对象定义的流程
1.当spring容器搜索到@EnableJpaRepositories类时,会自动调用此注解所包含的@Import(JpaRepositoriesRegistrar.class)类来把新搜索到的类定义加载到容器工厂中。
@Inherited
@Import(JpaRepositoriesRegistrar.class)
public @interface EnableJpaRepositories {
2.然后会调到org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport.registerBeanDefinitions 注册BEAN 定义对象。
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry, BeanNameGenerator generator) {
Assert.notNull(metadata, "AnnotationMetadata must not be null!");
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
Assert.notNull(this.resourceLoader, "ResourceLoader must not be null!");
if (metadata.getAnnotationAttributes(this.getAnnotation().getName()) != null) {
AnnotationRepositoryConfigurationSource configurationSource = new AnnotationRepositoryConfigurationSource(metadata, this.getAnnotation(), this.resourceLoader, this.environment, registry, generator);
RepositoryConfigurationExtension extension = this.getExtension();
RepositoryConfigurationUtils.exposeRegistration(extension, registry, configurationSource);
RepositoryConfigurationDelegate delegate = new RepositoryConfigurationDelegate(configurationSource, this.resourceLoader, this.environment);
delegate.registerRepositoriesIn(registry, extension);
}
}
3.在扫描DAO包时org.springframework.data.repository.config.
RepositoryConfigurationSourceSupport.getCandidates,
public Streamable<BeanDefinition> getCandidates(ResourceLoader loader) {
RepositoryComponentProvider scanner = new RepositoryComponentProvider(this.getIncludeFilters(), this.registry);
scanner.setConsiderNestedRepositoryInterfaces(this.shouldConsiderNestedRepositories());
scanner.setEnvironment(this.environment);
scanner.setResourceLoader(loader);
this.getExcludeFilters().forEach((it) -> {
scanner.addExcludeFilter(it);
});
return Streamable.of(() -> {
return this.getBasePackages().stream().flatMap((it) -> {
return scanner.findCandidateComponents(it).stream();
});
});
}
4.在创建RepositoryComponentProvider的构造方法中,会加入Repository注解,RepositoryDefinition类的include filter,
public RepositoryComponentProvider(Iterable<? extends TypeFilter> includeFilters, BeanDefinitionRegistry registry) {
super(false);
Assert.notNull(includeFilters, "Include filters must not be null!");
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
this.registry = registry;
if (includeFilters.iterator().hasNext()) {
for (TypeFilter filter : includeFilters) {
addIncludeFilter(filter);
}
} else {
super.addIncludeFilter(new InterfaceTypeFilter(Repository.class));
super.addIncludeFilter(new AnnotationTypeFilter(RepositoryDefinition.class, true, true));
}
addExcludeFilter(new AnnotationTypeFilter(NoRepositoryBean.class));
}
5.RepositoryComponentProvider继承于ClassPathScanningCandidateComponentProvider 这里面实际上是调用
ClassPathScanningCandidateComponentProvider.scanCandidateComponents去搜索指定包目录下的符合条件的对象。
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = super.findCandidateComponents(basePackage);
Iterator var3 = candidates.iterator();
while(var3.hasNext()) {
BeanDefinition candidate = (BeanDefinition)var3.next();
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate);
}
}
return candidates;
}
这里面搜索到的candidates为所有系统中的dao文件。
三、dataSource对象的加载过程
1.org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,这个类在有配置spring.datasource.type时使用PooledDataSourceConfiguration初始化配置(即是外部指定数据源池),没有时使用EmbeddedDatabaseConfiguration初始化配置。
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@Conditional(EmbeddedDatabaseCondition.class)
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
@Import(EmbeddedDataSourceConfiguration.class)
protected static class EmbeddedDatabaseConfiguration {
}
@Configuration(proxyBeanMethods = false)
@Conditional(PooledDataSourceCondition.class)
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class,
DataSourceJmxConfiguration.class })
protected static class PooledDataSourceConfiguration {
}
/**
* {@link AnyNestedCondition} that checks that either {@code spring.datasource.type}
* is set or {@link PooledDataSourceAvailableCondition} applies.
*/
static class PooledDataSourceCondition extends AnyNestedCondition {
PooledDataSourceCondition() {
super(ConfigurationPhase.PARSE_CONFIGURATION);
}
@ConditionalOnProperty(prefix = "spring.datasource", name = "type")
static class ExplicitType {
}
}
/**
* {@link Condition} to detect when an embedded {@link DataSource} type can be used.
* If a pooled {@link DataSource} is available, it will always be preferred to an
* {@code EmbeddedDatabase}.
*/
static class EmbeddedDatabaseCondition extends SpringBootCondition {
private static final String DATASOURCE_URL_PROPERTY = "spring.datasource.url";
private final SpringBootCondition pooledCondition = new PooledDataSourceCondition();
}
}
2.由于我们指定的spring.datasource.type=com.alibaba.druid.pool.DruidDataSource,所以加载外部数据源连接池配置。然后会加载到DataSourceConfiguration.Generic会根据TYPE去创建数据源。
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type")
static class Generic {
@Bean
DataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
}
3.org.springframework.boot.jdbc.DataSourceBuilder去创建数据源。
public T build() {
Class<? extends DataSource> type = getType();
DataSource result = BeanUtils.instantiateClass(type);
maybeGetDriverClassName();
bind(result);
return (T) result;
}
四、org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration进行jpa的几个对象初始化。
1.org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration会import导入HibernateJpaConfiguration.class,
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(HibernateProperties.class)
@ConditionalOnSingleCandidate(DataSource.class)
class HibernateJpaConfiguration extends JpaBaseConfiguration {
HibernateJpaConfiguration(DataSource dataSource, JpaProperties jpaProperties,
ConfigurableListableBeanFactory beanFactory, ObjectProvider<JtaTransactionManager> jtaTransactionManager,
HibernateProperties hibernateProperties,
ObjectProvider<Collection<DataSourcePoolMetadataProvider>> metadataProviders,
ObjectProvider<SchemaManagementProvider> providers,
ObjectProvider<PhysicalNamingStrategy> physicalNamingStrategy,
ObjectProvider<ImplicitNamingStrategy> implicitNamingStrategy,
ObjectProvider<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers) {
super(dataSource, jpaProperties, jtaTransactionManager);
this.hibernateProperties = hibernateProperties;
this.defaultDdlAutoProvider = new HibernateDefaultDdlAutoProvider(providers);
this.poolMetadataProvider = new CompositeDataSourcePoolMetadataProvider(metadataProviders.getIfAvailable());
this.hibernatePropertiesCustomizers = determineHibernatePropertiesCustomizers(
physicalNamingStrategy.getIfAvailable(), implicitNamingStrategy.getIfAvailable(), beanFactory,
hibernatePropertiesCustomizers.orderedStream().collect(Collectors.toList()));
}
@Override
protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
return new HibernateJpaVendorAdapter();
}
@Override
protected Map<String, Object> getVendorProperties() {
Supplier<String> defaultDdlMode = () -> this.defaultDdlAutoProvider.getDefaultDdlAuto(getDataSource());
return new LinkedHashMap<>(this.hibernateProperties
.determineHibernateProperties(getProperties().getProperties(), new HibernateSettings()
.ddlAuto(defaultDdlMode).hibernatePropertiesCustomizers(this.hibernatePropertiesCustomizers)));
}
}
2.而HibernateJpaConfiguration这个类又继承于org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration,所以会加载JpaBaseConfiguration的@BEAN配置。这里面会创建几个JPA的重要对象,如
EntityManagerFactoryBuilder用来创建实体管理器的工厂对象。
JpaVendorAdapter为jpa厂商适配器。主要用来指定实现JPA的具体组件,如HIBERNATE等。
LocalContainerEntityManagerFactoryBean用来创建具体的实体管理器工厂对象。
PlatformTransactionManager用来创建事务管理器。
@Import(DataSourceInitializedPublisher.Registrar.class)
public abstract class JpaBaseConfiguration implements BeanFactoryAware {
private final DataSource dataSource;
private final JpaProperties properties;
private final JtaTransactionManager jtaTransactionManager;
private ConfigurableListableBeanFactory beanFactory;
protected JpaBaseConfiguration(DataSource dataSource, JpaProperties properties,
ObjectProvider<JtaTransactionManager> jtaTransactionManager) {
this.dataSource = dataSource;
this.properties = properties;
this.jtaTransactionManager = jtaTransactionManager.getIfAvailable();
}
@Bean
@ConditionalOnMissingBean
public PlatformTransactionManager transactionManager(
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManagerCustomizers.ifAvailable((customizers) -> customizers.customize(transactionManager));
return transactionManager;
}
@Bean
@ConditionalOnMissingBean
public JpaVendorAdapter jpaVendorAdapter() {
AbstractJpaVendorAdapter adapter = createJpaVendorAdapter();
adapter.setShowSql(this.properties.isShowSql());
if (this.properties.getDatabase() != null) {
adapter.setDatabase(this.properties.getDatabase());
}
if (this.properties.getDatabasePlatform() != null) {
adapter.setDatabasePlatform(this.properties.getDatabasePlatform());
}
adapter.setGenerateDdl(this.properties.isGenerateDdl());
return adapter;
}
@Bean
@ConditionalOnMissingBean
public EntityManagerFactoryBuilder entityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter,
ObjectProvider<PersistenceUnitManager> persistenceUnitManager,
ObjectProvider<EntityManagerFactoryBuilderCustomizer> customizers) {
EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(jpaVendorAdapter,
this.properties.getProperties(), persistenceUnitManager.getIfAvailable());
customizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
return builder;
}
@Bean
@Primary
@ConditionalOnMissingBean({ LocalContainerEntityManagerFactoryBean.class, EntityManagerFactory.class })
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder factoryBuilder) {
Map<String, Object> vendorProperties = getVendorProperties();
customizeVendorProperties(vendorProperties);
return factoryBuilder.dataSource(this.dataSource).packages(getPackagesToScan()).properties(vendorProperties)
.mappingResources(getMappingResources()).jta(isJta()).build();
}
protected abstract AbstractJpaVendorAdapter createJpaVendorAdapter();
protected abstract Map<String, Object> getVendorProperties();
3.创建org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration实例化对象。这个会初始化数据源。
protected JpaBaseConfiguration(DataSource dataSource, JpaProperties properties,
ObjectProvider<JtaTransactionManager> jtaTransactionManager) {
this.dataSource = dataSource;
this.properties = properties;
this.jtaTransactionManager = jtaTransactionManager.getIfAvailable();
}
4.创建jpaVendorAdapter对象。可以看到JPA厂商适配器对象,目前用的最多是hibernate,系统中有一个实现。
这里指定实体管理器和其工厂类的实现对象。
public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter {
private final HibernateJpaDialect jpaDialect = new HibernateJpaDialect();
private final PersistenceProvider persistenceProvider;
private final Class<? extends EntityManagerFactory> entityManagerFactoryInterface;
private final Class<? extends EntityManager> entityManagerInterface;
@SuppressWarnings("deprecation")
public HibernateJpaVendorAdapter() {
this.persistenceProvider = new SpringHibernateJpaPersistenceProvider();
this.entityManagerFactoryInterface = org.hibernate.jpa.HibernateEntityManagerFactory.class;
this.entityManagerInterface = org.hibernate.jpa.HibernateEntityManager.class;
}
5.创建EntityManagerFactoryBuilder,会注入jpaVendorAdapter,persistenceUnitManager
@Bean
@ConditionalOnMissingBean
public EntityManagerFactoryBuilder entityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter,
ObjectProvider<PersistenceUnitManager> persistenceUnitManager,
ObjectProvider<EntityManagerFactoryBuilderCustomizer> customizers) {
EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(jpaVendorAdapter,
this.properties.getProperties(), persistenceUnitManager.getIfAvailable());
customizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
return builder;
}
6.创建LocalContainerEntityManagerFactoryBean,这个是实体管理器工厂类的工厂BEAN,用来创建实体管理器工厂对象的。
@Bean
@Primary
@ConditionalOnMissingBean({ LocalContainerEntityManagerFactoryBean.class, EntityManagerFactory.class })
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder factoryBuilder) {
Map<String, Object> vendorProperties = getVendorProperties();
customizeVendorProperties(vendorProperties);
return factoryBuilder.dataSource(this.dataSource).packages(getPackagesToScan()).properties(vendorProperties)
.mappingResources(getMappingResources()).jta(isJta()).build();
}
具体的创建这个对象代码,
org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder.Builder.build方法,用来创建实体管理器工厂类的工厂BEAN。
public LocalContainerEntityManagerFactoryBean build() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
if (EntityManagerFactoryBuilder.this.persistenceUnitManager != null) {
entityManagerFactoryBean
.setPersistenceUnitManager(EntityManagerFactoryBuilder.this.persistenceUnitManager);
}
if (this.persistenceUnit != null) {
entityManagerFactoryBean.setPersistenceUnitName(this.persistenceUnit);
}
entityManagerFactoryBean.setJpaVendorAdapter(EntityManagerFactoryBuilder.this.jpaVendorAdapter);
entityManagerFactoryBean.setDataSource(this.dataSource);
entityManagerFactoryBean.setPackagesToScan(this.packagesToScan);
return entityManagerFactoryBean;
}
7.在实体管理器工厂属性设置回调afterPropertiesSet方法中,会构建本地工厂buildNativeEntityManagerFactory。最终构建的工厂对象为org.hibernate.internal.SessionFactoryImpl
public SessionFactory build() {
this.metadata.validate();
StandardServiceRegistry serviceRegistry = this.metadata.getMetadataBuildingOptions().getServiceRegistry();
BytecodeProvider bytecodeProvider = (BytecodeProvider)serviceRegistry.getService(BytecodeProvider.class);
this.addSessionFactoryObservers(new SessionFactoryObserverForBytecodeEnhancer(bytecodeProvider));
return new SessionFactoryImpl(this.metadata, this.buildSessionFactoryOptions(), HQLQueryPlan::new);
}
五、实例化DAO对象的流程
1.缺省的DAO对象所映射的实体类为org.springframework.data.jpa.repository.support.
SimpleJpaRepository代理对象。
public SimpleJpaRepository(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
Assert.notNull(entityInformation, "JpaEntityInformation must not be null!");
Assert.notNull(entityManager, "EntityManager must not be null!");
this.entityInformation = entityInformation;
this.em = entityManager;
this.provider = PersistenceProvider.fromEntityManager(entityManager);
}
2.这个类依赖EntityManager,所以会接着创建实体管理器对象。这个实体管理器对象所映射的工厂方法为public static javax.persistence.EntityManager org.springframework.orm.jpa.SharedEntityManagerCreator.createSharedEntityManager(javax.persistence.EntityManagerFactory),这个实际上是一个实体管理器的Jdk动态代理对象。
public static EntityManager createSharedEntityManager(EntityManagerFactory emf, @Nullable Map<?, ?> properties,
boolean synchronizedWithTransaction, Class<?>... entityManagerInterfaces) {
ClassLoader cl = null;
if (emf instanceof EntityManagerFactoryInfo) {
cl = ((EntityManagerFactoryInfo) emf).getBeanClassLoader();
}
Class<?>[] ifcs = new Class<?>[entityManagerInterfaces.length + 1];
System.arraycopy(entityManagerInterfaces, 0, ifcs, 0, entityManagerInterfaces.length);
ifcs[entityManagerInterfaces.length] = EntityManagerProxy.class;
return (EntityManager) Proxy.newProxyInstance(
(cl != null ? cl : SharedEntityManagerCreator.class.getClassLoader()),
ifcs, new SharedEntityManagerInvocationHandler(emf, properties, synchronizedWithTransaction));
}
3.这个动态代理对象包装了实体管理器工厂对象,然后使用工厂对象创建具体的实体管理器,也可以去接口做不同的转发。这里的targetFactory=org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,也就是JPA初始化时生成的工厂对象。
private static class SharedEntityManagerInvocationHandler implements InvocationHandler, Serializable {
private final EntityManagerFactory targetFactory;
public SharedEntityManagerInvocationHandler(
EntityManagerFactory target, @Nullable Map<?, ?> properties, boolean synchronizedWithTransaction) {
this.targetFactory = target;
this.properties = properties;
this.synchronizedWithTransaction = synchronizedWithTransaction;
initProxyClassLoader();
}
4.接着初始化JpaRepositoryFactoryBean类,此类为工厂类(在创建具体的容器对象前首先要实例化工厂类,这是SPRING的知识,不再详解),后面实例化DAO对象,就是调用此类的getObject方法。这个对象创建后,会调用此类的afterPropertiesSet,最终会调用
SessionFactoryImpl.createEntityManager方法
RepositoryFactoryBeanSupport.afterPropertiesSet
public void afterPropertiesSet() {
this.factory = createRepositoryFactory();
RepositoryFragments customImplementationFragment = customImplementation //
.map(RepositoryFragments::just) //
.orElseGet(RepositoryFragments::empty);
RepositoryFragments repositoryFragmentsToUse = this.repositoryFragments //
.orElseGet(RepositoryFragments::empty) //
.append(customImplementationFragment);
this.repository = Lazy.of(() -> this.factory.getRepository(repositoryInterface, repositoryFragmentsToUse));
if (!lazyInit) {
this.repository.get();
}
}
最终创建的factory属性中,有实体管理器,和几个拦截器,用来拦截处理@QUERY,等注解的方法。
5.重点讲下这里面创建RepositoryFactoryBeanSupport(JpaRepositoryFactoryBean继承于他)的属性repository的生成。由于非懒加载,所以会初始化实例。
public <T> T getRepository(Class<T> repositoryInterface, RepositoryFragments fragments) {
if (LOG.isDebugEnabled()) {
LOG.debug("Initializing repository instance for {}…", repositoryInterface.getName());
}
Object target = getTargetRepository(information);
// Create proxy
ProxyFactory result = new ProxyFactory();
result.setTarget(target);
result.setInterfaces(repositoryInterface, Repository.class, TransactionalProxy.class);
if (MethodInvocationValidator.supports(repositoryInterface)) {
result.addAdvice(new MethodInvocationValidator());
}
result.addAdvisor(ExposeInvocationInterceptor.ADVISOR);
result.addAdvice(new QueryExecutorMethodInterceptor(information, projectionFactory, queryLookupStrategy,
namedQueries, queryPostProcessors));
composition = composition.append(RepositoryFragment.implemented(target));
result.addAdvice(new ImplementationMethodExecutionInterceptor(composition));
T repository = (T) result.getProxy(classLoader);
if (LOG.isDebugEnabled()) {
LOG.debug("Finished creation of repository instance for {}.", repositoryInterface.getName());
}
return repository;
}
这里的target就是simpleJpaResposity
最终生成的代理对象为这样,包含实体对象,拦截器对象,实现接口等。
repository为一个JDK的动态代理对象,包装的就 是上面的result,spring的ProxyFactory。
6.最终容器的依赖注入DAO对象,就是调用上面工厂类的getObject方法。也就是返回上面的JDK代理对象。
public T getObject() {
return this.repository.get();
}
六、DAO层接口调用的流程
1.看CONTROLLER的DAO字段属性,可以看到就是上文生成的代理对象。
2.由于我们的DAO层此方法这样写的
@Query(value = "select a.* from fanli_mingxi_new a where a.relate_id=?1 ",nativeQuery = true)
public List<UserMingxi> getUserMingxiByRelate_id(int relate_id);
所以会由QueryExecutorMethodInterceptor来进行处理。
QueryExecutorMethodInterceptor.doInvoke方法中,就会根据queries查找对应的实体查询对象。
private Object doInvoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
if (hasQueryFor(method)) {
QueryMethodInvoker invocationMetadata = invocationMetadataCache.get(method);
if (invocationMetadata == null) {
invocationMetadata = new QueryMethodInvoker(method);
invocationMetadataCache.put(method, invocationMetadata);
}
RepositoryQuery repositoryQuery = queries.get(method);
return invocationMetadata.invoke(repositoryQuery, invocation.getArguments());
}
return invocation.proceed();
}
可以看到em也是上文创建的JPA代理对象,内部封装了 factory [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,最终通过持久层调用hibernate的sessionFactoryImpl去创建session(继承了entityManager)
3.然后调用到em.createNativeQuery(queryString, type),最终映射到
SharedEntityManagerInvocationHandler类的反射调用去创建本地查询 。
4.创建完查询后,就开始执行查询,然后就调用到hibernate的查询逻辑,查询完返回结果。
七、原生的调用entityManager来创建查询的流程
1.同上面DAO创建流程基本一样,只是少了拦截器转换为entityManager的流程。实际上DAO层的封装,也只是通过拦截器转发到实体管理器进行本地查询。
public class UserMingXiService {
private EntityManager entityManager;
private EntityManagerFactory entityManagerFactory;
public UserMingXiService(EntityManager entityManager, EntityManagerFactory entityManagerFactory) {
this.entityManager = entityManager;
this.entityManagerFactory = entityManagerFactory;
}
public List<UserMingxi> getMingXiList(int mingxiId){
Query query = entityManager.createNativeQuery("select a.* from fanli_mingxi_new a where a.relate_id=" + mingxiId);
List<UserMingxi> userMingxiList = query.getResultList();
return userMingxiList;
}
}
创建的本地查询和前文一样。