Java ee 企业应用开发:第6章 购物车_第1页
Java ee 企业应用开发:第6章 购物车_第2页
Java ee 企业应用开发:第6章 购物车_第3页
Java ee 企业应用开发:第6章 购物车_第4页
Java ee 企业应用开发:第6章 购物车_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

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

文档简介

1、第6章 购物车6.1 开发步骤6.2 知识点:Hibernate:数据关联6.3 知识点:Hibernate:数据加载方式第6章 购物车当用户浏览到满意的图书时,可以选择数量,并点击购买按钮,将图书放入服务器的内存中,如图6-1所示。图6-1 浏览商品,添加到购物车第6章 购物车用户可以随时点击购物车,以显示往购物车中存放的书籍。显示购物车的内容,如图6-2所示。图6-2 显示购物车第6章 购物车当用户结帐时,将用户在购物车中购买的商品放入数据库中,并给用户一个帐号,可以去查询。如果用户没有登录,则不能进行结帐功能。图6-3 结帐6.1 开发步骤6.1.1 添加到购物车开发的步骤:步骤1:创建

2、购物车模型步骤2:DAO步骤3:Service步骤4:Action步骤5:Spring步骤6:JSP具体操作如下:步骤1 创建购物车模型购物车模型Cart如图6-4所示。图6-4 购物车模型6.1.1 添加到购物车购物车所在的位置,如图6-5所示。图6-5 购物车模型所在位置6.1.1 添加到购物车Cart.javapackage org.apex.ookstore.model;public class Cart protected Map items; public Cart() if(items= =null) items=new HashMap(); public void addBoo

