<%@ page contentType="text/html; charset=gb2312"%> 在Java SE中使用Hibernate框架
网站公告:   ◆北天JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!  
加入收藏
设为首页
联系站长
承接项目
  相关资源:网站首页 | 免费培训学院 | 技术论坛 | JAVA聊天室 | 作家专栏 | 开发工具 | 认证考试 | 会员俱乐部
  JAVA技术初学者园地 | jsp与servlet | javascript | Java源代码 | EJB | web service | 应用服务器 | JAVA综合知识
  设计研究设计模式 | 设计框架 | Struts | Spring | Hibernate | 开源项目 | 面向对象设计 | 设计综合知识
  数 据 库MYSQL | SQL Server | Sybase | Oracle | DB2 | Informix | Access | 数据库综合知识
  其他资源:AJAX新技术 | 网站开发 | ERP软件 | OA办公软件 | 商业智能BI | 开发综合知识 | 承接项目 | 项目试用

 
 
在Java SE中使用Hibernate框架
     发布者: 发布时间:2007-09-23
目前人们很容易发现Hibernate正迅速的成为流行的J2EE的O/R映射工具和数据集成框架(如果不是最流行的)。Hibernate为企业应用开发者操作关系数据库的提供了清晰明了而又强大的工具。然而如果你需要在外部访问那些包装在J2EE web应用里的实体,情况又怎样呢?你的开发跟应用独立分开,却又相同的实体以访问你的数据吗?又或者你得编写附加的web组件来管理对数据的内部访问吗?

  在很多情况下,这些问题都会出现。我的情况是我的公司需要将来自多个供应商,有着多种文件格式的记录导入到数据库里。我想起我以前经常使用的方法,那就是编写Shell和SQL教本(甚至是存储过程)来导入数据。但是由于我们的数据模型太过复杂,我决定在web应用之外尽可能的利用现有的实体,Spring DAO以及服务并且开发一个自定义的J2SE命令行数据加载工具。

  大问题:你该怎样呢?

  现在很多Hibernate的文档和范例都是绑定在容器上。不管是web应用还是内部的大型应用,总会使用到容器的。人们有很好的理由去使用它。容器是设计来提供对各种特性的支持,例如事务处理,线程以及安全。现今,这些特性都是开发中等规模和企业应用所必需的工具。然而当你需要在容器之外访问实体时,你该怎样呢?你是使用现有的架构和代码呢,还是会从一个不同的角度来解决问题,比如说完全采用另一种开发语言?当然,我们没有正确答案。在本文的余下部分,我将说明我的方法:就是在Spring容器之外重用现有的实体/POJO。

  起初,脚本语言,例如Perl,Python,Ruby甚至Tcl(是的,我以前也做过这个)看起来有很多优势。它们能省下很多时间,可以轻易得到初始结果,还能规避许多Hibernate潜在的复杂度。人们完全可能只用几行代码就可以连接数据库,查询结果,已经打印输出到终端屏幕或者日志文件。然而,取决于你的数据模型,事情也(总是)会变得相当复杂。譬如说你有一个表 person, 其中有一个外键属于表 address。当我们添加数据的时候,表address没有正确的插入数据,就会导致表person 也不能插入了。这是个很典型的事务处理方面的问题。也许有人会说在脚本语言中这个问题不难解决,就像在你的主程序里一样。可是问题仍然存在,为什么要这样做呢?业务逻辑不是已经在你的应用里面了吗?为什么要在写一遍代码呢?而且这并不是唯一的情况,你必须重复你的工作和业务逻辑,这样就会带来出错的可能。

  然而,有些人会觉得这样也行,他们使用自己觉得最适合的工具。也许你已经因为程序之外的原因而有了某种独立的架构;也许你会在独立的数据库里加载和测试数据,然后在通过各种测试后再迁移到产品的数据库里;又也许你把数据库维护外包出去,你只需要把相关文件发给合作伙伴让他们去处理那些问题。总之,总会有很多理由不使用现有的Hibernate数据层。没有谁对谁错,只是如果你可以也愿意在你的应用之外使用现有的代码,请往下看。我会告诉你一些方法,这能解决你不少的烦恼噢。

  配置

  如果你觉得可以在容器之外使用现有的Hibernate对象的话,那你首先要做的事就是得自己手工管理所有的配置项,在本文余下部分我所采用的方法是使用一个基于命令行的JAVA程序。既然你已经配置了Hibernate XML配置文件,你应该知道需要提供的参数,例如JNDI DataSource名,实体映射文件,还有其他一些处理SQL日志的属性。如果你想使用命令行程序的话,你就得解决如何解析XML文件和把它添加到配置项中的这些问题。虽然解析XML文件也不难,但这本身并不是我们的重点。因此,我建议使用propetries文件,properties文件比较直观而且容易加载并从中读取数据。下面是配置Hibernate所需要的最小属性集(不包括任何实体映射)。

  清单1:

