购物车原理以及实现
本⽂讲什么, 本⽂其实就是项⽬3的精华。
可以看到,购物车这样⼀个功能模块,在各种购物类APP或者web应⽤中绝对是必不可少的东西.不论在⼤学中的课程设计,还是在实际的项⽬开发中,绝对⾮常重要且有些复杂的内容.
在实际操作中,⾝边有很多的⼩伙伴遇到编写购物车的代码的时候,有时候真的是⼀脸懵逼,总是搞不明⽩设计的思路,这就是本⽂写作的原因.
所以,本⽂适合搞不清楚购物车实现原理,知道原理但是实际编码不知道如何下⼿的⼩伙伴,我将给出⼀个思路以及实际的代码供⼤家参考.
在本⽂中,我将会⽤尽可能简单的句⼦,表达出我想表达的意思.废话不多说,开始我们的购物车实战!
购物车的⼏种实现⽅式
购物车的实现⽅式有很多,但是最常见的就三种:Cookie,Session,数据库.三种⽅法各有优劣,适合的场景各不相同.
Cookie⽅法:通过把购物车中的商品数据写⼊Cookie中,再通过浏览器进⾏读取.这个⽅法,适合在⽤户没有登录的情况下使⽤,但是有个⾮常严重的缺点,即在⽤户禁⽤了Cookie的时候是⽆法使⽤的.
Session⽅法:通过Session来保存商品信息,这确实是个好的⽅法,适合⽤户已经登录的情况,将数据放在Session中,⽤户就能读取购物车中的商品信息,⽽且速度⼗分的快.但是缺点也很明显,由于Session是建⽴在⽤户客户端和服务器之间的,在Session中保存数据,⽆疑会增加服务器的负担.
数据库(Redis):数据库⽆疑是⼀种⾮常棒的保存购物车中信息的有效途径,且能够持久化保存,但是问题也很明显,那就是读取速度会差强⼈意.
好了,下⾯来说⼀下⼏种实现⽅式的应⽤场景.
当⽤户没有登录的情况下,⽤户将商品加⼊购物车,此时的商品信息是写⼊了Cookie中,并且会设置⼀个保存时间,即使关闭浏览器过⼀段时间访问仍能看到购物车中的信息.(或者将购物数据写⼊Session中,但是关闭浏览器,购物车中的信息也就不见了)
⽤户登陆后,如果在Session中存储了商品信息且没有关闭浏览器(如果在Cookie中存储了商品信息且没有过期),将会读取其中的商品信息,并且将这些信息写⼊数据库中进⾏持久保存.
本⽂的⾏⽂⽅式说明
经过上⾯的讲解,我想你⼀定对购物车有所了解,为了使读者更加清晰的明⽩购物车的实现,我们省去了在未结算的状态下的持久化数据库.
也就是说,在⽂章中,我将使⽤Session来实现购物车,并且当⽤户没有登录的情况下,禁⽌⽤户将商品加⼊购物车.当然你不必为此担忧,即使我这样做,我的代码已经包括了整个购物操作的绝⼤多数步骤.请耐⼼向下看.
此外,本⽂使⽤SSM框架作为⾏⽂代码.
如果你是初学者也不必担⼼,我将为你提供⼀套项⽬的源代码,可以在我的GitHub中获取:餐厅点餐系统,这套系统是基于servlet+jsp+mysql开发的,注释⾮常完善,当然最重要的模块也就是下单模块肯定是有的,⽽且⾮常完善,欢迎下载.
购物车模块的实现
数据库设计
⽤户表
字段 意义
id ⽤户id
userName ⽤户名
password ⽤户密码
商品表
字段 意义
id 商品id
commName 商品名称
price 商品价格
订单表
字段 意义
id 订单id
commName 商品名称
count 商品数量
subtotal 商品⼩计
total 总价
⽤户登录
为了实现我上述的思路,肯定是要求⽤户先⾏登录.代码如下.
LoginController
@Controller
public class LoginController {
private LoginService loginService;
private CommonService commonService;
js购物车结算代码
@Autowired
public LoginController(LoginService loginService, CommonService commonService) {        this.loginService = loginService;
thismonService = commonService;
}
@RequestMapping("/login")
public String login(User user, HttpSession session, Model model) {
//登录验证
if (loginService.isUser(user)) {
List<Common> commons = commonService.selectAllCommons();
model.addAttribute("commons", commons);
model.addAttribute("username", Username());
//把⽤户信息保存到session中
session.setAttribute("user", user);
return "shopping";
} else {
model.addAttribute("message", "⽤户名或密码错误");
return "index";
}
}
}
这是最常规的⽤户登录的代码,思路就是拿着⽤户名到数据库⾥⾯查询,如果能查到,则说明⽤户名⽆误,如果查不到则说明没有此⽤户,提⽰⽤户注册.如果⽤户名存在,再⽐对密码,⼀般密码不会像我们这样直接在数据库⾥⾯使⽤明⽂密码,都是会加盐的(MD5算法).如果⽐对密码的结果为true,则⽤
户可以登录.⽐对过程isUser的代码如下.
@Service
public class LoginService {
private UserMapper userMapper;
@Autowired
public LoginService(UserMapper userMapper) {
this.userMapper = userMapper;
}
/**
* 判断⽤户名或密码是否正确
* @param user
* @return
*/
public boolean isUser(User user){
UserExample example = new UserExample();
UserExample.Criteria criteria  = ateCriteria();
criteria.Username());
List<User> eqUser = userMapper.selectByExample(example);
//如果没有查询到user,则返回false
if (eqUser == null){
return false;
}
(0).getPassword().Password());
}
}
确认⽤户登录以后,需要把⽤户信息放在session中以便后续过程使⽤.
###⽤户购物模块
当⽤户登录以后,展⽰在⽤户眼前的界⾯是这样的(页⾯模板来⾃菜鸟教程,经过改编):
左栏中的数据来⾃登录代码中的
List<Common> commons = commonService.selectAllCommons();
model.addAttribute("commons", commons);
当点击加⼊购物车以后,触发onlick事件:onclick="javascript:joinCart(${common.id})"详细代码如下:
function joinCart(id) {
$.ajax({
url: "${tPath}/shop/joinCart",
data: "id=" + id,
type: "POST",
success: function (result) {
alert("加⼊购物车成功!");
//清空购物车列表
$("#shop_cart tbody").empty();
//动态构建购物车列表
var obj = result;
$.each(obj,function (index,item) {
var emptyTd = $("<td></td>").append("#");
var commnameTd = $("<td></td>").append(itemmname);
var countTd = $("<td></td>").unt);
var subtotalTd = $("<td></td>").append(item.subtotal);
$("<tr></tr>")
.append(emptyTd)
.append(commnameTd)
.append(countTd)
.append(subtotalTd)
.appendTo("#shop_cart tbody");
//设置总⾦额
var totalSpan = ElementById("subtotal");
totalSpan.innerHTML = al;
});
}
})
}
可以看到,当触发这个⽅法时,实际上是使⽤了异步请求的⽅式向服务端发送数据,服务端做相应处理以后,封装购物车列表,然后把购物车商品列表以JSON格式传回,也就是封装在result中,利⽤js,动态构建购物车列表.于是就出现下⾯这种情况.
当将商品加⼊购物车以后:
⾸先提⽰⽤户已经加⼊购物车,然后在利⽤异步请求构建整个购物车,如果你对前端的了解并不是很深,不必担⼼,这部分内容实际上很简单,你可以随便百度⼀下这个知识点,记住就好了.实际上就是利⽤js操作json数据⽽已.
其实对于初学者来说,感觉上⾯的过程挺神奇的,其实不然.前端的代码看完了,我就来给你详细的解释⼀下后端的代码.
⾸先,可以将后段代码分成两部分,⼀部分是判断,各种判断,另外⼀部分是封装数据,相对简单.
//标识符:判断是否存在此商品
boolean flag = false;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。