如今,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. 安卓图片框架:universal-image-loader的高速使用

    在安卓开发过程中难免会遇到下面几个情况: 1.图片异步载入 2.图片缓存 3.图片显示 4.其他--(忘记了) 以上的这些情况,可能要自己去写不少代码去实现这些功能.并且对于一些新手,可能写了半天,发 ...

  2. list 去重复

    两层遍历,如果后面的元素和前面的相同,就把后面的删除,达到去重复的目的. 比较的元素可以是list中含有的任意唯一性的元素. for(int x = 0;x < xglist.size()-1; ...

  3. KVC和KVO

    OC中的一个比较有特色的知识点:KVC和KVO 一.KVC操作OC中的KVC操作就和Java中使用反射机制去访问类的private权限的变量,很暴力的,这样做就会破坏类的封装性,本来类中的的priva ...

  4. 安全的PHP代码编写准则

    原文链接 绝不要信任外部数据或输入 关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据.外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据. ...

  5. 安装Eclipse Color Theme

    我们都知道eclipse默认的颜色主题是白色的背景,但是如果想改变代码编辑区的背景颜色,需要怎么办呢? 今天给大家介绍一个非常赞的eclipse,可以很方便的根据自己的需求选择喜欢的颜色主题,其他的不 ...

  6. The method replace(int, Fragment, String) in the type FragmentTransaction is not applicable for the arguments (int, SettingFragment, String)

    The method replace(int, Fragment, String) in the type FragmentTransaction is not applicable for the ...

  7. JQuery easyui (4)Tooltip (提示组件) 组件

    ps:先来一波美图 Tooltip的加载方式: 1,class加载 <a href="#" title="tooltip">hello word&l ...

  8. Android 拨号器的简单实现

    功能实现:一个EditView 一个拨打按钮,输入号码跳转到拨号界面 界面布局:activity_call.xml //线性垂直布局:一个EditView文本.一个Button按钮 1 <Lin ...

  9. jQuery 源码分析和使用心得 - core.js

    core是jQuery的核心内容, 包含了最基础的方法, 比如我们常用的 $(selector, context), 用于遍历操作的 each, map, eq, first 识别变量类型的 isAr ...

  10. 关于RSA加密

    RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密. RSA的算法涉及三个参数,n.e1.e2. 其中,n是两个大质数p.q的积,n的二进制 ...