商城项目(下)

32.主页-热销排行-持久层

“热销排行”将显示所有分类中销量最高的4条数据,由于目前没有销量数据,可以将规则调整为“优先级最高的4条数据”。

所以,在查询时,执行的SQL语句应该是:

SELECT 
	id, title, price, image 
FROM 
	t_goods 
WHERE 
	status=1 AND num>0
ORDER BY 
	priority DESC
LIMIT 0, 4

则在持久层接口中添加抽象方法:

List<Goods> findByPriority(Integer count);

33.主页-热销排行-业务层

将持久层的抽象方法复制到业务层接口中,并修改方法名称,在业务层实现类中,通过私有方法调用持久层,然后,接口中的公有方法通过调用私有方法实现功能。

34.主页-热销排行-控制器层

在控制器类中添加处理请求的方法

@GetMapping("/hot")
public ResponseResult<List<Goods>> getHotGoods() {
	List<Goods> list
		= goodsService.getByPriority(4);
	return new ResponseResult<List<Goods>>(SUCCESS, list);
}

35.购物车-加入购物车-持久层

1. 数据表

CREATE TABLE t_cart (
	id INT AUTO_INCREMENT,
	uid INT NOT NULL COMMENT '用户id',
	gid BIGINT NOT NULL COMMENT '商品id',
	price BIGINT(20) NOT NULL COMMENT '商品价格',
	count INT NOT NULL COMMENT '商品数量',
	created_user VARCHAR(50),
	created_time DATETIME,
	modified_user VARCHAR(50),
	modified_time DATETIME,
	PRIMARY KEY (id)
);

2. 实体类

3. 设计SQL语句

加入购物车的操作有2种情况:此前没有该商品;购物车中已有该商品。前者,应该执行INSERT操作,后者,应该执行UPDATE操作。

至于执行哪种操作,应该先判断“购物车中是否已经存在该商品的信息”:

SELECT 
	id, count
FROM 
	t_cart
WHERE
	gid=? AND uid=?

新加入此前未加入的商品时:

INSERT INTO t_cart (
	除了id以外的所有字段
) VALUES (
	值列表
)

如果加入购物车的商品是在购物车中已存在的,应该只更新数量:

UPDATE 
	t_cart
SET 
	'count'=?
WHERE
	id=?

4. 接口与抽象方法

Cart findByUidAndGid(
	@Param("uid") Integer uid, 
	@Param("goodsId") Long goodsId);

Integer addnew(Cart cart);

Integer updateCount(
	@Param("id") Integer id, 
	@Param("count") Integer count);

5. XML映射

<!-- 新增购物车数据 -->
<!-- Integer addnew(Cart cart) -->
<insert id="addnew"
	useGeneratedKeys="true"
	keyProperty="id">
	INSERT INTO t_cart (
		uid, gid,
		price, count,
		created_user, created_time,
		modified_user, modified_time
	) VALUES (
		#{uid}, #{gid},
		#{price}, #{count},
		#{createdUser}, #{createdTime},
		#{modifiedUser}, #{modifiedTime}
	)
</insert>

<!-- 更新购物车中商品的数量 -->
<!-- Integer updateCount(
	@Param("id") Integer id, 
	@Param("count") Integer count) -->
<update id="updateCount">
	UPDATE 
		t_cart
	SET 
		count=#{count}
	WHERE 
		id=#{id}
</update>

<!-- 根据用户id和商品id查询购物车数据 -->
<!-- Cart findByUidAndGid(
	@Param("uid") Integer uid, 
	@Param("goodsId") Long goodsId) -->
<select id="findByUidAndGid"
	resultType="cn.tedu.store.entity.Cart">
	SELECT 
		id, count
	FROM 
		t_cart
	WHERE 
		uid=#{uid} AND gid=#{goodsId}
</select>

分析业务

void addToCart(Cart cart) 
	throws InsertException, UpdateException;

