大数据正式京淘12 电玩女神 2022-06-01 10:25 283阅读 0赞 # 大数据正式京淘12 # # 【前台我的购物车系统】 # ### 展示购物车信息 ### * ![d5hGk2y.png][] ### 添加商品到购物车 ### * ![HsO6UvE.png][] ### 更改购物车中商品的数量 ### * ![RK91irD.png][] * 局部刷新 * 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. 访问形如“购物车”、“订单”的功能 * ![e9VYQ3y.png][] 2. 判断是否登录,即拦截,进行相应的操作 * ![WcK5Cw3.png][] * 原理: * 将具有一定规则的发送到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】 * 冗余字段 * 例如:【总金额】 * 表设计 * ![8DACsaI.png][] ### 搭建订单系统 ### * 新建maven项目jt\_order * 修改相应的项目项目属性 * 添加配置文件 * 测试运行 ### 订单模块 ### * 生成订单模块 * 提交订单模块 ### 订单模块流程图示 ### * 购物车去结算 * ![HEWKWMB.png][] * 订单页面 * ![avneKhF.png][] * 提交订单:显示提交成功 # 订单系统部分代码展示 # ### 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> # 补充--范式 # ### 三范式 ### * 第一范式 * 强调列的原子性,不可再拆分 * 例子 * ![A3JLq7l.png][] * 第二范式 * 满足第一范式 * 包含两个内容 1. 必须有主键 2. 非主键字段必须完全依赖于主键,不能部分依赖主键 * 例子 * ![SH5OoNm.png][] * 第三范式 * 满足第一范式 * 是第二范式的一个特例 * 非主键属性必须依赖主键属性,不能依赖于非主键属性 * 例子 * ![Xn63y9J.png][] * 总结 * 三范式是在数据库初期使用(时间换取空间),能外键关联,就用外键关联,能不冗余数据设计,就不设计 ### 反范式 ### * 违反第二、第三范式就是反范式 [d5hGk2y.png]: https://i.imgur.com/d5hGk2y.png [HsO6UvE.png]: https://i.imgur.com/HsO6UvE.png [RK91irD.png]: https://i.imgur.com/RK91irD.png [e9VYQ3y.png]: https://i.imgur.com/e9VYQ3y.png [WcK5Cw3.png]: https://i.imgur.com/WcK5Cw3.png [8DACsaI.png]: https://i.imgur.com/8DACsaI.png [HEWKWMB.png]: https://i.imgur.com/HEWKWMB.png [avneKhF.png]: https://i.imgur.com/avneKhF.png [A3JLq7l.png]: https://i.imgur.com/A3JLq7l.png [SH5OoNm.png]: https://i.imgur.com/SH5OoNm.png [Xn63y9J.png]: https://i.imgur.com/Xn63y9J.png
相关 大数据正式京淘3 大数据正式京淘3 EasyUI简介 文档 每个组件的easyui有属性、方法和事件。用户可以方便地扩展。 属性 Dear 丶/ 2022年06月02日 12:51/ 0 赞/ 187 阅读
相关 大数据正式京淘2 大数据正式京淘2 项目统一 编码:UTF-8 环境:JDK1.8 Maven:3.5 数据库:5.5 项目支撑系统搭建 新建w 末蓝、/ 2022年06月02日 12:27/ 0 赞/ 165 阅读
相关 大数据正式京淘1 大数据正式京淘1 技术点 Spring、SpringMVC、Mybatis框架 富客户端EasyUI、KindEditor图文控件 Maven项目 梦里梦外;/ 2022年06月02日 12:26/ 0 赞/ 129 阅读
相关 大数据正式京淘正式14 大数据正式京淘正式14 传统的检索方式 1.文本检索/windows检索 全文检索、全文遍历 加载到内存中 缺点:数据一多,无法高效查询 蔚落/ 2022年06月01日 13:54/ 0 赞/ 135 阅读
相关 大数据正式京淘12 大数据正式京淘12 【前台我的购物车系统】 展示购物车信息 ![d5hGk2y.png][] 添加商品到购物车 ![HsO6UvE.png 电玩女神/ 2022年06月01日 10:25/ 0 赞/ 284 阅读
相关 大数据正式京淘10 大数据正式京淘10 数据库的读写分离 电商项目京淘项目的瓶颈有哪些 1. 数据库瓶颈 2. IO【图片(文件)的上传】 我就是我/ 2022年06月01日 07:19/ 0 赞/ 160 阅读
相关 大数据正式京淘9 大数据正式京淘9 redis集群总结 引入槽道:14384个虚拟槽道,扩展节点,无需修改代码 删除节点 1. 线路割接 2. 心已赠人/ 2022年06月01日 06:23/ 0 赞/ 194 阅读
相关 大数据正式京淘8 大数据正式京淘8 Redis集群 为什么用redis集群 Redis哨兵的缺点 1. 横向扩展不方 爱被打了一巴掌/ 2022年06月01日 05:36/ 0 赞/ 268 阅读
还没有评论,来说两句吧...