jpa的初步入门
2015-10-31 21:28
381 查看
网上关于jpa的例子很多,今天还是来讲入门,主要在例子中讲解一下各个jpa实现的对比,首先来一个hibernate对于jpa的实现,首先是jpa的配置文件
META-INF下的persist.xml,目前jpa规范中必须是放在这个目录下。
测试代码如下
这样虽然会报错,没有配置mysql的driverclass,但是会输出org.hibernate.ejb.EntityManagerFactoryImpl@16e481a
在这里我们是没有配置provider的,
在persist.xml中provider不是必须配置的,但是如果你的项目中出现多个jpa实现,这时候你想使用哪个provider就必须配置相应的provider,在这里我没有配置provider,但它使用了hibernate,
jpa是PersistenceProviderResolverHolder的CachingPersistenceProviderResolver
在这里我们看到是通过查找meta-inf/services/javax.persistence.spi.PersistenceProvider中的内容来使用相应的provider,在hibernate-entitymanager中看到了
查找的是这个provider,在这个provider里面会读取配置persist.xml然后生成entitymanagerFactory
这里使用的org.hibernate.ejb.hibernatePersitence作为provider,在createEntityMangeFactory中使用的EJB3Configuration来创建entitymanageFactory,其中有一段代码如下
在这里,如果xml的provider为空,或者provider不为空但是与自己本身的名字相等则创建entitymanageFactory,否则返回空。只要entityManageFactory创建完成,配置读取就完毕了。
为此,我将多个jpa的实现集成的项目中,EclipseLink,openJpa。如果我的persist.xml中的provider没有写,则默认创建hibernate的provider,然后程序结束,如果xml中写了EclipseLink的provider,则会先执行hibernate,然后执行Eclipselink的provider,然后创建成功。如果配置openjpa的则openjpa的provider是最后一个执行的,这里执行的顺序不固定,在不同的机器上可能不同,但是即使配置了多个jpa,也可以指定想要的jpa实现,唯一的就是实现的效率的问题。也可以不同的persistunit指定不同的jpa实现。
META-INF下的persist.xml,目前jpa规范中必须是放在这个目录下。
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="jpa" transaction-type="RESOURCE_LOCAL"> <properties> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/> </properties> </persistence-unit> </persistence>
测试代码如下
package org.ww; import javax.persistence.Persistence; public class JpaTest { public static void main(String[] args) { System.out.println(Persistence.createEntityManagerFactory("jpa")); } }
这样虽然会报错,没有配置mysql的driverclass,但是会输出org.hibernate.ejb.EntityManagerFactoryImpl@16e481a
在这里我们是没有配置provider的,
在persist.xml中provider不是必须配置的,但是如果你的项目中出现多个jpa实现,这时候你想使用哪个provider就必须配置相应的provider,在这里我没有配置provider,但它使用了hibernate,
jpa是PersistenceProviderResolverHolder的CachingPersistenceProviderResolver
private void loadResolverClasses(ClassLoader cl) { synchronized ( resolverClasses ) { try { Enumeration<URL> resources = cl.getResources( "META-INF/services/" + PersistenceProvider.class.getName() ); Set<String> names = new HashSet<String>(); while ( resources.hasMoreElements() ) { URL url = resources.nextElement(); InputStream is = url.openStream(); try { names.addAll( providerNamesFromReader( new BufferedReader( new InputStreamReader( is ) ) ) ); } finally { is.close(); } } for ( String s : names ) { @SuppressWarnings( "unchecked" ) Class<? extends PersistenceProvider> providerClass = (Class<? extends PersistenceProvider>) cl.loadClass( s ); WeakReference<Class<? extends PersistenceProvider>> reference = new WeakReference<Class<? extends PersistenceProvider>>(providerClass); //keep Hibernate atop if ( s.endsWith( "HibernatePersistence" ) && resolverClasses.size() > 0 ) { WeakReference<Class<? extends PersistenceProvider>> movedReference = resolverClasses.get( 0 ); resolverClasses.add( 0, reference ); resolverClasses.add( movedReference ); } else { resolverClasses.add( reference ); } } } catch ( IOException e ) { throw new PersistenceException( e ); } catch ( ClassNotFoundException e ) { throw new PersistenceException( e ); } } }
在这里我们看到是通过查找meta-inf/services/javax.persistence.spi.PersistenceProvider中的内容来使用相应的provider,在hibernate-entitymanager中看到了
查找的是这个provider,在这个provider里面会读取配置persist.xml然后生成entitymanagerFactory
public static EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) { EntityManagerFactory emf = null; List<PersistenceProvider> providers = getProviders(); for ( PersistenceProvider provider : providers ) { emf = provider.createEntityManagerFactory( persistenceUnitName, properties ); if ( emf != null ) { break; } } if ( emf == null ) { throw new PersistenceException( "No Persistence provider for EntityManager named " + persistenceUnitName ); } return emf; }
这里使用的org.hibernate.ejb.hibernatePersitence作为provider,在createEntityMangeFactory中使用的EJB3Configuration来创建entitymanageFactory,其中有一段代码如下
if ( metadata.getProvider() == null || IMPLEMENTATION_NAME.equalsIgnoreCase( metadata.getProvider() ) ) { //correct provider //lazy load the scanner to avoid unnecessary IOExceptions Scanner scanner = null; URL jarURL = null; if ( metadata.getName() == null ) { scanner = buildScanner( metadata.getProps(), integration ); jarURL = JarVisitorFactory.getJarURLFromURLEntry( url, "/META-INF/persistence.xml" ); metadata.setName( scanner.getUnqualifiedJarName(jarURL) ); } if ( persistenceUnitName == null && xmls.hasMoreElements() ) { throw new PersistenceException( "No name provided and several persistence units found" ); } else if ( persistenceUnitName == null || metadata.getName().equals( persistenceUnitName ) ) { if (scanner == null) { scanner = buildScanner( metadata.getProps(), integration ); jarURL = JarVisitorFactory.getJarURLFromURLEntry( url, "/META-INF/persistence.xml" ); } //scan main JAR ScanningContext mainJarScanCtx = new ScanningContext() .scanner( scanner ) .url( jarURL ) .explicitMappingFiles( metadata.getMappingFiles() ) .searchOrm( true ); setDetectedArtifactsOnScanningContext( mainJarScanCtx, metadata.getProps(), integration, metadata.getExcludeUnlistedClasses() ); addMetadataFromScan( mainJarScanCtx, metadata ); ScanningContext otherJarScanCtx = new ScanningContext() .scanner( scanner ) .explicitMappingFiles( metadata.getMappingFiles() ) .searchOrm( true ); setDetectedArtifactsOnScanningContext( otherJarScanCtx, metadata.getProps(), integration, false ); for ( String jarFile : metadata.getJarFiles() ) { otherJarScanCtx.url( JarVisitorFactory.getURLFromPath( jarFile ) ); addMetadataFromScan( otherJarScanCtx, metadata ); } return configure( metadata, integration ); } } } } return null;
在这里,如果xml的provider为空,或者provider不为空但是与自己本身的名字相等则创建entitymanageFactory,否则返回空。只要entityManageFactory创建完成,配置读取就完毕了。
为此,我将多个jpa的实现集成的项目中,EclipseLink,openJpa。如果我的persist.xml中的provider没有写,则默认创建hibernate的provider,然后程序结束,如果xml中写了EclipseLink的provider,则会先执行hibernate,然后执行Eclipselink的provider,然后创建成功。如果配置openjpa的则openjpa的provider是最后一个执行的,这里执行的顺序不固定,在不同的机器上可能不同,但是即使配置了多个jpa,也可以指定想要的jpa实现,唯一的就是实现的效率的问题。也可以不同的persistunit指定不同的jpa实现。
相关文章推荐
- Angry Bots源码分析
- Hibernate中继承关系映射二
- [LeetCode]题解(python):037-Sudoku Solver
- HDU 5521 [ACM 2015 沈阳] Meeting [最短路]
- Python Excel解析
- Unix环境高级编程学习笔记之进程环境(1)
- 常用的正则表达式
- 20151031的NOIP模拟赛
- C-指针
- 支持Python3的图表库
- [hdu5521 Meeting]最短路
- Ubuntu 14.04 安装 Python3
- 项目冲刺链接汇总
- 导航布局和视频弹出框制作
- Python验证码识别处理实例
- c语言之动态栈的功能实现
- 错误处理:vmware下克隆centos7配置静态ip地址网卡问题
- 2015ACM/ICPC亚洲区沈阳站-重现赛 1004 Pagodas
- leetcode 220: Contains Duplicate III Java
- Xcode插件及cocoapods不能正常使用的解决方法