[问题的由来]
一般来说,通用的商业产品都可以访问多数据库。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
|
分享到:
相关推荐
包括TOPLink JPA,Hibernate JPA,Open Jpa,jpa批注
JavaEE源代码 spring-toplinkJavaEE源代码 spring-toplinkJavaEE源代码 spring-toplinkJavaEE源代码 spring-toplinkJavaEE源代码 spring-toplinkJavaEE源代码 spring-toplinkJavaEE源代码 spring-toplinkJavaEE源...
toplink jpa的中文注解参考,虽然老了一点基本上还是很有用的。 原来下载的一个兄弟的chm,里面的锚链接有问题,反编译后修改了链接,并且保留html格式,使用更方便。
Oracle Toplink JPA
javaee实现jpa的toplink相关jar包。完整版。
myeclipse_jpa_toplink.swf
JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中,图 1很好地描述了JPA的结构: Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用的对象持久...
JPA文档_学TOPLINK必看_PDF格式
JPA用于整合现有的ORM技术,可以简化现有Java EE和Java SE应用的对象持久化的开发工作,实现ORM的统一。JPA作为一项对象持久化的标准,不但可以获得Java EE应用服务器的支持,还可以直接在Java SE中使用。JPA必将...
JPA由EJB 3.0软件专家组开发,作为JSR-220实现的一部分。但它不囿于EJB 3.0,你可以在Web应用、甚至桌面应用中使用。JPA的宗旨是为POJO提供持久化...目前Hibernate 3.2、TopLink 10.1.3以及OpenJPA都提供了JPA的实现。
JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。 JPA支持XML和JDK5.0注解两种元数据的形式。 JPA的总体思想和现有Hibernate、TopLink、...
JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。 JPA支持XML和JDK5.0注解两种元数据的形式。 JPA的总体思想和现有Hibernate、TopLink、...
Hibernate、iBATIS、TopLink、Castor JDO、Apache OJB等这么多持久层框架,你还在为学习上面那个框架而苦恼吗?你还为研究下一代是那个而头疼吗? 朋友,学习JPA吧!JPA的出现就是解决您上面的苦恼的。
toplink mysql5 开发工具:Eclipse3.3 for...简要过程(先导好mysqlJDBC包和toplink包,进mysql建好数据库), 1.新建pojo类,加入Annotation 2.在src目录下建META-INF目录,写好persistence.xml文件 3.写测试类 自动完成建表
JPA(java persistence api)是JavaEE5.0平台的标准的ORM规范。而Hibernate、TopLink和OpenJPA为JPA的一种实现方式。 本文档主要是对其注解的详细说明。
在目前很多项目来说,引入此规范,能更好的代码复用,持久层和控制层相当于进一步的解耦合了,你只需要开启项目之前好好地建立领域模型。 那么用JSF取代Struts2或者更早一点的Struts1又是为何!答案依然是,它是规范...
为数不多的TopLink中文文档,珍惜啊 为数不多的TopLink中文文档,珍惜啊 为数不多的TopLink中文文档,珍惜啊
现在可以从结果集中直接取得第一条记录 (JPA1.0 只允许从一个 unique 结果集中反回单个记录 ) ,指定 query 结果集的最大值,访问各个供应商的底层实体对象 manager 或 query ,最后就是加入悲观锁 (JPA1.0 只...
10.2.3 在Java SE环境下使用 TopLink JPA实现 374 10.2.4 在Java SE环境下使用 EntityManager 377 10.2.5 使用orm.xml管理O/R映射 379 10.3 理解实体 382 10.3.1 持久化上下文和持久化单元 382 10.3.2 实体类的要求 ...
The Java Persistence API (JPA) is the Java standard for mapping Java objects to a relational database. Even though proprietary mapping products like Hibernate and TopLink still exist, they are now ...