3、k(Integer bookid,Orderitem orderitem)/是否存在,如果存在,更改数量/如果不存在的话,添加入集合if(items.countainsKey(“bookid”) Orderitem _orderitem=items.get(bookid); _orderitem.setQuantity(_orderitem.getOrderitemid()+orderitem.getQuantity(); items.put(bookid,_orderitem);else items.put(bookid,orderitem);6.1.1 添加到购物车 /更新购物车的数量pu

4、blic void updateCart(Integer bookid, Orderitem orderitem) items.put(bookid,orderitem);/覆盖/计算总价格public int getTotalPrice() int totalPrice=0; for(Iterator it=items.values().iterator();it.hasNext();) Orderitem orderitem=(Orderitem)it.next(); Book book=orderitem.getBook(); int quantity=orderitem.getQuan

5、tity(); totalPrice+=book.getPrice()*quantity; return totalPrice; 6.1.1 添加到购物车步骤2 DAODAO层主要的类为BaseDAO类,IBookDAO接口和BookDAO类。在IBookDAO中定义了getBookById()方法,通过这个方法可以根据id号,得到书的信息。BookDAO具体实现了这个接口。如图6-6所示。图6-6 DAO主要类6.1.1 添加到购物车这些类在项目中的位置如图6-7所示。图6-7 文件在项目中的位置6.1.1 添加到购物车IBookDAO.javapackage org.apex.bookst

6、ore.dao;import java.util.List;import org.bookstore.vo.Book;public interface IBookDAO public List getBookByCatalogid(Integer catalogid);public List getBookByCatalogidPaging(Integer catalogid,int currentPage,int pageSize);public int getTotalByCatalog(Integer catalogid);public Book getBookById(Integer

7、bookid);修改BookDAO.javapublic Book getBookById(Integer bookid)Session session=getSession();Book book=(Book)session.get(Book.class, bookid);session.close();return book;6.1.1 添加到购物车步骤3 Service图6-8 Service层主要类图6.1.1 添加到购物车文件在项目中的位置如图6-9所示。图6-9 文件在项目中的位置6.1.1 添加到购物车IBookService.javapackage org.apex.books

8、tore.service;import java.util.List;import org.apex.bookstore.vo.Book;public interface IBookService public List getBookByCatalogid(Integer catalogid);public List getBookByCatalogidPaging(Integer catalogid,int currentPage,int pageSize);public int getTotalByCatalog(Integer catalogid);public Book getBoo

9、kById(Integer bookid);BookService.javapublic Book getBookById(Integer bookid)return bookDAO.getBookById(bookid);6.1.1 添加到购物车步骤4 ActionShoppingAction通过addToCart()方法,完成将图书放入购物车的业务逻辑。类图如图6-10所示。图6-10 主要类图6.1.1 添加到购物车文件在项目中的位置如图6-11所示。图6-11 文件在项目中的位置6.1.1 添加到购物车创建ShoppingAction.java步骤5 Springapplication

10、Context.xml 步骤6 JSPbrowseBookPaging.jsp用来进行分页浏览。图6-12 文件在项目中的位置6.1.1 添加到购物修改browseBookPaging.jsp img src=/bookstore/picture/ width=100 书名: 价格:元 数量: input type=hidden value= name=”bookid” 创建addToCart_success.jspinput type=hidden value= 6.1.1 添加到购物修改BookAction.java;public String browseBookPaging() thr

11、ows ExceptionSystem.out.println(why?);int totalSize=bookService.getTotalByCatalog(catalogid);Pager pager=new Pager(currentPage,totalSize);/List books=bookService.getBookByCatalogid(catalogid);List books=bookService.getBookByCatalogidPaging(catalogid, currentPage, pager.getPageSize();Map request=(Map

12、)ActionContext.getContext().get(request);request.put(books, books);request.put(pager,pager);/购物车要返回时,需要记住返回的地址Map session=ActionContext.getContext().getSession();request.put(catalogid,catalogid);return SUCCESS;6.1.2 显示购物车开发的步骤:步骤1: Model步骤2:Action步骤3:Spring步骤4:JSP具体操作如下:步骤1 ModelCart模型中的updateCart方法

13、用于更新购物车。如图6-4所示,位置在6-5所示。修改Cart.java步骤2 ActionShoppingAction中的UpdateCart用于完成更新购物车的功能。修改shoppingAction.javapublic String updateCart() throws ExceptionMap session=ActionContext.getContext().getSession();Cart cart=(Cart)session.get(cart);cart.updateCart(bookid, quantity);session.put(cart, cart);return

14、SUCCESS;6.1.2 显示购物车配置struts.xml /showCart.jsp 步骤3 Spring步骤4 JSP修改head.jsp购物车创建showCart.jsp 您购物车上的商品: 书名: 价格: input type=hidden name=bookid value= 消费金额: 对不起,您还没有选购商品! 6.1.3 结帐开发的步骤:步骤1 DAO步骤2 Service步骤3 Action步骤4 Spring步骤5 JSP具体操作如下步骤1 DAO主要涉及的类和接口为IOrderDAO接口和OrderDAO类。IOrderDAO接口中定义了insertOrder方法,用

15、来将插入到order表和orderitem表中。6.1.3 结帐图6-13 DAO类IOrderDAO.javapackage org.apex.bookstore.dao;import org.apex.bookstore.vo.Orders;public interface IOrderDAO public Orders insertOrder(Orders order);6.1.3 结帐OrderDAO.javapackage org.apex.bookstore.dao.impl;import org.apex.bookstore.dao.BaseDAO;import org.apex

16、.bookstore.dao.IOrderDAO;import org.apex.bookstore.vo.Orders;import org.hibernate.Session;import org.hibernate.Transaction;public class OrderDAO extends BaseDAO implements IOrderDAOpublic Orders saveOrder(Orders order) Session session = getSession(); Transaction tx = session.beginTransaction();sessi

17、on.save(order);mit();session.close();return order;6.1.3 结帐步骤2 ServiceService层主要的类和接口为接口IOrderService,这个接口定义了saveOrder方法,用于结帐。OrderService具体实现了这个接口。图6-14 Service层主要类图6.1.3 结帐创建IOrderService.javapackage org.apex.bookstore.service;import org.apex.bookstore.vo.Orders;public interface IOrderService publi

18、c Orders saveOrder(Orders order);6.1.3 结帐创建OrderService.javapackage org.bookstore.service.impl;import org.apex.bookstore.dao.IOrderDAO;import org.apex.bookstore.service.IOrderService;import org.apex.bookstore.vo.Orders;public class OrderService implements IOrderService private IOrderDAO orderDAO;pub

19、lic void setOrderDAO(IOrderDAO orderDAO) this.orderDAO = orderDAO;public Orders saveOrder(Orders order) return orderDAO.saveOrder(order);6.1.3 结帐步骤3:Action使用ShoppingAction类的checkOut()完成结帐功能,类图如图6-10所示。修改ShoppingAction.javapublic String checkout() throws ExceptionMap session=ActionContext.getContext(

20、).getSession();User user=(User)session.get(user);Cart cart=(Cart)session.get(cart); if(user=null | cart=null) return ERROR;Orders order=new Orders();order.setOrderdate(new Date();order.setUser(user);for(Iterator it =cart.getItems().values().iterator();it.hasNext();) Orderitem orderitem=(Orderitem)it

21、.next(); orderitem.setOrders(order); order.getOrderitems().add(orderitem);orderService.saveOrder(order);Map request=(Map)ActionContext.getContext().get(request);request.put(order,order);return SUCCESS;6.1.3 结帐配置struts.xml /jsp/checkout_success.jsp步骤4 SpringapplicationContext.xml 6.1.3 结帐步骤5 JSP修改sho

22、wCart.jsp结帐创建checkout_success.jsp订单添加成功,您的订单已经下达, 您的订单号,我们会在三日内寄送图书给您!退出登录注意点:这时运行程序会出现错误,需要修改 修改Order.hbm.xml6.2 知识点:HIBERNATE:数据关联6.2.1 多对一实体与实体间的关系为多对一的关系,在现实中很常见。例如,在学校宿舍管理中,学生作为使用者User与房间Room的关系就是多对一的关系,多个学生使用一个房间。图6-15 实体多对一关联6.2.1 多对一 如图所示,可以借room_id让使用者与房间产生关联,可以建立如下的user和room表格:CREATE TABLE

23、 user( id INT(11) NOT NULL auto_increment PRIMARY KEY, name VARCHAR(100) NOT NULL default , room_id INT(11);CREATE TABLE room( id INT(11) NOT NULL auto_increment PRIMARY KEY address VARCHAR(100) NOT NULL default );用程序来表示的话,User类如下public class User private Integer id; private Sstring name; private Ro

24、om room; 6.2.1 多对一User类中有一个room属性,将参考Room实例,多个User实例可共同参考一个Room实例,Room类代码如下:public class Room private Integer id; private String address; 映射文件Room.hbm.xml 6.2.1 多对一很简单的一个映射文件,而在user.hbm.xml中,使用来标识映射多对一关系: 6.2.1 多对一在的设定中,cascade表示主控方(User)进行save,update,delete等相关操作时,被控方(Room)是否也要进行相关操作.即,存储或更新User实例时,

25、当中的Room实例是否也一起对数据库发生存储或更新操作,设定为all,表示主控方进行任何操作,被空方也进行对应操作.下面是一个存储的例子:Room room1=new Room();Room room2=new Room();User user1=new User();User user2=new User();User user3=new User();room1.setAddress(“NTU-M8-419”);room2.setAddress(“NTU-G3-302”);user1.setName(“bush”);user1.setRoom(room1);user2.setName(“T

26、om”);user2.setRoom(room2);user3.setName(“Grace”);user3.setRoom(room2);6.2.1 多对一Session session=sessionFactory.openSession();Transaction tx=session.beginTransaction();session.save(user1); /主控方操作,被控方也会对应操作。session.save(user2);session.save(user3);mit();session.close();最后的结果是,room表格插入了两条记录roomid address

27、1 NTU-M8-4192 NTU-G3-302userid name room_id1 bush 12 Tom 13 Grace 26.2.1 多对一在Hibernate映像文件中,cascade属性的设置映像程序的编写,cascade属性预设值是none。以多对一的范例来看,如果设定cascade不为true,则必须分别对User实例与Room实例进行存储,如下:session.save(room1); /存储Room实例session.save(room2);session.save(user1); /存储User实例session.save(user2);session.save(us

28、er3);6.2.2 一对多多对一的关系反过来就是一对多的关系,一对多关系在系统实现中也很常见。典型的例子就是父亲与孩子的关系、房间与使用者的关系。在下面的示例中,每个Room都关联到多个User,即一个房间可以多人居住。图6-16 一对多6.2.2 一对多User.javapublic class User private Integer id; private String name; 而在Room类别中,使用Set来记录多个Userpublic class Room private Integer id; private String address; private Set users

29、; 这种方式即所谓单向一对多关系,也就是Room实例知道User实例的存在,而User实例则没有意识到Room实例。(在多对一中,则是单向多对一关系,即User知道Room的存在,但Room不知道User的存在。)6.2.2 一对多在映射文件上,user.hbm.xml: 在单向关系中,被参考的对象其映射文件就如单一实例一样的配置,接下来看看room.hbm.xml,使用标识配置一对多:Room.hbm.xml 6.2.2 一对多可以如下存储实例:User user1 = new User();User user2=new User();User user3=new User();Room r

30、oom1=new Room();Room room2=new Room();user1.setName(bush); user2.setName(tom); user3.setName(grace); room1.setUsers(new HashSet();room1.setAddress(NTU-M8-419);room1.addUser(user1);room1.addUser(user2); room2.setUsers(new HashSet();room2.setAddress(NTU-G3-302);room2.addUser(user3); Session session =

31、sessionFactory.openSession();Transaction tx = session.beginTransaction();session.save(room1); / cascade 操作session.save(room2); mit();session.close();6.2.2 一对多在数据库中将存储以下的表格id name room_id 1 bush 1 2 tom 1 3| grace 2 rommid address1 NTU-M8-4192 NTU-G3-3026.2.3 双向关联在多对一,一对多中都是单向关联,也就是其中一方关联到另一方,而另一方不知道

32、自己被关联。如果让双方都意识到另一方的存在,就形成了双向关联,在多对一,一对多的例子改写以下,重新设计User类如下:图6-17 双向关联6.2.3 双向关联public class User private Integer id; private String name; private Room room; Room类如下:public class Room private Integer id; private String address; private Set users; 6.2.3 双向关联这样,User实例可参考Room实例而维持多对一关系,而Room实例记得User实例而维

33、持一对多关系。在映射文件User.hbm.xml: 6.2.3 双向关联Room.hbm.xml 6.2.3 双向关联映射文件双方都设定了cascade为save-update,所以可以用多对一的方式来维持关联:User user1 = new User();User user2=new User();Room roo1=new Room();user1.setName(bush); user2.setName(caterpillar); room1.setAddress(NTU-M8-419);user1.setRoom(room1);user2.setRoom(room1); Sessio

34、n session = sessionFactory.openSession();Transaction tx = session.beginTransaction();session.save(user1);session.save(user2);mit();session.close();6.2.3 双向关联或者反过来由一对多的方式来维持关联:User user1 = new User();User user2=new User();Room room1=new Room();user1.setName(bush); user2.setName(caterpillar); room1.se

35、tUsers(new HashSet();room1.setAddress(NTU-M8-419);room1.addUser(user1);room1.addUser(user2); Session session = sessionFactory.openSession();Transaction tx = session.beginTransaction();session.save(room1); mit();session.close();6.2.3 双向关联这里有个效率问题可以讨论,上面程序Hibernate将使用以下的SQL进行存储:Hibernate: insert into

36、room (address) values (?)Hibernate: insert into user (name, room_id) values (?, ?)Hibernate: insert into user (name, room_id) values (?, ?)Hibernate: update user set room_id=? where id=?Hibernate: update user set room_id=? where id=?上面的写法标识关联由Room单方面维护,而主控方也是Room。User不知道Room的room_id是多少,所以必须分别存储Room与

37、User之后,再更新user的room_id。在一对多,多对一形成双向关联的情况下,可以将关联维持的控制交给多的一方。这样会比较有效率。理由不难理解,就像在公司中,老板要记住所有员工的名字慢,每一个员工都记住老板的名字快。6.2.3 双向关联所以在一对多,多对一形成双向关联的情况下,可以在“一”的一方设定控制反转,也就是当存储“一”的一方时,将关联维持的控制权交给“多”的一方。就上面的例子来说,可以设定room.hbm.xml如下: 6.2.3 双向关联由于关联的控制交给“多”的一方,所以直接存储“一”方前,“多”的一方必须意识到“一”的存在,所以程序修改如下:User user1 = new

38、 User();User user2 = new User(); Room room1 = new Room(); user1.setName(bush); user2.setName(tom); room1.setUsers(new HashSet();room1.setAddress(NTU-M8-419);room1.addUser(user1);room1.addUser(user2);/多方必须意识到单方的存在user1.setRoom(room1);user2.setRoom(room1); Session session = sessionFactory.openSession(

39、);Transaction tx = session.beginTransaction();session.save(room1); mit();session.close();上面的程序Hibernate将使用以下的SQL:Hibernate: insert into room (address) values (?)Hibernate: insert into user (name, room_id) values (?, ?)Hibernate: insert into user (name, room_id) values (?, ?)6.2.4 一对一 一对一关联在Hibernate

40、中有两种方式:主键关联和唯一外键关联。1主键关联不需借助外部字段,直接通过两个表的主键进行关联。此时,必须保证两个表的主键值一致。在Hibernate中,通常借助foreign标识符生成器策略来完成。简单地说,这种情况是两个表的主键相等的内连接。基于主键关联的单向一对一关联通常使用一个特定的id生成器foreign。例如,User和Room对象就是一对一的关系。一个人只有一个房间,一房间只有一个人。数据库中创建表的SQL语句如下:CREATE TABLE user( id INT(11) NOT NULL auto_increment PRIMARY KEY, name VARCHAR(100

41、) NOT NULL default );CREATE TABLE room( id INT(11) NOT NULL auto_increment PRIMARY KEY, address VARCHAR(100) NOT NULL default );6.2.4 一对一图6-18 一对一6.2.4 一对一User.hbm.xml Room.hbm.xml user 6.2.4 一对一Room的id主键,使用foreign表示与外键共享主键,即与User实体共享主键。Constrained设定为true,表示约束room的主键必须与user中对应数据的主键相同。一个存储的实例如下:User

42、user1=new User();Room room1=new Room();user1.setName(“bush”);room1.setAddress(“NTU-L8-219”);/相互设定关联user1.setRoom(room1);room1.setUser(user1);Session session=sessionFactory.openSession();Transaction tx=session.beginTransaction();session.save(user1);2唯一外键关联在主动方加入外键进行关联,这样主动方与被动方的影射关系实际上就成为了多对一的关联。基于外键

43、关系的单向一对一关联和单向多对一关联几乎是一样的。唯一的不同是单向一对一关联中的外键具有唯一性约束。6.2.5 多对多作者BookAuthor可以拥有一系列的书Book,而某个Book也可以属于不同的作者BookAuthor(合作写的书)。这个关联是双向的,而且关联的两端都是“多“。称之为多对多关联。对于多对多关联的实现一般有两种可选方案:类似一对多情形中的最常用方案,为关联的双方增加到对方的外键。该方案的好处是取数据时不需要连接操作,只要读一张表就可以,操作比较简单,缺点是会造成数据冗余。另一种方法是新增一张包含关联双方主键的关联表。这时在读取数据时,需要连接该关联表和数据表。优点是没有数据

44、冗余,缺点是带来了一定实现复杂度。注意:由于多对多关联的性能不佳,因此,在设计中应该避免大量使用。6.3 知识点:HIBERNATE:数据加载方式在传统JDBC操作中,通常通过SQL语句加载所需的数据进行处理,当SQL提交之后,这些数据就被读取待用。而在Hibernate世界里,拥有了更多的选择(针对关联数据)。Hibernate支持以下数据加载方式:即时加载(Immediate Loading)当实体加载完成之后,立即加载其关联数据。延迟加载(Lazy Loading)实体加载时,其关联数据并非立刻获取。而是当关联数据第一次被访问时再进行读取。预先加载(Eager Loading)预先加载时

45、,实体及其关联对象同时读取,这与即时加载类似。不过实体及其关联数据是通过一条SQL语句(基于外连接)同时读取。批量加载(Batch Loading)对于即时加载和延迟加载,可以采用批量加载方式进行性能上的优化。下面,分别对几种加载方式进行介绍。即时加载(Immediate Loading)6.3 知识点:HIBERNATE:数据加载方式在一对多映射的示例中,引入了用户(User)及其地址(Address)的关联示例。其中配置中,描述关联关系的部分如下:set name=”address” table=”address” inverse=”true” cascade=”none” sort=”unsorted” lazy=”false”此时运行如下代码String hql=”from User where name=Tom”;List list=session.createQuery(hql).list();System.out.println(“Query finished.”);iterator it=list.iterator();while(it.hasNext()User user=(User)it.next();System.out.println(user.getName();System.out.println(user.getAddres

温馨提示

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

评论

0/150

提交评论