您的位置: 旅游网 > 明星

在Eclipse中使用Hibernate(3)

发布时间:2019-12-04 11:56:30

如果您确实遵照了这些步骤,您就会发现执行时首次尝试将会失败:Hibernate抱怨说配置文件没有包含映射引用,而按要求至少要有一个。啊哈!所以,这就是图16底部XMLBuddy出现黄色下划线警告的原因。我们可以很容易地解决这个问题,具体方法是在Package Explorer视图中的Track.hbm.xml映射文档上右击,然后在新的Hibernate Synchronizer子菜单中选择Add Mapping Reference。这对XMLBuddy来说是正确的做法,可以让运行继续。遗憾的是,运行没有继续多久。下一个错误是无法在JNDI中找到JTA UserTransaction初始上下文。显然我并非惟一遇到这种问题的人,在一个论坛主题中相关的讨论如火如荼,但是还没有人找到解决方案。  因为知道我不需要使用JTA,所以我想知道为什么Hibernate要尝试找到JTA。我打开了Hibernate配置文件(图16),然后寻找Hibernate Synchronizer中的任何可疑之处。无疑有几行是最有嫌疑的:

<property name="hibernate.transaction.factory_class">

net.sf.hibernate.transaction.JTATransactionFactory

</property>

<property name="jta.UserTransaction">

java:comp/UserTransaction

</property>

