CGB2005-京淘19(数组集合互转,商品详情页面展现 ,购物车系统,ctrl+h/f,sql按照字段写,消费生产者启动顺序,mapper复制路径,时间设置now,resful简化接收,伪静态路径)

注意事项

数组转集合: 普通循环遍历 , Arrays.asList(xxx)要求需要转换的数组必须是包装类型。

集合转数组: 普通循环遍历,集合名.toArray(xxx)转换后得值是包装类型。
全局搜索页面js的请求为 ctrl+h 单独搜索页面的关键字ctrl+f

写sql语句的查询条件与数据库的字段保持一致,而不是和po类的属性一致。只不过接收参数或者查询的结果封装到po类时要求属性和字段保持一致,可以用驼峰 resultMap as指定别名

1 商品详情展现:
域对象取值分析 重构manage为微服务架构
2.购物车模块实现: 增 删 改事务控制
查询:
关于消费者 生产者启动顺序说明 @Reference(check = false) @Autowired(required=false)
自动类型转换说明 写sql查询的条件是 数据库字段而不是po属性
mapper文件实现查询: 鼠标复制全称限定类名方式 如何在SqlYog中直接修改表记录
修改:
@ResponseBody //ajax结束的标识符.(虽然没有返回值但是请求时ajax发送的)
时间设置: 代码 new Date( ) sql中 now()
删除:
resful接收参数简化形式:普通方式接收参数 对象接收
新增:
普通重定向 redirect 伪静态拼接.html

1 商品详情展现

1.1业务说明

说明:当用户点击某个商品时,需要跳转到商品的详情页面中, 页面名称为item.jsp(web中)。
解释:
1). 根据url,http://www.jt.com/items/562379.html分析可知页面数据展现方式为伪静态的方式,562370位商品的itemId,所以商品详情页面的数据是根据itemId展现商品信息,并且在item.sp中展现数据。
2).根据url为www.jt.com可知,域名相同排除跨域,又因为发送的请求是在前台项目web中,而商品详情数据是在商品后台管理项目manage中,所以为Dubbo服务的远程调用。
在这里插入图片描述

在这里插入图片描述

1.2 页面js分析

说明:由取值方式分析可知,此为通过域对象的取值方式,所以在后台代码应该由Model存值。
在这里插入图片描述
在这里插入图片描述

1.3 将jt-manage改造为Dubbo项目

说明:web,common项目之前重构过了,所以只需要重构manage即可。

1.3.1 先创建接口(common)

说明:在jt-common中创建中立的接口
在这里插入图片描述

1.3.2 编辑YML配置文件(manage)

说明: 添加dubbo的配置即可.
在这里插入图片描述

server:
  port: 8091
  servlet:
    context-path: /
spring:
  datasource:
    #引入druid数据源
    #type: com.alibaba.druid.pool.DruidDataSource
    #driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root

  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp
#mybatis-plush配置
mybatis-plus:
  type-aliases-package: com.jt.pojo
  mapper-locations: classpath:/mybatis/mappers/*.xml
  configuration:
    map-underscore-to-camel-case: true

logging:
  level: 
    com.jt.mapper: debug

#关于Dubbo配置
dubbo:
  scan:
    basePackages: com.jt    #指定dubbo的包路径 为了扫描此项目下的dubbo注解(@service),可以指定大点的范围com,jt
  application:              #应用名称
    name: provider-manage     #一个接口对应一个服务名称(一个接口可以有多个实现,但是如果实现同一个接口则提供的服务也应该是同一个。 eg:老王 老李都卖菜则实现同一个接口,老孙卖肉则和老王老李实现不同的借口)
  registry: #注册中心 2181连接的是从机 backup(备用) 用户获取数据从机中获取 主机只负责监控整个集群 实现数据同步,所以这个地方要连接从机而不是主机
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
  protocol:  #指定协议 name:dubbo固定写法
    name: dubbo  #使用dubbo协议(tcp-ip)  web-controller直接调用sso-Service
    port: 20881  #每一个服务都有自己特定的端口 不能重复.


1.3.3 创建实现类DubboItemServiceImpl(manage)

在这里插入图片描述

1.3.4 创建控制层ItemController(web)

在这里插入图片描述

1.4 实现商品详情具体展现

1.4.1 编辑ItemController(web)

package com.jt.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.Item;
import com.jt.pojo.ItemDesc;
import com.jt.service.DubboItemService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ItemController {
    //服务器处理业务需要时间,可能还没有来得及响应你就走了.所以设定个超时时间.时间到了还没有报错
    @Reference(check = false,timeout = 3000)
    private DubboItemService itemService;

    /**
     * 业务: 根据itemId查询商品信息(item/itemDesc)
     * url地址: http://www.jt.com/items/562379.html
     * 参数:   562379(itemId)    restFul风格接收
     * 返回值:  页面逻辑名称,item.jsp
     * 页面取值: 分析页面js为域对象的取值方式
     *      ${item.title }/${itemDesc.itemDesc }   ( item商品对象   itemDesc商品详情对象)
     *  问题:商品
     *  思路:对象从哪获取??? jt-web ~~~jt-manage
     *      1.重构jt-manage项目 (web消费者之前改造过了)
     *      2.创建中立接口DubboItemService
     *      3.实现业务调用获取item/itemDesc对象
     * */
    @RequestMapping("/items/{itemId}")
    public String findItemById(@PathVariable Long itemId, Model model){
        //商品详情和商品表的id一致 根据id查 id是唯一的所以查询的结果唯一 就用单个的对象来接
        Item item = itemService.findItemById(itemId);
        ItemDesc itemDesc = itemService.findItemDescById(itemId);
        //将对象保存在request域中
        model.addAttribute("item", item);
        model.addAttribute("itemDesc", itemDesc);
        return "item";
    }
}

在这里插入图片描述

1.4.2 编辑ItemService(common)

在这里插入图片描述

1.4.3 编辑DubboItemServiceImpl(manage)

在这里插入图片描述

package com.jt.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.jt.mapper.ItemDescMapper;
import com.jt.mapper.ItemMapper;
import com.jt.pojo.Item;
import com.jt.pojo.ItemDesc;
import org.springframework.beans.factory.annotation.Autowired;

@Service(timeout = 3000)
public class DubboItemServiceImpl implements DubboItemService{

    @Autowired
    private ItemMapper itemMapper;       //商品信息的Mapper层
    @Autowired
    private ItemDescMapper itemDescMapper;  //商品详情信息的mapper

    @Override
    public Item findItemById(Long itemId) {
        return itemMapper.selectById(itemId);
    }

    @Override
    public ItemDesc findItemDescById(Long itemId) {
        return itemDescMapper.selectById(itemId);
    }
}

1.4.4 页面展现(manage web)

在这里插入图片描述
直接返回页面没有查询数据页面结构为:
在这里插入图片描述

2.购物车模块实现

2.1 创建服务提供者jt-cart项目

2.1.1 新建项目

在这里插入图片描述

2.1.2 添加继承/依赖/插件

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <artifactId>jt-cart</artifactId>

    <parent>
        <artifactId>jt</artifactId>
        <groupId>com.jt</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <!--添加依赖项-->
    <dependencies>
        <dependency>
            <groupId>com.jt</groupId>
            <artifactId>jt-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <!--添加插件-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

2.1.3 编辑POJO(common中)

在这里插入图片描述

@TableName("tb_cart")
@Data
@Accessors(chain = true)
public class Cart extends BasePojo{

    @TableId(type = IdType.AUTO)
    private Long id;            //购物车ID号
    private Long userId;        //用户ID号
    private Long itemId;        //商品ID号
    private String itemTitle;   //商品标题
    private String itemImage;   //图片
    private Long itemPrice;     //商品价格
    private Integer num;        //商品数量
    /*    create table tb_cart
            (
    id                   bigint(20) not null auto_increment,
    user_id              bigint(20),
    item_id              bigint(20),
    item_title           varchar(100),
    item_image           varchar(200),
    item_price           bigint(20) comment '单位:分',
    num                  int(10),
    created              datetime,
    updated              datetime,
    primary key (id),
    key AK_user_itemId (user_id, item_id)
);*/
}

