知识大全 如何在JAVA SE中使用Hibernate
Posted 实体
篇首语:家资是何物,积帙列梁梠。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 如何在JAVA SE中使用Hibernate相关的知识,希望对你有一定的参考价值。
如何在JAVA SE中使用Hibernate 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
目前人们很容易发现Hibernate正迅速的成为流行的J EE的O/R映射工具和数据集成框架(如果不是最流行的) Hibernate为企业应用开发者操作关系数据库的提供了清晰明了而又强大的工具 然而如果你需要在外部访问那些包装在J EE web应用里的实体 情况又怎样呢?你的开发跟应用独立分开 却又相同的实体以访问你的数据吗?又或者你得编写附加的web组件来管理对数据的内部访问吗?
在很多情况下 这些问题都会出现 我的情况是我的公司需要将来自多个供应商 有着多种文件格式的记录导入到数据库里 我想起我以前经常使用的方法 那就是编写Shell和SQL教本(甚至是存储过程)来导入数据 但是由于我们的数据模型太过复杂 我决定在web应用之外尽可能的利用现有的实体 Spring DAO以及服务并且开发一个自定义的J SE命令行数据加载工具
大问题 你该怎样呢?
现在很多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所需要的最小属性集(不包括任何实体映射)
清单
hibernate dialect=net sf hibernate dialect PostgreSQLDialectnnection driver_class= postgresql Drivernnection url=jdbc:postgresql://devserver/devdbnnection username=dbusernnection password=dbpasswordhibernate query substitutions yes Y 正如你所看到的 上面的属性值指定了数据库方言 JDBC驱动 数据库url 用户名 用户密码 以及是否使用查找替换 只要定义以上几项数值并保存在文件hibernate properties里(要放置在你的类路径里面哦) 就能很轻松的加载 填充到Hibernate Configuation类里面
清单
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( );String driver = props getProperty( nnection driver_class );String connUrl = props getProperty( nnection url );String username = props getProperty( nnection username );String password = props getProperty( nnection password ); // In my examples I use Postgres but Hibernate // supports virtually every popular dbms out there Class forName( 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文件中加载 如下所示
清单
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包包含了映射文件 以下就是一种查找映射关系的方法
清单
String cp = System getProperty( java class path );String jarFile = null;List hbmList = null;String[] cparr = cp split( \\\\: );for(int j= ;j<cparr length;j++) // The following assumes our entities // are wrapped up in a jar file // called dbobjs jar if(cparr[j] indexOf( dbobjs jar ) != ) 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 es back as JarFile$JarFileEntry JarEntry entry = (JarEntry)e nextElement(); if(entry getName() indexOf( hbm xml ) != ) 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 对象 如下所示
清单
Configuration cfg = new Configuration(); Iterator iterator = erator();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的支持
清单
import 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 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 server:// java:/p/env/obj/hibernateSession private Session session; public PersonDAO() try Context initCtx = new InitialContext(); Context envCtx = (Context) initCtx lookup( java:p/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 server:// java:/p/env/obj/hibernateSession private Session session; public PersonDAO() try Context initCtx = new InitialContext(); Context envCtx = (Context) initCtx lookup( java:p/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 接下来就不断尝试把
结论
cha138/Article/program/Java/ky/201311/28684相关参考
JavaSE6新特性:JavaDB&n 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 年底Sun
Java进阶:在SE6中调用编译器的两种方法[4] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
Java进阶:在SE6中调用编译器的两种方法[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
Java进阶:在SE6中调用编译器的两种方法[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
Java进阶:在SE6中调用编译器的两种方法[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
知识大全 Java SE 6 新特性: Instrumentatio
JavaSE6新特性:Instrumentatio 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
JavaSE引路蜂地图开发示例 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 引路蜂地图也提供对
JavaSE6调用Java编译器的两种新方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&nbs
JavaSE6新特性:HTTP增强 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 摘要 Jav
给JavaSE注入脚本语言的活力 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 年月日