如今,Hibernate正在迅速成为非常流行的(如果不是最流行的)J2EE O/R映射程序/数据集成框架。它为开发人员提供了处理企业中的关系数据库的整洁、简明且强大的工具。但如果外部需要访问这些已被包装在J2EE Web应用程序中的实体又该怎么办?是开发独立但相同的实体来访问数据,还是另外编写Web组件来管理内部访问的数据?

  在某种程度上,这些问题是一定会发生的,对于我来说,当我的公司要向数据库中加载来自多个供应商的多种文件格式的记录时,就出现了这些问题。我考虑过以前常用的方法:用shell和SQL脚本(甚至存储过程)来加载数据。但由于数据模型过于复杂,我决定尽量利用现有的实体、Spring DAO以及Web应用程序之外的服务,并开发定制的J2SE命令行数据加载程序。

  重要问题:我们是否应该这样做?

  目前与Hibernate有关的大部分文档和例子都基于在容器中使用Hibernate。无论Hibernate是用于Web应用程序还是内部的“胖应用程序”,总是涉及到一个容器。这样做是有原因:容器支持各种特性,比如事务处理、线程和安全性。现在,要开发中型和企业应用程序,有一些工具是必需的。但当我们需要在容器外部访问实体对象时要怎么做?是使用现有的基础架构和代码呢,还是从另一种角度甚至还可能使用另一种语言去解决问题?当然,这个问题没有正确答案,在本文余下的部分中我将解释我所使用的方法,即,在Spring容器外重用现有的实体/POJO。

  脚本语言(如:Perl、Python、Ruby,甚至是Tcl)乍一看都有一些优点。很多时候,脚本语言可以快速开发,并易于获得初始结果,它还可以绕过Hibernate底层的复杂性。有可能在短短数行内就连接到数据库、选择一些结果并将其打印到屏幕或某个日志文件中。但受数据模型的影响,事情可能(通常情况下都会)变得非常复杂。假设有一张person表,其中有一个到address表的外键,在插入数据时,address没有被正确插入,这会导致person也不能被插入:这是典型的事务问题。有人可能会辩解说在脚本语言中这个问题并不难解决,就像在主应用程序中所做的那样。但还是有问题存在:为什么要这样做?如果逻辑已经存在于应用程序中,为什么还要再次进行编码?而且这并不是唯一的问题,我们将需要复制工作和逻辑,还可能由此产生许多错误。
  有些人可能认为这些都不是大问题,并用自认为是最合适的工具来解决这些问题。也许您已经由于编码之外的原因使用了某种独立的基础架构。也许您事先将数据上传到独立的数据库中并进行充分测试,然后再将数据迁移到生产数据库中。又或者您的数据库维护工作已经外包出去,您只需要将文件发送给合作伙伴公司,由他们来解决这些问题。最后,可能还有许多其他原因造成您并没有使用现有的Hibernate数据层——不管这些原因正确与否。但如果您可以并打算在应用程序之外使用现有的代码库,请继续往下读。我将介绍一些技巧,并解决一些令人头疼的问题。

  配置

  一旦决定在容器之外使用现有的Hibernate对象,那么首先就必须自己管理所有的配置。下文介绍的方法是使用一个独立的Java命令行应用程序。既然已经设置了Hibernate XML配置文件,那么您应该知道哪些参数是必需的,比如JNDI DataSource名称、实体映射文件以及用于记录SQL的各种属性。如果您决定使用命令行应用程序,那就一定要解决如何分析XML文件并把它添加到新配置中的问题。分析XML文档不是不可能的,但是这有时会带来一些其他的小任务。因此我建议使用常规的属性文件。属性文件的加载非常简单,而且从其中取值也很容易。下面的例子示范了配置Hibernate所需的最小属性集(没有任何实体映射)。

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

正如您所看到的,上面的属性指定了数据库的非标准语言,JDBC驱动类、数据库服务器名称、用户名、密码以及是否使用查询替换。一旦定义这些属性并保存到hibernate.properties文件(应该在类路径下)中,就很容易加载它们并传递给Hibernate Configuration对象。

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);

段代码描述了如何从hello包加载Message的实体定义。但这种方式只适用于某些情况,对大部分实体来说这样做是乏味且容易出错的,这些代码必须人工维护,每次增加新的实体都要更新加载程序代码 。真令人厌烦!有一种更容易的发现并加载这些映射的方法,可以使这些映射与.jar一样经常保持最新。   首先,正如在web应用程序或企业应用程序中一样,映射文件必须保存在类路径中,这样Hibernate才能正常工作。这是一件好事,因为只需使用同样的.jar文件并找到这些映射文件名。如果在类路径中有多个.jar文件,则需要指定哪个文件包含映射。下面的代码是寻找映射的方法之一。

文章来自 Java开发频道:http://bbs.it-home.org/thread-3134-1-1.html