2.1.4 编辑DubboCartService接口

在这里插入图片描述

2.1.5 编辑Cart代码结构

在这里插入图片描述
1). 主启动类
在这里插入图片描述

2). service实现类
在这里插入图片描述
3).mapper接口
在这里插入图片描述

4). 编辑YML配置文件

server:
  port: 8094
  servlet:
    context-path: /
spring:
  datasource:
    #引入druid数据源
    #type: com.alibaba.druid.pool.DruidDataSource
    #driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root

#关于Dubbo配置
dubbo:
  scan:
    basePackages: com.jt    #指定dubbo的包路径 为了扫描此项目下的dubbo注解(@service),可以指定大点的范围com,jt
  application:              #应用名称
    name: provider-cart1     #一个接口对应一个服务名称(一个接口可以有多个实现,但是如果实现同一个接口则提供的服务也应该是同一个。 eg:老王 老李都卖菜则实现同一个接口,老孙卖肉则和老王老李实现不同的借口)
  registry: #注册中心 2181连接的是从机 backup(备用) 用户获取数据从机中获取 主机只负责监控整个集群 实现数据同步,所以这个地方要连接从机而不是主机
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
  protocol:  #指定协议 name:dubbo固定写法
    name: dubbo  #使用dubbo协议(tcp-ip)  web-controller直接调用sso-Service
    port: 20882  #每一个服务都有自己特定的端口 不能重复.


  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp
#mybatis-plush配置
mybatis-plus:
  type-aliases-package: com.jt.pojo
  mapper-locations: classpath:/mybatis/mappers/*.xml
  configuration:
    map-underscore-to-camel-case: true

logging:
  level: 
    com.jt.mapper: debug

2.1.6 启动测试

在这里插入图片描述

2.2 购物车列表展现

2.2.1 关于启动顺序报错说明

说明:在公司编写启动项目的脚本,不一定是先启动生产者,如果先启动消费者后台会报错。
eg:现在jt项目的web前台中用到Dubbo访问的有ItemController(需要启动manage生产者),UserController(需要启动sso生产者),以及将要写的cart1对应的控制层。但是现在完成的业务只有cart1模块,只需要启动web、cart1模块就行了没必要所有的生产者都启动。(因为只启动一个生产者,所以即便按顺序启动 生产者 消费者仍会报错)
在这里插入图片描述

如何解决这种启动时,因为先启动消费者或者生产者没有启动完导致的消费者后台报错呢???
在注入对象的注解上添加 check = false属性,@Reference(check = false)。表示消费者启动时不会校验是否有提供者,当程序调用时才会校验是否有提供者。

类似于这个功能的注解:
@Autowired(required=false):表示忽略当前要注入的bean,如果有直接注入,没有跳过,不会报错。
@Autowired(required=true):当使用@Autowired注解的时候,其实默认就是@Autowired(required=true),表示注入的时候,该bean必须存在,否则就会注入失败。

在这里插入图片描述
在这里插入图片描述
加上后启动正常:
在这里插入图片描述

2.2.2 页面分析

步骤:
1).在商品详情页面点击 去购物车结算
在这里插入图片描述

2). 页面url分析
说明:当用户点击购物车结算按钮时,需要跳转到购物车展现页面。页面为cart.jsp
在这里插入图片描述
3).页面js分析:
页面:items="${cartList}" 域对象取值。

4).业务说明:
当用户点击购物车按钮时,应该根据userId查询购物车数据信息,之后在cart.jsp中展现列表信息.
要求: 只查询userId=7的购物车列表信息.之后进行页面展现。

解释:
为什么要用userId查询???
答:id为全国的购物车id,userid为用户的id,itemId为商品的id。执行中操作流程:用户先进入购物车,在购物车中根据用户自己的id查询购物车中的数据,所以是使用用户自己的id进行查询而不是全国购物车的id查询。
为什么userId先写死???
答:因为现在还没有做如何动态的获取userId的业务。
在这里插入图片描述
为什么单单要查userId =7这个用户的id号???

因为:数据库创建表时有一条userid=7的数据,所以=7可以查询成功.
在这里插入图片描述

2.2.3 创建CartController(web)

在这里插入图片描述

package com.jt.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.Cart;
import com.jt.service.DubboCartService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
@RequestMapping("/cart")
public class CartController {

    @Reference(check = false,timeout = 3000)//消费者启动时不会效验是否有提供者。
    private DubboCartService cartService;

    /**
     业务需求: 根据userId查询购物车数据
     * 1.购物车列表数据展现
     * url地址: http://www.jt.com/cart/show.html
     * 参数:    动态获取userId  暂时没有
     * 返回值:  页面逻辑名称  cart.jsp
     * 页面取值: ${cartList}
     * 应该将数据添加到域对象中 Request域  model工具API操作request对象
     *
     */
    @RequestMapping("/show") //伪静态拦截的是后缀跟这个路径没有关系
    public String show(Model model){
        //1.暂时将userId写死    7L
        // long userId=7在int范围内可以转(自动转换),现在是包装类型(基本类型和包装类型之间不能自动类型转换,必须是同为包装或者同为基本类型),转换通过自动装箱功能(要求类型相同比如:都是long类型,所以加L转换为long类型实现自动装箱)
        Long userId = 7l;
        //由页面取值看出查询的结果为list集合类型
        List<Cart> cartList = cartService.findCartListByUserId(userId);
        model.addAttribute("cartList",cartList);
        return "cart";


    }
}

