用户模块
三:一级分类的查询
  1. 创建一级分类表并导入基本数据
CREATE TABLE `category` (
  `cid` int(11) NOT NULL AUTO_INCREMENT,
  `cname` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
  1. 建包及相应的类:
    • com.weiwei.shopping.category
      • action :CategoryAction
      • service :CategoryService:业务层对象
      • dao :CategoryDao:持久层对象
      • vo :Category:实体对象 ;Category.hbm.xml:映射文件
 
  1. 对Service和DAO进行配置:
    • 在DAO中注入sessionFactory
    • 在Service中注入DAO
 
  1. 需要在IndexAction中注入一级分类的Service.
    • IndexAction   调用   CategoryService   调用   CategoryDao
    • 将一级分类的数据显示到页面
    • 将一级分类的数据存入到session中:因为之后很多页面都会用到。
 
五:首页上热门商品的显示
  1. 建表:
创建二级分类的表:
CREATE TABLE `categorysecond` (
  `csid` int(11) NOT NULL AUTO_INCREMENT,
  `csname` varchar(255) DEFAULT NULL,
  `cid` int(11) DEFAULT NULL,
  PRIMARY KEY (`csid`),
  KEY `FK936FCAF21DB1FD15` (`cid`),
  CONSTRAINT `FK936FCAF21DB1FD15` FOREIGN KEY (`cid`) REFERENCES `category` (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=utf8;
创建商品表:
CREATE TABLE `product` (
  `pid` int(11) NOT NULL AUTO_INCREMENT,
  `pname` varchar(255) DEFAULT NULL,
  `market_price` double DEFAULT NULL,
  `shop_price` double DEFAULT NULL,
  `image` varchar(255) DEFAULT NULL,
  `pdesc` varchar(255) DEFAULT NULL,
  `is_hot` int(11) DEFAULT NULL,
  `pdate` datetime DEFAULT NULL,
  `csid` int(11) DEFAULT NULL,
  PRIMARY KEY (`pid`),
  KEY `FKED8DCCEFB9B74E02` (`csid`),
  CONSTRAINT `FKED8DCCEFB9B74E02` FOREIGN KEY (`csid`) REFERENCES `categorysecond` (`csid`)
) ENGINE=InnoDB AUTO_INCREMENT=80 DEFAULT CHARSET=utf8;
 
  1. 建包及相应的类:
    • com.weiwei.shopping.product
      • action :ProductAction
      • service :ProductService:业务层对象
      • dao :ProductDao:持久层对象
      • vo :Product:实体对象 ;Product.hbm.xml:映射文件
 
  1. 对Service和DAO进行配置:
    • 在DAO中注入sessionFactory
    • 在Service中注入DAO
 
  1. 需要在IndexAction中注入商品的Service.
    • IndexAction  调用  ProductService  调用  ProductDao
    • 查询热门商品
    • is_hot: 0:不是热门商品  1:是热门商品;
    • 查询带有个数
    • 分页查询
    • 将查询到的数据保存到值栈中
 
六:首页上最新商品的显示
  1. IndexAction  调用   ProductService  调用   ProductDao
    • 查询最新商品:
    • 按商品上传日期倒序进行排序 只显示10个.
    • 将查询到记录保存到值栈中:
 
七:首页上点击商品显示商品详情
  1. 点击商品链接:
       * 传递商品id.
  1. 编写Action:
* 编写Action类,继承ActionSupport实现模型驱动接口.
* 编写一个执行的方法.
  1. 配置Action:
* 在applicationContext.xml中配置Action
* 在struts.xml中配置Action
  1. 在Action中调用Service完成根据ID进行查询的方法:
* 注入ProductService.
* 完成查询
  1. 在页面上显示相应数据 :
* 页面转向
* 修改页面
* 显示数据
     显示数据时可以直接通过模型驱动的model对象拿数据。例如:
src="${pageContext.request.contextPath}/<s:property value="model.image"/>"
<s:property value="model.shop_price"/>
 
八:首页上点击一级分类,查询商品列表:(左侧一级分类和二级分类关联查询)
  1. 创建二级分类的包及类:
    • com.weiwei.shopping.categorysecond
      • action :CategorySecondAction
      • service :CategorySecondService
      • dao :CategorySecondDao
      • vo :CategorySecond
      • CategorySecond.hbm.xml
 
  1. 配置一级分类和二级分类的关联关系:
    • Category.xml
 <!-- 配置一个二级分类的集合   按照编号进行排序  懒加载默认是true,为了不延迟改为false-->
          <set order-by="csid" name="categorySeconds" lazy="false">
              <key column="cid"></key>
              <one-to-many class="com.weiwei.shopping.categorysecond.vo.CategorySecond"/>
          </set>
    • CategorySecond.hbm.xml
           <!--
            相对于一级分类,二级分类是many的一端 :在二级分类中配置many-to-one
            name:实体类中的属性
            column:表中的外键字段
           -->
           <many-to-one name="category" class="com.weiwei.shopping.category.vo.Category" column="cid"></many-to-one>
 
  1. 点击一级分类的链接:
    • 传递一级分类的cid,根据cid查询所有商品.
 
  1. 编写Action:
    • 接收cid:
    • 编写一个执行的方法:因为再ProductService中已经做了FindAll()方法,所以在这里直接注入ProductService 调用方法,然后返回字符串进行页面跳转。
    • 在页面上用迭代标签迭代显示左侧分类 ;
    • 关联查找:直接从session中获得一级分类的数据,需要在映射文件中配置一级分类上二级分类的集合(lazy="false" );并且为了数据顺序不变,按二级分类的遍号排序显示(order-by="csid" )。
 
九:首页上点击一级分类,查询商品列表:(显示商品列表)
  1. 查询商品,带有分页显示商品
    • 回到商品列表页面
    • 需要查询:商品集合,当前页数,总页数(总记录数),每页显示记录数.( 将后台的这些数据带到页面上,首选:值栈 )
    • 将这些数据封装到一个分页类中。(最后将分页类保存到值栈中就OK)。
  1. 在工具包中封装一个PageBean。
  2. 完成查询:
    • 传递当前页数到ProductAction中,提供set方法;
    • 调用ProductService的FindByPageCid()方法完成查询;参数:Cid,page;
方法返回的是PageBean;
  1. 配置二级分类和商品关联关系——类似于一级分类月二级分类的配置。
注意:在页面上从值栈中、模型驱动取PageBean不用加#;从session中取值需要加#.
 
十:商品分类页面根据二级分类ID查询商品
  1. 点击二级分类链接:
    • 传递csid
    • 传递page=1
  1. 编写Action :
    • 接收csid:
    • 接收page
  1. 调用Service完成查询:
    • 封装成PageBean
  1. 在页面中进行显示
 
购物车模块
一:创建表、包结构及映射文件。
二:将商品添加进购物车
  1. 封装购物车对象
    • Cart:购物车对象
      • CartItem的集合
      • total:总计 = 小计相加
      • 功能:
        • 将购物项添加到购物车
        • 从购物车中移出购物项
        • 清空购物车
     /*功能1:将购物项添加到购物车*/
     public void addCart(CartItem cartItem){
          /*判断购物车中是否已经存在该购物项
           *   存在:
           *        数量增加
           *        总计 = 总计 + 购物项小计
           * 不存在:
           *        向map中添加购物项
           *        总计 = 总计 + 购物项小计
           * */
          //获得商品id
          Integer pid = cartItem.getProduct().getPid();
          //判断购物车中是否存在该购物项:
          if(map.containsKey(pid)){
              //存在
              //获取原来的购物项
              CartItem OcartItem = map.get(pid);
              OcartItem.setCount(OcartItem.getCount() + cartItem.getCount());
          } else {
              //不存在
              map.put(pid, cartItem);
          }
          //设置总计的值
          total += cartItem.getSubtotal();
     }
    • CartItem:购物项
      • Product:商品信息
      • count:购买某种商品的数量
      • subtotal:购买某种商品的小计=单价*数量(Product.shop_price*count)
 
      提示:(1)set集合每添加一个顺序就会变化:所以购物车中不用set;若只为显示购物车,则用list集合就足够了,但是为了能够删除商品,我们选择用map集合,通过key可以删除选中商品。
               (2)通过JS提交表单:document.getElementById("表单ID").submit();
               (3)在购物车中显示商品:${pageContext.request.contextPath}/<s:property value="#cartItem.product.image":在页面上从值栈中取PageBean不用加#;从session中取值需要加#.
               
 
三:清空购物车
    • 在CartAction中:
      • 获得购物车
      • 调用clearCart()方法
    • 在页面上:
      • 用struts迭代标签判断
        • 若购物车为空则不显示相关按钮、表单
        • 若不为空则显示表单、相关商品
 
四:移出购物项
    • 点击页面的移出链接,传入pid
    • 在CartAction中:
      • 获得购物车
      • 调用removeCart()方法
 
注意:
session序列化的异常。
session销毁三种情况:
(1)服务器超时:30分钟;
(2)服务器非正常关闭:如从控制台直接关tomcat(点stop是正常关闭,启动会抛序列化异常)
(3)手动调用session的销毁方法(如本项目中的退出功能);
 
所以让实体类实现序列化接口就解决了:
/*实现序列化的接口,以免服务器抛未序列化异常*/
public class Cart implements Serializable{···}
 
 
订单模块
一:建表:数据库设计模块已完成;
二:创建订单模块的包、类:
  • com.weiwei.shopping.order
    • action :OrderAction
    • service :OrderService
    • dao :OrderDao
    • vo :
      • Order
      • Order.hbm.xml
      • OrderItem
      • OrderItem.hbm.xml
 
三:配置:
  • applicationContext.xml
  • 配置映射
  • OrderAction   调用   OrderService   调用   OrderDao
  • 实现提交订单时页面的跳转:修改我的购物车页面的提交按钮链接,再编写OrderAction、配置struts.xml
 
四:订单页面数据生成并显示
  • 生成订单
    • 保存订单的数据
    • 在页面中显示订单数据
    • 通过模型驱动的对象将数据传递到页面.(原理还是值栈)
  • 我的订单
    • 根据用户的uid查询当前用户的所有的订单
 
五:付款
  • 在线付款原理图:
          本项目采用第二种方式。
  • 在线付款流程分析
  • 本项目付款功能流程
    • 跳转到页面:根据订单的oid查询订单.
    • 在页面中对其进行付款
  • 付款功能的实现
    • 在线支付的方式
    • 在线支付
    • 与第三方支付公司对接:(易宝)
    • 在线支付的流程
    • 付款功能代码实现
    • 修改订单数据:(收货人,地址,电话)
    • 完成付款的功能
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

SSH实战 · 唯唯乐购项目(中)的更多相关文章

  1. SSH实战 · 唯唯乐购项目(上)

    前台需求分析 一:用户模块 注册 前台JS校验 使用AJAX完成对用户名(邮箱)的异步校验 后台Struts2校验 验证码 发送激活邮件 将用户信息存入到数据库 激活 点击激活邮件中的链接完成激活 根 ...

  2. SSH实战 · 唯唯乐购项目(下)

    后台模块 一:后台用户模块 引入后台管理页面 创建adminuser表: CREATE TABLE `adminuser` (   `uid` int(11) NOT NULL AUTO_INCREM ...

  3. 《 .NET并发编程实战》实战习题集 - 3 - CRUD项目中使用FP

    先发表生成URL以印在书里面.等书籍正式出版销售后会公开内容.

  4. SSH实战 · SSH项目开发环境搭建

    一:SSH整合 创建一个新的WEB项目 引入struts2.3.15.3: jar包:                 struts-2.3.15.3\apps\struts2-blank.war\W ...

  5. RabbitMQ之项目中实战

    说了那么多,还不是为了在项目中进行实战吗,在实践中检验真理,不然我学他干嘛,不能解决项目中的实际问题的技术都是耍流氓... 一.后台管理系统发送消息 瞎咧咧:后台管理系统发送消息到交换机中,然后通知其 ...

  6. 【一起学设计模式】观察者模式实战:真实项目中屡试不爽的瓜娃EventBus到底如何实现观察者模式的?

    申明 本文章首发自本人公众号:壹枝花算不算浪漫,如若转载请标明来源! 感兴趣的小伙伴可关注个人公众号:壹枝花算不算浪漫 22.jpg 前言 之前出过一个设计模式的系列文章,这些文章和其他讲设计模式的文 ...

  7. 实战派 | Java项目中玩转Redis6.0客户端缓存!

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 哈喽大家好啊,我是Hydra. 在前面的文章中,我们介绍了Redis6.0中的新特性客户端缓存client-side caching,通过tel ...

  8. MVC项目中WebViewPage的实战应用

    由于公司的项目可能会卖到国外,所以需要支持多语言.今天我就在目前的项目中实现了多语言功能,下面记录我的具体实现. 1.相信很多朋友在用MVC做项目时候,都会遇到“视图必须派生自 WebViewPage ...

  9. 【知识必备】浅淡MVP在Android项目中的实战演习,让代码结构更简单~

    一.写在前面 讲道理,这次是真的笔者很久都没有更新blog了,主要最近维护的框架问题也是层出不穷,而且对技术交流群的解答也让我身心疲惫,所以在这里跟关注我的人说声抱歉,没有定期给你们带来福利,那么这里 ...

随机推荐

  1. Syscan360会议胸牌破解揭秘

    Syscan360会议胸牌破解揭秘 背景 有幸参加今年11月份的上海Syscan360安全会议,会议期间有一个亮点就是360的独角兽团队设计了一款电子badge(胸牌)供参加人员进行破解尝试,类似于美 ...

  2. iOS开发系列--Swift语言

    概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...

  3. C语言 · 矩形面积交

    问题描述 平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴.对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积. 输入格式 输入仅包含两行,每行描述一个矩形. 在每行中 ...

  4. 多线程的通信和同步(Java并发编程的艺术--笔记)

    1. 线程间的通信机制 线程之间通信机制有两种: 共享内存.消息传递.   2. Java并发 Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式执行,通信的过程对于程序员来说是完全透 ...

  5. HTTPS简介

    一.简单总结 1.HTTPS概念总结 HTTPS 就是对HTTP进行了TLS或SSL加密. 应用层的HTTP协议通过传输层的TCP协议来传输,HTTPS 在 HTTP和 TCP中间加了一层TLS/SS ...

  6. SQL Server-聚焦查询计划Stream Aggregate VS Hash Match Aggregate(二十)

    前言 之前系列中在查询计划中一直出现Stream Aggregate,当时也只是做了基本了解,对于查询计划中出现的操作,我们都需要去详细研究下,只有这样才能对查询计划执行的每一步操作都了如指掌,所以才 ...

  7. 设计模式之创建类模式大PK

                                        创建类模式大PK 创建类模式包括工厂方法模式.建造者模式.抽象工厂模式.单例模式和原型模式,他们能够提供对象的创建和管理职责.其 ...

  8. python 数据类型 -- 元组

    元组其实是一种只读列表, 不能增,改, 只可以查询 对于不可变的信息将使用元组:例如数据连接配置 元组的两个方法: index, count >>> r = (1,1,2,3) &g ...

  9. BPM配置故事之案例7-公式计算

    行政主管发来邮件.要求物资明细表增加"单价""总价"."单价"由其审批时填写,"总价"根据"单价"与 ...

  10. H3 BPM引擎API接口

    引擎API接口通过 Engine 对象进行访问,这个是唯一入口. 示例1:获取组织机构对象 this.Engine.Organization.GetUnit("组织ID"); 示例 ...