在Java SE中使用Hibernate处理数据的更多相关文章

  1. 数据结构与算法(3)- C++ STL与java se中的vector

    声明:虽然本系列博客与具体的编程语言无关.但是本文作者对c++相对比较熟悉,其次是java,所以难免会有视角上的偏差.举例也大多是和这两门语言相关. 上一篇博客概念性的介绍了vector,我们有了大致 ...

  2. JAVA面试中问及HIBERNATE与 MYBATIS的对比,在这里做一下总结

    我是一名java开发人员,hibernate以及mybatis都有过学习,在java面试中也被提及问道过,在项目实践中也应用过,现在对hibernate和mybatis做一下对比,便于大家更好的理解和 ...

  3. JAVA面试中问及HIBERNATE与 MYBATIS的对比,在这里做一下总结(转)

    hibernate以及mybatis都有过学习,在java面试中也被提及问道过,在项目实践中也应用过,现在对hibernate和mybatis做一下对比,便于大家更好的理解和学习,使自己在做项目中更加 ...

  4. 在Java程序中使用Hibernate

    Hibernate是一种ORM框架,ORM全称为Object-Relative Database-Mapping,在Java对象与关系数据库之间建立某种映射,以实现直接存取Java对象(一般为实体类) ...

  5. JAVA面试中问及HIBERNATE与 MYBATIS的对比

    第一方面:开发速度的对比 就开发速度而言,Hibernate的真正掌握要比Mybatis来得难些.Mybatis框架相对简单很容易上手,但也相对简陋些.个人觉得要用好Mybatis还是首先要先理解好H ...

  6. Java 虚拟机中的运行时数据区分析

    本文基于 JDK1.8 阐述分析 运行过程 我们都知道 Java 源文件通过编译器编译后,能产生相应的 .Class 文件,也就是字节码文件.而字节码文件通过 Java 虚拟机中的解释器,编译成特定机 ...

  7. Java SE中的Synchronized

    1 引言 在多线程并发的编程中Synchronized一直是元老级的角色,很多人会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化以后,有些情况下它并不那么重了. ...

  8. Java项目中基于Hibernate分页总结

    1,First of all,  we should have a wrapper class for page,this class can calculate the startRow by th ...

  9. 【译】Java SE 14 Hotspot 虚拟机垃圾回收调优指南

    原文链接:HotSpot Virtual Machine Garbage Collection Tuning Guide,基于Java SE 14. 本文主要包括以下内容: 优化目标与策略(Ergon ...

随机推荐

  1. Android常见布局问题

    原文链接:http://www.cnblogs.com/Birdmafly/p/3809802.html 好久没写博了,因为最近在忙着做一个app,实在是没有时间.现在快完工了.想着还是把这个布局问题 ...

  2. viewPager使用时加载数据时显示IllegalStateException异常,解决不了。。。。

    从newsPager中得到newsDetailTitles标题的详细内容,这是通过构造器传过来的.打印日志78行能打印,45行打印出来共size是12.但是程序出现了异常java.lang.Illeg ...

  3. 相比于python2.6,python3.0的新特性。

    这篇文章主要介绍了相比于python2.6,python3.0的新特性.更详细的介绍请参见python3.0的文档. Common Stumbling Blocks 本段简单的列出容易使人出错的变动. ...

  4. [iOS]手把手教你实现微信小视频

    本文个人原创,转载请注明出处,谢谢. 前段时间项目要求需要在聊天模块中加入类似微信的小视频功能,这边博客主要是为了总结遇到的问题和解决方法,希望能够对有同样需求的朋友有所帮助. 效果预览: 这里先罗列 ...

  5. TCP/IP详解之:ICMP协议

    ICMP协议: ICMP是IP层的一个组成部分,ICMP报文是在IP数据报内部被传输的,用于在IP主机.路由器之间传递控制消息.控制消息是指网络不通.主机是否可达.路由是否可用等网络本身的消息.这些控 ...

  6. mysql自定义循环函数

    FUNCTION deyes.f_getSplitStringByIndex1_8(stringIn text, delimiter varchar(10), indexIn int) RETURNS ...

  7. Nginx 拒绝指定IP访问

    来源 : http://www.ttlsa.com/nginx/nginx-deny-ip-access/   闲来无事,登陆服务器,发现有个IP不断的猜测路径.试图往服务器上传文件(木马).于是查看 ...

  8. js屏蔽浏览器(IE和FireFox)的刷新和右键等功能

    //一.js屏蔽浏览器(IE和FireFox)的刷新功能 document.onkeydown=function() { if ((window.event.keyCode==116)|| //屏蔽 ...

  9. java.util.Random 类的 nextInt(int num )

    随机产生3个67~295的整数并找出数值居中的数 并输出中间的数例如:100,225和200,输出200 要随机产生某个范围内的整数,用 java.util.Random 类的 nextInt(int ...

  10. codeforces 8C. Looking for Order 状压dp

    题目链接 给n个物品的坐标, 和一个包裹的位置, 包裹不能移动. 每次最多可以拿两个物品, 然后将它们放到包里, 求将所有物品放到包里所需走的最小路程. 直接状压dp就好了. #include < ...