10天手敲一个SpringBoot网上商城项目(七)——显示商品详情功能及加入购物车功能的实现

静态资源及sql文件分享
链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr
提取码:23gr

显示商品详情

1.显示商品详情-持久层

1.1规划需要执行的SQL语句

根据商品id显示商品详情的SQL语句

SELECT * FROM t_product WHERE id=?
1.2设计接口和抽象方法

在ProductMapper接口中添加抽象方法

/**
 * 根据商品id查询商品详情
 * @param id 商品id
 * @return 匹配的商品详情,如果没有匹配的数据则返回null
 */
Product findById(Integer id);
1.3编写映射

在ProductMapper.xml文件中配置findById(Integer id)方法的映射

<select id="findById" resultMap="ProductEntityMap">
    select * from t_product where id=#{id}
</select>

2.显示商品详情-业务层

2.1规划异常

如果商品数据不存在,应该抛出ProductNotFoundException,所以创建ProductNotFoundException异常类并使其继承ServiceException

/** 商品数据不存在的异常 */
public class ProductNotFoundException extends ServiceException {
    /**重写ServiceException的所有构造方法*/
}
2.2设计接口和抽象方法及实现

1.在业务层IProductService接口中添加findById(Integer id)抽象方法

/**
 * 根据商品id查询商品详情
 * @param id 商品id
 * @return 匹配的商品详情,如果没有匹配的数据则返回null
 */
Product findById(Integer id);

2.在ProductServiceImpl类中,实现接口中的findById(Integer id)抽象方法

@Override
public Product findById(Integer id) {
    Product product = productMapper.findById(id);
    // 判断查询结果是否为null
    if (product == null) {
        throw new ProductNotFoundException("尝试访问的商品数据不存在");
    }
    // 将查询结果中的部分属性设置为null
    product.setPriority(null);
    product.setCreatedUser(null);
    product.setCreatedTime(null);
    product.setModifiedUser(null);
    product.setModifiedTime(null);

    return product;
}

3.显示商品详情-控制层

3.1处理异常

在BaseController类中的handleException()方法中添加处理ProductNotFoundException的异常

else if (e instanceof ProductNotFoundException) {
	result.setState(4006);
    result.setMessage("访问的商品数据不存在的异常");
}
3.2 设计请求
  • /products/{id}/details
  • Integer id
  • GET
  • JsonResult<Product>
3.3处理请求

在ProductController类中添加处理请求的getById()方法

@GetMapping("{id}/details")
public JsonResult<Product> getById(@PathVariable("id") Integer id) {
    Product data = productService.findById(id);
    return new JsonResult<Product>(OK, data);
}

4.显示商品详情-前端页面

1.首页将商品id发送给详情页后,详情页需要从url中裁取获得该id,实现方法在jquery-getUrlParam.js中(目前怎么实现裁取可以先不学),所以需要在product.html页面中导入该js文件,这里我在body标签内部的最后引入该js文件

<script type="text/javascript" src="../js/jquery-getUrlParam.js"></script>

2.在product.html页面中body标签内部的最后添加获取当前商品详情的代码

<script type="text/javascript">
            //调用jquery-getUrlParam.js文件的getUrlParam方法获取商品id
            var id = $.getUrlParam("id");
            console.log("id=" + id);
            $(document).ready(function() {
                $.ajax({
                    url: "/products/" + id + "/details",
                    type: "GET",
                    dataType: "JSON",
                    success: function(json) {
                        if (json.state == 200) {
                            console.log("title=" + json.data.title);
                            //html()方法:
                            // 假设有个标签<div id="a"></div>
                            //那么$("#a").html(<p></p>)就是给该div标签加p标签
                            //$("#a").html("我爱中国")就是给该div标签填充"我爱中国"内容
                            $("#product-title").html(json.data.title);
                            $("#product-sell-point").html(json.data.sellPoint);
                            $("#product-price").html(json.data.price);

                            for (var i = 1; i <= 5; i++) {
                                $("#product-image-" + i + "-big").attr("src", ".." + json.data.image + i + "_big.png");
                                $("#product-image-" + i).attr("src", ".." + json.data.image + i + ".jpg");
                            }
                        } else if (json.state == 4006) { // 商品数据不存在的异常
                            location.href = "index.html";
                        } else {
                            alert("获取商品信息失败!" + json.message);
                        }
                    }
                });
            });
        </script>

加入购物车

1.创建数据表

1.使用use命令先选中store数据库

USE store;

2.在store数据库中创建t_cart用户数据表