public void addToCart(Cart cart) {
	// 1. 查询:findByUidAndGid(uid, gid)
	// 2. 新增:addnew(cart)
	// 3. 更新:updateCount(id, count)
	// -------------------------------
	// 根据参数cart中的uid和gid查询数据
	// 判断查询结果是否为null
	// 是:该用户尚未在购物车中添加该商品,则执行新增
	// 否:该用户已经在购物车中添加该商品,则取出此前查询到的数据中的id和count
	// -- 根据上一步取出的count与参数cart中的count(此次用户提交的count),相加得到新的count
	// -- 执行更新
}

36.购物车-加入购物车-控制器层

1. 处理新异常

2. 设计请求

请求路径:/cart/add
请求参数:HttpSession, Cart
请求类型:POST
响应数据:ResponseResult<Void>
是否拦截:拦截,在拦截器黑名单中添加 /cart/**

3. 处理请求

先创建cn.tedu.store.controller.CartController类,继承自BaseController,添加@RestController@RequestMapping("/cart")注解,添加@Autowired private ICartService cartService;属性。

然后,添加处理请求的方法:

@GetMapping("/add")
public ResponseResult<Void> addToCart(HttpSession session, Cart cart) {
	// 从session中获取username
	// 从session中获取uid
	// 将uid封装到cart中
	// 执行业务方法
	// 返回
}

完成后,通过http://localhost:8080/cart/add?gid=998&price=1024&count=6进行测试,测试无误,则将请求修改为@PostMapping

37.购物车-显示列表-持久层

显示列表时,单查t_cart表无法查询到足够显示的数据,需要联合t_goods表一起查询:

SELECT 
	t_cart.id, 
	uid, gid, 
	t_cart.price AS oldPrice, count, 
	t_goods.price AS newPrice,
	title, image
FROM 
	t_cart 
INNER JOIN
	t_goods
ON
	t_cart.gid = t_goods.id
WHERE 
	uid=?
ORDER BY 
	id DESC

以上查询结果是没有匹配的实体类的!则需要创建与以上查询结果匹配的VO类cn.tedu.store.vo.CartVO

public class CartVO {
	private Integer id;
	private Integer uid;
	private Long gid;
	private String title;
	private String image;
	private Integer count;
	private Long oldPrice;
	private Long newPrice;
	// SET/GET,Serializable
}

所以,在接口中的抽象方法应该是:

List<CartVO> findByUid(Integer uid);

配置映射时:

resultType="cn.tedu.store.vo.CartVO"

38.购物车-显示列表-业务层

在业务层接口中添加新的抽象方法:

List<CartVO> getByUid(Integer uid);

在实现类中,先添加与持久层方法一致的私有方法,然后实现接口中定义的公有方法。

39.购物车-显示列表-控制器层

设计请求

请求路径:/cart/list
请求类型:GET / POST
请求参数:HttpSession
响应数据:ResponseResult<List<CartVO>>
是否拦截:是,但无需修改配置

处理请求

@RequestMapping("/list")
public ResponseResult<List<CartVO>> getByUid(HttpSession session) {
	// 获取uid
	// 查询
	// 返回
}

40.购物车-增加数量-持久层

增加数量可以通过现有的updateCount(id, count)方法来实现,主要过程应该是:根据id找出数据,将原有的数量取出,增加1,然后更新数据表。

则需要新增:

SELECT uid, count FROM t_cart WHERE id=?

对应的方法可以是:

Cart findById(Integer id);

41.购物车-增加数量-业务层

抽象方法:

void addCount(Integer id, Integer uid)
	throws CartNotFoundException, 
		AccessDeniedException,
			UpdateException;

实现:

public void addCount(Integer id, Integer uid) {
	// 根据id查询数据
	// 判断数据是否为null
	// 是:抛出异常:CartNotFoundException

	// 判断数据归属是否不匹配
	// 是:抛出异常:AccessDeniedException

	// 获取原来的数量
	// 将数量+1
	// 更新购物车数据中的数量:updateCount(id, count)
}

42.购物车-增加数量-控制器

@GetMapping("/add_count")
public ResponseResult<Void> addCount(
	@RequestParam("id") Integer id,
	HttpSession session) {

}

43.确认订单-显示确认页-持久层

在显示“确认订单”页面时,主要显示“所有收货地址”和“前序页面所勾选的购物车数据”,由于“所有收货地址”对应的功能已经完成,无须再次开发,在最后处理界面时直接显示即可。

需要“根据一系列id获取购物车中的数据”的功能,则抽象方法:

List<CartVO> findByIds(Integer[] ids);

映射的SQL语句为:

SELECT 
	t_cart.id, 
	uid, gid, 
	t_cart.price AS oldPrice, count, 
	t_goods.price AS newPrice,
	title, image
FROM 
	t_cart 
INNER JOIN
	t_goods
ON
	t_cart.gid = t_goods.id
WHERE 
	t_cart.id IN
	<foreach collection="array"
		item="id" seperator=","
		open="(" close=")">
		#{id}
	</foreach>
ORDER BY t_cart.id DESC

44.确认订单-显示确认页-业务层

参考其它查询功能完成业务层开发。

45.确认订单-显示确认页-控制器层

@GetMapping("/get_by_ids")
public ResponseResult<List<CartVO>>
	getByIds(Integer[] ids) {
	// 参考/cart/list
}

46.订单-创建订单-持久层

创建订单数据表

DROP TABLE IF EXISTS t_order;

CREATE TABLE t_order (
	id INT AUTO_INCREMENT COMMENT 'id',
	
	uid INT COMMENT '数据归属用户',

	recv_name VARCHAR(20) COMMENT '收货人姓名',
	recv_phone VARCHAR(20) COMMENT '收货人电话',
	recv_district VARCHAR(30) COMMENT '收货的省市区',
	recv_address VARCHAR(50) COMMENT '收货详细地址',

	pay BIGINT COMMENT '支付金额',

	order_time DATETIME COMMENT '下单时间',
	status INT COMMENT '订单状态:0-未支付,1-已支付,2-已取消',

	created_user VARCHAR(20) COMMENT '创建者',
	created_time DATETIME COMMENT '创建时间',
	modified_user VARCHAR(20) COMMENT '最后修改者',
	modified_time DATETIME COMMENT '最后修改时间',
	PRIMARY KEY(id)
) DEFAULT CHARSET=UTF8;

DROP TABLE IF EXISTS t_order_item;

CREATE TABLE t_order_item (
	id INT AUTO_INCREMENT COMMENT 'id',

	oid INT COMMENT '归属订单的id',

	goods_id BIGINT COMMENT '商品id',
	goods_image VARCHAR(500) COMMENT '商品图片',
	goods_title VARCHAR(100) COMMENT '商品标题',
	goods_count INT COMMENT '商品数量',
	goods_price BIGINT COMMENT '商品价格',

	created_user VARCHAR(20) COMMENT '创建者',
	created_time DATETIME COMMENT '创建时间',
	modified_user VARCHAR(20) COMMENT '最后修改者',
	modified_time DATETIME COMMENT '最后修改时间',
	PRIMARY KEY(id)
) DEFAULT CHARSET=UTF8;

创建实体类

创建cn.tedu.store.entity.Ordercn.tedu.store.entity.OrderItem这2个实体类。

接口

创建cn.tedu.store.mapper.OrderMapper接口,并声明2个抽象方法:

Integer insertOrder(Order order);

Integer insertOrderItem(OrderItem orderItem);

映射文件

复制得到OrderMapper.xml并配置:

<!-- 插入订单数据 -->
<!-- Integer insertOrder(Order order) -->
<insert id="insertOrder"
	useGeneratedKeys="true" keyProperty="id">
	INSERT INTO t_order (
		uid,
		recv_name, recv_phone,
		recv_district, recv_address,
		pay, order_time, status,
		created_user, created_time,
		modified_user, modified_time
	) VALUES (
		#{uid},
		#{recvName}, #{recvPhone},
		#{recvDistrict}, #{recvAddress},
		#{pay}, #{orderTime}, #{status},
		#{createdUser}, #{createdTime},
		#{modifiedUser}, #{modifiedTime}
	)
</insert>

<!-- 插入订单商品数据 -->
<!-- Integer insertOrderItem(OrderItem orderItem) -->
<insert id="insertOrderItem"
	useGeneratedKeys="true" keyProperty="id">
	INSERT INTO t_order_item (
		oid,
		goods_id, 
		goods_image, goods_title,
		goods_price, goods_count,
		created_user, created_time,
		modified_user, modified_time
	) VALUES (
		#{oid},
		#{goodsId}, 
		#{goodsImage}, #{goodsTitle},
		#{goodsPrice}, #{goodsCount},
		#{createdUser}, #{createdTime},
		#{modifiedUser}, #{modifiedTime}
	)
</insert>

47.订单-创建订单-业务层

IAddressService中声明并完成:

Address getById(Integer id);

创建业务层接口cn.tedu.store.service.IOrderService并添加抽象方法:

Order createOrder(
	Integer uid, String username,
	Integer addressId, 
	Integer[] cartIds);

创建业务层实现类cn.tedu.store.service.impl.OrderServiceImp,添加注解、声明持久层对象、添加未实现的方法、添加私有方法,然后:

@Autowired
private IAddressService addressService;
@Autowired
private ICartService cartService;

@Transactional
public Order createOrder(Integer uid, String username, Integer addressId, Integer[] cartIds) {
	// 创建Date对象
	
	// 声明pay变量
	// List<CartVO> cartService.getByIds(ids)
	// 遍历集合,过程中,计算总价pay
	// 创建List<OrderItem> orderItems
	// -- 创建OrderItem
	// -- item属性:goods_5,OK
	// -- item属性:4个日志,OK
	
	// 创建Order对象
	// order属性:uid,OK
	// order属性:pay,OK

	// 通过addressService.getById()得到收货地址数据
	// order属性:recv_4,OK

	// order属性:order_time,OK
	// order属性:status,OK,值为0

	// order属性:4个日志,OK

	// 插入订单数据并获取oid:insertOrder(order)

	// 遍历orderItems
		// item属性:oid

		// 插入订单商品数据
	// }

}

控制器方法:

@RequestMapping("/create")
public ResponseResult<Order> createOrder(
	HttpSession session, 
	Integer addressId, Integer[] cartIds) {

}

48.订单-查询订单详情-持久层

分析SQL语句:

select 
	t_order.id,
	uid,
	recv_name, recv_phone, 
	recv_district, recv_address,
	pay, status,
	goods_id,
	goods_image, goods_title,
	goods_price, goods_count
from 
	t_order 
inner 
	join t_order_item 
on 
	t_order.id=t_order_item.oid 
where 
	t_order.id=?

以上查询结果没有匹配的实体类,且以上查询是关联查询,通常需要有匹配的VO类,则创建cn.tedu.store.vo.OrderVO类:

public class OrderVO {
	private Integer id;
	private Integer uid;
	private String recvName;
	private String recvPhone;
	private String recvDistrict;
	private String recvAddress;
	private Long pay;
	private Integer status;
	private List<OrderItem> items;
	// SET / GET / Serializable
}

则接口中的抽象方法:

OrderVO findById(Integer id);

然后,在配置映射时,还需要先配置<resultMap>

<!-- 查询订单详情得到OrderVO的映射配置 -->
<resultMap id="Order_VO_Map" 
	type="cn.tedu.store.vo.OrderVO">
	<id column="id" property="id" />
	<result column="uid" property="uid" />
	<result column="recv_name" property="recvName" />
	<result column="recv_phone" property="recvPhone" />
	<result column="recv_district" property="recvDistrict" />
	<result column="recv_address" property="recvAddress" />
	<result column="pay" property="pay" />
	<result column="status" property="status" />
	<collection property="items"
		ofType="cn.tedu.store.entity.OrderItem">
		<result column="goods_id" property="goodsId" />
		<result column="goods_image" property="goodsImage" />
		<result column="goods_title" property="goodsTitle" />
		<result column="goods_price" property="goodsPrice" />
		<result column="goods_count" property="goodsCount" />
	</collection>
</resultMap>

<!-- 根据id查询订单详情 -->
<!-- OrderVO findById(Integer id) -->
<select id="findById" resultMap="Order_VO_Map">
	SELECT 
		t_order.id,
		uid,
		recv_name, recv_phone, 
		recv_district, recv_address,
		pay, status,
		goods_id,
		goods_image, goods_title,
		goods_price, goods_count
	FROM 
		t_order 
	INNER JOIN
		t_order_item 
	ON 
		t_order.id=t_order_item.oid 
	WHERE 
		t_order.id=#{id}
</select>

完成后,执行单元测试。

OrderVO 
[
	id=4, 
	uid=1, 
	recvName=小范同学, 
	recvPhone=, 
	recvDistrict=山东省, 莱芜市, 钢城区, 
	recvAddress=, 
	pay=97230, 
	status=0, 
	items=[
		OrderItem [id=null, oid=null, goodsId=10000022, goodsImage=/images/portal/13LenovoIdeaPad310_black/, goodsTitle=联想(Lenovo)IdeaPad310经典版黑色, goodsCount=10, goodsPrice=5119], 
		OrderItem [id=null, oid=null, goodsId=10000017, goodsImage=/images/portal/12DELLXPS13-silvery/, goodsTitle=戴尔(DELL)XPS13-9360-R1609 13.3高配版银色, goodsCount=10, goodsPrice=4604]]]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、学会各类开发软件安装、项目导入以及项目发布,含项目源码,需求文档,配套软件等 2、该项目主要功能完善,主要用于简历项目经验丰富,以及毕业设计或者二次开发 3、提供项目源码,设计文档、数据库sql文件以及所有配套软件,按照教程即可轻松实现项目安装部署 本课程为素材版,需要实战版的同学可以点击如下链接: 项目实战课程:代码视频讲解版如下java项目实战之电商系统全套(前台和后台)(java毕业设计ssm框架项目)https://edu.csdn.net/course/detail/25771java项目之oa办公管理系统(java毕业设计)https://edu.csdn.net/course/detail/23008java项目之hrm人事管理项目(java毕业设计)https://edu.csdn.net/course/detail/23007JavaWeb项目实战之点餐系统前台https://edu.csdn.net/course/detail/20543JavaWeb项目实战之点餐系统后台https://edu.csdn.net/course/detail/19572JavaWeb项目实战之宿舍管理系统(Java毕业设计含源码)https://edu.csdn.net/course/detail/26721JavaWeb项目实战之点餐系统全套(前台和后台)https://edu.csdn.net/course/detail/20610java项目实战之电子商城后台(java毕业设计SSM框架项目)https://edu.csdn.net/course/detail/25770java美妆商城项目|在线购书系统(java毕业设计项目ssm版)https://edu.csdn.net/course/detail/23989系统学习课程:JavaSE基础全套视频(环境搭建 面向对象 正则表达式 IO流 多线程 网络编程 java10https://edu.csdn.net/course/detail/26941Java Web从入门到电商项目实战挑战万元高薪(javaweb教程)https://edu.csdn.net/course/detail/25976其他素材版(毕业设计或课程设计)项目:点击老师头像进行相关课程学习

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值