Hibernateinaction学习笔记.doc_第1页
Hibernateinaction学习笔记.doc_第2页
Hibernateinaction学习笔记.doc_第3页
Hibernateinaction学习笔记.doc_第4页
Hibernateinaction学习笔记.doc_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Hibernate in action学习笔记第一章 理解O/R持久化一,常见的设计难点:用一个User和BillingDetails的例子来解释;User有多个Bill,User里面有User的相关信息,包括name, address等等,BillingDetails中用User的主键作为外键。1, 粒度问题比如User的Adrress字段包括了city, street, zipcode等等信息,在Java中可以用一个Address类来持有这些信息,然而在数据库中情况就不一样了;最直接的是现在的数据库大多都支持的UDT(user-defined column types),可以将Address作为一个整体存入到数据库中,但是这样的类型在不同数据库中很难移植,所以在实践中很少用这样的方法;通常的做法是在数据库中将Address的条目都作为单独的column,比如ADDRESS_CITY。相比较而言,数据库只能表现出两层的粒度关系,显然不如Java的类型更加灵活。(书3.5)2, 子类型问题 (书3.6)Java中我们经常会用到继承,我们扩展一下上面的例子,我们为BillingDetails类扩展出一些子类:CreditCard, DirectDebit, Cheque等等。我们需要建立几个不同的table来存储这些子类,然而数据库却并不支持它们之间的继承关系;一个标准的外键依赖严格地对应一个table,我们无法直接用一个外键对应多个表。3, 标识问题(书3.4 5.0)显然对于我们的User表,使用Username作为主键是一种很坏的设计,尤其当我们可能会改变username的时候,一般,我们会增加一个字段UserID来作为主键和外键使用。如何将这个字段对应到java中也是一个问题。Java中通常会用=和equals()来判断两个对象是否相同,很多时候,会有多个不恒等的对象对应于数据库中同一条数据,如何正确的equals()就是一个问题。4, 如何关联的问题(书3.0 6.0)接下来我们关注一下映射和处理classes之间的关系到数据库中,所有的外键都是必需的么?在我们的例子中,Address, User, BillingDetails三个Class是关联的,然而在数据库中,不同的是BillingDetails独自一个表,而Address则不是。关联的映射和实体关联的管理在任何对象持久化的方案中都是中心的概念。面向对象的语言使用对象引用和Collection来表现关联(association)。而在关系数据库中,关联是用foreign key来表示的。对象的引用本身具有方向性,如果两个object有双向的关联,你就必须在两个object中都定义这种联系,比如在User中:private Set billingDetails; 而在BillingDetails中:private User user;Java中可能会有many-to-many的关联,而数据表之间只可能有one-to-many和one-to-one的关联;如果你想在数据库中表现一个many-to-many的关联,则你需要引进一个新的联接表,这张表在对象模型中没有相应的表现,比如一个USER_BILLINGDETAILS表。5, object graph navigation的问题(书4.0 7.0)在Java中,如果你要访问某个User的billing的信息,你会这样子做:someUser.getBillingDetails().getAccountNumber();这在面向对象中很自然,通常被叫做“walking the object graph”。然而在SQL数据库中,这样子就不是一种有效的方法;提高数据访问效率的最简单重要的一点就是尽可能减少对数据库的request次数,也就是减少SQL查询的次数,(也可以使用存储过程和JDBC batch API)。通常有效的对关联数据的查询是通过使用不同表之间的join来进行的,多少个表进行join取决于你访问对象的深度,比如:select * from USER u left outer join BILLING_DETAILS bd on .总结:解决上面的问题需要花费相当的时间和精力,根据经验,在一个Java应用中30%以上的代码是用来解决这些单调乏味的SQL/JDBC相关工作。二,持久层和其他在中大型的项目中,通常会按照职能组织classes,持久层就是其中之一。其他的关注层有表示,工作流,业务逻辑。还有所谓的“横切”关注,横切关注多半会被框架代码所实现。典型的横切关注有logging, authorization, transaction等等。通常最好的做法是把所有与持久化相关的类和组件组织在一起,在多层系统构架中成为一个独立的持久层。我们接下来会先看看这种多层的构架以及为什么使用它,然后我们关注一下我们最关心的持久层以及一些实现持久层的方法。1, 多层架构(Layered architecture)多层架构通过在不同层次的实现之间定义接口,从而使一个层上的实现的改变不会明显地影响其它层。通常它们有如下规则:l 所有层从上到下通信,一个层紧紧依赖于它下面的那个层;l 每一层都不会察觉到除了它下面那层之外的所有层的存在;一般典型的应用都是用三层结构:presentition, business logic, persistence。l Presentation layerl Business layerl Persistence layerl Databasel Helper/Utility classes2, 使用SQL/JDBC处理持久层这是Java中最常用的处理持久层的方法,开发者要熟悉rdbms,了解SQL知道如何同表和外键打交道。除此,他们能使用广泛使用的DAO模式在business logic中隐藏复杂笨重的JDBC/SQL代码。DAO模式非常好的一个模式,我们强烈建议你在ORM中也使用它(第8章)。然而对每个domain class手动编码持久化是相当可观的,尤其是当需要不同的SQL方言支持。比如有一个UserDAO的接口,和UserDAOOracleImpl和UserDAOSybaseImpl。为什么不用ORM的工具呢,不要自己去写ORM工具,也不用掏钱去买ORM工具,因为已经有了一个强大的,免费的开源产品-Hibernate(汗。)“不要再发明轮子”去开发你自己的ORM,就算你不想使用ORM,你还是想和SQL database直接打交道,也有好的框架帮助你,iBATIS就是一个开源的项目,可以帮助你简化JDBC。3, 使用序列化Java有一种内建的持久机制:序列化,它可以将graph of objects变为字节流,然后可以把这个字节流持久化到一个文件或数据库中。序列化也被用在java的RMI方面,通过它来传递复杂的对象。序列化的另外一个用途是在集群的节点间复制应用程序的状态(state)。为什么不使用序列化来做持久层呢?不幸的是一个持久化的对象图只能作为一个整体来访问,这样你就不能只访问或更新其中的一个object或它的子图。4, 考虑使用EJB entity beanEntity beans比较特殊的是,与其它方案不同,它是由委员会完全制作出来的。而其他的方案(DAO, serialization and ORM)则是多年开发经验的精华。先天的设计缺陷使BMP效率奇差,而CMP虽有所改观,仍然无法作为一种O/R的方案。l CMP beans和表中关系模型被定义为one-to-one的类型;l 另一方面,CMP过于细粒度而导致难于重用;一个可重用的组件应该是一个粗粒度的对象,有一个稳定的外部接口(至少schema稍变化时不变);l 尽管EJB有着继承实现的优点,但是entity bean却不支持多态的关联和查询,而这正是“真”ORM的特征;l Entity bean尽管EJB规范规定的目标很好,但它本身却不够轻便;CMP的mapping metadata很严重地依赖于具体的容器;很多应用程序选择Hibernate就是因为它足够轻便,可以在不同的app server中移植;l Entity bean不是可序列化的;所以我们必须自己定义额外的DTO当我们想把数据传输到远程的客户端时;l EJB是一个intrusive模型;它要求一种不自然的java风格而且使得在容器外面重用变得异常困难;这在TDD中是一个巨大的障碍(又见TDD);5, Object-oriented database systems一个OODBMS更像是应用程序环境的扩展而不仅仅是一个额外的数据存储。OODBMS通常是作为一种多联接的实现,把后端的数据存储,对象cache,客户程序,紧密地连接起来而且通过自己的网络协议互相作用。OODBMS通过自上而下的与自身语言的绑定,可以让编程语言具有持久化的能力,因此OODBMS可以同OO应用环境进行无缝联接,而不象现在需要通过中间语言SQL。与ANSI SQL类似,对象数据库也有标准的查询接口,ODMG定义了一个API,一个查询语言,一个元语言,一个用来绑定C+,Java的宿主语言。大多数的对象数据库都不同程度地支持ODMG的标准,但还没有完全支持的产品。虽然ODMG规范已经到3.0,但仍然不成熟而且缺少吸引人的特点。ODMG也不再活跃了,最近JDO规范开始了新的可能,JDO由OODB community的成员带领,而且已经被一些OODB的产品作为主要API所采用,不仅仅是被ODMG支持。总而言之,OODB并没有流行起来,甚至在不远的将来也不会。所以大多数的开发者依旧需要在关系数据库上工作。6, 其他的选择XML持久化时在序列化的基础上的变种(不解);XML不过是一种特殊格式的text file。三,ORM1, 什么是ORM?简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。l 这也同时暗示者额外的执行开销;然而,如果ORM作为一种中间件实现,则会有很多机会做优化,而这些在手写的持久层并不存在。l 更重要的是用于控制转换的元数据需要提供和管理;但是同样,这些花费要比维护手写的方案要少;而且就算是遵守ODMG规范的对象数据库依然需要类级别的元数据。一般的ORM包括以下四部分:l 一个对持久类对象进行CRUD操作的API;l 一个语言或API用来规定与类和类属性相关的查询;l 一个规定mapping metadata的工具;l 一种技术可以让ORM的实现同事务对象一起进行dirty checking, lazy association fetching以及其他的优化操作。一般的ORM要解决的问题:1, 持久类应该是什么样的粒度?是细粒度的JavaBeans,还是像EJB那样是某些组件类型;2, metadata如何定义?3, 如何组织类的继承层次,如何处理多态联合,抽象类,接口等等;4, 对象的区别和等同如何与数据库的主键联系起来;如何将一个类实例对应于一条纪录;5, 持久化逻辑和业务域对象如何在运行时互相作用,解决的方案有:source generation; runtime reflection ; runtime bytecode generation(Hibernate用cglib); buildtime bytecode enhancement(JDO是这样的?).6, 持久对象的生命周期;7, 应该为排序,查询,联合提供什么样的功能;8, 如何有效的取得关联的数据;除了上面的还有2条重要的数据访问方面的技术问题:l 事务和并发;l cache管理和(并发);在3,4,5章将分别介绍hibernate如何解决这些问题。第二章 介绍,整合Hibernate一,Hello World示例的目标是存储信息到database并取出来用作显示;有一个简单的持久类:Messagepublic class Message private Long id;private String text;private Message nextMessage;private Message() public Message(String text) this.text = text;/getter/setter method这里Message有三个属性,id, text, nextMessage;我们使用了Long类型作为标识符,事实上,Hibernate允许你用任何类型作为标识符类型;Message的三个属性有JavaBean式的访问方法,同样也有一个没有参数的构造方法(私有的);Message的实例可以被Hibernate管理(比如持久化它),也可以用在其他地方;因为Message并没有继承任何Hibernate的类或接口,你可以像一个普通的Java class一样地使用它:Message message = new Message(“Hello World”);System.out.println(message.getText();这也正是Hibernate同其他持久化方案(EJB等)相比的重要特点;当我们要存储一个新的Message到database的时候:Session session = getSessionFactory().openSession();Transaction tx = session.beginTransaction();Message message = new Message(“Hello World”);session.save(message);mit();session.close();至于id这个属性我们并没有给它set值,当然数据库中它是主键不能为null,我们会在xml中指定它的生成方式,所以在save()方法被调用的时候,它的值会由Hibernate框架生成并赋值。接着,我们演示如何从数据库中取出我们刚才存进去的值:Session newSession = getSessionFactory().openSession();Transaction newTransaction = newSession.beginTransaction();List messages = newSession.find(“from Message as m order by m.text asc”);/显示结果newTmit();newSession.close();上面find()中的字符串就是Hibernate的查询,用Hibernate自己的查询语言(HQL);如果没有用过ORM工具,你也许会想知道SQL语句应该在代码或其他什么地方,然而并没有,所有的SQL都是在运行期生成的(对于所有可重用的SQL是在启动时生成的)。为了做到上面,Hibernate需要更多关于Message类如何持久化的信息。这些信息通常以xml的格式提供,mapping文档定义了Message类的属性如何对应MESSAGE表的列。如何用内嵌注释的代码生成xml将在第三章介绍,xml生成db schema也在后面介绍。二,理解Hibernate框架API设计的一个主要目的就是让组件之间的interface尽可能的小;然而在实际中,ORM的APIs并不是很小,但是不用担心,你不必马上理解Hibernate所有的接口。上图中表示的Hibernate接口可以大概分为以下几种:l 应用程序调用的用来执行基本CRUD和查询的接口;应用的业务/控制逻辑对Hibernate依赖的主要部分就是这些接口,包括Session,Transaction,Query。l 应用程序基础代码调用的用来配置Hibernate的接口,最重要的就是Configuration类;比如我们有一个HibernateUtil类用来配置Hibernate。l Callback接口让应用程序可以对发生在Hibernate内部的事件作出反应,比如Interceptor, Lifecycle和Validatable接口。l 允许应用程序扩展Hibernate强大的映射功能的接口,比如UserType, CompositeUserType和IdentifierGenerator,你就可以以你的方式生成主键。也就是配置,使用,响应,扩展HibernateHibernate使用了很多已有的Java API,比如JDBC, JTA, JNDI;JDBC提供了对关系数据库共同功能的底层抽象,从而使几乎所有带JDBC驱动的数据库都被Hibernate支持。JNDI和JTA使得Hibernate可以和J2EE app server整合在一起。我们接着大致看看每一个借口:1, the core interfacesl Session interface:Session接口是应用程序最常用的,一个Session的实例是轻型的,创建和销毁都是廉价的;这点很重要,你的应用程序需要经常创建销毁session,很可能每次请求都做。Hibernate session不是线程安全的,你必须设计成同一时间一个线程在使用。Hibernate的session是一个介于connection和transaction之间的一个概念,我们有时会把session叫做persistence manager,因为它是执行持久化相关操作(存储,取出)的接口。在第四章4.2我们会详细讨论。l SessionFactory interface:应用程序通过SessionFactory取得Session实例;SessionFactory肯定不是轻型的,它是打算被很多应用线程共享的,典型的就是整个应用程序使用一个SessionFactory(在应用程序初始化是创建);然而如果你的应用程序要通过Hibernate访问不同的数据库,那么你就需要为每个数据库创建一个;SessionFactory缓存生成的SQL statements和Hibernate需要在运行时使用的mapping信息;l Configuration interface:Configuration是用来配置和启动Hibernate的,应用程序使用Configuration实例去指定mapping文件以及Hibernate的配置属性,然后创建SessionFactory;l Transaction interface:Transaction接口是一个可选的API,应用程序可以不使用它而选择在底层代码中自己控制transaction;一个Transaction抽象了底层的事务实现,可能是JDBC transaction,可能是JTA UserTransaction也可能是CORBA transaction;这使得Hibernate应用在不同的运行环境中保持轻便;第5章会详细介绍;l Query and Criteria interface:Query接口让你可以在数据库上作查询,而且控制查询如何执行;查询可以用HQL或者SQL写成;一个Query的实例用来绑定查询参数,限制查询返回的记录条数,最后执行查询;Criteria接口非常类似,它让你可以创建和执行面向对象的标准查询;为了不让你的代码冗长,Hibernate提供了在Session接口上的简单的方法让你可以在一行代码中执行查询;一个Query实例是轻型的,而且可以在Session的外部创建它(使用当然还是在里面);第7章详细讨论它;2, Callback interfaces回调接口让应用程序可以在某些事件发生的时候接收到通知(比如一个对象load, save, delete);你的应用程序不必实现这些回调接口,但是他们在实现某些功能是很有用处;l Lifecycle和Validatable接口允许一个持久对象对它自己的持久化周期中的事件作出响应;一个持久化周期是围绕着一个对象的CURD操作的;实现这些接口会污染你的代码,所以本书不讨论它们的用法;l Interceptor接口是为了让应用程序不implement Hibernate的接口同样处理回调而引入的;Interceptor的实现实例是作为参数传递给持久化对象的;我们将在第8章讨论;3, TypesType在Hibernate中是一个很基础很强大的概念,一个Type对象是一个Java类型到数据库一个字段的映射(事实上,一个类型可以对应多个数据库字段)。所有持久类的持久属性(包括关联)都有一个对应的Hibernate Type。Hibernate有很多的内建Type,覆盖了所有的Java primitive类型和很多的JDK类包括Currency, Calendar, byte, Serializable等等;更进一步,Hibernate支持用户子定义的types,UserType和CompositeUserType接口就是让你增加你自己的Type;你可以使用这项功能是普通的类比如Address, Name能够很方便优雅地被处理;6.1章将详细介绍。4, Extension interfacesHibernate很多的功能都是可配置的,这也就允许你在Hibernate内建的做法不够好的时候,你可以把你自己的实现插入到Hibernate中。当然你要实现一些接口:l 主键的生成(IdentifierGenerator接口);l SQL方言支持(Dialect抽象类);l 缓存策略(Cache和CacheProvider接口);l JDBC连接管理(ConnectionProvider接口);l 事务管理(TransactionFactory, Transaction和TransactionManagerLookup接口)l ORM策略(ClassPersister接口层次);l 属性访问策略(PropertyAccessor接口);l Proxy创建(ProxyFactory接口);Hibernate为以上的接口提供了至少一种的实现方式,你通常情况下并不需要重新实现它们,当你要实现的时候,Hibernate的实现可以作为你的参考。三,基本配置Hibernate可以在几乎所有的Java应用程序和开发环境中配置,运行;通常Hibernate在两层三层应用中使用,客户端一般是浏览器,Swing和SWT客户端也是常见的;要理解在被管理和不被管理的环境中配置Hibernate的区别就很重要了:(Managed的环境很多事情都会帮你做,你不用操心;而Non-managerd的环境中事情基本上都要靠你自己去做,管理;)l 被管理的环境(Managed environment):共有资源,诸如数据库连接和在声明文件中指定的事务边界和安全;像Jboss,Weblogic, WebSphere这样的J2EE服务器都是被管理环境。l 不被管理的环境(Non-managed environment):通过线程池提供基础的并发控制;像Jetty, Tomcat这样的Servlet Container为Java Web应用提供了一个不被管理的服务器环境;一个独立的桌面或cmd应用程序也被认为是不被管理的;不被管理的环境不会提供自动事务管理,资源管理,顶层的安全结构;应用程序自己管理数据库连接和划分事务边界。Hibernate尽量抽象它所处的外部环境,在两种环境中都可以配置使用。不管在哪一种环境中你首先要做的就是启动Hibernate,实际上,这点很容易做,你只要从一个Configuration创建一个SessionFactory。1, 创建一个SessionFactory为了创建一个SessionFactory,你首先要在应用程序初始化的时候创建一个单一的Configuration实例,用它来指定mapping文件的位置;然后你就可以用它创建SessionFactory,一旦SessionFactory创建后,你就可以抛弃Configuration类了;Configuration cfg = new Configuration();cfg.addResource(“hello/Message.hbm.xml”);cfg.setProperties(System.getProperties();SessionFactory sessions = cfg.buildSessionFactory();Mapping文件Message.hbm.xml的位置是相对于应用程序的classpath的根部;Tip:方法链(Method Chaining)是很多Hibernate接口支持的一种编程样式,它在Smalltalk中比在Java中更流行一些,一些人认为这样的代码难于读懂和debug,但是它还是很方便的;很多Java开发者在没有返回值的时候声明方法为void,而Smalltalk中没有void,这时返回的就是接收类的类型,比如:SessionFactory sessions = new Configuration().addResource(“hello/Message.hbm.xml”).setProperties(System.getProperties().buildSessionFactory();这样你就不必声明一个你以后不会用的变量:Configuration cfg,如果你使用这种代码样式,最好将每次方法调用写在不同的行里,方便你debug找到具体位置。习惯上,Hibernate的mapping文件以class名+.hbm.xml组成,并且习惯上每一个持久类对应一个mapping文件;Hibernate文档强烈建议把mapping文件和相应的持久类放在同一个目录中;这样你就要经常在必要的时候调用addResource()方法load mapping文件,如果你遵守刚才的约定,你还可以使用方法addClass()来load mapping文件,把持久类作为参数:SessionFactory sessions = new Configuration().addClass(org.hibernate.auction.model.Item.class).addClass(org.hibernate.auction.model.Category.class).setProperties(System.getProperties().buildSessionFactory();addClass()方法会假设你的mapping文件的名字,以及和class文件在同一位置。当然,配置Hibernate不仅仅是指定mapping文件,你还要指定如何得到数据库连接和其他一些影响Hibernate运行期行为的参数;指定配置参数有以下的方式:l 传递一个java.util.Properties对象给Configuration.setProperties()作为参数;l 设置系统属性 java Dproperty=value;l 在classpath上放一个名为perties的属性文件;l 在classpath上放一个名为hibernate.cfg.xml包含元素的xml文件;一二很少使用,三四的选择就依据用户的喜好了。有一个很少使用的方法可以允许应用程序在创建Session的时候提供一个JDBC连接,比如:Session session = sessions.openSession(myConnection);这种用法就不需要你在属性中指定数据库连接,但是如果一个应用可以通过配置来使用环境中的数据库连接,那我们不推荐使用这种方法。在所有的配置信息中,数据库连接设定势最重要的,而它在被管理的和不被管理的环境中是不同的,所以我们分开来讨论:2, 在不被管理的环境中配置(Configuration in non-managed environments)在不被管理的环境中,比如一个servlet container中,应用程序负责得到JDBC连接,Hibernate作为应用的一部分,也就负责得到这些连接。所以你要告诉Hibernate如何得到JDBC连接。通常,为每一次数据库操作新建一个连接是很不明智的,取而代之,应用程序应该使用一个JDBC连接池,使用池的原因:l 得到新的连接是很昂贵的;l 维护很多idle的连接也是昂贵的;l 创建prepared statements对于一些驱动也是很昂贵的;既然non-managed环境没有实现连接池,那么应用程序必须实现自己的池策略或使用第三方的库(比如c3p0);没有Hibernate的时候,应用程序代码自己调用连接池得到JDBC连接,并执行SQL语句;有了Hibernate,应用程序使用Hibernate Session和Query接口进行持久化操作,而Hibernate和JDBC连接池进行交互。Hibernate支持的连接池包括C3P0和Apache的DBCP和Proxool,你可以在使用的时候比较性能,然后决定。Hibernate比较倾向于C3P0和Proxool;Hibernate同样也提供了默认实现的连接池,除了测试尽量不要使用它,毕竟它不够专业。开始Hibernate如果你在perties中声明了属性,你所要做的就是把这个文件放到应用程序的classpath上,当Hibernate第一次初始化的时候(也就是你创建Configuration对象的时候)它会自动检测到和读取文件;我们总结一下我们已知道的事情:1, 下载数据库驱动jar和hibernate2.jar并把它们放到classpath上;2, 把Hibernate依赖的包加入classpath,它们在下载的hibernate/lib目录中;3, 选择一个Hibernate支持的JDBC连接池,并且在properties文件中配置它,当然不要忘记指定JDBC连接及方言属性;4, 把perties文件放到classpath上,让Configuration知道它的存在;5, 在你的应用程序中创建一个Configuration实例,并且通过addResource()或addClass()方法load XML格式的mapping文件;从Configuration创建一个SessionFactory;3,在被管理环境中配置(Configuration in managed environments)被管理的环境通常会处理某些横切面,比如应用安全(认证授权),连接池和事务管理。J2EE app Server是典型的被管理环境。虽然app server通常被设计来支持EJB,而你又不打算使用EJB entity bean,但是你仍然可以利用它提供的管理服务。Hibernate通常和session bean, message-driven bean一起使用,EJB像servlet,jsp,或独立的程序一样调用Hibernate的API;Hibernate相关的代码在被管理和不被管理的环境之间非常的轻便。一个app server将一个连接池包装成一个绑定JNDI的datasource暴露给外部,一个javax.jdbc.Datasource实例。你必须用JNDI告诉Hibernate去哪里寻找这个datasource,提供一个完全的JNDI名,比如:hibernate.connection.datasource = java:/comp/env/jdbc/AuctionDBhibernate.transaction.factory_class = net.sf.hibernate.transaction.JTATransactionFactoryhibernate.transaction.manager_lookup_class = net.sf.hibernate.transaction.JbossTransactionManagerLookuphibernate.dialect = net.sf.hibernate.dialect.PostgreSQLDialect这个配置文件首先给出datasource的JNDI名(datasource必须在应用程序声明文件中配置,这个与不同的服务器相关),然后集成Hibernate和JTA,接着Hibernate需要知道如何定位应用服务器的TransactionManager来集成容器的事务管理(这里Hibernate提供了大多数流行server的支持JbossTransactionManagerLookup),最后就是SQL方言的指定。JTA是Java标准的事务API,它用来在J2EE被管理的环境中控制事务。这叫做CMT(container-managed transaction),如果有一个JTA事务manager存在,JDBC连接就会被这个manager全权管理,而在不被管理的环境中,应用程序直接管理JDBC的连接和事务。因此,两种环境下事务的方法是不同的,幸运的是Hibernate抽象出了Transaction接口,可以让代码轻便地在两种环境中移植,而这种底层的策略只要在属性hibernate.connection. factory_class里面设置两个可选的值:net.sf.hibernate.transaction.JDBCTransactionFacotry;net.sf.hibernate.transaction.JTATransactionFactory;详细的讨论在5。1章;Tomcat虽然提供了datasource,你可以使用它,但是它并没有transaction manager,所以它还是一个non-managed environments四,高级配置设定hibernate.show_sql:true会在控制台上打印出所有生成的SQL语句,在debug时很有用1, 使用XML格式的配置使用xml格式的配置文件可以完全配置SessionFactory,而且比perties文件更好的是,hibernate.cfg.xml文件可以指定mapping文件的位置; net.sf.hibernate.dialect.Oracle9Dialect oracle.jdbc.driver.OracleDriver rst rst jdbc:oracle:oci8:pas_new l document type声明了dtd;l session-factory的可选属性name,同属性文件的hibernate.session_factory_name是等价的,下一节讨论;l 这里属性不用指定hibernate前缀;l mapping文件可以使用文件名指定,不需要再同class文件放在一起;hibernate.cfg.xml放在classpath中就可以被找到,当然你也可以指定它的位置改变它的名字,然后使用configure()方法来指定:SessionFactory sessions = new Configuration().configure(“/hibernate-config/auction.cfg.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论