CREATE TABLE t_cart (
	cid INT AUTO_INCREMENT COMMENT '购物车数据id',
	uid INT NOT NULL COMMENT '用户id',
	pid INT NOT NULL COMMENT '商品id',
	price BIGINT COMMENT '加入时商品单价',
	num INT COMMENT '商品数量',
	created_user VARCHAR(20) COMMENT '创建人',
	created_time DATETIME COMMENT '创建时间',
	modified_user VARCHAR(20) COMMENT '修改人',
	modified_time DATETIME COMMENT '修改时间',
	PRIMARY KEY (cid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.创建购物车的实体类

在entity包下创建购物车的Cart实体类并使其继承BaseEntity

/**购物车数据的实体类*/
public class Cart extends BaseEntity {
    private Integer cid;
    private Integer uid;
    private Integer pid;
    private Long price;
    private Integer num;
/**
 * get,set
 * equals和hashCode
 * toString
 */
}

3.加入购物车-持久层

3.1规划需要执行的SQL语句

1.向购物车表中插入商品数据的SQL语句

insert into t_cart (除了cid以外的所有字段) values (匹配的值列表);

2.如果当前商品已经在购物车存在,则直接更新商品即可

update t_cart set num=? where cid=?

3.在插入或者更新具体执行哪个语句,取决于数据库中是否有当前的这个购物车商品的数据,需要查询语句才能确定

select * from t_cart where uid=? and pid=?
3.2设计接口和抽象方法

在mapper包下创建CartMapper接口,并添加抽象方法

public interface CartMapper {
    
    /**
     * 插入购物车数据
     * @param cart 购物车数据
     * @return 受影响的行数
     */
    Integer insert(Cart cart);

    /**
     * 修改购物车数据中商品的数量
     * @param cid 购物车数据的id
     * @param num 新的数量
     * @param modifiedUser 修改执行人
     * @param modifiedTime 修改时间
     * @return 受影响的行数
     */
    Integer updateNumByCid(
            @Param("cid") Integer cid,
            @Param("num") Integer num,
            @Param("modifiedUser") String modifiedUser,
            @Param("modifiedTime") Date modifiedTime);

    /**
     * 根据用户id和商品id查询购物车中的数据
     * @param uid 用户id
     * @param pid 商品id
     * @return 匹配的购物车数据,如果该用户的购物车中并没有该商品,则返回null
     */
    Cart findByUidAndPid(
            @Param("uid") Integer uid,
            @Param("pid") Integer pid);
}
3.3编写映射

在resources.mapper文件夹下创建CartMapper.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.cy.store.mapper.CartMapper">
    <resultMap id="CartEntityMap" type="com.cy.store.entity.Cart">
        <id column="cid" property="cid"/>
        <result column="created_user" property="createdUser"/>
        <result column="created_time" property="createdTime"/>
        <result column="modified_user" property="modifiedUser"/>
        <result column="modified_time" property="modifiedTime"/>
    </resultMap>

    <!-- 插入购物车数据-->
    <insert id="insert" useGeneratedKeys="true" keyProperty="cid">
        insert into t_cart (uid, pid, price, num, created_user, created_time, modified_user, modified_time)
        values (#{uid}, #{pid}, #{price}, #{num}, #{createdUser}, #{createdTime}, #{modifiedUser}, #{modifiedTime})
    </insert>

    <!-- 修改购物车数据中商品的数量-->
    <update id="updateNumByCid">
        update t_cart set
            num=#{num},
            modified_user=#{modifiedUser},
            modified_time=#{modifiedTime}
        where cid=#{cid}
    </update>

    <!-- 根据用户id和商品id查询购物车中的数据-->
    <select id="findByUidAndPid" resultMap="CartEntityMap">
        select * from t_cart where uid=#{uid} AND pid=#{pid}
    </select>
</mapper>
3.4单元测试

创建CartMapperTests测试类进行测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class CartMapperTests {
    @Autowired
    private CartMapper cartMapper;

    @Test
    public void insert() {
        Cart cart = new Cart();
        cart.setUid(11);
        cart.setPid(10000001);
        cart.setNum(3);
        cart.setPrice(4L);//长整型
        cartMapper.insert(cart);
    }

    @Test
    public void updateNumByCid() {
        cartMapper.updateNumByCid(1, 4, "张三", new Date());
    }

    @Test
    public void findByUidAndPid() {
        Cart cart = cartMapper.findByUidAndPid(11, 10000001);
        System.out.println(cart);
    }
}

4.加入购物车-业务层

4.1规划异常

在插入数据时,可能抛出InsertException异常;在修改数据时,可能抛出UpdateException异常.这两个异常已开发

4.2设计接口和抽象方法及实现

1.在com.cy.store.service包下创建ICartService接口,并添加抽象方法

该抽象方法都需要哪些参数呢,还是依据持久层,看持久层三条sql语句的实现需要什么参数:

findByUidAndPid:查询购物车数据,参数是uid,pid

insert:插入购物车数据,参数是cart对象(属性有cid,uid,pid,price,num)

updateNumByCid:修改购物车中商品数量,参数是cid,num,modifiedUser,modifiedTime

price可以通过业务层中调用ProductMapper接口的findById获取,modifiedTime在业务层实现类的内部创建,所以需要的参数是uid,pid,num,username

经过这次分析结合以前给业务层方法声明参数,可以发现即使持久层的方法参数是实体类对象,业务层的方法参数也大多不是实体类对象,因为实体类的部分属性是可以在业务层进行拼接然后封装到实体类对象中,再传给持久层(比如这里的price),这样的话就降低了前端传递数据的压力,如果该对象的所有方法都必须由前端传递过来,那么业务层方法参数可以是实体类对象(如注册用户时业务层的方法参数就是User对象)

public interface ICartService {
    /**
     * 将商品添加到购物车
     * @param uid 当前登录用户的id
     * @param pid 商品的id
     * @param amount 增加的数量
     * @param username 当前登录的用户名
     */
    void addToCart(Integer uid, Integer pid, Integer amount, String username);
}

2.创建CartServiceImpl类,并实现ICartService接口.在类中声明CartMapper持久层对象和IProductService处理商品数据的业务对象,并实现业务层的抽象方法

@Service
public class CartServiceImpl implements ICartService {
    /**购物车的业务层依赖于购物车的持久层以及商品的持久层*/
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private ProductMapper productMapper;

    @Override
    public void addToCart(Integer uid, Integer pid, Integer amount, String username) {

        //根据参数pid和uid查询购物车中该商品是否已经存在
        Cart result = cartMapper.findByUidAndPid(uid, pid);

        Integer cid = result.getCid();
        Date date = new Date();
        if (result == null) {
            Cart cart = new Cart();

            //封装数据:uid,pid,amount
            cart.setUid(uid);
            cart.setPid(pid);
            cart.setNum(amount);//注意前端传来amount时并没有和数据库商品数量进行求和

            //查询商品数据,得到商品价格并封装
            Product product = productMapper.findById(pid);
            cart.setPrice(product.getPrice());

            //封装数据:4个日志
            cart.setCreatedUser(username);
            cart.setCreatedTime(date);
            cart.setModifiedUser(username);
            cart.setModifiedTime(date);

            Integer rows = cartMapper.insert(cart);
            if (rows != 1) {
                throw new InsertException("插入数据时出现未知异常");
            }
        } else {
            //从查询结果中取出原数量,与参数amount相加,得到新的数量
            Integer num = result.getNum() + amount;//加入购物车时只会有+不可能有-

            Integer rows = cartMapper.updateNumByCid(
                result.getCid(),
                num,
                username,
                date);
            if (rows != 1) {
                throw new InsertException("更新数据时产生未知异常");
            }
        }
    }
}
4.3单元测试

创建测试类CartServiceTests并编写测试方法。

@RunWith(SpringRunner.class)
@SpringBootTest
public class CartServiceTests {
    @Autowired
    private ICartService cartService;

    @Test
    public void addToCart() {
        cartService.addToCart(11, 10000002, 5, "Tom");
    }
}

5.加入购物车-控制层

5.1处理异常

InsertException异常和UpdateException异常都已经设置到BaseController类中了,这里无需重复开发

5.2设计请求
  • /carts/add_to_cart
  • post
  • Integer pid, Integer amount, HttpSession session
  • JsonResult<Void>
5.3处理请求

在controller包下创建CartController类并继承BaseController类,在类中添加处理请求的addToCart()方法

@RestController
@RequestMapping("carts")
public class CartController extends BaseController {
    @Autowired
    private ICartService cartService;

    @RequestMapping("add_to_cart")
    public JsonResult<Void> addToCart(Integer pid, Integer amount, HttpSession session) {
        cartService.addToCart(
                getUidFromSession(session),
                pid,
                amount,
                getUsernameFromSession(session));
        return new JsonResult<Void>(OK);
    }
}

启动服务,登录账号后在地址栏输入http://localhost:8080/carts/add_to_cart?pid=10000002&amount=5进行测试

6.加入购物车-前端页面

在product.html页面中的body标签内的script标签里为“加入购物车”按钮添加点击事件

回顾一下在ajax函数中data参数的数据设置的方式

  • data:$(“选择的form表单”).serialize()。当需要提交的参数过多并且在同一个表单中时使用

  • data:new FormData($(“选择的form表单”)[0])。只适用提交文件

  • data:“username=TOM”。手动拼接,适合参数值固定并且参数值列表有限.等同于

    var user = "控件某属性值或控件文本内容或自己声明的值"
    data: "username="+user
    
  • 使用JSON格式提交数据

    data: {
        "username": "Tom",
        "age": 18
    }
    
  • 使用RestFul风格不属于前端给后端传参数

这里表单里面有很多无用参数,所以不使用表单提交

$("#btn-add-to-cart").click(function() {
    $.ajax({
        url: "/carts/add_to_cart",
        type: "POST",
        data: {
            "pid": id,
            "amount": $("#num").val()
        },
        dataType: "JSON",
        success: function(json) {
            if (json.state == 200) {
                alert("增加成功!");
            } else {
                alert("增加失败!" + json.message);
            }
        },
        error: function(xhr) {
            alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status);
            location.href = "login.html";
        }
    });
});

点击"加入购物车"按钮后页面跳转的实现:product.html导入的product.js文件里面实现了点击后跳转

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
SpringBoot项目基于springboot框架的网上商城系统的设计与实现一个使用Spring Boot技术开发的电子商务平台。该网上商城系统提供了一套完整的电商解决方案,包括商品展示、购物车、订单管理、支付处理以及后台管理等功能。 以下是对网上商城系统的核心功能介绍: 1. **商品管理**:系统允许商家方便地上架、编辑和下架商品,同时支持丰富的商品属性设置,如价格、库存、分类等。 2. **用户账户**:顾客可以注册个人账户,享受个性化的购物体验,包括订单跟踪、喜好记录和历史浏览。 3. **购物车与结算流程**:用户可将商品添加至购物车,并在准备就绪后进入简洁明了的结算流程。 4. **支付接口集成**:系统集成了多种支付方式,包括但不限于信用卡、支付宝、微信支付等,确保交易的便捷性与安全性。 5. **订单管理系统**:商家可以通过后台管理系统查看和处理客户订单,实现订单的自动化管理。 6. **搜索与推荐机制**:提供高效的商品搜索引擎,并根据用户的购买历史和浏览习惯智能推荐商品。 7. **移动端优化**:采用响应式设计或提供专门的移动应用,确保在不同设备上都能提供一致的用户体验。 8. **安全性与隐私保护**:实施必要的安全措施来保护用户的个人信息和交易数据的安全。 9. **促销与营销工具**:内置促销模块支持优惠券、打折、限时活动等多种营销策略。 10. **数据分析与报告**:后台提供销售数据统计和分析功能,帮助商家了解业务状况并做出决策。 通过这些功能,基于Spring Boot网上商城系统不仅提高了商品销售的便利性和效率,还为商家提供了强大的数据分析工具来优化营销策略和提升顾客满意度。系统的架构设计注重性能、可用性和可维护性,以支持高并发的用户访问和动态的数据更新。其模块化的设计也便于未来根据电子商务需求或技术进步增加新功能或升级现有功能,确保软件的长期适用性和技术前瞻性。
首先,你需要在你的 MySQL 数据库中创建一个会员购物车表,用于存储会员购物车中的商品信息。 接下来,你需要在 Spring Boot 中创建一个控制器类,用于处理清空某一个会员购物车的请求。例如: ```java @Controller public class CartController { @Autowired private CartService cartService; @GetMapping("/cart/{memberId}/clear") public String clearCart(@PathVariable("memberId") Long memberId) { cartService.clearCart(memberId); return "redirect:/cart"; } } ``` 在上面的代码中,`CartService` 是一个服务类,用于处理购物车相关的业务逻辑。`clearCart` 方法接收一个会员 ID,通过调用 `cartService.clearCart` 方法清空该会员的购物车,并重定向到购物车页面。 接下来,让我们来实现 `CartService` 类。首先,你需要在 `CartService` 类中注入一个 `CartRepository`,用于访问会员购物车表中的数据。例如: ```java @Service public class CartService { @Autowired private CartRepository cartRepository; public void clearCart(Long memberId) { cartRepository.deleteByMemberId(memberId); } } ``` 在上面的代码中,`deleteByMemberId` 方法通过会员 ID 删除该会员购物车中的所有商品信息。 最后,你需要在 `CartRepository` 接口中定义一个 `deleteByMemberId` 方法,用于执行删除操作。例如: ```java public interface CartRepository extends JpaRepository<Cart, Long> { void deleteByMemberId(Long memberId); } ``` 在上面的代码中,`Cart` 是一个实体类,用于映射会员购物车表中的数据。 现在,你已经完成了清空某一个会员购物车的功能。当用户访问 `/cart/{memberId}/clear` URL 时,会员购物车中的所有商品信息将被清空。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

认真生活的灰太狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值