在
						
								Eclipse’s RCP
						
						中配置
						
								Hibernate
						
				
		
		
				
						1
				
				、起因
		
		
				一个同学问起在
				RCP
				中怎么配置
				Hibernate
				。我让他参考我的另一篇文章《在
				Eclipse RCP
				中使用
				Spring
				》,奈何他仍然搞不定,我想这是对
				Hiberate
				和
				Spring
				缺乏整体认识的原故吧。
		
		
				
						
						 
				
		
		
				
						2
				
				、原理
		
		
				现在一般的框架大都采“配置文件+
				JAR
				包”形式,用配置文件来配置一些
				JAR
				包中类所需要用到的变量,而配置文件一般又采用
				XML
				格式。因此无论是配置
				Spring
				还是
				Hibernate
				,关键是能让程序读到
				XML
				配置文件。
		
		
				
						 
				
		
		
				在
				WEB
				项目中,配置文件一般放在
				src
				目录(实现在编译后则会自动转到存放
				class
				的顶层目录),那么
				RCP
				下又应放在哪里呢?当然也是
				src
				目录。在《在
				Eclipse RCP
				中使用
				Spring
				》一文中还给出了另外一种方式,在这篇文章里我将给出三种配置文件的存放方式,以及相应的读取方法。希望大家可以由此对如何读取外部文件有进一步的理解。
		
		
				
						 
				
		
		
				在
				Spring
				一文中,我是把
				xml
				文件放在
				src
				下,然后用
				Spring
				提供的一个类来读取,如下:
		
		
				
						
								
										ctx = new ClassPathXmlApplicationContext("/myspring.xml");
								
								   
						
				
		 
		
				
						 
				
		
		
				同学问了
				Hibernate
				没有
				ClassPathXmlApplicationContext
				类,该怎么办呢?举一反三呀。让我们看看
				Hibernate
				是如何读取其配置文件
				hibernate.cfg.xml
				,代码如下。
		
		
				
						
								conf = new Configuration().configure()
						
				
		 
		
				
						 
				
		
		
				Configuration
				就是中文翻译为“配置”,而此类是
				Hibernate
				程序执行第一个要用到的类,它的功能就是读取配置文件
				hibernate.cfg.xml
				,生成一个配置类实例(里面包含着
				hibernate.cfg.xml
				的配置信息)。只不过
				Hibernate
				和
				Spring
				不用,
				Spring
				的配置文件由用户创建,可以千变万变。而
				hibernate
				的也就一个,因此就给它设了一个默认文件名为:
				hibernate.cfg.xml
				,默认路径为放在
				src
				目录下。所以
				configure()
				没有带任何参数。但实际可以发现
				configure
				方法是多态的,它还有如下形式。
		
		
				configure(java.lang.String);
		
		
				configure(java.net.URL);
		
		
				configure(java.io.File);
		
		
				configure(org.w3c.dom.Document)
		
		
				
						 
				
		
		
				这些方法使得生成
				Configuration
				实例的方式灵活多变,这和
				Spring
				提供各种读取
				xml
				配置的类的想法是一样。
		
		
				
						 
				
		
		
				
						3
				
				、实例
		
		
				实例环境:
				Eclipse3.2 + Hibernate 3.1.3
		
		
				
						 
				
		
		
				先给出项目的结构如下,然后我们一步步完成它
		
		
				
						
						
								
								
								
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
								
								
								
								
								
						
				
		
		
				
						
								
 
				
		
		
				
						 
				
		
		
				
						(1)       
				
				先用
				Eclipse
				的
				RCP
				向导创建一个
				RCP
				项目,模板选
				Hello World
				。
		
		
				
						(2)       
				
				然后在项目下创建一个
				lib
				目录,把
				hibernate
				的所有
				jar
				包全复制进去,接着要配置后这些加入的
				jar
				包。《
				Eclipse
				从入门到精通》里称之为配置库引用。
				RCP
				的库引用不能乱配,请遵寻如下方法:
		
		
				
						l           
				
				打开
				plugin.xml
				文件,找到“运行时”项的“类路径”把所有
				jar
				包加入,如下图:
		
		
				
				
		
		
				
						
								
								
								
