在 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.blogjava.net/Files/chengang/my_hibernate_rcp_1_nojar.rar
5 、后话
在构架来说,如果你的 RCP 是多用户使用的,我并不赞成直接在 RCP 中使用 Hibernate 去访问数据库,一般来说应该把数据库的访问代码封装在一个网上的中央控制器上,而各个 RCP 客户端通过访问这个中央控制器来访问数据库。这样做的好处是数据库操作得以集中控制,否则数据一致性的问题将会很难保证。
作者简介
陈刚,广西桂林人,著作有《Eclipse从入门到精通》
您可以通过其博客了解更多信息和文章:http://www.ChenGang.com.cn