0 Comments

开发购物车应用程序

发布于:2013-07-04  |   作者:广州网站建设  |   已聚集:人围观

【51CTO.com独家特稿】一、简介

在本篇(最后一篇)中,我们有两个目的:首先,我们想实现一个Hibernate数据库更新(实际上是一个“插入”操作),它涉及到两个数据库表格(Driver和Car)之间的“一对多”的关系。注意,我们是在一个适当配置的Hibernate事务中实现这种更新的;而且其中,我们将展示事务的提交和回滚这两种情形。其次,我们将通过一个购物车的例子来探讨一下实际开发中的应用程序设计问题。
广州网站建设,网站建设,广州网页设计,广州网站设计

二、执行数据库插入操作的Servlet示例

在前面的文章中,我们分析了Context.xml文件,web.xml,HibernateUtil.java,hibernate.cfg.xml,以及映射文件Driver.hbm.xml和Car.hbm.xml及其相应的Java类文件—Driver.java和Car.java。在本篇中,所有这些文件将继续使用而不作任何改变。

现在,让我们把注意力立即转向servlet本身—InsertViaHibernate.java。其代码如下:

 


				

package tomcatJndi; import java.io.IOException; import java.io.PrintWriter; import org.apache.log4j.Logger; import org.hibernate.SessionFactory; import org.hibernate.Session; import org.hibernate.Query; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.hibernate.Session; public class InsertViaHibernate extends HttpServlet { public InsertViaHibernate() { super(); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println(""); out.println(""); out.println("  "); out.println("  "); Session session = null; try  { session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); Car bigSUV = new Car(); bigSUV.setManufacturer("Ford"); bigSUV.setModel("Expedition"); bigSUV.setYear(2005); Driver jill = getDriverByName("Jill", session); addCarToDriver(jill, bigSUV, session); session.getTransaction().commit();    //自动地关闭会话 } catch (Exception e)  { session.getTransaction().rollback(); throw new ServletException(); } out.println("  "); out.println(""); out.flush(); out.close(); } public Driver getDriverByName (String name, Session session)  { Query q = session.createQuery("from Driver d where d.name = :name"); q.setString("name," name); Driver newOwner = (Driver) q.list().get(0); return newOwner; } public void addCarToDriver(Driver theOwner, Car theCar, Session session)  {  theOwner.getCarsOwned().add(theCar);  session.save(theCar); session.save(theOwner); } }

 

在这个程序中首先要注意的是,就象在第二篇中一样,我们首先通过对SessionFactory.openSession方法的调用(借助于HibernateUtil)来引用Hibernate会话;然后,我们通过Session.beginTransaction()启动一个Hibernate事务。对addCarToDriver()方法的调用产生了两个对象实例—Car和Driver—都被保存在Hibernate会话中。注意目前为止,还没有发生任何实际的数据库更新。当我们回到doGet()方法时,它调用session.getTransaction().commit(),从而最终使两个MySQL表格都被更新。

在上一篇中,我们提到了跟随在Hibernate查询后面的面向对象方法。在当前的更新操作中,你再次看到了它—仅引用了Java类,而没有涉及到MySQL表格。而且,在这些Java代码中根本没有对数据库列car.fk_driver_id(表格car中的外键,在使用原始JDBC时,它允许这个表格和driver表格关联到一起)的引用。

请注意上面catch语句中的rollback语句;这种情况是需要认真测试的。其中一种测试方法是把下列语句:
广州网站建设,网站建设,广州网页设计,广州网站设计

 


				

Driver jill = getDriverByName("Jill");

 

改变为:

 


				

Driver nosuch = getDriverByName("Melvin");

 

现在,让我们来分析一下这个getDriverByName()方法。在此,它假定q.list()方法返回一个至少有一个成员的java.util.List。然而,根本不存在名为“Melvin”的成员。结果是,q.list().get(0)将抛出一个IndexOutOfBoundsException异常—返回到doGet()方法中的catch语句。然后, doGet()方法调用getTransaction.rollback()。

三、Multi-Http-Request业务事务

到目前为止的本系列的所有示例中,方法调用:

 


				

session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction();

 

 


				

session.getTransaction().commit();//自动地关闭会话

 

都发生于同一个Http请求中。根本没有出现一系列的屏幕把beginTransaction和commit分离开来,并且不存在任何用户“介入”—因为session.beginTransaction打开一个实际的数据库事务,而session.getTransaction.commit实际上执行相应的数据库提交操作。上面这些步骤永远不应该被任何用户“介入”所分离。可以想象,作为用户,他一定希望在这一系列屏幕(对应于单个业务事务)间插入几个用于“观察”的屏幕;但是,使数据库锁打开这么长的一段时间必须会阻碍与其它活动用户相关的许多并发事务的操作—带来一定的“瓶颈”问题。

在Hibernate参考文档及其它已出版的Hibernate参考资料中都把这种multi-Http-request业务事务称作一种“长时间运行的事务”或称作一种“对话性事务”(也被称作一个“业务事务”。注意,这三个短语含义是一样的,而且其中任何一个都与数据库事务或Hibernate事务有关)。Hibernate为处理长时间运行的事务提供了现成的工具。例如,你可以在用户“介入”之前把对象从Hibernate会话分离开来,然后当用户提交下一屏幕时重新依附它们,之后你就可以再次使用它们。一直以来我们被推荐:在使用Hibernate时,应该使打开Hibernate会话的时间尽可能缩短—尽可能有限。总之,我们应该想尽一切办法,通过单个方法来实现“打开Hibernate会话→启动事务→保存需要保存的任何对象实例→然后提交事务”—就象你已经在本系列的示例中所看到的一样。应该尽可能避免再使用任何其它方法。不要试图使用一个Hibernate会话—它会在跨越多个Http请求时一直保持打开状态。

但是,你完全有理由问:对于multi-Http-request业务事务的情况如何呢?—例如,一种购物车情形?下面让我们来作详细讨论。

飞机