2.2.4 编辑CartService(cart1)

在这里插入图片描述

package com.jt.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.CartMapper;
import com.jt.pojo.Cart;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@Service
public class DubboCartServiceImpl implements DubboCartService{
    @Autowired
    private CartMapper cartMapper;

    @Override
    public List<Cart> findCartListByUserId(Long userId) {
        QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
        //column代表的是数据库的字段属性 要在cart类上添加 
        queryWrapper.eq("user_id", userId);
        return cartMapper.selectList(queryWrapper);

        //return cartMapper.findCartListByUserId(userId); 普通方式写法


    }
}


2.2.5 普通方式编写mapper文件(cart1)

在这里插入图片描述

<?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.jt.mapper.CartMapper">
    <select id="findCartListByUserId" resultType="com.jt.pojo.Cart">
        SELECT * FROM tb_cart WHERE user_id=#{userId}
    </select>
</mapper>

鼠标复制接口 pojo的全称限定路径说明:
选择项目列表想要复制的po类上或接口上右键—Copy—Copy Reference
eg:com.jt.mapper.CartMapper
在这里插入图片描述

2.2.6 页面效果展现(启动cart1 manage web)

说名:因为现在没有动态获取id,所以显示不出来图片,可以在淘宝复制个图片地址出入数据库即可。
如何在SqlYog中修改表记录??
如下图
在这里插入图片描述

在这里插入图片描述

2.3 完成购物车数量修改操作

2.3.1 页面分析

业务说明:当用户点击数量修改时会把修改的数量传到后台,如果数量修改成功,则会在页面js调用修改价格的方法对价格进行修改。
解释:价格修改不需要在查询数据库了,因为查询页面时已经把价格显示到页面了,所以只需在页面js中进行计算,而sql只需要修改数量和update时间即可。
在这里插入图片描述

2.3.2 页面url分析

URL:http://www.jt.com/cart/update/num/562379/10
562379:商品id
10:修改的数量
在这里插入图片描述

2.3.3 页面JS分析

1).在购物车页面点击+ -号,由于添加了点击事件会发送请求。
在这里插入图片描述
2).根据页面js可以看出没有用到data,所以不需要返回值,直接刷新页面即可。
在这里插入图片描述

