• SpringBoot项目--电脑商城【加入购物车】


    1.创建数据表

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

    USE store;
    

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

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

    2.创建购物车的实体类

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

    1. /**购物车数据的实体类*/
    2. public class Cart extends BaseEntity {
    3. private Integer cid;
    4. private Integer uid;
    5. private Integer pid;
    6. private Long price;
    7. private Integer num;
    8. /**
    9. * get,set
    10. * equals和hashCode
    11. * toString
    12. */
    13. }

    3.持久层[Mapper]

    规划需要执行的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=?
    

    2设计接口和抽象方法

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

    1. public interface CartMapper {
    2. /**
    3. * 插入购物车数据
    4. * @param cart 购物车数据
    5. * @return 受影响的行数
    6. */
    7. Integer insert(Cart cart);
    8. /**
    9. * 修改购物车数据中商品的数量
    10. * @param cid 购物车数据的id
    11. * @param num 新的数量
    12. * @param modifiedUser 修改执行人
    13. * @param modifiedTime 修改时间
    14. * @return 受影响的行数
    15. */
    16. Integer updateNumByCid(
    17. @Param("cid") Integer cid,
    18. @Param("num") Integer num,
    19. @Param("modifiedUser") String modifiedUser,
    20. @Param("modifiedTime") Date modifiedTime);
    21. /**
    22. * 根据用户id和商品id查询购物车中的数据
    23. * @param uid 用户id
    24. * @param pid 商品id
    25. * @return 匹配的购物车数据,如果该用户的购物车中并没有该商品,则返回null
    26. */
    27. Cart findByUidAndPid(
    28. @Param("uid") Integer uid,
    29. @Param("pid") Integer pid);
    30. }

    3编写映射

    在resources.mapper文件夹下创建CartMapper.xml文件,并在文件中配置以上三个方法的映射

    1. "1.0" encoding="UTF-8" ?>
    2. mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="com.cy.store.mapper.CartMapper">
    6. <resultMap id="CartEntityMap" type="com.cy.store.entity.Cart">
    7. <id column="cid" property="cid"/>
    8. <result column="created_user" property="createdUser"/>
    9. <result column="created_time" property="createdTime"/>
    10. <result column="modified_user" property="modifiedUser"/>
    11. <result column="modified_time" property="modifiedTime"/>
    12. resultMap>
    13. <insert id="insert" useGeneratedKeys="true" keyProperty="cid">
    14. insert into t_cart (uid, pid, price, num, created_user, created_time, modified_user, modified_time)
    15. values (#{uid}, #{pid}, #{price}, #{num}, #{createdUser}, #{createdTime}, #{modifiedUser}, #{modifiedTime})
    16. insert>
    17. <update id="updateNumByCid">
    18. update t_cart set
    19. num=#{num},
    20. modified_user=#{modifiedUser},
    21. modified_time=#{modifiedTime}
    22. where cid=#{cid}
    23. update>
    24. <select id="findByUidAndPid" resultMap="CartEntityMap">
    25. select * from t_cart where uid=#{uid} AND pid=#{pid}
    26. select>
    27. mapper>

    4单元测试

    创建CartMapperTests测试类进行测试

    1. @RunWith(SpringRunner.class)
    2. @SpringBootTest
    3. public class CartMapperTests {
    4. @Autowired
    5. private CartMapper cartMapper;
    6. @Test
    7. public void insert() {
    8. Cart cart = new Cart();
    9. cart.setUid(11);
    10. cart.setPid(10000001);
    11. cart.setNum(3);
    12. cart.setPrice(4L);//长整型
    13. cartMapper.insert(cart);
    14. }
    15. @Test
    16. public void updateNumByCid() {
    17. cartMapper.updateNumByCid(1, 4, "张三", new Date());
    18. }
    19. @Test
    20. public void findByUidAndPid() {
    21. Cart cart = cartMapper.findByUidAndPid(11, 10000001);
    22. System.out.println(cart);
    23. }
    24. }

    4.业务层[Service]

    1规划异常

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

    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对象)

    1. public interface ICartService {
    2. /**
    3. * 将商品添加到购物车
    4. * @param uid 当前登录用户的id
    5. * @param pid 商品的id
    6. * @param amount 增加的数量
    7. * @param username 当前登录的用户名
    8. */
    9. void addToCart(Integer uid, Integer pid, Integer amount, String username);
    10. }

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

    1. @Service
    2. public class ICartServiceImpl implements ICartService {
    3. /*
    4. 由于购物车的业务依赖于购物车和商品的持久层,若通过session获取数据
    5. */
    6. @Autowired
    7. private CartMapper cartMapper;
    8. @Autowired
    9. private ProductMapper productMapper;
    10. @Override
    11. public void addToCart(Integer uid, Integer pid, Integer amount, String username) {
    12. //查询购物车是否已经存在【查看用户之前是否将该商品加入过购物车】
    13. Cart result = cartMapper.findByUidAndPid(uid, pid);
    14. Date date = new Date();
    15. if(result == null) {//新增商品
    16. Cart cart = new Cart();
    17. //封装数据:uid,pid,amount
    18. cart.setUid(uid);
    19. cart.setPid(pid);
    20. cart.setNum(amount);
    21. //查询商品数据,得到商品价格进行封装
    22. Product product = productMapper.findById(pid);
    23. cart.setPrice(product.getPrice());
    24. //封装数据:4个日志
    25. cart.setCreatedUser(username);
    26. cart.setCreatedTime(date);
    27. cart.setModifiedUser(username);
    28. cart.setModifiedTime(date);
    29. Integer rows = cartMapper.insert(cart);
    30. if(rows != 1) {
    31. throw new InsertException("未知异常 在 插入数据");
    32. }
    33. } else {//更新num值
    34. //从查询结果中取出原数量,与参数amount相加,得到新的数量
    35. Integer num = result.getNum() + amount;//加入购物车时只会有+不可能有-
    36. Integer rows = cartMapper.updateNumByCid(result.getCid(), num, username, date);
    37. if(rows != 1) {
    38. throw new UpdateException("未知异常 在 更新数据");
    39. }
    40. }
    41. }
    42. }

    3单元测试

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

    1. @RunWith(SpringRunner.class)
    2. @SpringBootTest
    3. public class CartServiceTests {
    4. @Autowired
    5. private ICartService cartService;
    6. @Test
    7. public void addToCart() {
    8. cartService.addToCart(11, 10000002, 5, "Tom");
    9. }
    10. }

    5.控制层[Contrroller]

    1处理异常

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

    2设计请求

    • /carts/add_to_cart
    • post
    • Integer pid, Integer amount, HttpSession session
    • JsonResult

    3处理请求

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

    1. @RestController
    2. @RequestMapping("carts")
    3. public class CartController extends BaseController {
    4. @Autowired
    5. private ICartService cartService;
    6. @RequestMapping("add_to_cart")
    7. public JsonResult addToCart(Integer pid, Integer amount, HttpSession session) {
    8. cartService.addToCart(
    9. getUidFromSession(session),
    10. pid,
    11. amount,
    12. getUsernameFromSession(session));
    13. return new JsonResult(OK);
    14. }
    15. }

    6.前端页面

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

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

    • data:$(“选择的form表单”).serialize()。当需要提交的参数过多并且在同一个表单中时使用
    • data:new FormData($(“选择的form表单”)[0])。只适用提交文件
    • data:“username=TOM”。手动拼接,适合参数值固定并且参数值列表有限.等同于
    1. var user = "控件某属性值或控件文本内容或自己声明的值"
    2. data: "username="+user
    • 使用JSON格式提交数据
    1. data: {
    2. "username": "Tom",
    3. "age": 18
    4. }
    • 使用RestFul风格不属于前端给后端传参数

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

    1. $("#btn-add-to-cart").click(function() {
    2. $.ajax({
    3. url: "/carts/add_to_cart",
    4. type: "POST",
    5. data: {
    6. "pid": id,
    7. "amount": $("#num").val()
    8. },
    9. dataType: "JSON",
    10. success: function(json) {
    11. if (json.state == 200) {
    12. alert("增加成功!");
    13. } else {
    14. alert("增加失败!" + json.message);
    15. }
    16. },
    17. error: function(xhr) {
    18. alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status);
    19. location.href = "login.html";
    20. }
    21. });
    22. });

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

  • 相关阅读:
    基础练习 圆的面积
    手动开平方数(结果为整数)-2022
    【深入理解设计模式】外观设计模式
    计算机毕业设计 基于微信小程序的校园商铺系统的设计与实现 Java实战项目 附源码+文档+视频讲解
    顶级架构师编写,《DDD领域驱动设计笔记》,看到内容后才明白啥叫顶级,一分钱一分货
    【快速解决】实验四 对话框 《Android程序设计》实验报告
    存储模块 --- Cache
    Sklearn基础教程
    linux 开发板以太网通过Ubuntu上外网方法
    我的创作纪念日-成为CSDN创作者的 第4096天
  • 原文地址:https://blog.csdn.net/m0_63077733/article/details/132819473