正 文

在Java SE中使用Hibernate处理数据


www.7dspace.com  更新日期:2006-2-16 15:07:15  七度空间


  使用Session

  关于这方面的具体内容,因为可以找到各种与Hibernate、持久化和查询对象有关的文章、教程或者大量关于使用事务的例子,所以我不再介绍任何细节。而是考虑要用实体作什么,以及它们是如何影响Hibernate Session对象的。能否使用现有的业务对象甚至数据访问对象?在设置数据层时,我使用Spring以及它所提供的一些管理连接、事务和Session 的类。这些对象都使用与Spring紧密集成的各种规则和关系定义在XML配置文件中。首先,DAO对象通过Spring的依赖注入(参见Bruce Tate的《Five Things I Love About Spring》)注入到服务中,然后配置服务以捕获特定的DAO异常(在XML配置文件中),这种异常是Spring可以正确处理的。虽然我觉得将 Spring集成到数据加载应用程序中的工作量很大,我还是对DAO对象进行了细微的调整。这样,这些对象就可以在web应用程序之外使用了。

  假设我在PersonDAO中有一个用来保存person对象的方法。由于容器已经设置好了Hibernate Session,我就不能在容器外重用这一DAO方法,因为它需要使用已经存在并完全配置好的Session对象。下面的代码是使用Spring容器所提供的Session支持后的典型PersonDAO:

import org.springframework.orm.hibernate.HibernateTemplate;
import test.pojos.Person;

public class PersonDAO extends HibernateTemplate {

 public PersonDAO(){}

 public Person save(Person aPerson) {
  if(aPerson != null) super.save(person);
  return person;
 }
}

  上面的类扩展了Spring的HibernateTemplate类,该类提供了使用Hibernate的所有基本方法。因为 HibernateTemplate管理了大部分普通操作,您只需将注意力集中在特定的持续需求上。当然这里也应该有适当的异常操作,但作为示例来说上面的代码已经足够了。
现在,要给Session增加在容器外使用的支持方法,只需做少量改动:

import org.springframework.orm.hibernate.HibernateTemplate;
import net.sf.hibernate.Session;
import test.pojos.Person;

public class PersonDAO extends HibernateTemplate {

 public PersonDAO(){}

 public void setExternalSessionFactory(Session aSession){
  setSessionFactory(session.getSessionFactory());
 }

 public Person save(Person aPerson) {
  if(aPerson != null) super.save(person);
  return person;
 }
}

  因为HibernateTemplate扩展了HibernateAccessor,我就可以从选中的任何Session对象设置SessionFactory。这是Spring高度灵活的设计之一,可以使代码重用变得更容易。

  也许您现在没有使用Spring,那么就要采取完全不同的方法。假设您没有使用Spring奇妙的依赖注入,那么从JNDI中查找Session对象的代码如下:

import net.sf.hibernate.Session;

public class PersonDAO {

 // This example assumes that there is a Hibernate
 // Session object at the following JNDI location
 // on a Tomcat 5.5 server:
 // java:/comp/env/obj/hibernateSession

 private Session session;

 public PersonDAO(){
  try {
   Context initCtx = new InitialContext();
   Context envCtx = (Context)
   initCtx.lookup("java:comp/env");
   session = (Session)envCtx.
   lookup("obj/hibernateSession");
  }catch(Exception e) {
   e.printStackTrace();
  }
 }

 public Person save(Person aPerson) {
  if(aPerson != null) session.save(person);
  return person;
 }
}

  上面的代码依靠应用容器使Hibernate Session对象可用。在容器之外使用这些对象的最简单的方法是再增加一个接收Session对象的构造函数:

import net.sf.hibernate.Session;

public class PersonDAO {

 // This example assumes that there is a Hibernate
 // Session object at the following JNDI location
 // on a Tomcat 5.5 server:
 // java:/comp/env/obj/hibernateSession

 private Session session;

 public PersonDAO(){
  try {
   Context initCtx = new InitialContext();
   Context envCtx = (Context)
   initCtx.lookup("java:comp/env");
   session = (Session)envCtx.
   lookup("obj/hibernateSession");
  }catch(Exception e) {
   e.printStackTrace();
  }
 }

 public PersonDAO(Session aSession){
  session = aSession;
 }

 public Person save(Person aPerson) {
  if(aPerson != null) session.save(person);
  return person;
 }
}

  显然,我们没有处理许多异常和事务问题,或者说我们在许多方法之间共享了Session对象,但根据容器或框架处理对象实例的方式,这可能会引起一些并发问题。但我认为上面的示例清楚地演示了可以重用许多现有的数据层代码,这只需要一点创造性思维。记住,如果打算在应用服务器之外使用实体和DAO,那么就要测试,测试,再测试!

  结束语

  正如我们所看到的,在web容器外使用Hibernate实体和 DAO有很多窍门,但是这确实可以做到。最大的挑战是找到实体映射并解决如何重新配置或扩充已有的数据访问对象(DAO)的问题。对于后者,要小心管理自己的事务,因为有可能无法依赖于任何现有的业务服务。但是到最后,您可以访问所有实体以及用于对它们进行持久化的对象,这可以节省重新开发所花费的大量时间。祝您好运!

2页,页码:[1] [2] 

上一篇:FullDisk让你的硬盘使用情况一目了然
下一篇:ASP.NET2.0中使用数据源控件之参数
标题:在Java SE中使用Hibernate处理数据 作者:Jong Lee 来源:bea
收藏此页】【打印】【关闭
站 内 搜 索
 

热 点 导 读
特 别 推 荐