在
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