
🧸安清h:个人主页****
🎥个人专栏:【Spring篇】** 【计算机网络】 【Mybatis篇】**
🚦作者简介: 一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。

目录
🚀1.显示勾选的购物车数据-持久层
✨1.1规划SQL语句
1.用户在购物车列表中通过随即勾选相关的商品,在点击"结算"按钮后跳转到结算页面,在这个页面中需要展示用户在上个页面所勾选的购物车对应的数据。列表的展示,展示的内容还是来自于购物车表。两个页面需要将用户勾选的cid传递给下一个页面。
当前只要cid的值能够达到in里面的任意一个值,都属于满足整体的where条件。用户在前端所传递过来的这个?的值,在后台可以用一个集合来接收到,然后层层传递给mapper,mapper用一个集合来代替就行了,只要cid属于集合中任意一个数就符合条件了。
sql
select
cid,
uid,
pid,
t_cart.price,
t_cart.num,
title,
t_product.price as realPrice,
image
from t_cart
left join t_product on t_cart.pid = t_product.id
where cid in (?,?,?)
order by t_cart.created_time desc
✨1.2设计接口和抽象方法
java
List<CartVO> findVOByCid(Integer[] cids);
✨1.3配置SQL映射
XML
<select id="findVOByCid" resultType="com.cy.store.Vo.CartVO">
select
cid,
uid,
pid,
t_cart.price,
t_cart.num,
title,
t_product.price as realPrice,
image
from t_cart
left join t_product on t_cart.pid = t_product.id
where cid in (
<foreach collection="array" item="cid" separator=","> --把每个cid拿到,中间用,分隔
#{cid}
</foreach>
)
order by t_cart.created_time desc
</select>
进行单元测试
java
@Test
public void findVOByCids() {
Integer[] cids = {1,2,3,9};
System.out.println(cartMapper.findVOByCid(cids));
}
🚀2.显示勾选的购物车数据-业务层
2.1查询语句,无异常规划。
✨2.2设计接口和抽象方法
java
List<CartVO> getVOByCid(Integer uid, Integer[] cids);
✨2.3完成抽象方法的设计
java
@Override
public List<CartVO> getVOByCid(Integer uid,Integer[] cids) {
List<CartVO> list = cartMapper.findVOByCid(cids);
Iterator<CartVO> it = list.iterator();
while (it.hasNext()) {
CartVO cartVO = it.next();
if (!cartVO.getUid().equals(uid)) { //表示当前的数据不属于当前的用户
//从集合中移除这个元素
list.remove(cartVO);
}
}
return list;
}
🚀3.显示勾选的购物车数据-控制层
✨3.1设计请求
请求路径:/carts/list
请求方式:POST
请求数据:Integer[] cids ,HttpSession session
响应结果:JsonResult<List<CartVO>>
✨3.2处理请求
java
@RequestMapping("list")
public JsonResult<List<CartVO>> getVOByCid(Integer[] cids, HttpSession session) {
List<CartVO> data = cartService.getVOByCid(getuidFromSession(session), cids);
return new JsonResult<>(OK, data);
}
🚀4.1显示勾选的购物车数据-前端页面
1.把type属性改成submit,让其自动提交。
java
<input type="submit" value=" 结 算 " class="btn btn-primary btn-lg link-account" />
2.orderConfirm.html页面中添加自动加载从上个页面中传递过来的cids数据,再去请求ajax,再在ajax中进行填充到当前的某个区域。
3.注释掉以下代码:
javascript
<script src="../js/orderConfirm.js" type="text/javascript" charset="utf-8"></script>
javascript
<script type="text/javascript">
$(document).ready(function() {
showCartList();
});
function showCartList() {
$("#cart-list").empty();
$.ajax({
url: "/carts/list",
type: "GET",
data: location.search.substr(1), //截问号后的第一个参数
dataType: "JSON",
success: function(json) {
if (json.state == 200) {
let list = json.data;
let allCount = 0;
let allPrice = 0;
for (let i = 0; i < list.length; i++) {
let tr = '<tr>\n' +
'<td><img src="..#{image}collect.png" class="img-responsive" /></td>\n' +
'<td>#{title}</td>\n' +
'<td>¥<span>#{price}</span></td>\n' +
'<td>#{num}</td>\n' +
'<td><span>#{totalPrice}</span></td>\n' +
'</tr>';
tr = tr.replace("#{image}",list[i].image);
tr = tr.replace("#{title}",list[i].title);
tr = tr.replace("#{price}",list[i].realPrice);
tr = tr.replace("#{num}",list[i].num);
tr = tr.replace("#{totalPrice}",list[i].realPrice*list[i].num);
$("#cart-list").append(tr);
allCount += list[i].num;
allPrice += list[i].realPrice*list[i].num;
}
$("#all-count").html(allCount);
$("#all-price").html(allPrice);
}
},
error: function (xhr) {
alert("结算时发生未知的异常"+xhr.status);
}
});
}
</script>
🚀4.2购物车页面显示收货地址列表-前端页面
1.收货地址存放在一个select下拉列表中,将查询到的当前登录用户的收货地址动态的加载到这个下拉列表中.从数据库的角度是一个select查询语句。已经编写了根据用户的uid来查询当前用户的收货地址数据。
2.orderConfirm.html页面中,收货地址数据的展示需要自动进行加载,需要将方法的逻辑放在ready函数中。
javascript
$(document).ready(function() {
showCartList();
showAddressList();
});
javascript
function showCartList() {
$("#address-list").empty();
$.ajax({
url: "/addresses/",
type: "GET",
dataType: "JSON",
success: function(json) {
if (json.state == 200) {
let list = json.data;
for (let i = 0; i < list.length; i++) {
var opt = '<option value="#{aid}">#{name} #{tag} #{provinceName}#{cityName}#{areaName}#{address} #{tel}</option>';
opt = opt.replace("#{aid}",list[i].aid);
opt = opt.replace("#{name}",list[i].name);
opt = opt.replace("#{tag}",list[i].tag);
opt = opt.replace("#{provinceName}",list[i].provinceName);
opt = opt.replace("#{cityName}",list[i].cityName);
opt = opt.replace("#{areaName}",list[i].areaName);
opt = opt.replace("#{address}",list[i].address);
opt = opt.replace("#{tel}",list[i].tel);
$("#address-list").append(opt);
}
}
},
error: function (xhr) {
alert("结算时发生未知的异常"+xhr.status);
}
});
}
🎯1.创建订单-数据表
在数据库store中创建数据表t_order和t_order_item。
sql
CREATE TABLE t_order (
oid INT AUTO_INCREMENT COMMENT '订单id',
uid INT NOT NULL COMMENT '用户id',
recv_name VARCHAR(20) NOT NULL COMMENT '收货人姓名',
recv_phone VARCHAR(20) COMMENT '收货人电话',
recv_province VARCHAR(15) COMMENT '收货人所在省',
recv_city VARCHAR(15) COMMENT '收货人所在市',
recv_area VARCHAR(15) COMMENT '收货人所在区',
recv_address VARCHAR(50) COMMENT '收货详细地址',
total_price BIGINT COMMENT '总价',
status INT COMMENT '状态:0-未支付,1-已支付,2-已取消,3-已关闭,4-已完成',
order_time DATETIME COMMENT '下单时间',
pay_time DATETIME COMMENT '支付时间',
created_user VARCHAR(20) COMMENT '创建人',
created_time DATETIME COMMENT '创建时间',
modified_user VARCHAR(20) COMMENT '修改人',
modified_time DATETIME COMMENT '修改时间',
PRIMARY KEY (oid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE t_order_item (
id INT AUTO_INCREMENT COMMENT '订单中的商品记录的id',
oid INT NOT NULL COMMENT '所归属的订单的id',
pid INT NOT NULL COMMENT '商品的id',
title VARCHAR(100) NOT NULL COMMENT '商品标题',
image VARCHAR(500) COMMENT '商品图片',
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 (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
🎯2.创建订单-实体类
在com.cy.store.entity包下创建Order类并使其继承基类。
java
public class Order extends BaseEntity {
private Integer oid;
private Integer uid;
private String recvName;
private String recvPhone;
private String recvProvince;
private String recvCity;
private String recvArea;
private String recvAddress;
private Long totalPrice;
private Integer status;
private Date orderTime;
private Date payTime;
。。。。。。
}
在com.cy.store.entity包下创建OrderItem类并使其继承基类。
java
public class OrderItem extends BaseEntity {
private Integer id;
private Integer oid;
private Integer pid;
private String title;
private String image;
private Long price;
private Integer num;
......
}
🎯3.创建订单-持久层
✨3.1规划SQL语句
1.将数据插入到订单表中。
sql
insert into t_order (oid除外所有的字段) values (字段值)
2.将数据插入订单项表中。
sql
insert into t_order_item (id除外所有的字段) values (字段值)
✨3.2设计接口和抽象方法
创建一个OrderMapper接口,接口中添加以上两个SQL对象的抽象方法。
java
public interface OrderMapper {
/**
* 插入订单数据
* @param order 订单数据
* @return 受影响的行数
*/
Integer insertOrder(Order order);
/**
* 插入订单项的数据
* @param orderItem 订单项数据
* @return 受影响的行数
*/
Integer insertOrderItem(OrderItem orderItem);
}
✨3.3配置SQL映射
1.创建OrderMapper.xml文件。
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.OrderMapper">
<insert id="insertOrder" useGeneratedKeys="true" keyProperty="oid">
insert into t_order (
uid, recv_name, recv_phone, recv_province, recv_city, recv_area, recv_address,
total_price,status, order_time, pay_time, created_user, created_time, modified_user,
modified_time
) values (
#{uid}, #{recvName}, #{recvPhone}, #{recvProvince}, #{recvCity}, #{recvArea},
#{recvAddress}, #{totalPrice}, #{status}, #{orderTime}, #{payTime}, #{createdUser},
#{createdTime}, #{modifiedUser}, #{modifiedTime}
)
</insert>
<insert id="insertOrderItem" useGeneratedKeys="true" keyProperty="id">
insert into t_order_item (
oid, pid, title, image, price, num, created_user,
created_time, modified_user, modified_time
) values (
#{oid}, #{pid}, #{title}, #{image}, #{price}, #{num}, #{createdUser},
#{createdTime}, #{modifiedUser}, #{modifiedTime}
)
</insert>
</mapper>
2.单元测试。
java
@Test
public void insertOrder(){
Order order = new Order();
order.setUid(6);
order.setRecvName("子敬");
order.setRecvPhone("384570219");
orderMapper.insertOrder(order);
}
@Test
public void insertOrderItem(){
OrderItem orderItem = new OrderItem();
orderItem.setOid(1);
orderItem.setPid(10000002);
orderItem.setTitle("广博(GuangBo)皮面日程本子 计划记事本效率手册米色FB60322");
orderMapper.insertOrderItem(orderItem);
}
🎯4.创建订单-业务层
1.在IAddressService接口中定义根据收货地址的id获取收货地址的数据。
java
Address getByAid(Integer aid);
2.实现方法。
java
@Override
public Address getByAid(Integer aid,Integer uid) {
Address address =addressMapper.findByAid(aid);
if(address == null){
throw new AddressNotFoundException("收货地址数据不存在");
}
if(address.getUid().equals(uid)){
throw new AccessDeniedException("非法数据访问");
}
address.setProvinceCode(null);
address.setCityCode(null);
address.setAreaCode(null);
address.setCreatedUser(null);
address.setCreatedTime(null);
address.setModifiedUser(null);
address.setModifiedTime(null);
return address;
}
3.在service包下创建IOrderService接口添加抽象方法用于创建订单。
java
public interface IOrderService {
Address create(Integer aid,Integer uid,String username,Integer[] cids);
}
4.创建实现类OrderServiceImpl。
java
@Autowired
private OrderMapper orderMapper;
@Autowired
private IAddressService addressService;
@Autowired
private ICartService cartService;
@Override
public Order create(Integer aid, Integer uid, String username, Integer[] cids) {
//即将要下单的列表
List<CartVO> list = cartService.getVOByCid(uid,cids);
//计算商品的总价
Long totaolPrice = 0L;
Address address = addressService.getByAid(aid, uid);
Order order = new Order();
order.setUid(uid);
//收货地址数据
order.setRecvName(address.getName());
order.setRecvPhone(address.getPhone());
order.setRecvProvince(address.getProvinceName());
order.setRecvCity(address.getCityName());
order.setRecvArea(address.getAreaName());
order.setRecvAddress(address.getAddress());
//支付,总价,时间
order.setStatus(0);
order.setTotalPrice(totaolPrice);
order.setOrderTime(new Date());
//日志
order.setCreatedUser(username);
order.setCreatedTime(new Date());
order.setModifiedUser(username);
order.setModifiedTime(new Date());
Integer rows = orderMapper.insertOrder(order);
if(rows != 1){
throw new InsertException("插入时异常");
}
//创建订单详细项的数据
for(CartVO c : list){
//创建一个订单项数据对象
OrderItem orderItem = new OrderItem();
orderItem.setOid(order.getOid());
orderItem.setPid(c.getPid());
orderItem.setTitle(c.getTitle());
orderItem.setImage(c.getImage());
orderItem.setPrice(c.getPrice());
orderItem.setNum(c.getNum());
//日志字段
orderItem.setCreatedUser(username);
orderItem.setCreatedTime(new Date());
orderItem.setModifiedUser(username);
orderItem.setModifiedTime(new Date());
//插入数据操作
rows = orderMapper.insertOrderItem(orderItem);
if(rows != 1){
throw new InsertException("插入时异常");
}
orderMapper.insertOrderItem(orderItem);
}
return order;
}
5.创建测试方法并完成测试。
java
@SpringBootTest
public class OrderServiceTests {
@Autowired
private IOrderService orderService;
@Test
public void create(){
Integer[] cids = {3,4};
Order order = orderService.create(12,6,"小明",cids);
System.out.println(order);
}
}
🎯5.创建订单-控制层
✨5.1设计请求
请求路径:/orders/create/
请求参数:Integer aid,Integer[] cids,HttpSession session
请求类型:POST
响应结果:JsonResult<Order>
✨5.2处理请求
创建一个OrderController类,并编写处理请求方法。
java
@RequestMapping("/orders/")
@RestController
public class OrderController extends BaseController{
@Autowired
private IOrderService orderService;
@RequestMapping("create")
public JsonResult<Order> create(Integer aid, Integer[] cids, HttpSession session){
Order data = orderService.create(aid,getuidFromSession(session),getUsernameFromSession(session),cids);
return new JsonResult<>(OK,data);
}
}
🎯6.创建订单-前端页面
在订单确定页面中添加发送请求的处理方法。
javascript
$("#btn-create-order").click(function() {
let aid = $("#address-list").val();
let cids = location.search.substr(1);
$.ajax({
url: "/orders/create",
type: "GET",
data: "aid="+aid + "&" + cids,
dataType: "JSON",
success: function(json) {
if (json.state == 200) {
location.href = "payment.html";
alert("订单创建成功");
console.log(json.data) //调试
} else {
alert("创建订单失败" + json.message);
}
},
error: function(xhr) {
alert("创建订单数据时产生未知的异常" + xhr.status);
}
});
});
感谢各位的陪伴,最后一篇也更完啦🎉🎉🎉