[问题的由来]
一般来说,通用的商业产品都可以访问多数据库。TopLink也不例外,其中的JPA号称支持上十种数据库平台,而且还可以动态增加。那么具体的技术细节是怎么样呢?怎么实现的呢?
我们来看一看TopLink的源代码是如何实现的。
[源代码分析]
第一步:在登陆访问数据库时,首先执行下面的函数
public void loginAndDetectDatasource() throws DatabaseException {
preConnectDatasource();
Connection conn = null;
try{
conn = (Connection)getReadLogin().connectToDatasource(null);
getLogin().setPlatformClassName(DBPlatformHelper.getDBPlatform(conn.getMetaData().getDatabaseProductName(), getSessionLog()));
}catch (SQLException ex){
DatabaseException dbEx = DatabaseException.errorRetrieveDbMetadataThroughJDBCConnection();
// Typically exception would occur if user did not provide correct connection
// parameters. The root cause of exception should be propogated up
dbEx.initCause(ex);
throw dbEx;
}finally{
if (conn != null){
try{
conn.close();
}catch (SQLException ex){
DatabaseException dbEx = DatabaseException.errorRetrieveDbMetadataThroughJDBCConnection();
// Typically exception would occur if user did not provide correct connection
// parameters. The root cause of exception should be propogated up
dbEx.initCause(ex);
throw dbEx;
}
}
}
connect();
postConnectDatasource();
}
|
第二步:在上面的函数中,有一个特别重要的函数,大家注意看,叫做DBPlatformHelper.getDBPlatform()
下面我们来看看这个函数到底做了什么?
public static String getDBPlatform(String vendorName, SessionLog logger) {
initializeNameToVendorPlatform(logger);
String detectedDbPlatform = null;
if(vendorName != null) {
detectedDbPlatform = matchVendorNameInProperties(vendorName, _nameToVendorPlatform, logger);
}
if (logger.shouldLog(SessionLog.FINE) ) {
logger.log(SessionLog.FINE, "dbPlaformHelper_detectedVendorPlatform", detectedDbPlatform );
// NOI18N
}
if (detectedDbPlatform == null) {
if(logger.shouldLog(SessionLog.INFO)) {
logger.log(SessionLog.INFO, "dbPlaformHelper_defaultingPlatform", vendorName, DEFAULTPLATFORM); // NOI18N
}
detectedDbPlatform = DEFAULTPLATFORM;
}
return detectedDbPlatform;
}
|
大家注意看,上面这个函数的第一行是:
initializeNameToVendorPlatform(logger);
这个函数是干什么的?是不是就是访问多数据库强大功能的秘密呢?我们再往下面看。
第三步:秘密原来在这里
private static Properties initializeNameToVendorPlatform(SessionLog logger) {
synchronized(DBPlatformHelper.class) {
if(_nameToVendorPlatform == null) {
_nameToVendorPlatform = new Properties();
try {
loadFromResource(_nameToVendorPlatform, VENDOR_NAME_TO_PLATFORM_RESOURCE_NAME, DBPlatformHelper.class.getClassLoader() );
} catch (IOException e) {
logger.log(SessionLog.WARNING, "dbPlaformHelper_noMappingFound", VENDOR_NAME_TO_PLATFORM_RESOURCE_NAME);
}
}
}
return _nameToVendorPlatform;
}
|
大家注意看,上面这个函数中,有一个很关键的一行代码
loadFromResource(_nameToVendorPlatform,VENDOR_NAME_TO_PLATFORM_RESOURCE_NAME, DBPlatformHelper.class.getClassLoader() );
这行代码干的事情就是动态的对应到不同的数据库平台。那么到底是怎么做到的呢?
这行代码中有一个变量,名字叫做[VENDOR_NAME_TO_PLATFORM_RESOURCE_NAME]
它的真实面貌如下:
private final static String VENDOR_NAME_TO_PLATFORM_RESOURCE_NAME =PROPERTY_PATH + "VendorNameToPlatformMapping.properties"; //NOI18N
|
关键问题出现了,原来它是最后找到了一个配置文件,通过它解决不同数据库的访问难题,那么最后我们来看看这个配置文件里面写着什么。
第四步:配置文件
#Property file containing mapping between vendor name and vendor platform
#The key of the property is in form of java regular expression.
#At runtime, vendor name obtained from DatabaseMetaData#getDatabaseProductName()
#is matched against the regular expresion to derive the DatabasePlaform we are
#running against.
SQL\ Anywhere=oracle.toplink.essentials.platform.database.SQLAnyWherePlatform
(?i)oracle.*=oracle.toplink.essentials.platform.database.oracle.OraclePlatform
(?i)(sybase.*)|(adaptive\ server\ enterprise.*)|(SQL\ Server)=oracle.toplink.essentials.platform.database.SybasePlatform
(?i)microsoft.*=oracle.toplink.essentials.platform.database.SQLServerPlatform
#Use JavaDBPlatform as the platform for Derby
(?i).*derby=oracle.toplink.essentials.platform.database.JavaDBPlatform
(?i).*db2.*=oracle.toplink.essentials.platform.database.DB2Platform
(?i)pointbase.*=oracle.toplink.essentials.platform.database.PointBasePlatform
(?i)mysql.*=oracle.toplink.essentials.platform.database.MySQL4Platform
(?i)informix.*=oracle.toplink.essentials.platform.database.InformixPlatform
(?i)postgresql.*=oracle.toplink.essentials.platform.database.PostgreSQLPlatform
(?i).*symfoware.*=oracle.toplink.essentials.platform.database.SymfowarePlatform
|
分享到:
相关推荐
**Java Persistence API (JPA)** 是Java平台上的一个标准,用于管理关系数据库中的数据。它为Java开发者提供了一种对象关系映射(ORM)机制,将业务对象与数据库表进行映射,使得开发者可以使用面向对象的方式来操作...
### EJB_JPA数据库持久层开发详解 #### JPA与数据持久化技术 **数据持久化**是指将程序运行时的数据保存到永久存储设备中,以便在下次运行时能够读取和使用这些数据。在Java领域,有多种数据持久化技术,包括序列...
Java Persistence API(JPA)是Java EE平台中的一个标准,用于管理关系数据库中的对象-关系映射(ORM)。它提供了一种方式,让开发者可以用面向对象的编程模型来操作数据库,而无需直接编写SQL语句。TopLink是Oracle...
注解是一种简单、表达性强的在Java源代码上添加元数据的方法,这些元数据在编译时会被嵌入到对应的Java类文件中,由TopLink JPA在运行时解释以管理JPA行为。 例如,要将一个Java类标记为JPA实体,可以使用@Entity...
TopLink也实现了Java Persistence API(JPA),这是Java EE平台的一部分,提供了一套标准的ORM规范。通过JPA,TopLink可以与其他遵循JPA的应用程序组件无缝集成,例如EJB和Spring框架。 6. **动态模型** TopLink...
JPA是Java平台的企业版(Java EE)规范的一部分,它是一个ORM(对象关系映射)规范,允许开发者通过Java的面向对象的模型来操作数据库中的表。Hibernate是一个流行的、成熟的ORM框架,它实现了JPA规范。Hibernate...
JPA的主要目标是统一ORM框架,如Hibernate和TopLink,以减少不同框架间的兼容性问题,并提供一个标准的API,让开发者可以编写出与特定持久化提供商无关的代码。 **JPA的核心概念和技术**: 1. **ORM映射元数据**:...
这使得开发者可以将Java对象轻松地持久化到数据库中。 2. Java持久化API:这一API允许开发者操作实体对象,执行创建(Create)、读取(Read)、更新(Update)和删除(Delete)等操作。JPA在后台自动处理与数据库...
Java Persistence API (JPA) 是Java EE 6中用于对象关系映射(ORM)的重要组件,它提供了一个标准的API,使得开发人员可以方便地将Java对象持久化到关系数据库中,解决了不同ORM框架之间的兼容性问题。JPA不仅适用于...
- **兼容性**:使用JPA接口进行编程,可以轻松切换到其他持久化层实现,如TopLink或iBatis等,降低了项目的依赖风险。 - **统一性**:JPA提供了一套标准的API,使得开发人员在处理不同类型的数据库时,可以采用一致...
- **创建JPAHello项目**:这一步包括创建数据库表、创建项目、添加JPA能力到项目中、使用JPA配置文件编辑器修改persistence.xml文件等内容。 - **使用反向工程快速生成JPA实体类和DAO**:MyEclipse提供了一键式工具...
Spring Boot JPA是基于Java Persistence API(JPA)和ORM框架如Hibernate、TopLink、JDO等的一个封装,旨在简化Java应用中的数据访问和持久化工作。JPA本身是由Sun官方提出的规范,它定义了一种标准接口,用于管理和...
文件名为 "framework" 的压缩包可能包含了这个集成项目的源代码、配置文件、资源文件等,用于演示如何在实际开发中集成和使用这些技术。解压并研究这些文件可以帮助我们深入理解这些框架之间的协作方式,以及如何在...
JPA是Java EE平台的一部分,用于管理关系数据库中的对象。它提供了一种标准的接口,使得开发者可以使用面向对象的方式来操作数据库,而无需关心底层SQL语句的编写。JPA通过ORM(Object-Relational Mapping)机制将...
Java持久化技术的发展历程中,从早期的TopLink、CocoBase、ODMG,到Entity Bean、JDO,再到Hibernate、iBATIS,以及后来的EJB3和Java Persistence API (JPA),ORM解决方案逐渐成熟和完善。每种技术都有其特点和适用...
【网络记账本小项目(struts2集成...同时,提供的`usernote.sql`可能是数据库脚本,用于初始化或还原数据库结构,而`myweb`可能包含项目的源代码和资源配置,进一步深入研究这些文件将有助于全面了解项目的工作原理。
本章节将通过一个简单的示例来介绍如何使用JPA将数据库中的数据显示出来。主要包括以下几个步骤: 1. **加载驱动程序**:为了能够与数据库通信,首先需要加载相应的JDBC驱动。 2. **创建数据库及表**:在数据库中...
为了在项目中使用JPA,需要在`persistence.xml`配置文件中指定持久化提供者(如Hibernate或TopLink),以及数据源的连接信息。这个文件不仅指导容器初始化`EntityManagerFactory`,还定义了数据源的配置,是JPA应用...
9. **jalopy-1.5rc3.jar**:Jalopy是一个源代码格式化和重构工具,帮助开发者遵循统一的编码风格,提高代码可读性和团队协作效率。 10. **xercesImpl-2.6.2.jar**:Xerces是Apache的一个XML解析器,实现了W3C的DOM...