hibernate.dialect=net.sf.hibernate.dialect.PostgreSQLDialect
hibernate.connection.driver_class=org.postgresql.Driver
hibernate.connection.url=jdbc:postgresql://devserver/devdb
hibernate.connection.username=dbuserhibernate.connection.password=dbpassword
hibernate.query.substitutions yes Y

  正如你所看到的,上面的属性值指定了数据库方言,JDBC驱动,数据库url,用户名,用户密码,以及是否使用查找替换。只要定义以上几项数值并保存在文件hibernate.properties里(要放置在你的类路径里面哦),就能很轻松的加载,填充到Hibernate Configuation类里面。

  清单2:

Properties props = new Properties();
try {
 props.load(props.getClass().getResourceAsStream("hibernate.properties"));
}catch(Exception e){
 System.out.println("Error loading hibernate properties.");
 e.printStackTrace();
 System.exit(0);
}
String driver = props.getProperty("hibernate.connection.driver_class");
String connUrl = props.getProperty("hibernate.connection.url");
String username = props.getProperty("hibernate.connection.username");
String password = props.getProperty("hibernate.connection.password");
// In my examples, I use Postgres, but Hibernate
// supports virtually every popular dbms out
there.Class.forName("org.postgresql.Driver");
Connection conn = DriverManager.getConnection(connUrl, username, password);
Configuration cfg = new Configuration();
cfg.setProperties( props );
SessionFactory sessions = cfg.buildSessionFactory();
Session session = sessions.openSession(conn);

  这样我们就得到了Hibernate Session类了。但我们也有必要解决如何利用现有的实体映射这个问题。在《Hibernate in Action》一书中,提到怎样从实体映射XML文件中加载,如下所示:

  清单3:

Configuration cfg = new Configuration();
cfg.addResource("hello/Message.hbm.xml");
cfg.setProperties( System.getProperties() );
SessionFactory sessions = cfg.buildSessionFactory();

  这段代码清晰的说明了从hello包里加载Message实体定义的过程。对于这个例子来说还好,但对那些有多个实体的应用来说,就很单一而且容易出错。不仅映射关系是硬编码,还得手工管理每次添加一个新的实体就要更新实体加载的代码。其实有跟简单的方法去查找和加载映射关系以使其与最新的jar文件保持一致。

  首先,在你的web服务器或者企业服务器里,映射文件需要放置在类路径里,这样Hibernate才能正常的运行。这样做是很有好处的,因为你所需要做的就是使用同样的jar包和查找相应的映射文件的名字。因为你可能会有多个jar文件在你的类路径里,你需要指定哪个jar包包含了映射文件。以下就是一种查找映射关系的方法

  清单4:

String cp = System.getProperty("java.class.path");
String jarFile = null;
List hbmList = null;String[] cparr = cp.split("\\:");
for(int j=0;j // The following assumes our entities
 // are wrapped up in a jar file
 // called dbobjs.jar
 if(cparr[j].indexOf("dbobjs.jar") != -1)
  jarFile=(cparr[j]);
}
if(jarFile != null){
 JarFile jar = new JarFile(new File(jarFile));
 Enumeration e = jar.entries();
 if(e.hasMoreElements())
 {
  hbmList = new ArrayList();
  while(e.hasMoreElements()){
   // Object comes back as JarFile$JarFileEntry
   JarEntry entry = (JarEntry)e.nextElement();
   if(entry.getName().indexOf(".hbm.xml") != -1)
   {
    hbmList.add(entry.getName());
   }
  }
 }else {
  System.out.println("Error: The entity jar dbobjs.jar was not found in " + "classpath: " + cp);
 }
}

  上面的代码主要完成了以下几件事情:获取Java虚拟机初始化的classpath系统属性;查找含有实体映射文件的jar包;解析映射文件的名字,然后添加到一个ArrayList对象中去。当我们的ArrayList对象装满了实体映射的名字后,就可以将其传递到Hibernate Configuration 对象,如下所示:

  清单5:

Configuration cfg = new Configuration();
Iterator iterator = hbmFileNames.iterator();
while(iterator.hasNext()){
 cfg.addResource((String)iterator.next());
}

  只要我们在Hibernate Session 对象里配置好正确的映射关系,我们就可以将实体拿来使用了。

使用Session

  关于这一点,你可以参考关于Hibernate和持久层的文章或者指南,也可以查询各种对象和实例来了解怎么使用事务,所以我不打算详细说这些内容。相反,我会更多考虑使用实体后我们需要做什么?这会对Hibernate Session 对象有怎样的影响?是否可以使用现有的业务对象,甚至是数据访问对象?当我建立数据层的时候,我使用了Spring及其提供的一些类来管理数据库连接,事务和会话。这些对象都在XML配置文件里面定义了,并与很多规则和关系紧密集成在Spring里。首先,通过Spring的依赖注射,DAO对象会被引入到应用服务中(关于依赖注射,参见Bruce Tate的《Five Things I Love About Spring》一书)。然后,配置应用服务以捕获DAO异常(通过XML配置文件),让Spring去处理。可是因为我觉得把Spring集成到数据加载应用里会带来相当大的工作量。我对DAO对象做了轻微的修改,使得可以在web应用之外使用他们。

  例如说在PersonDAO类里面有一个保存person对象的方法。如果Hibernate Session 是由容器建立的,那这个方法就不能在容器外使用,因为这需要一个配置好的Session对象。以下是一个典型的PersonDAO,它由Spring 容器提供了对Session的支持。

  清单6:

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的支持,我们只需要做一些小小的改动:

  清单7:

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对象:

  清单8:

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参数的构造函数,如下所示:

  清单9:

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)。处理后者时,要小心处理事务问题,因为没有应用服务可以依赖了。不过最后,我们还是可以访问所有的实体和进行持久化的对象,这样能省下大量的重新开发代码的时间。祝您好运!!

(转载文章请保留出处:北天JAVA技术网(www.java114.com))
 
更多精彩文章:
Java程序员的存储过程
Java程序员的存储过程
JDBC数据库连接的问题
Hibernate的事务和并发(ZT)
用JavaBean编写SQLServer数据库连接类
Java数据库编程中的基本步骤和常用技巧
 
最近评论:
        
Great work
manualidades de baby shower reflexiones power point bishop tudor bismarck church lista de verbos irregulares y regulares bui yah kah jeans heart evangelista latest pictures tamela mann dead crissy moran sample videos carta de renuncia sensation del bloque lyrics kamus dewan bahasa pinoy erotic stories pianta geografica lombardia jeana keough and playboy pics carrie ann inaba pics nude ms rpido y furioso lil amber models myers plow parts buy melissa dettwiller videos niktoutro ragnarok online private server
        
Thank you
csc lawyers incorporating service california mugen street fighter alpha 3 characters delishis from flavor of love neopets free jelly light blonde punk bob haircut radio diffusione suono www daily ajit jalandhar com manele gratis miko sinz video childrens printable chore charts kayla sirius myspace ifilm uncensored clip forum caveviet com napkin nights sacramento doc truyen audio nguyen ngoc ngan lisa robertson pictures free latest pgm file for viewsat fotos de la taina boyd cottington hot rods free pool aimer
        
