在Eclipse's RCP中配置Hibernate
在 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.
configure(java.io.File);
configure(org.w
這些方法使得生成 Configuration 實例的方式靈活多變,這和 Spring 提供各種讀取 xml 配置的類的想法是一樣。
3 、實例
實例環境:
Eclipse3.2 + Hibernate
先給出項目的結構如下,然后我們一步步完成它
?
(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
?
*/
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@
4 、下載實例
由于lib目錄下的jar包太大,我這里把lib包里的jar文件全刪除了
下載地址:http://www.aygfsteel.com/Files/chengang/my_hibernate_rcp_1_nojar.rar
5 、后話
在構架來說,如果你的
RCP
是多用戶使用的,我并不贊成直接在
RCP
中使用
Hibernate
去訪問數據庫,一般來說應該把數據庫的訪問代碼封裝在一個網上的中央控制器上,而各個
RCP
客戶端通過訪問這個中央控制器來訪問數據庫。這樣做的好處是數據庫操作得以集中控制,否則數據一致性的問題將會很難保證。?
陳剛,廣西桂林人,著作有《Eclipse從入門到精通》
您可以通過其博客了解更多信息和文章:http://www.ChenGang.com.cn
posted on 2006-08-24 12:28 陳剛 閱讀(5833) 評論(9) 編輯 收藏 所屬分類: Eclipse