我试着把上述内容注释掉并再次运行,这第三次运行成功了。运行没有出现错误,我的数据出现在数据库中。哇!运行可以信赖的antdb目标(Developer's Notebook一书的第1章中对此有说明)便可以看到所有数据(确实很简单),如图20所示。如果您要这样做,要确保从一个antschema开始创建数据库模式,或者清空来自前面实验中的任何测试数据。

图20.测试程序所创建的数据

注意,可以在Eclipse中运行Ant目标,具体方法是右击(或控制单击)Package Explorer中的build.xml文件,选择Run An,然后使用Eclipse对话框选择目标。酷吧?

图21.在Eclipse中运行Ant

使用查询取回数据相当简单,尽管这次的代码很接近于常规的使用Hibernate生成的普通数据访问类所使用的代码。即使Hibernate Synchronizer为处理指定查询生成了大量帮助器方法,我还是认为它们中间没有哪一个方法特别有用,因为它们都坚持运行查询后返回结果列表,而不是提供可以直接使用的Query对象。这使您无法使用Query的方便的类型安全的参数设置方法。因为这一点,我决定一定要让RootDAO对象为我提供一个Hibernate Session,以便使用老式的方法。我认为我可以编辑Hibernate Synchronizer使用的任何模板来生成我想要的任何方法,如果我要使用它来开发一个项目,我几乎肯定我会这么做。

实际上,进一步考虑的话,因为当获得一个活动的Session时,您只能处理Query,DAO所提供的方法已经达到了最佳效果。如果您想像我在这个例子中所做的那样处理查询,您必须总是自己进行会话管理。可以把会话管理嵌入到“您自己的”那一半DAO所提供的业务逻辑中,这就可以同时利用两方面的好处了。这正是Hibernate Synchronizer提供的拆分类模型如此有用的另一个原因。我将在下面对此进行深入探讨。

不管怎样,下面是我第一次想出的代码,基本上等同于书中48-49页上给出的代码:

package com.oreilly.hh;

import java.sql.Time;

import java.util.ListIterator;

import net.sf.hibernate.HibernateException;

import net.sf.hibernate.Query;

import net.sf.hibernate.Session;

import com.oreilly.hh.dao.TrackDAO;

import com.oreilly.hh.dao._RootDAO;

/**

* Use Hibernate Synchronizer's DAOs to run a query

*/

public class QueryTest3 {

public static void main(String[] args) throws HibernateException {

// Load the configuration file and get a session

_RootDAO.initialize();

Session session = _RootDAO.createSession();

try {

// Print the tracks that will fit in five minutes

Query query = session.getNamedQuery(

TrackDAO.QUERY_COM_OREILLY_HH_TRACKS_NO_LONGER_THAN);

query.setTime("length", Time.valueOf("00:05:00"));

for (ListIterator iter = query.list().listIterator() ;

iter.hasNext() ; ) {

Track aTrack = (Track)iter.next();

System.out.println("Track: \"" + aTrack.getTitle() +

"\", " + aTrack.getPlayTime());

}

} finally {

// No matter what, close the session

session.close();

}

}

}

TrackDAO提供的一个优秀特性是静态常量,通过它,我们可以请求指定查询,消除任何由于字符串输入错误而引起运行时错误的可能性。我喜欢这一点!为这个测试类设置和执行Run配置,将会生成预期的输出,如图22所示。

图22. Eclipse控制台视图中的查询结果

我前面提到过,运行这个类之后,我意识到,借助于Hibernate Synchronizer所提供的模型,可以用一种更好的方法来实现它。因为指定查询是与该数据访问对象相关的映射文件的一项特性,所以如果我们将查询放入TrackDAO对象中(这才是它真正属于的地方),那么这个对象看起来应该是下面这个样子:

package com.oreilly.hh.dao;

import java.sql.Time;

import java.util.List;

import net.sf.hibernate.HibernateException;

import net.sf.hibernate.Query;

import net.sf.hibernate.Session;

import com.oreilly.hh.base.BaseTrackDAO;

/**

* This class has been automatically generated by Hibernate Synchronizer.

* For more information or documentation, visit The Hibernate Synchronizer page

* at http://www.binamics.com/hibernatesync or contact Joe Hudson at joe@binamics.com.

*

* This is the object class that relates to the TRACK table.

* Any customizations belong here.

*/

public class TrackDAO extends BaseTrackDAO {

// Return the tracks that fit within a particular length of time

public static List getTracksNoLongerThan(Time time)

throws HibernateException

{

Session session = _RootDAO.createSession();

try {

// Print the tracks that will fit in five minutes

Query query = session.getNamedQuery(

QUERY_COM_OREILLY_HH_TRACKS_NO_LONGER_THAN);

query.setTime("length", time);

return query.list();

} finally {

// No matter what, close the session

session.close();

}

}

}

这样做更好更清晰,还进一步简化了QueryTest3中的main()方法:

public static void main(String[] args) throws HibernateException {

// Load the configuration file and get a session

_RootDAO.initialize();

// Print the tracks that fit in five minutes

List tracks = TrackDAO.getTracksNoLongerThan(Time.valueOf("00:05:00"));

for (ListIterator iter = tracks.listIterator() ;

iter.hasNext() ; ) {

Track aTrack = (Track)iter.next();

System.out.println("Track: \"" + aTrack.getTitle() +

"\", " + aTrack.getPlayTime());

}

}

显然,这是一种在使用Hibernate Synchronizer时处理指定查询的方法。做一次快速测试就可以确认它生成同样的输出,而且它的代码也要好很多。

您是否想使用Hibernate Synchronizer来生成它自己的数据访问对象类型暂且放下,我们还有最后一项重要特性要探讨。

编辑映射

Hibernate Synchronizer的一个主要吸引力就在于它为映射文档提供的专业化的编辑器。可以配置这个编辑器,以便只要保存文件就自动重新生成相关数据对象,但是这只是一个锦上添花的功能;即使不打算使用该插件的代码生成器,您也可能希望使用这个编辑器。它为您提供映射文档元素的智能完成功能,以及一个图形化的大纲视图,可以在这个视图中操纵这些元素。

但是,如果从Developer's Notebook一书中的下载源代码开始,就至少得有一项技巧才可以让编辑器工作。在下载的文件中,映射文档的扩展名为“.hbm.xml”,而只有以“.hbm”结尾的文件才能调用编辑器。理论上,可以在Eclipse中配置扩展名映射,以便使具有这两种扩展名的文件都能使用插件的映射文档编辑器,但是我无法使其生效,而且我注意到支持论坛上有人面临着与我相同的问题。所以,至少目前最好的做法就是重命名文件。(如果您坚持使用基于Ant的标准代码生成,请确保更新build.xml中的codegen目标以使用新的扩展名。)

天津爱维医院张木超
太原市迎泽区中医医院褥疮烧伤科专家
太原治疗早泄方法
遵义癫痫中医院
昆明最好的看妇科的医院
猜你会喜欢的
猜你会喜欢的