在
Eclipse’s RCP
中配置
Hibernate
1
、起因
一個(gè)同學(xué)問(wèn)起在
RCP
中怎么配置
Hibernate
。我讓他參考我的另一篇文章《在
Eclipse RCP
中使用
Spring
》,奈何他仍然搞不定,我想這是對(duì)
Hiberate
和
Spring
缺乏整體認(rèn)識(shí)的原故吧。
?
2
、原理
現(xiàn)在一般的框架大都采“配置文件+
JAR
包”形式,用配置文件來(lái)配置一些
JAR
包中類所需要用到的變量,而配置文件一般又采用
XML
格式。因此無(wú)論是配置
Spring
還是
Hibernate
,關(guān)鍵是能讓程序讀到
XML
配置文件。
?
在
WEB
項(xiàng)目中,配置文件一般放在
src
目錄(實(shí)現(xiàn)在編譯后則會(huì)自動(dòng)轉(zhuǎn)到存放
class
的頂層目錄),那么
RCP
下又應(yīng)放在哪里呢?當(dāng)然也是
src
目錄。在《在
Eclipse RCP
中使用
Spring
》一文中還給出了另外一種方式,在這篇文章里我將給出三種配置文件的存放方式,以及相應(yīng)的讀取方法。希望大家可以由此對(duì)如何讀取外部文件有進(jìn)一步的理解。
?
在
Spring
一文中,我是把
xml
文件放在
src
下,然后用
Spring
提供的一個(gè)類來(lái)讀取,如下:
ctx?=?new?ClassPathXmlApplicationContext("/myspring.xml");
???
?
同學(xué)問(wèn)了
Hibernate
沒(méi)有
ClassPathXmlApplicationContext
類,該怎么辦呢?舉一反三呀。讓我們看看
Hibernate
是如何讀取其配置文件
hibernate.cfg.xml
,代碼如下。
conf = new Configuration().configure()
?
Configuration
就是中文翻譯為“配置”,而此類是
Hibernate
程序執(zhí)行第一個(gè)要用到的類,它的功能就是讀取配置文件
hibernate.cfg.xml
,生成一個(gè)配置類實(shí)例(里面包含著
hibernate.cfg.xml
的配置信息)。只不過(guò)
Hibernate
和
Spring
不用,
Spring
的配置文件由用戶創(chuàng)建,可以千變?nèi)f變。而
hibernate
的也就一個(gè),因此就給它設(shè)了一個(gè)默認(rèn)文件名為:
hibernate.cfg.xml
,默認(rèn)路徑為放在
src
目錄下。所以
configure()
沒(méi)有帶任何參數(shù)。但實(shí)際可以發(fā)現(xiàn)
configure
方法是多態(tài)的,它還有如下形式。
configure(java.lang.String);
configure(java.net.URL);
configure(java.io.File);
configure(org.w3c.dom.Document)
?
這些方法使得生成
Configuration
實(shí)例的方式靈活多變,這和
Spring
提供各種讀取
xml
配置的類的想法是一樣。
?
3
、實(shí)例
實(shí)例環(huán)境:
Eclipse3.2 + Hibernate 3.1.3
?
先給出項(xiàng)目的結(jié)構(gòu)如下,然后我們一步步完成它
?
?
(1)??????
先用
Eclipse
的
RCP
向?qū)?chuàng)建一個(gè)
RCP
項(xiàng)目,模板選
Hello World
。
(2)??????
然后在項(xiàng)目下創(chuàng)建一個(gè)
lib
目錄,把
hibernate
的所有
jar
包全復(fù)制進(jìn)去,接著要配置后這些加入的
jar
包?!?/span>
Eclipse
從入門到精通》里稱之為配置庫(kù)引用。
RCP
的庫(kù)引用不能亂配,請(qǐng)遵尋如下方法:
l??????????
打開(kāi)
plugin.xml
文件,找到“運(yùn)行時(shí)”項(xiàng)的“類路徑”把所有
jar
包加入,如下圖:
l??????????
再找到“構(gòu)建”項(xiàng)的“額外類路徑條目”
l??????????
當(dāng)配置完成后,轉(zhuǎn)到項(xiàng)目屬性的庫(kù)引用就可以看到“插件依賴項(xiàng)”添加了各
jar
包,如下圖所示:

注:如果出現(xiàn)
no class found
之類的異常,先檢查沒(méi)有包含這個(gè)類的
jar
包,再檢查這個(gè)
jar
包的庫(kù)引用是否配置好了。
?
(3)??????
把一個(gè)
hibernate.cfg.xml
分三份放在如圖位置上(分成三份是為了試驗(yàn)三種路徑讀取方法),把
hibernate.cfg.xml
中無(wú)關(guān)緊要的信息都刪除掉,我的
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)??????
接下來(lái)寫(xiě)測(cè)試程序,直接在
Perspective.java
里寫(xiě)了,代碼如下:
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(); //
對(duì)默認(rèn)存放路徑的讀取方法
??????? path2(); //
對(duì)第二種存放路徑的讀取方法
??????? path3(); //
對(duì)第三種存放路徑的讀取方法
??? }
?
???
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
,關(guān)于此文件的更多信息,看這篇文章:
Plugin
和
App
的統(tǒng)一路徑接口
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;
?
/**
?
*
用于插件項(xiàng)目和非插件項(xiàng)目,提供兩者通用的方法接口
?
*
@author
chengang
2006
-
3
-
30
?
*/
public
class
ProjectUtil {
?
???
private
static
AbstractUIPlugin
plugin
= Activator.getDefault();
?
???
private
ProjectUtil() {}
?
???
/**
????
*
判斷當(dāng)前的運(yùn)行狀態(tài)是否為插件方式
????
*
@return
true=
插件方式運(yùn)行
????
*/
???
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)???????
運(yùn)行
RCP
,如果配置文件找得到則
System.out.println(conf);
會(huì)打印出
org.hibernate.cfg.Configuration@1c1eceb
。如果找不到則打印出null,還會(huì)拋出異常org.hibernate.HibernateException: /hibernate.cfg.xml not found
?
4
、下載實(shí)例
由于lib目錄下的jar包太大,我這里把lib包里的jar文件全刪除了
下載地址:http://www.tkk7.com/Files/chengang/my_hibernate_rcp_1_nojar.rar
?
5
、后話
在構(gòu)架來(lái)說(shuō),如果你的
RCP
是多用戶使用的,我并不贊成直接在
RCP
中使用
Hibernate
去訪問(wèn)數(shù)據(jù)庫(kù),一般來(lái)說(shuō)應(yīng)該把數(shù)據(jù)庫(kù)的訪問(wèn)代碼封裝在一個(gè)網(wǎng)上的中央控制器上,而各個(gè)
RCP
客戶端通過(guò)訪問(wèn)這個(gè)中央控制器來(lái)訪問(wèn)數(shù)據(jù)庫(kù)。這樣做的好處是數(shù)據(jù)庫(kù)操作得以集中控制,否則數(shù)據(jù)一致性的問(wèn)題將會(huì)很難保證。?
作者簡(jiǎn)介
陳剛,廣西桂林人,著作有《Eclipse從入門到精通》
您可以通過(guò)其博客了解更多信息和文章:http://www.ChenGang.com.cn???