My feedback
galeria de niurka en playboy dibujos para colorear de baby shower free phim nguoi lon divini rae video lyrics to bubble gum by rasheeda wild style graffiti alphabet kmart employment application allisa lies song lyrics hentai avatar the last airbender porn mickey james nude cawangan polis trafik ivanka trump maxim no more complaining lyrics coco nicole austin gerald levert funeral services www mydish olive garden com xanga aim fades outer limit tattoos riccardo scamarcio foto monopoly scratch n win
        
Thank you
the biggst dritbike tad hilgenbrink shirtless cute cheap maternity clothes no explode side effects ne patriots myspace layouts marika dominczyk pics free birthday invitation maker layla kayleigh nude phim nguoi lon com vn nickel and dimed summary tracee ellis ross vibe vixen pics floxite company inc 15x magnification alvin s glenn buffiethebody com sample of condolence letter fotos de belinde desnuda mallu adult actress gundam seed destiny wallpaper samsungusa com offer descuidos galilea montijo
        
Thank you
calcolo piano ammortamento mutuo inglese rob dyrdek bio stop and shop supermarket circular new ithaca double barrels lyrics this why im hot pinay kantutan kalibugan philippines altantuya shaariibuu mongolian short bob hair styles sam mcguffey video ejemplo de carta renuncia pinoy scandals nude angelica panganiban eyes by rogue wave lyrics hutch caller tune code shaina magdayao pictures platano con salami lyrics myspace div overlay layout princess hours ost perhaps love lyric letras goticas abecedario maple story simulator
        
My feedback
carmen winstead sewer fusetv pants off winx club ricerca numeri cellulari tim winx disegni colorati truth or dare stories mature inculate a sangue xavier university football in 1971 graigs list houston craigs kari mythbusters maxim did miley and nick kiss redeem camel cash c notes pirate king bot sss philippines inquiry clown joker drawings kmart online application customers miko sinz free fotos calendario taina power rangers operation overdrive cast amanda auclair pics
        
My feedback
craigslist detroit michigan tamagotchi cheats v4 stanley tookie williams funeral pictures gossip datuk khalid mat jiwa nude picture of rosanna roces pansat 2500a bin birdman and lil wayne kissing miley cyrus bra and panties pictures huck finn spark notes fei lun hai wallpaper kari jobe revelation new pics of deelishis magnum 4d result in malaysia cobray ss 12ga tyra b still in love www the sammyboy forum aksi lucah mat rempit video four leaf clover tattoos gambar bawang merah putih sajak ana abadi
        
My feedback
top 100 ro private server naruto mugen char myfirsttime cikgu amira insite fds employeeconnection videos de sofia zamolo chelis chili gifts animate gratis delicious flava flav our lady of medgegoria desi masala stories scary exorcist maze gaia online gold cheats downloads foglio calcolo stipendio 2007 free zwinky money cheats anne geddes com myspace layout camo naruto mugen chars downloads marykay comintouch https wwe divas uncensored london charles naked
        
Great work
blood and crypts gang sesshoumaru and kagome lemon jawatan kosong sabah 2007
        
Thank you
isolanti per cappotti phimsex viet nam free brooke burke playboy blog lucah melayu pitbull fighting clips galilea montijo cogiendo ingrosso bomboniere vicenza larissa aurora pics tijuana donkey show video omarion and usher icebox remix lyrics coi phim online free chalie boy bumpa grill lyrics truyen danh cho nguoi lon att yahoo virus protection spyware corbin bleu shirtless nicole coco austin com nikki catsouras crash resepi melayu asanti af120 22inch fotos niurka marzo
        
标 题:   
内 容:   
 
                                  
 
免责声明:该文章由网友发表,如果对您造成侵权,请联系站长

首页 - 承接项目 - 网站地图 - 联系我们 -
版权所有北天JAVA技术工作室 ICP证号:粤ICP备06079815号