$(".increment").click(function(){//+
			//找到自己兄弟标签内的input标签
			var _thisInput = $(this).siblings("input");
			//对兄弟input标签的值进行+1 evel做算术计算加保险的,计算是值不是字符串  外面的val为赋值操作(因为原先有值)
			_thisInput.val(eval(_thisInput.val()) + 1);
			//之后发送请求(路径 商品id 数量)调用方法刷新总价,可以看出没有用到data,即不需要返回值
			$.post("/cart/update/num/"+_thisInput.attr("itemId")+"/"+_thisInput.val(),function(data){
				TTCart.refreshTotalPrice();
			});
		});

2.3.4 编辑CartController(web)

提示:
1.userid=7
2.由于页面没有对返回值进行校验,所以返回值为void.
3.更新数量的sql:update tb_cart set num=" xxx", update=“xxx” where user_id=“xxx” and item_id=“xxx”
解释:更新需要修改更新时间,先找到全国购物车中用户自己的购物车id,在找到用户需要修改的商品id。
4.MP形式
在这里插入图片描述

package com.jt.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.Cart;
import com.jt.service.DubboCartService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("/cart")
public class CartController {

    @Reference(check = false,timeout = 3000)//消费者启动时不会效验是否有提供者。
    private DubboCartService cartService;
    /**
     * 业务说明: 完成购物车数量的更新操作
     * url地址: http://www.jt.com/cart/update/num/562379/9
     * 参数: itemId/num
     * 返回值:  void
     */
    @RequestMapping("/update/num/{itemId}/{num}")
    @ResponseBody  //ajax结束的标识符.(虽然没有返回值但是请求时ajax发送的)
    public void updateCartNum(Cart cart){   //如果{name}即key 与po属性的名称一致,则可以自动的赋值.  controller规则

        Long userId = 7L;
        cart.setUserId(userId);
        cartService.updateCartNum(cart);
    }

   /* //常规获取参数:
    public void updateCartNum(@PathVariable Long itemId, @PathVariable Integer num){

        Long userId = 7L;
        Cart cart =new Cart();
        cartService.updateCartNum(userId,itemId,num);
    }
*/



   

2.3.5 编辑CartService(cart1)

说明:更新操作在接口中 添加事务管理
在这里插入图片描述
在这里插入图片描述

package com.jt.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.jt.mapper.CartMapper;
import com.jt.pojo.Cart;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@Service
public class DubboCartServiceImpl implements DubboCartService{
    @Autowired
    private CartMapper cartMapper;
    @Override
    public void updateCartNum(Cart cart) {

        cartMapper.updateCartNum(cart); //普通方式写sql更新

       /* //1.准备修改的数据  根据对象中不为null的元素当做set条件 Mp方式写更新
        Cart cartTemp = new Cart();
        cartTemp.setNum(cart.getNum());

        //2.根据对象中不为null的元素当做where条件
                UpdateWrapper<Cart> updateWrapper =
                new UpdateWrapper<>(cart.setNum(null));
        *//*updateWrapper.eq("user_id", cart.getUserId())
                     .eq("item_id", cart.getItemId());*//*
        cartMapper.update(cartTemp,updateWrapper);*/


    }
}

2.3.6 编辑CartMapper(sql方式更新)

在这里插入图片描述

package com.jt.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jt.pojo.Cart;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public interface CartMapper extends BaseMapper<Cart> {


    /**
     * 更新时间写法:
     * 写在代码中: cart.setUpdated(new Date());
     * 写在sql中: update=now()
     */
    @Update("update tb_cart set num=#{num}, updated=now() where user_id=#{userId} and  item_id=#{itemId}")
    void updateCartNum(Cart cart);
}


2.3.7 访问测试

点击数量进行修改,之后点击刷新发现数量已经发送变化,并且价格也随之改变。
在这里插入图片描述
在这里插入图片描述

2.4 购物车删除操作

2.4.1 页面分析

说明: 根据itemId和userId删除购物车数据.重定向到购物车列表页面即可.
在这里插入图片描述

2.4.2 页面url分析

在这里插入图片描述

2.4.3 页面js分析

通过a标签直接发送请求,返回值页面没用到,常规:增 删 改无返回值。
在这里插入图片描述

2.4.4 编辑CartController(web)

在这里插入图片描述

package com.jt.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.Cart;
import com.jt.service.DubboCartService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("/cart")
public class CartController {

