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;
在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
- */
- }
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=?
在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);
- }
在resources.mapper文件夹下创建CartMapper.xml文件,并在文件中配置以上三个方法的映射
- "1.0" encoding="UTF-8" ?>
- 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>
-
-
- <select id="findByUidAndPid" resultMap="CartEntityMap">
- select * from t_cart where uid=#{uid} AND pid=#{pid}
- select>
- mapper>
创建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);
- }
- }
在插入数据时,可能抛出InsertException异常;在修改数据时,可能抛出UpdateException异常.这两个异常已开发
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 ICartServiceImpl implements ICartService {
- /*
- 由于购物车的业务依赖于购物车和商品的持久层,若通过session获取数据
- */
- @Autowired
- private CartMapper cartMapper;
- @Autowired
- private ProductMapper productMapper;
-
- @Override
- public void addToCart(Integer uid, Integer pid, Integer amount, String username) {
- //查询购物车是否已经存在【查看用户之前是否将该商品加入过购物车】
- Cart result = cartMapper.findByUidAndPid(uid, pid);
- Date date = new Date();
- if(result == null) {//新增商品
- Cart cart = new Cart();
- //封装数据:uid,pid,amount
- cart.setUid(uid);
- cart.setPid(pid);
- cart.setNum(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 {//更新num值
- //从查询结果中取出原数量,与参数amount相加,得到新的数量
- Integer num = result.getNum() + amount;//加入购物车时只会有+不可能有-
-
- Integer rows = cartMapper.updateNumByCid(result.getCid(), num, username, date);
-
- if(rows != 1) {
- throw new UpdateException("未知异常 在 更新数据");
- }
- }
- }
- }
创建测试类CartServiceTests并编写测试方法。
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class CartServiceTests {
- @Autowired
- private ICartService cartService;
-
- @Test
- public void addToCart() {
- cartService.addToCart(11, 10000002, 5, "Tom");
- }
- }
InsertException异常和UpdateException异常都已经设置到BaseController类中了,这里无需重复开发
- /carts/add_to_cart
- post
- Integer pid, Integer amount, HttpSession session
- JsonResult
在controller包下创建CartController类并继承BaseController类,在类中添加处理请求的addToCart()方法
- @RestController
- @RequestMapping("carts")
- public class CartController extends BaseController {
- @Autowired
- private ICartService cartService;
-
- @RequestMapping("add_to_cart")
- public JsonResult
addToCart(Integer pid, Integer amount, HttpSession session) { - cartService.addToCart(
- getUidFromSession(session),
- pid,
- amount,
- getUsernameFromSession(session));
- return new JsonResult
(OK); - }
- }
在product.html页面中的body标签内的script标签里为“加入购物车”按钮添加点击事件
回顾一下在ajax函数中data参数的数据设置的方式
- var user = "控件某属性值或控件文本内容或自己声明的值"
- data: "username="+user
- 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文件里面实现了点击后跳转