TopLink源代码分析 JPA中的Session实现
[什么是JPA]
Java Persistence API
JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用的对象持久化的开发工作;其二,Sun希望整合对ORM技术,实现天下归一。
JPA由EJB 3.0软件专家组开发,作为JSR-220实现的一部分。但它不囿于EJB 3.0,你可以在Web应用、甚至桌面应用中使用。JPA的宗旨是为POJO提供持久化标准规范,由此可见,经过这几年的实践探索,能够脱离容器独立运行,方便开发和测试的理念已经深入人心了。目前Hibernate 3.2、TopLink 10.1.3以及OpenJPA都提供了JPA的实现。
JPA的总体思想和现有Hibernate、TopLink,JDO等ORM框架大体一致。总的来说,JPA包括以下3方面的技术:
ORM映射元数据,JPA支持XML和JDK 5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;
JPA 的API,用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。
查询语言,这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
[TopLinke中的JPA源代码---数据库session的实现]
通过JPA访问数据库的代码 sessionManager manager = new sessionManager.getMananger();
|
接上面的getSession函数 public synchronized AbstractSession getSession(String sessionName, ClassLoader objectClassLoader, boolean shouldLoginSession, boolean shouldRefreshSession, boolean shouldCheckClassLoader) { AbstractSession session = (AbstractSession)getSessions().get(sessionName); if (shouldCheckClassLoader && (session != null) && !session.getDatasourcePlatform().getConversionManager().getLoader().equals(objectClassLoader)) { //bug 3766808 if a different classloader is being used then a reload of the session should //be completed otherwise failures may occur shouldRefreshSession = true; } if ((session == null) || shouldRefreshSession) { if (session != null) { if (session.isDatabaseSession() && session.isConnected()) { ((DatabaseSession)session).logout(); }
getSessions().remove(sessionName); } } if (session == null) { logAndThrowException(SessionLog.WARNING, ValidationException.noSessionFound(sessionName, "")); } else if (shouldLoginSession && !session.isConnected()) { ((DatabaseSession)session).login(); }
return session; } |
以上程序中 session.login()中对应的真实处理函数 /** * PUBLIC: * Connect to the database using the predefined login. * The login must have been assigned when or after creating the session. * * @see #login(Login) */ public void login() throws DatabaseException { preConnectDatasource(); connect(); postConnectDatasource(); } |
以上第一个调用函数 ① preConnectDatasource() 主要做数据库连接前的处理 代码如下 /** * INTERNAL: * This method includes all of the code that is issued before the datasource * is connected to. */ protected void preConnectDatasource(){ //Bug#3440544 Check if logged in already to stop the attempt to login more than once if (isLoggedIn) { throw ValidationException.alreadyLoggedIn(this.getName()); } this.platform = null; if (isInProfile()) { getProfiler().initialize(); } updateProfile(SessionProfiler.LoginTime, new Date(System.currentTimeMillis()));
// Login and initialize getEventManager().preLogin(this); //setup the external transaction controller getServerPlatform().initializeExternalTransactionController(); log(SessionLog.INFO, null, "topLink_version", DatasourceLogin.getVersion()); if (getServerPlatform().getServerNameAndVersion() != null) { log(SessionLog.FINE, null, "application_server_name_and_version", getServerPlatform().getServerNameAndVersion()); } } |
以上第一个调用函数 ② connect(); 正式连接数据库 代码如下 /** * Connect to the database. * Exceptions are caught and re-thrown as TopLink exceptions. */ protected void connect(Login login) throws DatabaseException { setDatasourceConnection(login.connectToDatasource(this)); setIsConnected(true); } |
[总结]
以上主要分析了TOPLINK中关于JPA连接数据库session的源代码分析