l           
				
				再找到“构建”项的“额外类路径条目”
		
		
				
				
		
		
				
						
								
								
								
l           
				
				当配置完成后,转到项目属性的库引用就可以看到“插件依赖项”添加了各
				jar
				包,如下图所示:

		
		
				
				
		
		
				
						
								
										
										
注:如果出现
								no class found
								之类的异常,先检查没有包含这个类的
								jar
								包,再检查这个
								jar
								包的库引用是否配置好了。
						
				
		
		
				
						 
				
		
		
				
						(3)       
				
				把一个
				hibernate.cfg.xml
				分三份放在如图位置上(分成三份是为了试验三种路径读取方法),把
				hibernate.cfg.xml
				中无关紧要的信息都删除掉,我的
				hibernate.cfg.xml
				精减后如下
		
		
				
						
								<?xml version='1.0' encoding='utf-8'?>
						
				
				
						
								
										 
								
						
				
				
						
								
										<!DOCTYPE hibernate-configuration PUBLIC
								
						
				
				
						
								
										
												          
										
										"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
								
						
				
				
						
								
										
												          
										
										"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"
										>
								
						
				
				
						
								
										 
								
						
				
				
						
								<hibernate-configuration>
						
				
				
						
								
										
												  
										
										<session-factory>
								
						
				
				
						
								
										
												    
										
										<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
								
						
				
				
						
								
										
												    
										
										<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
								
						
				
				
						
								
										
												    
										
										<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/jbpm</property>
								
						
				
				
						
								
										
												    
										
										<property name="hibernate.connection.username">root</property>
								
						
				
				
						
								
										
												    
										
										<property name="hibernate.connection.password">123456</property>
								
						
				
				
						
								
										
												  
										
										</session-factory>
								
						
				
				
						
								</hibernate-configuration>
						
				
		 
		
				
						 
				
		
		
				
						(4)       
				
				接下来写测试程序,直接在
				Perspective.java
				里写了,代码如下:
		
		
				
						
								
										
												package
										
										my_hibernate_rcp_1;
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												import
										
										java.io.IOException;
								
						
				
				
						
								
										
												import
										
										java.net.URL;
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												import
										
										org.eclipse.ui.IPageLayout;
								
						
				
				
						
								
										
												import
										
										org.eclipse.ui.IPerspectiveFactory;
								
						
				
				
						
								
										
												import
										
										org.hibernate.cfg.Configuration;
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												public
										
										
												
														class
												Perspective implements IPerspectiveFactory {
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												    
												
														public
												
												
														void
												createInitialLayout(IPageLayout layout) {
								
						
				
				
						
								
										
												        path1(); //
								
								对默认存放路径的读取方法
						
				
				
						
								
										
												        path2(); //
								
								对第二种存放路径的读取方法
						
				
				
						
								
										
												        path3(); //
								
								对第三种存放路径的读取方法
						
				
				
						
								
										
												    }
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												    
												
														private
												
												
														void
												path1() {
								
						
				
				
						
								
										
												        Configuration conf = null;
								
						
				
				
						
								
										
												        
												
														try
												{
								
						
				
				
						
								
										
												            conf = new Configuration().configure();
								
						
				
				
						
								
										
												        } catch (Exception e) {
								
						
				
				
						
								
										
												            e.printStackTrace();
								
						
				
				
						
								
										
												        }
								
						
				
				
						
								
										
												        System.out.println(conf);
								
						
				
				
						
								
										
												    }
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												    
												
														private
												
												
														void
												path2() {
								
						
				
				
						
								
										
												        Configuration conf = null;
								
						
				
				
						
								
										
												        
												
														try
												{
								
						
				
				
						
								
										
												            conf = new Configuration().configure("/my_hibernate_rcp_1/hibernate_path2.cfg.xml");
								
						
				
				
						
								
										
												        } catch (Exception e) {
								
						
				
				
						
								
										
												            e.printStackTrace();
								
						
				
				
						
								
										
												        }
								
						
				
				
						
								
										
												        System.out.println(conf);
								
						
				
				
						
								
										
												    }
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												    
												
														private
												
												
														void
												path3() {
								
						
				
				
						
								
										
												        URL url = ProjectUtil.getURL("/config.files/hibernate_path3.cfg.xml");
								
						
				
				
						
								
										
												        printText(url);
								
						
				
				
						
								
										
												        
												//
										
								
						
				
				
						
								
										
												        Configuration conf = null;
								
						
				
				
						
								
										
												        
												
														try
												{
								
						
				
				
						
								
										
												            conf = new Configuration().configure();
								
						
				
				
						
								
										
												        } catch (Exception e) {
								
						
				
				
						
								
										
												            e.printStackTrace();
								
						
				
				
						
								
										
												        }
								
						
				
				
						
								
										
												        System.out.println(conf);
								
						
				
				
						
								
										
												    }
								
						
				
				
						
								
										 
								
						
				
				
						
								
										
												    
												
														private
												
												
														void
												printText(URL url) {
								
						
				
				
						
								
										
												        
												
														byte
												[] b = newbyte[1000];
								
						
				
				
						
								
										
												        
												
														try
												{
								
						
				
				
						
								
										
												            url.openStream().read(b);
								
						
				
				
						
								
										
												        } catch (IOException e) {
								
						
				
				
						
								
										
												            e.printStackTrace();
								
						
				
				
						
								
										
												        }
								
						
				
				
						
								
										
												        System.out.println(new String(b));
								
						
				
				
						
								
										
												    }
								
						
				
				
						
								}
						
				
		 
		
				
						 
				
		
		
				
						(5)       
				
				然后是
				path3
				用到的
				ProjectUtil.java
				,关于此文件的更多信息,看这篇文章:
				
						
								
										Plugin
										
												和
										
										App
										
												的统一路径接口
										
								
						
				
		
		
				
						
								package
						
						my_hibernate_rcp_1;
						
								
								
						
				
				
						
								import
						
						java.io.IOException;
						
								
								
						
				
				
						
								import
						
						java.io.InputStream;
						
								
								
						
				
				
						
								import
						
						java.net.MalformedURLException;
						
								
								
						
				
				
						
								import
						
						java.net.URL;
						
								
								
						
				
				
						
								 
						
				
				
						
								import
						
						org.eclipse.core.runtime.FileLocator;
						
								
								
						
				
				
						
								import
						
						org.eclipse.core.runtime.Path;
						
								
								
						
				
				
						
								import
						
						org.eclipse.ui.plugin.AbstractUIPlugin;
						
								
								
						
				
				
						
								 
						
				
				
						/**
						
								
								
						
				
				
						
								 
						
						*
						
						
						用于插件项目和非插件项目,提供两者通用的方法接口
						
								
								
						
				
				
						
								 
						
						*
						
						
						
								@author
						
						
						
						chengang
						
						
						
								2006
								-
								3
								-
								30
						
						
								
								
						
				
				
						
								 
						
						*/
						
								
								
						
				
				
						
								public
						
						
						
						
								class
						
						ProjectUtil {
						
								
								
						
				
				
						
								 
						
				
				
						
								    
						
						
								private
						
						
						
						
								static
						
						AbstractUIPlugin 
						
								plugin
						
						= Activator.getDefault();
						
								
								
						
				
				
						
								 
						
				
				
						
								    
						
						
								private
						
						ProjectUtil() {}
						
								
								
						
				
				
						
								 
						
				
				
						
								    
						
						/**
						
								
								
						
				
				
						
								     
						
						*
						
						
						判断当前的运行状态是否为插件方式
						
								
								
						
				
				
						
								     
						
						*
						
						
						
								@return
						
						
						
						true=
						插件方式运行
						
								
								
						
				
				
						
								     
						
						*/
						
								
								
						
				
				
						
								    
						
						
								private
						
						
						
						
								static
						
						
						
						
								boolean
						
						isPlugin() {
						
								
								
						
				
				
						
								        
						
						
								return
						
						
						
						
								plugin
						
						!= 
						
								null
						
						;
						
								
								
						
				
				
						
								    }
						
								
								
						
				
				
						
								 
						
				
				
						
								    
						
						
								public
						
						
						
						
								static
						
						URL getURL(String path) {
						
								
								
						
				
				
						
								        
						
						
								if
						
						(isPlugin())
						//
						如果是插件
						
								
								
						
				
				
						//            return plugin.find(new Path(path));
						
								
								
						
				
				
						
								        
								
								
								  
						
						
								return
						
						FileLocator.find(
						
								plugin
						
						.getBundle(), 
						
								new
						
						Path(path), 
						
								null
						
						);
						
								
								
						
				
				
						
								        
						
						
								else
						
						
								
								
						
				
				
						
								            
						
						
								try
						
						{
						
								
								
						
				
				
						
								                
						
						
								return
						
						
						
						
								new
						
						URL(
						"file:"
						+ path);
						
								
								
						
				
				
						
								            } 
						
								catch
						
						(MalformedURLException e) {
						
								
								
						
				
				
						
								                
						
						
								throw
						
						
						
						
								new
						
						
						
						
								RuntimeException
						
						(path + 
						" is error"
						, e);
						
								
								
						
				
				
						
								            }
						
								
								
						
				
				
						
								  
								  }
						
								
								
						
				
				
						
								 
						
				
				
						
								    
						
						
								public
						
						
						
						
								static
						
						InputStream getInputStream(String path) {
						
								
								
						
				
				
						
								        URL url = getURL(path);
						
								
								
						
				
				
						
								        
						
						
								try
						
						{
						
								
								
						
				
				
						
								            
						
						
								return
						
						url.openStream();
						
								
								
						
				
				
						
								        } 
						
								catch
						
						(IOException e) {
						
								
								
						
				
				
						
								            
						
						
								throw
						
						
						
						
								new
						
						RuntimeException(e);
						
								
								
						
				
				
						
								        }
						
								
								
						
				
				
						
								    }
						
								
								
						
				
				
						
								 
						
				
				
						}
				
		 
		
				
						 
				
		
		
				
						(6)        
				
				运行
				RCP
				,如果配置文件找得到则
				System.out.println(conf);
				会打印出
				org.hibernate.cfg.Configuration@1c1eceb
				。如果找不到则打印出null,还会抛出异常org.hibernate.HibernateException: /hibernate.cfg.xml not found
		
		
				
						 
				
		
		
				
						4
				
				、下载实例
		
		
				由于lib目录下的jar包太大,我这里把lib包里的jar文件全删除了
		
		下载地址:http://www.blogjava.net/Files/chengang/my_hibernate_rcp_1_nojar.rar
		
				
						 
				
		
		
				
						5
				
				、后话
		
		
				在构架来说,如果你的
				RCP
				是多用户使用的,我并不赞成直接在
				RCP
				中使用
				Hibernate
				去访问数据库,一般来说应该把数据库的访问代码封装在一个网上的中央控制器上,而各个
				RCP
				客户端通过访问这个中央控制器来访问数据库。这样做的好处是数据库操作得以集中控制,否则数据一致性的问题将会很难保证。 
作者简介
陈刚,广西桂林人,著作有《Eclipse从入门到精通》
您可以通过其博客了解更多信息和文章:http://www.ChenGang.com.cn