    @Reference(check = false,timeout = 3000)//消费者启动时不会效验是否有提供者。
    private DubboCartService cartService;



    /**
     * 删除购物车数据 使用对象接收resful参数
     * url地址:http://www.jt.com/cart/delete/562379.html
     * 参数:   562379   获取itemId
     * 返回值:  重定向到购物车的展现页面
     */
    @RequestMapping("/delete/{itemId}")
    public String deleteCart(Cart cart){
        Long userId = 7L;
        cart.setUserId(userId);
        cartService.deleteCart(cart);
        return "redirect:/cart/show.html";
    }

//普通的方式接收参数:
    /**
     * 购物车删除操作
     * url地址: http://www.jt.com/cart/delete/562379.html
     * 参数:    获取itemId
     * 返回值:  重定向到购物车的展现页面
     */
   /* @RequestMapping("/delete/{itemId}")
    public String deleteCarts(@PathVariable Long itemId){

        Long userId = 7L;
        cartService.deleteCart(userId,itemId);
        return "redirect:/cart/show.html";
    }*/
}

2.4.5 编辑CartService(cart1)

注意添加事务控制
在这里插入图片描述

package com.jt.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.CartMapper;
import com.jt.pojo.Cart;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.List;

@Service
public class DubboCartServiceImpl implements DubboCartService{
    @Autowired
    private CartMapper cartMapper;

    @Override
    public void deleteCart(Cart cart) {  //itemId/userId
        /*//根据对象中不为null的元素充当where条件 mp第一种
        cartMapper.delete(new QueryWrapper<>(cart));*/

       /* QueryWrapper<Cart> queryWrapper = new QueryWrapper<>(); mp第二种
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("item_id", itemId);
        cartMapper.delete(queryWrapper);
*/
        //sql第三种
        cartMapper.deleteCart(cart);
    }
}    

2.4.6 编译CartMapper(cart1)

在这里插入图片描述

@Delete("delete from tb_cart where  user_id=#{userId} and  item_id=#{itemId}")
void deleteCart(Cart cart);

2.4.7 访问测试

在这里插入图片描述
在这里插入图片描述

2.5 购物车新增操作

2.5.1 需求说明

说明: 如果用户点击购入购物车时,应该将用户的提交数据插入到tb_cart表中,并且重定向到购物车列表页面.
注意事项: 如果用户重复提交数据,则应该数量更新.
在这里插入图片描述

2.5.2 页面url分析

url地址: http://www.jt.com/cart/add/562379.html
562379:商品id
.html:伪静态
在这里插入图片描述
参数分析:根据下面页面js和url的参数分析,可知页面提交的参数没有接收商品的id,而这个id拼接在了url的路径上。因为新增业务需要根据商品id进行修改,页面又没有接收这个参数,所以通过reful风格接收商品id,最终在控制层有2个参数:form表单提交的参数对象和商品id的参数。又因为商品id中在resful风格中的key和对象的属性名保持一致,所以可以直接用一个个对象来接受。
在这里插入图片描述

2.5.3 页面js分析

说明:全局搜索页面js的请求为 ctrl+h 单独搜索页面的关键字ctrl+f
步骤:
1).在商品详情页面点击加入购物车,页面显示结构为form表单的提交方式,但没有submit按钮,根据标签的点击事件提交参数。
在这里插入图片描述

