功能简述
本例采用jsp+servlet+mysql+jdbc+c3p0+ajax简单实现一个购物车的功能。
- 项目结构
service那层可以忽略,就不实现登录的功能了,还得加过滤器,主要就实现购物车就行了
JQ + jar包
链接:https://pan.baidu.com/s/1KN8EvSlraH_tHaynzW3znw
提取码:86je
复制这段内容后打开百度网盘手机App,操作更方便哦
项目源码:
链接:https://pan.baidu.com/s/1HjRL67r8JJg5KM2jhKthLA
提取码:4i2r
复制这段内容后打开百度网盘手机App,操作更方便哦
具体实现
在开发购物车之前,首先要把几个关键类之间的关系理清楚
首先各个类的意义:
- Product 产品
- User 用户
- Order 订单
- OrderItem 订单项
前3者都好理解,订单项需要解释一下。
比如阁下在某宝下了一次订单,这个订单包括了
黑色的丝袜 一条
娃娃 两个
抹布 三个
蜡烛 四个
一条记录就是一个订单项,对应一种商品,以及购买数量。
第一步建立product并且进行展示
在本地数据库中创建数据库cart
create database cart;
-
建立商品表product
CREATE TABLEproduct
(
id
int(11) DEFAULT NULL,
name
varchar(50) DEFAULT NULL,
price
float DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8; -
插入数据
insert into product values(1,‘黑色的丝袜’,500);
insert into product values(2,‘娃娃’,2500);
insert into product values(3,‘抹布’,180);
insert into product values(4,‘蜡烛’,0.20); -
product实体类
-
jdbc工具类
package com.chenchangjie.utils;import com.mchange.v2.c3p0.ComboPooledDataSource;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class JDBCUtil {private static ComboPooledDataSource dataSource;static {dataSource = new ComboPooledDataSource("testc3p0");}public static Connection getConnection() throws SQLException {Connection connection = null;connection = dataSource.getConnection();return connection;}public static void Close(ResultSet resultSet, PreparedStatement statement,Connection connection) throws SQLException {if(resultSet != null)resultSet.close();if(statement != null)statement.close();if(connection != null)connection.close();}
}
- c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?><c3p0-config><named-config name="testc3p0"><!--指定连接池的初始属性--><property name="jdbcUrl">jdbc:mysql://localhost:3306/cart?characterEncoding=utf-8&serverTimezone=UTC</property><property name="user">root</property><property name="password">你的密码</property><property name="driverClass">com.mysql.cj.jdbc.Driver</property><!--初始化连接池中的连接数量--><property name="initialPoolSize">20</property><!--请求过多时能连接的最大数量--><property name="maxPoolSize">40</property><!--一次可以递增的连接数量--><!--当连接池中剩余两个就开始递增--><property name="acquireIncrement">10</property><!--当连接池中到达最低剩余数量时,开始递增--><property name="minPoolSize">2</property></named-config>
</c3p0-config>
package com.chenchangjie.eneity;public class Product {private int id;private String name;private float price;public Product(int id, String name, float price) {this.id = id;this.name = name;this.price = price;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public float getPrice() {return price;}public void setPrice(float price) {this.price = price;}
}
- 从数据库中查询商品的接口以及实现类(还有通过id获取商品后面会用到)
package com.chenchangjie.Repository;import com.chenchangjie.eneity.Product;import java.util.List;public interface ProductRepository {List<Product> returnProduct();Product getProductById(int id);
}
实现类ProductRepositoryImpl.java
package com.chenchangjie.Repository.impl;import com.chenchangjie.Repository.ProductRepository;
import com.chenchangjie.eneity.Product;
import com.chenchangjie.utils.JDBCUtil;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;public class ProductRepositoryImpl implements ProductRepository {@Overridepublic List<Product> returnProduct() {List<Product> list = new ArrayList<>();Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = JDBCUtil.getConnection();String sql = "select * from product order by id";statement = connection.prepareStatement(sql);resultSet = statement.executeQuery();while(resultSet.next()){list.add(new Product(resultSet.getInt("id"),resultSet.getString("name"),resultSet.getFloat("price")));}} catch (SQLException throwables) {throwables.printStackTrace();} finally {try {JDBCUtil.Close(resultSet,statement,connection);} catch (SQLException throwables) {throwables.printStackTrace();}}return list;}@Overridepublic Product getProductById(int id) {Product product = null;Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = JDBCUtil.getConnection();String sql = "select * from product where id = ?";statement = connection.prepareStatement(sql);statement.setInt(1,id);resultSet = statement.executeQuery();while (resultSet.next()){product = new Product(resultSet.getInt(1),resultSet.getString(2),resultSet.getFloat(3));}} catch (SQLException throwables) {throwables.printStackTrace();}return product;}
}
- productServlet.java通过接收前端的数据和请求然后响应回去,响应的数据来源就是上面的
ProductRepositoryImpl.java
package com.chenchangjie.servlet;import com.chenchangjie.Repository.ProductRepository;
import com.chenchangjie.Repository.impl.ProductRepositoryImpl;
import com.chenchangjie.eneity.Product;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;@WebServlet("/productList")
public class ProductServlet extends HttpServlet {private ProductRepository productRepository = new ProductRepositoryImpl();@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {List<Product> list = productRepository.returnProduct();req.setAttribute("list",list);req.getRequestDispatcher("index.jsp").forward(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}
index.jsp```html
<%--Created by IntelliJ IDEA.User: 陈老CDate: 2020-12-9Time: 15:21To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8" import="java.util.*"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head><title>Title</title><script type="text/javascript" src="/js/jquery-1.7.2.js"></script><script type="text/javascript">$(function () {// console.log("login");$("button.AddCartBtn").click(function () {// console.log("click");let num = parseInt($("input.num").val());let pid = parseInt($(this).attr("pid"));// console.log(num + " " + pid);$.ajax({url:'/addOrderItem',type:'post',dataType:'text',data:'type=add&pid=' + pid + '&num=' + num,success:function (data) {alert("添加购物车成功")}});})});</script>
</head>
<body>
<c:if test="${!empty user}"><div align="center">当前用户: ${user.name}</div>
</c:if>
<table align='center' border='1' cellspacing='0'><tr><td>id</td><td>名称</td><td>价格</td><td>购买</td></tr><c:forEach items="${list}" var="product" varStatus="st"><tr><td>${product.id}</td><td>${product.name}</td><td>${product.price}</td><td>数量<input class="num" type="text" value="1" name="num">
<%-- <input id="addCart" type="submit" value="购买">--%><!--多个部件不用id选择器,用类选择器--><button class="AddCartBtn" pid="${product.id}">加入购物车</button></td></tr></c:forEach>
</table>
<a href="listOrderItem.jsp">购物车</a>
<%--<form action="/productList" method="get"><input type="submit" value="购物车"/>--%>
</body>
</html>
然后访问localhost:8080/productList
就能看见商品
点击加入购物车按钮就会进入/addOrderItem
进入相应的逻辑处理,这里是通过ajax异步请求到/addOrderItem
里面;
- OrderItemAddServlet.java
package com.chenchangjie.servlet;import com.chenchangjie.Repository.ProductRepository;
import com.chenchangjie.Repository.impl.ProductRepositoryImpl;
import com.chenchangjie.eneity.OrderItem;
import com.chenchangjie.eneity.Product;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;@WebServlet("/addOrderItem")
public class OrderItemAddServlet extends HttpServlet {private ProductRepository productRepository = new ProductRepositoryImpl();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {int num = Integer.parseInt(req.getParameter("num"));int pid = Integer.parseInt(req.getParameter("pid"));String type = req.getParameter("type");Product product = productRepository.getProductById(pid);OrderItem orderItem = new OrderItem(product,num);List<OrderItem> list = (List<OrderItem>) req.getSession().getAttribute("ois");if(list == null){list = new ArrayList<>();req.getSession().setAttribute("ois",list);}//检查是否有重复的数量boolean flag = false;for(OrderItem o : list){if(o.getProduct().getId() == product.getId()){o.setNum(o.getNum() + num);flag = true;break;}}if(!flag)list.add(orderItem);resp.sendRedirect("index.jsp");}
}
- listOrderItem.jsp展示购物车里面的内容
<%--Created by IntelliJ IDEA.User: 陈老CDate: 2020-12-9Time: 17:14To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><h1 align="center" >购物车</h1>
<table align='center' border='1' cellspacing='0'><tr><td>商品名称</td><td>单价</td><td>数量</td><td>小计</td></tr><c:forEach items="${ois}" var="oi" varStatus="st"><tr><td>${oi.product.name}</td><td>${oi.product.price}</td><td>${oi.num}</td><td>${oi.product.price*oi.num}</td><td><a href="/deleteOrderItem?pName=${oi.product.name}" type="delete">删除</a></td></tr></c:forEach>
</table><a href="/productList">回到购物页面</a>