以下皆为部分代码,详见 https://github.com/liyuelian/furniture_mall.git
Cart.java
增加方法updateCount()
/**
* 根据家居id和count,修改指定cartItem的数量和总价
*
* @param id 家居id
* @param count 指定id的家居的数量
*/
public void updateCount(int id, int count) {
//获取指定的cartItem
CartItem item = items.get(id);
if (null != item) {//如果cartItem不为空
//更新数量
item.setCount(count);
//某家居总价 = 单价 * 数量(为了安全使用get方法获取数量count)
item.setTotalPrice(item.getPrice().multiply(new BigDecimal(item.getCount())));
}
}
CartServlet.java
增加方法updateCount()
/**
* 更新购物车的某个家居数量
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void updateCount(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int id = DataUtils.parseInt(req.getParameter("id"), 0);
int count = DataUtils.parseInt(req.getParameter("count"), 1);
//获取session中的购物车
Cart cart = (Cart) req.getSession().getAttribute("cart");
if (null != cart) {
cart.updateCount(id, count);
}
//回到请求更新家居购物车的页面
resp.sendRedirect(req.getHeader("Referer"));
}
cart.jsp
添加绑定事件,当点击修改对应的家居数量时,向服务器发送更新家居信息的请求
<script type="text/javascript">
$(function () {
/*--------------------------
Cart Plus Minus Button
----------------------------*/
var CartPlusMinus = $(".cart-plus-minus");
CartPlusMinus.prepend('<div class="dec qtybutton">-</div>');
CartPlusMinus.append('<div class="inc qtybutton">+</div>');
$(".qtybutton").on("click", function () {
var $button = $(this);
var oldValue = $button.parent().find("input").val();
if ($button.text() === "+") {
var newVal = parseFloat(oldValue) + 1;
} else {
// Don't allow decrementing below zero
if (oldValue > 1) {
var newVal = parseFloat(oldValue) - 1;
} else {
newVal = 1;
}
}
$button.parent().find("input").val(newVal);
var furnId = $button.parent().find("input").attr("furnId");
//发出修改购物车的请求
location.href =
"cartServlet?action=updateCount&count=" + newVal + "&id=" + furnId;
});
})
</script>
修改家居数量:
见21.2思路分析图
Cart.java添加删除购物车家居项的方法delItem()
/**
* 根据家居id删除对应的cartItem
*
* @param id 家居id
*/
public void delItem(int id) {
items.remove(id);
}
增加清空方法clear()
/**
* 清空items
*/
public void clear() {
items.clear();
}
CartServlet.java添加方法delItem()
/**
* 根据id删除购物车的某个家居信息
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void delItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int id = DataUtils.parseInt(req.getParameter("id"), 0);
//获取session中的购物车
Cart cart = (Cart) req.getSession().getAttribute("cart");
if (null != cart) {
cart.delItem(id);
}
//回到请求删除家居项的购物车页面
resp.sendRedirect(req.getHeader("Referer"));
}
增加clear()方法
/**
* 清空购物车
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void clear(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session的购物车
Cart cart = (Cart) req.getSession().getAttribute("cart");
if (null != cart) {
cart.clear();
}
//回到请求清空家居项的购物车页面
resp.sendRedirect(req.getHeader("Referer"));
}
cart.jsp
//清空购物车绑定确认事件
$("a.clearCart").click(function () {
return window.confirm("你确认要清空购物车吗?")
})
//给删除购物车绑定事件
$("a.delItem").click(function () {
//获取要删除的家居名
var furnName = $(this).parent().parent().find("td:eq(1)").text();
//使用确认弹窗
//点击确认,返回true,点击取消,返回false
return window.confirm("你确认要删除" + furnName + "吗?")
})
删除购物车项:
清空购物车:
创建订单表和订单项表
###
-- 设计 订单表order
-- 字段参考前端给的界面
-- mysql每个字段应尽量使用not null约束
-- 字段类型的设计应当和关联的表的字段保持一致
-- 外键是否要给?
-- 因为外键对效率有影响,应当从程序的业务保证数据的一致性,而不是db层保证
CREATE TABLE `order`(
`id` VARCHAR(64) PRIMARY KEY, #订单号,主键
`create_time` DATETIME NOT NULL, #订单生成时间
`price` DECIMAL(11,2) NOT NULL, #订单的总金额,类型应该和furn表的price类型对应
`status` TINYINT NOT NULL, #订单状态 0-未发货 1-已发货 2-已结账
`member_id` INT NOT NULL #从属的会员id -不需要外键约束
)CHARSET utf8 ENGINE INNODB;
###
-- 设计 订单项表order_item
CREATE TABLE `order_item`(
`id` INT PRIMARY KEY AUTO_INCREMENT, #订单项id,自增长
`name` VARCHAR(64) NOT NULL, #家居名
`price` DECIMAL(11,2) NOT NULL, #家居单价
`count` INT NOT NULL, #某项的家居数量
`total_price` DECIMAL(11,2) NOT NULL, #订单项 的总价
`order_id` VARCHAR(64) NOT NULL #从属的订单号
)CHARSET utf8 ENGINE INNODB;
Order.java
package com.li.furns.entity;
import java.math.BigDecimal;
import java.util.Date;
/**
* Order表示一个订单
*
* @author 李
* @version 1.0
*/
public class Order {
//属性
private String id;
private Date createTime;
private BigDecimal price;
private Integer status;
private Integer memberId;
public Order() {
}
public Order(String id, Date createTime, BigDecimal price, Integer status, Integer memberId) {
this.id = id;
this.createTime = createTime;
this.price = price;
this.status = status;
this.memberId = memberId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getMemberId() {
return memberId;
}
public void setMemberId(Integer memberId) {
this.memberId = memberId;
}
@Override
public String toString() {
return "Order{" +
"id='" + id + '\'' +
", createTime=" + createTime +
", price=" + price +
", status=" + status +
", memberId=" + memberId +
'}';
}
}
OrderItem.java
package com.li.furns.entity;
import java.math.BigDecimal;
/**
* @author 李
* @version 1.0
*/
public class OrderItem {
private Integer id;
private String name;
private BigDecimal price;
private Integer count;
private BigDecimal totalPrice;
private String orderId;
public OrderItem() {
}
public OrderItem(Integer id, String name, BigDecimal price, Integer count, BigDecimal totalPrice, String orderId) {
this.id = id;
this.name = name;
this.price = price;
this.count = count;
this.totalPrice = totalPrice;
this.orderId = orderId;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public BigDecimal getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(BigDecimal totalPrice) {
this.totalPrice = totalPrice;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
@Override
public String toString() {
return "OrderItem{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
", count=" + count +
", totalPrice=" + totalPrice +
", orderId='" + orderId + '\'' +
'}';
}
}
OrderDAO接口
package com.li.furns.dao;
import com.li.furns.entity.Order;
/**
* @author 李
* @version 1.0
*/
public interface OrderDAO {
/**
* 将传入的order对象保存到数据表order表
*
* @param order order对象
* @return 返回操作影响的行数
*/
public int saveOrder(Order order);
}
OrderDAOImpl实现类
package com.li.furns.dao.impl;
import com.li.furns.dao.BasicDAO;
import com.li.furns.dao.OrderDAO;
import com.li.furns.entity.Order;
/**
* @author 李
* @version 1.0
*/
public class OrderDAOImpl extends BasicDAO<Order> implements OrderDAO {
@Override
public int saveOrder(Order order) {
String sql =
"INSERT INTO `order`(`id`,`create_time`,`price`,`status`,`member_id`) " +
"VALUES(?,?,?,?,?)";
return update(sql, order.getId(), order.getCreateTime(),
order.getPrice(), order.getStatus(), order.getMemberId());
}
}
test包-OrderDAOImplTest测试
package com.li.furns.test;
import com.li.furns.dao.OrderDAO;
import com.li.furns.dao.impl.OrderDAOImpl;
import com.li.furns.entity.Order;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import java.util.Date;
/**
* @author 李
* @version 1.0
*/
public class OrderDAOImplTest {
private OrderDAO orderDAO = new OrderDAOImpl();
@Test
public void saveOrder() {
Order order = new Order("sn000002", new Date(),
new BigDecimal(300), 0, 1);
System.out.println(orderDAO.saveOrder(order));
}
}
OrderItemDAO接口
package com.li.furns.dao;
import com.li.furns.entity.OrderItem;
/**
* OrderItemDAO表示一个订单项
*
* @author 李
* @version 1.0
*/
public interface OrderItemDAO {
/**
* 将传入的orderItem对象保存到order_item表中
*
* @param orderItem
* @return
*/
public int saveOrderItem(OrderItem orderItem);
}
OrderItemDAOImpl
package com.li.furns.dao.impl;
import com.li.furns.dao.BasicDAO;
import com.li.furns.dao.OrderItemDAO;
import com.li.furns.entity.OrderItem;
/**
* @author 李
* @version 1.0
*/
public class OrderItemDAOImpl extends BasicDAO<OrderItem> implements OrderItemDAO {
@Override
public int saveOrderItem(OrderItem orderItem) {
String sql =
"INSERT INTO `order_item`(`id`,`name`,`price`,`count`,`total_price`,`order_id`) " +
"VALUES(?,?,?,?,?,?);";
return update(sql, orderItem.getId(), orderItem.getName(), orderItem.getPrice(),
orderItem.getCount(), orderItem.getTotalPrice(), orderItem.getOrderId());
}
}
test包-OrderItemDAOImplTest
package com.li.furns.test;
import com.li.furns.dao.OrderItemDAO;
import com.li.furns.dao.impl.OrderItemDAOImpl;
import com.li.furns.entity.OrderItem;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
/**
* @author 李
* @version 1.0
*/
public class OrderItemDAOImplTest {
private OrderItemDAO orderItemDAO = new OrderItemDAOImpl();
@Test
public void saveOrderItem() {
OrderItem orderItem = new OrderItem(null, "北欧小沙发", new BigDecimal(200),
3, new BigDecimal(600), "sn000001");
System.out.println(orderItemDAO.saveOrderItem(orderItem));
}
}
OrderService接口
package com.li.furns.service;
import com.li.furns.entity.Cart;
/**
* @author 李
* @version 1.0
*/
public interface OrderService {
/**
* 1.生成订单
* 2.订单是根据购物车来生成的,cart对象在session,通过web层,传入saveOrder
* 3.订单和会员id关联
*
* @param cart 购物车
* @param memberId 会员id
* @return 返回生成的订单号
*/
public String saveOrder(Cart cart, int memberId);
}
OrderServiceImpl实现类
package com.li.furns.service.impl;
import com.li.furns.dao.FurnDAO;
import com.li.furns.dao.OrderDAO;
import com.li.furns.dao.OrderItemDAO;
import com.li.furns.dao.impl.FurnDAOImpl;
import com.li.furns.dao.impl.OrderDAOImpl;
import com.li.furns.dao.impl.OrderItemDAOImpl;
import com.li.furns.entity.*;
import com.li.furns.service.OrderService;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author 李
* @version 1.0
*/
public class OrderServiceImpl implements OrderService {
private OrderDAO orderDAO = new OrderDAOImpl();
private OrderItemDAO orderItemDAO = new OrderItemDAOImpl();
private FurnDAO furnDAO = new FurnDAOImpl();
@Override
public String saveOrder(Cart cart, int memberId) {
//这里的业务相对而言比较综合
//任务:将cart购物车的数据以order和orderItem的形式保存到数据库中
/**
* 因为生成订单会操作多张表,设计到多表事务问题,使用ThreadLocal+MySQL事务机制+过滤器Filter
* 因为事务处理考虑的点比较多,这里先不处理,后面专门处理
*/
//1.构建一个对应的order对象
//先生成一个UUID,表示当前的订单号。要保证订单号是唯一的
String orderId = System.currentTimeMillis() + "" + memberId;
Order order = new Order(orderId, new Date(), cart.getCartTotalPrice(), 0, memberId);
//将order对象保存到数据库order表中
orderDAO.saveOrder(order);
//2.通过cart对象,遍历出CartItem家居项,构建orderItem对象
HashMap<Integer, CartItem> items = cart.getItems();
//遍历hm
/**
* 遍历方法一:entrySet
* 通过entrySet的方法遍历items,取出cartItem
* for(Map.Entry<Integer, CartItem> entry : items.entrySet()) {
* CartItem item = entry.getValue();
* ...
* }
*/
//遍历方法二:keySet
Set<Integer> keys = items.keySet();
for (Integer id : keys) {
//获取家居项
CartItem item = items.get(id);
//构建orderItem对象
OrderItem orderItem = new OrderItem(null, item.getName(), item.getPrice(),
item.getCount(), item.getTotalPrice(), orderId);
//将orderItem对象保存到数据库表order_item中
orderItemDAO.saveOrderItem(orderItem);
//更新furn表的对应记录的sales销量,stock存量
//(1)获取到furn对象
Furn furn = furnDAO.queryFurnById(id);
//(2)更新furn对象的sales销量,stock存量
furn.setSales(furn.getSales() + item.getCount());
furn.setStock(furn.getStock() - item.getCount());
//(3)更新到数据表中
furnDAO.updateFurn(furn);
}
//清空购物车
cart.clear();
//返回生成的订单号
return orderId;
}
}
test包-OrderServiceImplTest测试
package com.li.furns.test;
import com.li.furns.entity.Cart;
import com.li.furns.entity.CartItem;
import com.li.furns.service.OrderService;
import com.li.furns.service.impl.OrderServiceImpl;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
/**
* @author 李
* @version 1.0
*/
public class OrderServiceImplTest {
private OrderService orderService = new OrderServiceImpl();
@Test
public void saveOrder() {
//构建cart对象
Cart cart = new Cart();
cart.addItem(new CartItem(1, "北欧风格小桌子", new BigDecimal(180), 10, new BigDecimal(1800)));
cart.addItem(new CartItem(26, "简约风格小椅子", new BigDecimal(100), 5, new BigDecimal(500)));
String orderId = orderService.saveOrder(cart, 2);
System.out.println(orderId);
}
}
furn表对应的家居项:
-测试前
-测试后
order表:
order_item表:
配置OrderServlet
<servlet>
<servlet-name>OrderServlet</servlet-name>
<servlet-class>com.li.furns.web.OrderServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OrderServlet</servlet-name>
<url-pattern>/orderServlet</url-pattern>
</servlet-mapping>
OrderServlet:
package com.li.furns.web;
import com.li.furns.entity.Cart;
import com.li.furns.entity.Member;
import com.li.furns.service.OrderService;
import com.li.furns.service.impl.OrderServiceImpl;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
/**
* @author 李
* @version 1.0
*/
public class OrderServlet extends BasicServlet {
private OrderService orderService = new OrderServiceImpl();
/**
* 生成订单
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void saveOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取购物车cart
Cart cart = (Cart) req.getSession().getAttribute("cart");
if (null == cart || cart.isEmpty()) {//购物车不存在session或者购物车没有任何东西
// 转发到首页
req.getRequestDispatcher("/index.jsp").forward(req, resp);
return;//结束业务
}
//获取当前登录的memberId
Member member = (Member) req.getSession().getAttribute("member");
if (null == member) {//如果没有登录
//转发到登录页面
req.getRequestDispatcher("/views/member/login.jsp").forward(req, resp);
return;//结束业务
}
//生成订单
String orderId = orderService.saveOrder(cart, member.getId());
req.getSession().setAttribute("orderId", orderId);
//使用重定向到checkout.jsp页面
resp.sendRedirect(req.getContextPath() + "/views/order/checkout.jsp");
}
}
修改前端接口:略
未登录状态下添加家居到购物车,点击生成账单,请求转发登录页面
点击登录后重新返回购物车页面,点击生成订单,生成订单成功
数据库插入成功
order表
order_item表
furn表
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复
在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定
我刚刚安装了带有RVM的Ruby2.2.0,并尝试使用它得到了这个:$rvmuse2.2.0--defaultUsing/Users/brandon/.rvm/gems/ruby-2.2.0dyld:Librarynotloaded:/usr/local/lib/libgmp.10.dylibReferencedfrom:/Users/brandon/.rvm/rubies/ruby-2.2.0/bin/rubyReason:Incompatiblelibraryversion:rubyrequiresversion13.0.0orlater,butlibgmp.10.dylibpro
在Rails自动生成的功能测试(test/functional/products_controller_test.rb)中,我看到以下代码:classProductsControllerTest我的问题是:方法调用products()在哪里/如何定义?products(:one)到底是什么意思?看代码,大概意思是“创建一个产品”,但是它是如何工作的呢?注意我是Ruby/Rails的新手,如果这些是微不足道的问题,我深表歉意。 最佳答案 如果您查看test/fixtures文件夹,您会看到一个products.yml文件。这是在您创建