</div><!--brand-bar-->
			<ul id="choose" clstag="shangpin|keycount|product|choose">
				<li id='choose-type'></li><script type="text/javascript"> var ColorSize = [{"SkuId":1221882,"Size":"","Color":""}];</script>
								<li id="choose-amount">
					<div class="dt">购买数量:</div>
					<div class="dd">
						<div class="wrap-input">
								<a class="btn-reduce" href="javascript:;" onclick="setAmount.reduce('#buy-num')">减少数量</a>
								<a class="btn-add" href="javascript:;" onclick="setAmount.add('#buy-num')">增加数量</a>
								<form id="cartForm" method="post">
									<input class="text" id="buy-num" name="num" value="1" onkeyup="setAmount.modify('#buy-num');"/>
									<input type="hidden" class="text"  name="itemTitle" value="${item.title }"/>
									<input type="hidden" class="text" name="itemImage" value="${item.images[0]}"/>
									<input type="hidden" class="text" name="itemPrice" value="${item.price}"/>
								</form>
						</div>
					</div>
				</li>
		        <li id="choose-result"><div class="dt"></div><div class="dd"></div></li>
				<li id="choose-btns">
					<div id="choose-btn-append"  class="btn">
							<a class="btn-append " id="InitCartUrl" onclick="addCart();" clstag="shangpin|keycount|product|initcarturl">加入购物车<b></b></a>
					</div>
					<div id="choose-btn-easybuy" class="btn"></div>
					<div id="choose-btn-divide" class="btn"></div>
				</li>
			</ul><!--choose end-->
			<span class="clr"></span>
		</div>

2).页面JS解析
因为此页面的数据参数为隐藏域,所以不能直接通过设置submit按钮提交.
在这里插入图片描述

<a class="btn-append " id="InitCartUrl" onclick="addCart();" clstag="shangpin|keycount|product|initcarturl">加入购物车<b></b></a>
//利用post传值  
		function addCart(){
			var url = "http://www.jt.com/cart/add/${item.id}.html";
			//js原生写法获取第一个表单.并添加属性action设置url
			document.forms[0].action = url;		//js设置提交链接
			document.forms[0].submit();			//js表单提交
		}

2.5.4 编辑CartController(web)

在这里插入图片描述

package com.jt.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.Cart;
import com.jt.service.DubboCartService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("/cart")
public class CartController {

    @Reference(check = false,timeout = 3000)//消费者启动时不会效验是否有提供者。
    private DubboCartService cartService;



    /**
     * 业务需求: 完成购物车入库操作
     * url地址: http://www.jt.com/cart/add/562379.html
     * 参数:    form表单提交的数据/itemId   对象接收
     * 返回值:  重定向到购物车列表页面
     */
    @RequestMapping("/add/{itemId}")
    public String addCart(Cart cart){//因为k和属性itemId保持一致 可以直接用对象来接收
        Long userId = 7L;
        cart.setUserId(userId);
        cartService.addCart(cart);
        //因为没有用到ajax所以重定向用 redirect :/cart/show  又因为页面跳转是伪静态的方式所以路径需要拼接.html
        return "redirect:/cart/show.html";
    }
 
}

2.5.5 编辑CartService(cart1)

注意添加事务控制
在这里插入图片描述

package com.jt.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.CartMapper;
import com.jt.pojo.Cart;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.List;

@Service
public class DubboCartServiceImpl implements DubboCartService{
    @Autowired
    private CartMapper cartMapper;

    /**
     * 思路:如果重复加购则更新数量,因为同一种商品的多条记录在页面改变的是数量,而不是多一条条数据。
     *     1.先查询数据库 user_id/item_id
     *     2.判断返回值是否有结果
     *          true:    只做数量的更新
     *          false:   直接入库即可
     *   总结:根据用户id和商品id判断数据库是否有数据,即使有也只能有一条数据(因为数据库存值cart对象 数量代表一条数据记录
     *   里面的数量属性,表示相同数据在数据库只有一条,多条只需要增减数量字段),如过没有直接入库 如果有则只需要更新数量即可。
     *
     */
    @Override
    public void addCart(Cart cart) {
        QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", cart.getUserId());
        queryWrapper.eq("item_id", cart.getItemId());
        Cart cartDB = cartMapper.selectOne(queryWrapper);
        if(cartDB == null){
            //用户第一次加购
            cartMapper.insert(cart);
        }else{
            //更新数量  普通方式
            int num = cart.getNum() + cartDB.getNum(); //数量求和=新增的数量+原来的数据路存的数量
            cartDB.setNum(num).setUpdated(new Date());//只用到更新num和时间
            cartMapper.updateCartNum(cartDB);//更新之前写过了直接调用
        }


    }
}

2.5.6 页面测试

原来20个,加5个变为25个数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值