大数据正式12

大数据正式京淘12

【前台我的购物车系统】

展示购物车信息

添加商品到购物车

更改购物车中商品的数量

  • 局部刷新
    • ajax异步请求

购物车部分代码展示

  • controller层

     

    package com.peng.controller;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import com.peng.pojo.Cart;
    import com.peng.service.CartService;
    import com.peng.threadlocal.UserThreadLocal;
    
    @Controller
    @RequestMapping("/cart")
    public class CartController {
        @Autowired
        @Qualifier("cartService")
        private CartService cartService;
    
        // 展示购物车信息
        @RequestMapping("/show")
        public String show(Model model) {
            Long userId = UserThreadLocal.get().getId();
            System.err.println("=========333333333333===============:" + userId);
            List<Cart> cartList = cartService.show(userId);
            model.addAttribute("cartList", cartList);
            return "cart";
        }
    
        // 添加商品到购物车
        @RequestMapping("/add/{itemId}")
        public String addCart(@PathVariable Long itemId, Integer num) {
            Long userId = UserThreadLocal.get().getId();
            cartService.saveCart(userId, itemId, num);
            return "redirect:/cart/show.html";
        }
    
        // 更改购物车商品的数量
        @RequestMapping("/update/num/{itemId}/{num}")
        public String updataNum(@PathVariable Long itemId, @PathVariable Integer num) {
            Long userId = UserThreadLocal.get().getId();
            cartService.updateNum(userId, itemId, num);
            return "";// 局部刷新
        }
    
        // 删除啊购物车里的商品
        @RequestMapping("/delete/{itemId}")
        public String deleteItem(@PathVariable Long itemId) {
            Long userId = UserThreadLocal.get().getId();
            cartService.deleteItem(userId, itemId);
            return "redirect:/cart/show.html";
        }
    
    }
    
  • service层

    • service接口

       

      package com.peng.service;
      
      import java.util.List;
      
      import com.peng.pojo.Cart;
      
      public interface CartService {
          /**
           * 展示购物车信息
           * 
           * @param userId
           * @return
           */
          List<Cart> show(Long userId);
      
          /**
           * 保存购物车
           * 
           * @param userId
           * @param itemId
           * @param num
           */
          void saveCart(Long userId, Long itemId, Integer num);
      
          /**
           * 更新商品的数量
           * 
           * @param userId
           * @param itemId
           * @param num
           */
          void updateNum(Long userId, Long itemId, Integer num);
      
          /**
           * 删除商品
           * 
           * @param userId
           * @param itemId
           */
      
          void deleteItem(Long userId, Long itemId);
      }
      
    • service实现类

       

      package com.peng.service.impl;
      
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Service;
      
      import com.fasterxml.jackson.databind.JsonNode;
      import com.fasterxml.jackson.databind.ObjectMapper;
      import com.peng.pojo.Cart;
      import com.peng.pojo.Item;
      import com.peng.service.CartService;
      import com.peng.service.HttpClientService;
      
      @Service("cartService")
      public class CartServiceImpl implements CartService {
          @Autowired
          private HttpClientService httpClient;
          private ObjectMapper MAPPER = new ObjectMapper();
      
          @Override
          public List<Cart> show(Long userId) {
              List<Cart> carts = null;
              try {
                  String url = "http://cart.jt.com/cart/query/" + userId;
                  String jsonData = httpClient.doGet(url, "utf-8");
                  JsonNode jsonNode = MAPPER.readTree(jsonData);
                  JsonNode data = jsonNode.get("data");
                  // 转化为list对象
                  if (data.isArray() && data.size() > 0) {
                      carts = MAPPER.readValue(data.traverse(),
                              MAPPER.getTypeFactory().constructCollectionType(List.class, Cart.class));
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              }
      
              return carts;
          }
      
          @Override
          public void saveCart(Long userId, Long itemId, Integer num) {
              try {
                  // 获取数据
                  String url = "http://manage.jt.com/items/" + itemId;
                  String JsonItem = httpClient.doGet(url, "utf-8");
                  Item item = MAPPER.readValue(JsonItem, Item.class);
                  // 保存数据
                  url = "http://cart.jt.com/cart/save";
                  // 封装数据
                  Map<String, String> params = new HashMap<String, String>();
                  params.put("userId", userId + "");
                  params.put("itemId", itemId + "");
                  params.put("num", num + "");
                  params.put("itemTitle", item.getTitle());
                  params.put("itemImage", item.getImages()[0]);
                  params.put("itemPrice", item.getPrice() + "");
                  httpClient.doPost(url, params);
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
          @Override
          public void updateNum(Long userId, Long itemId, Integer num) {
              try {
                  String url = "http://cart.jt.com/cart/update/num/" + userId + "/" + itemId + "/" + num;
                  httpClient.doGet(url, "utf-8");
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
          @Override
          public void deleteItem(Long userId, Long itemId) {
              try {
                  String url = "http://cart.jt.com/cart/delete/" + userId + "/" + itemId;
                  httpClient.doGet(url, "utf-8");
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }
      

拦截器

  • 拦截过程
    1. 访问形如“购物车”、“订单”的功能
    2. 判断是否登录,即拦截,进行相应的操作
  • 原理:
    • 将具有一定规则的发送到controller的请求
    • 底层是面向切面编程
    • 例子:
      • 拦截器拦截地址,没有userId,系统转发到登录界面,如果已经登录,则将userId放到一个ThreadLocal【get、set、remove】中
  • 拦截的对象
    • 拦截订单
    • 拦截购物车
    • 不拦截游客能看的
  • 拦截时机
    • preHandle--controller处理之前-------选这个时机进行处理
    • postHandle--controller【包括后台的service和到层的处理】处理之后
    • afterCompletion--页面渲染之后到页面展示之前
  • 拦截代码展示

    • 拦截配置:在springmvc-config.xml中配置拦截器

       

      <!-- 拦截器 -->
      <mvc:interceptors>
          <mvc:interceptor>
              <!-- 拦截的请求地址:一个*代表下一级目录;两个*代表多级 -->
              <mvc:mapping path="/cart/**" />
              <bean class="com.peng.interceptor.CartInterceptor"></bean>
          </mvc:interceptor>
      </mvc:interceptors>
      
    • 拦截器类

       

      package com.peng.interceptor;
      
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      
      import org.apache.commons.lang3.StringUtils;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.servlet.HandlerInterceptor;
      import org.springframework.web.servlet.ModelAndView;
      
      import com.fasterxml.jackson.databind.JsonNode;
      import com.fasterxml.jackson.databind.ObjectMapper;
      import com.peng.pojo.User;
      import com.peng.service.HttpClientService;
      import com.peng.threadlocal.UserThreadLocal;
      import com.peng.util.CookieUtils;
      
      public class CartInterceptor implements HandlerInterceptor {
          /**
           * 实现逻辑: 1.从cooke中获取ticket 2.去访问sso,调用httpClient访问,访问redis
           * 3.user.json转化为user 4.获取数据userId,判断一下 5.共享数据解决线程的安全问题
           */
          @Autowired
          HttpClientService httpClient;
          private static final ObjectMapper om = new ObjectMapper();
      
          // controller之前
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                  throws Exception {
              // 在controller处理之前拦截
              String cookieName = "JT_TICKET";
              String ticket = CookieUtils.getCookieValue(request, cookieName);
              // 判断一下cookie
              if (StringUtils.isNotEmpty(ticket)) {
                  String url = "http://sso.jt.com/user/query/" + ticket;
                  String jsonString = httpClient.doGet(url, "utf-8");
                  if (StringUtils.isNotEmpty(jsonString)) {
                      JsonNode jsonNode = om.readTree(jsonString);
                      String jsonUser = jsonNode.get("data").asText();
                      // 将当前的用户对象转化
                      User user = om.readValue(jsonUser, User.class);
                      // 封装userId,共享数据到controller
                      UserThreadLocal.set(user);// 解决线程安全的问题--一次请求一定是一个线程对象
                      return true;
                  }
              }
              UserThreadLocal.set(null);// 这个作用:防止意外
              response.sendRedirect("/user/login.html");
              // 不放行--提醒登录
              return false;
          }
      
          // 持久层完成
          @Override
          public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                  ModelAndView modelAndView) throws Exception {
      
          }
      
          // 页面渲染到展示页面内容之前
          @Override
          public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                  throws Exception {
      
          }
      
      }
      
    • 线程安全类

       

      package com.peng.threadlocal;
      
      import com.peng.pojo.User;
      
      public class UserThreadLocal {
          private static ThreadLocal<User> ThreadUser = new ThreadLocal<User>();
      
          public static void set(User user2) {
              ThreadUser.set(user2);
          }
      
          public static User get() {
              return ThreadUser.get();
          }
      }
      

订单系统

订单商品表

  • 复合主键
    • 大于一个字段能够唯一的确定一条记录在数据表中国的位置
    • 例如:【itemId和orderId】
  • 冗余字段
    • 例如:【总金额】
  • 表设计

搭建订单系统

  • 新建maven项目jt_order
  • 修改相应的项目项目属性
  • 添加配置文件
  • 测试运行

订单模块

  • 生成订单模块
  • 提交订单模块

订单模块流程图示

  • 购物车去结算
  • 订单页面
  • 提交订单:显示提交成功

订单系统部分代码展示

controller层【jt_web】

 

package com.peng.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.peng.pojo.Cart;
import com.peng.pojo.Order;
import com.peng.service.OrderService;
import com.peng.threadlocal.UserThreadLocal;
import com.peng.vo.SysResult;

@Controller
@RequestMapping("/order")
public class OrderController {
    @Autowired
    @Qualifier("orderService")
    private OrderService orderService;

    // 生成订单
    @RequestMapping("/create")
    public String orderCarts(Model model) {
        Long userId = UserThreadLocal.get().getId();
        List<Cart> cartList = orderService.orderCarts(userId);
        model.addAttribute("carts", cartList);
        return "order-cart";
    }

    // 提交创建订单
    @RequestMapping("/submit")
    @ResponseBody
    public SysResult createOrder(Order order) {
        Long userId = UserThreadLocal.get().getId();
        System.err.println(order + ".....................................");// TODO:order信息不准
        order.setUserId(userId);
        String orderId = orderService.saveOrder(order);
        System.err.println(orderId + ".....................................");
        return SysResult.oK(orderId);
    }

    // 成功提交,转发到相应的成功页面
    @RequestMapping("/success")
    public String success(@PathVariable("id") String orderId, Model model) {
        Order order = orderService.queryOrderById(orderId);// Id为null
        model.addAttribute("order", order);
        return "success";
    }

}

service层【jt_web】

  • service接口

     

    package com.peng.service;
    
    import java.util.List;
    
    import com.peng.pojo.Cart;
    import com.peng.pojo.Order;
    
    public interface OrderService {
        /**
         * 通过userId查询所有的订单
         * 
         * @param userId
         * @return
         */
    
        List<Cart> orderCarts(Long userId);
    
        /**
         * 
         * 
         * @param order
         * @return
         */
        String saveOrder(Order order);
    
        /**
         * 通过编号查询订单信息
         * 
         * @param orderId
         * @return
         */
        Order queryOrderById(String orderId);
    }
    
  • service实现类

     

    package com.peng.service.impl;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.fasterxml.jackson.databind.JsonNode;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.peng.pojo.Cart;
    import com.peng.pojo.Order;
    import com.peng.service.HttpClientService;
    import com.peng.service.OrderService;
    
    @Service("orderService")
    public class OrderServiceImpl implements OrderService {
        @Autowired
        private HttpClientService httpClient;
        private ObjectMapper MAPPER = new ObjectMapper();
    
        @Override
        public List<Cart> orderCarts(Long userId) {
            List<Cart> carts = null;
            try {
                String url = "http://cart.jt.com/cart/query/" + userId;
                String jsonData = httpClient.doGet(url, "utf-8");
                JsonNode jsonNode = MAPPER.readTree(jsonData);
                JsonNode data = jsonNode.get("data");
                // 转化为list对象
                if (data.isArray() && data.size() > 0) {
                    carts = MAPPER.readValue(data.traverse(),
                            MAPPER.getTypeFactory().constructCollectionType(List.class, Cart.class));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return carts;
        }
    
        @Override
        public String saveOrder(Order order) {
            String orderId = order.getOrderId();
            try {
                String url = "http://order.jt.com/create";
                String jsonData = MAPPER.writeValueAsString(order);
                httpClient.doPostJson(url, jsonData);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return orderId;
        }
    
        @Override
        public Order queryOrderById(String orderId) {
            Order order = null;
            try {
                String url = "http://order.jt.com/query/" + orderId;
                String jsonDta = httpClient.doGet(url, "utf-8");
                order = MAPPER.readValue(jsonDta, Order.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return order;
        }
    
    }
    

Controller层【jt_order】

 

package com.peng.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.peng.pojo.Order;
import com.peng.service.OrderService;

@Controller("orderController")
@RequestMapping("/order")
public class OrderController {
    @Autowired
    @Qualifier("orderService")
    private OrderService orderService;

    private static final ObjectMapper MAPPER = new ObjectMapper();

    // 创建订单
    @RequestMapping("/create")
    @ResponseBody
    public String orderCreate(@RequestBody String json) {
        String orderId = "";
        try {
            Order order = MAPPER.readValue(json, Order.class);
            orderId = orderService.saveOrder(order);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return orderId;
    }

    // 查询订单
    @RequestMapping("/query/{orderId}")
    @ResponseBody
    public Order queryOrder(@PathVariable String orderId) {
        Order order = null;
        try {
            order = orderService.queryOrderById(orderId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return order;
    }
}

Service层【jt_order】

  • service接口

     

    package com.peng.service;
    
    import com.peng.pojo.Order;
    
    public interface OrderService {
        /**
         * 保存订单
         * 
         * @param order
         * @return
         */
        String saveOrder(Order order);
    
        /**
         * 查询订单
         * 
         * @param orderId
         * @return
         */
        Order queryOrderById(String orderId);
    }
    
  • service实现类

     

    package com.peng.service.impl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Service;
    
    import com.peng.mapper.OrderMapper;
    import com.peng.pojo.Order;
    import com.peng.service.BaseService;
    import com.peng.service.OrderService;
    
    @Service("orderService")
    public class OrderServiceImpl extends BaseService<Order> implements OrderService {
        @Autowired
        @Qualifier("orderMapper")
        private OrderMapper orderMapper;
    
        @Override
        public String saveOrder(Order order) {
            // 完成order的封装
            String orderId = order.getUserId() + "" + System.currentTimeMillis();
            orderMapper.orderCreate(order);
            return orderId;
        }
    
        @Override
        public Order queryOrderById(String orderId) {
            return orderMapper.queryOrderById(orderId);
        }
    
    }
    

dao层【jt_order】

  • Mapper接口

     

    package com.peng.mapper;
    
    import com.peng.pojo.Order;
    
    public interface OrderMapper extends SysMapper<Order> {
        /**
         * 新增订单
         * 
         * @param order
         */
        void orderCreate(Order order);
    
        /**
         * 查询订单
         * 
         * @param orderId
         * @return
         */
        Order queryOrderById(String orderId);
    }
    
  • Mapper的xml文件

     

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
      PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.peng.mapper.OrderMapper">
        <sql id="tableName">tb_order</sql>
        <!-- 返回封装 -->
        <resultMap type="Order" id="pojoResultMap" autoMapping="true">
            <id column="order_id" property="orderId" />
            <association property="orderShipping" javaType="OrderShipping"
                column="order_id" select="queryOrderShippingByOrderId" autoMapping="true"></association>
            <collection property="orderItems" javaType="Arraylist"
                ofType="OrderItem" autoMapping="true" select="queryOrderItemByOrderId"
                column="order_id">
            </collection>
        </resultMap>
        <!-- 通过订单号查询所有商品 -->
        <select id="queryOrderItemByOrderId" resultType="OrderItem"
            parameterType="String">
            SELECT * FROM tb_order_item WHERE order_id = #{orderId};
        </select>
        <!-- 通过订单号查询所有的订单 -->
        <select id="queryOrderShippingByOrderId" resultType="OrderShipping"
            parameterType="String">
            SELECT * FROM tb_order_shipping WHERE order_id =
            #{orderId};
        </select>
        <!-- 查询所有的订单 -->
        <select id="queryList" resultMap="pojoResultMap">
            SELECT
            *
            FROM
            <include refid="tableName" />
        </select>
        <!-- 通过订单编号查询所有的订单 -->
        <select id="queryOrderById" resultMap="pojoResultMap">
            SELECT
            *
            FROM
            <include refid="tableName" />
            WHERE order_id = #{id};
        </select>
        <!-- 新增订单 -->
        <insert id="orderCreate" useGeneratedKeys="true" keyProperty="id">
            INSERT INTO
            <include refid="tableName" />
            VALUES
            (#{orderId},#{payment},#{paymentType},#{postFee},#{status},#{createTime},#{updateTime},#{paymentTime},#{consignTime},#{endTime},#{closeTime},#{shippingName},#{shippingCode},#{userId},#{buyerMessage},#{buyerNick},#{buyerRate});
            INSERT INTO tb_order_item VALUES
            <foreach collection="orderItems" item="item" separator=",">
                (#{item.itemId},#{orderId},#{item.num},#{item.title},#{item.price},#{item.totalFee},#{item.picPath})
            </foreach>
            ;
            INSERT INTO tb_order_shipping VALUES
            (#{orderId},#{orderShipping.receiverName},#{orderShipping.receiverPhone},#{orderShipping.receiverMobile},#{orderShipping.receiverState},#{orderShipping.receiverCity},#{orderShipping.receiverDistrict},#{orderShipping.receiverAddress},#{orderShipping.receiverZip},NOW(),NOW());
        </insert>
    </mapper> 
    

补充--范式

三范式

  • 第一范式
    • 强调列的原子性,不可再拆分
      • 例子
  • 第二范式
    • 满足第一范式
    • 包含两个内容
      1. 必须有主键
      2. 非主键字段必须完全依赖于主键,不能部分依赖主键
    • 例子
  • 第三范式
    • 满足第一范式
    • 是第二范式的一个特例
    • 非主键属性必须依赖主键属性,不能依赖于非主键属性
    • 例子
  • 总结
    • 三范式是在数据库初期使用(时间换取空间),能外键关联,就用外键关联,能不冗余数据设计,就不设计

反范式

  • 违反第二、第三范式就是反范式

猜你喜欢

转载自my.oschina.net/architectliuyuanyuan/blog/1816928