购物车的实现(jsp的session+Java的Map的结合)

时间:2021-08-24 08:44:56

1:电商如此发达的现在,作为一个web开发程序猿,如果不会写购物车,真是有点不好意思找工作。所以抓紧练习啊,从上篇博客中抽离出如何实现购物车的功能。

2:首先需要理解购物车实现的一些基本步骤。
  2.1:首先考虑我购买的是哪一本书籍或者那一件商品,是不是,这里可以使用id传参确定购买的是那一件商品或者书籍,也可以使用session中取出哪一本书籍,这里采用从session的取出那一件商品或者书籍
       代码如:

      Book book=(Book)session.getAttribute("book");
     2.2:第二考虑如何把书籍放到购物车中
         2.1.1:首先考虑是否有购物车,如果没有,则创建,如果有直接使用
         2.1.2:其次先将购物车从session中拿出来,不存在就创建。
    代码如:

      Map<Integer,CartItem> cart=(Map<Integer,CartItem>)session.getAttribute("cart");
        //如果没有购物车,那么创建,只有第一次访问才会操作
        if(cart==null){
           //new一个购物车
          cart=new HashMap<>();
        }
    2.3:考虑如何把书籍放到购物车中
       2.1.1:第一考虑购物车中是否有该书籍,所以先从购物车中获取该书籍,如果为空,那么没有该书籍
     代码如:

    CartItem item=(CartItem)cart.get(book.getBookid());
       if(item==null){
             //如果购物车中不存在该书籍,那么创建,且数量默认为1
               item=new CartItem();
               //将书籍放到购物车中
              item.setBook(book);
              //将书籍的默认数量为1
              item.setNumber(1);
          }else{
              //如果购物车中以及有该书籍,那么数量加1
              item.setNumber(item.getNumber()+1);
          }
    2.4:考虑如何把购物车项(即挑选的书籍是哪一个和书本的数量)放到购物车中
      代码如:

    cart.put(book.getBookid(),item);
    2.5:将购物车放到session中,方便后面取出来
      代码如:

  session.setAttribute("cart", cart);


3:下面是具体的实现,从创建数据表开始,数据表book字段和数据名称如下所示:

 购物车的实现(jsp的session+Java的Map的结合)

4:下面创建实体类book.java;

 package com.bie.po;

 import java.io.Serializable;

 /**
* @author BieHongLi
* @version 创建时间:2017年2月27日 上午10:07:21
* 图书的实体类
*/
public class Book implements Serializable{ //实体类实现序列化,避免后面出现异常
private static final long serialVersionUID = 1L;
private Integer bookid;
private String bookname;
private Double price;
private String author;
private String pic;
private String publish;
public Integer getBookid() {
return bookid;
}
public void setBookid(Integer bookid) {
this.bookid = bookid;
}
public String getBookname() {
return bookname;
}
public void setBookname(String bookname) {
this.bookname = bookname;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
public String getPublish() {
return publish;
}
public void setPublish(String publish) {
this.publish = publish;
}
@Override
public String toString() {
return "Book [bookid=" + bookid + ", bookname=" + bookname + ", price=" + price + ", author=" + author
+ ", pic=" + pic + ", publish=" + publish + "]";
} }

5:创建好实体类接下来是写工具类BaseDao.java,用于连接数据库的操作,这些代码就不做多解释了,都已经写烂了。所以工具类一定要熟练书写

 package com.bie.utils;

 import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; /**
* @author BieHongLi
* @version 创建时间:2017年2月27日 上午10:09:00
* 连接数据库的工具类
*/
public class BaseDao { private static String driver="com.mysql.jdbc.Driver";
private static String url="jdbc:mysql:///test";
private static String user="root";
private static String password="123456"; /***
* 连接数据库的方法
* @return
* @throws ClassNotFoundException
* @throws SQLException
*/
public static Connection getCon() throws ClassNotFoundException, SQLException{
Class.forName(driver);//加载数据库驱动
System.out.println("测试加载数据库成功");
Connection con=DriverManager.getConnection(url, user, password);
System.out.println("测试数据库链接成功");
return con;
} /***
* 关闭数据库的方法
* @param con
* @param ps
* @param rs
*/
public static void close(Connection con,PreparedStatement ps,ResultSet rs){
if(rs!=null){//关闭资源,避免出现异常
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} /***
* 同意增删改的方法
* @param sql
* @param arr
* @return
*/
public static boolean addUpdateDelete(String sql,Object[] arr){
Connection con=null;
PreparedStatement ps=null;
try {
con=BaseDao.getCon();//第一步 :连接数据库的操作
ps=con.prepareStatement(sql);//第二步:预编译
//第三步:设置值
if(arr!=null && arr.length!=0){
for(int i=0;i<arr.length;i++){
ps.setObject(i+1, arr[i]);
}
}
int count=ps.executeUpdate();//第四步:执行sql语句
if(count>0){
return true;
}else{
return false;
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
} public static void main(String[] args) {
try {
BaseDao.getCon();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

6:写好工具类就可以进行写dao层(数据交互层),service层(业务逻辑层),先写数据交互层dao层,使用先创建接口再实现接口的方法

 package com.bie.dao;

 import java.util.List;

 import com.bie.po.Book;

 /**
* @author BieHongLi
* @version 创建时间:2017年2月27日 上午10:11:21
*
*/
public interface BookDao { /***
* 图书的查询的方法
* @param sql
* @param arr
* @return
*/
public List<Book> select(String sql,Object[] arr); /***
* 按照图书编号进行查询
* @param id
* @return
*/
public Book getBook(Integer id);
}
 package com.bie.dao.impl;

 import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; import com.bie.dao.BookDao;
import com.bie.po.Book;
import com.bie.utils.BaseDao; /**
* @author BieHongLi
* @version 创建时间:2017年2月27日 上午10:11:34
*
*/
public class BookDaoImpl implements BookDao{ @Override
public List<Book> select(String sql, Object[] arr) {
Connection con=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
con=BaseDao.getCon();//第一步连接数据库
ps=con.prepareStatement(sql);//第二步:预编译
if(arr!=null){
for(int i=0;i<arr.length;i++){
ps.setObject(i+1, arr[i]);
}
}
//第四步执行sql
rs=ps.executeQuery();
List<Book> list=new ArrayList<Book>();
while(rs.next()){
Book book=new Book();
book.setBookid(rs.getInt("bookid"));
book.setBookname(rs.getString("bookname"));
book.setPrice(rs.getDouble("price"));
book.setAuthor(rs.getString("author"));
book.setPic(rs.getString("pic"));
book.setPublish(rs.getString("publish")); list.add(book);
}
return list;
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//关闭资源,避免出现异常
BaseDao.close(con, ps, rs);
} return null;
} @Override
public Book getBook(Integer id) {
Connection con=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
con=BaseDao.getCon();//第一步连接数据库
String sql="select * from book where bookid = ? ";
ps=con.prepareStatement(sql);//第二步:预编译
ps.setInt(1, id); //第四步执行sql
rs=ps.executeQuery();
while(rs.next()){
Book books=new Book();
books.setBookid(rs.getInt("bookid"));
books.setBookname(rs.getString("bookname"));
books.setPrice(rs.getDouble("price"));
books.setAuthor(rs.getString("author"));
books.setPic(rs.getString("pic"));
books.setPublish(rs.getString("publish")); return books;
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//关闭资源,避免出现异常
BaseDao.close(con, ps, rs);
} return null;
} }

7:写好dao层(数据交互层),就可以写service层(业务逻辑层),写业务逻辑层service层,也是使用先创建接口再实现接口的方法

 package com.bie.service;

 import java.util.List;

 import com.bie.po.Book;

 /**
* @author BieHongLi
* @version 创建时间:2017年2月27日 上午10:13:38
*
*/
public interface BookService { /***
* 图书信息查询的方法
* @return
*/
public List<Book> select(Book book); /***
* 根据id进行查询
* @param id
* @return
*/
public Book getBook(Book book);
}
 package com.bie.service.impl;

 import java.util.ArrayList;
import java.util.List; import com.bie.dao.BookDao;
import com.bie.dao.impl.BookDaoImpl;
import com.bie.po.Book;
import com.bie.service.BookService; /**
* @author BieHongLi
* @version 创建时间:2017年2月27日 上午10:13:52
*
*/
public class BookServiceImpl implements BookService{ private BookDao dao=new BookDaoImpl(); public List<Book> select(Book book){
//String sql="select * from book ";
StringBuilder sql=new StringBuilder("select * from book where 1=1 ");
//sql语句
List<Object> list=new ArrayList<Object>();
if(book!=null){ if(book.getBookid()!=null && book.getBookid()!=0){
sql.append(" and bookid=? ");
list.add(book.getBookid());
}
/*list.add(book.getBookname());
list.add(book.getPrice());
list.add(book.getAuthor());
list.add(book.getPic());
list.add(book.getPublish());*/
} return dao.select(sql.toString(), list.toArray());
} @Override
public Book getBook(Book book) {
if(book.getBookid()!=null && book.getBookid()!=0){
return dao.getBook(book.getBookid());
}
return null;
} }

8:最后按照正常开发的话就是servlet层,但是这里将servlet层的代码写到了jsp里面。所以下面jsp页面才是大戏

  先创建一个book.jsp页面,用于显示从数据库查询到的图书数据

 <%@page import="java.util.List"%>
<%@page import="com.bie.service.impl.BookServiceImpl"%>
<%@page import="com.bie.po.Book"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>图书列表的页面</title>
</head>
<body>
<%
//图书的实体类创建一个对象
Book book=new Book();
//图书的业务逻辑层层
BookServiceImpl service=new BookServiceImpl();
List<Book> list=service.select(book);
%>
<div style="text-align:right;font-size:36px;">
<a href="docart.jsp">我的购物车</a>
</div>
<table align="center" width="100%">
<tr>
<th>编号</th>
<th>书名</th>
<th>价格</th>
<th>作者</th>
<th>封皮</th>
<th>出版社</th>
</tr>
<%
for(Book b:list){
%>
<tr align="center">
<td><%=b.getBookid() %></td>
<td><a href="dobook.jsp?id=<%=b.getBookid()%>"><%=b.getBookname() %></a></td>
<td><%=b.getPrice() %></td>
<td><%=b.getAuthor() %></td>
<td><%=b.getPic() %></td>
<td><%=b.getPublish() %></td>
</tr>
<%} %>
</table> </body>
</html>

9:当图书显示出来之后就可以根据图书编号查看图书详情了,接着写dobook.jsp页面和detail.jsp页面,这个显示图书的详细的信息的页面

 <%@page import="com.bie.service.impl.BookServiceImpl"%>
<%@page import="com.bie.service.BookService"%>
<%@page import="com.bie.po.Book"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>处理图书详细信息的页面</title>
</head>
<body>
<%
Book book=new Book();
String sid=request.getParameter("id");
Integer id=Integer.parseInt(sid);
BookService service=new BookServiceImpl();
book.setBookid(id);
Book books=service.getBook(book); session.setAttribute("book", books);
response.sendRedirect("detail.jsp");
%>
</body>
</html>
 <%@page import="com.bie.po.Book"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>图书详细信息的页面</title>
</head>
<body>
<%
Book book=(Book)session.getAttribute("book");
%>
<div style="text-align:right;font-size:36px;"> <a href="docart.jsp">我的购物车</a>
</div>
<table align="center" cellpadding="20" cellspacing="20">
<tr>
<td>图书编号</td>
<td>图书名称</td>
<td>图书价格</td>
<td>图书作者</td>
<td>图书封皮</td>
<td>图书出版社</td>
</tr>
<tr>
<td><%=book.getBookid() %></td>
<td><%=book.getBookname() %></td>
<td><%=book.getPrice() %></td>
<td><%=book.getAuthor() %></td>
<td><img src="data:images/<%=book.getPic() %>"></td>
<td><%=book.getPublish() %></td>
</tr>
<tr>
<td colspan="2"></td>
<td><a href="cart.jsp">添加到购物车</a></td>
<td><a href="book.jsp">图书列表</a></td> <td colspan="2"></td>
</tr>
</table>
</body>
</html>

10:写好上面的detail.jsp然后就可以在detail.jsp页面点击添加到购物车,下面实现购物车的功能,也是这个实现购物车的核心部分,参考的话是重点看的内容,当然在写购物车之前还需要创建一个实体类CartItem.java,用于存放图书的信息和购买的数量

 package com.bie.po;

 /**
* @author BieHongLi
* @version 创建时间:2017年2月27日 上午10:40:53
* 购物项
*/
public class CartItem { private Book book;// 图书对象的成员变量
private Integer number;// 购买的数量; public Book getBook() {
return book;
} public void setBook(Book book) {
this.book = book;
} public Integer getNumber() {
return number;
} public void setNumber(Integer number) {
this.number = number;
} }
 <%@page import="java.util.HashMap"%>
<%@page import="com.bie.po.CartItem"%>
<%@page import="java.util.Map"%>
<%@page import="com.bie.po.Book"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>添加到购物车</title>
</head>
<body>
<%
//购物车功能
//1:首先考虑我购买的是哪一本书籍,这里可以使用id确认也可以使用session中取出哪一本书籍
Book book=(Book)session.getAttribute("book"); //2:考虑如何把书籍放到购物车中
//2.1:首先考虑是否有购物车,如果没有,则创建,如果有直接使用
//2.2:其次先将购物车从session中拿出来,不存在就创建。
Map<Integer,CartItem> cart=(Map<Integer,CartItem>)session.getAttribute("cart");
//如果没有购物车,那么创建,只有第一次访问才会操作
if(cart==null){
//new一个购物车
cart=new HashMap<>();
} //3:考虑如何把书籍放到购物车中
//3.1:第一考虑购物车中是否有该书籍,所以先从购物车中获取该书籍,如果为空,那么没有该书籍
CartItem item=(CartItem)cart.get(book.getBookid());
if(item==null){
//如果购物车中不存在该书籍,那么创建,且数量默认为1
item=new CartItem();
//将书籍放到购物车中
item.setBook(book);
//将书籍的默认数量为1
item.setNumber(1);
}else{
//如果购物车中以及有该书籍,那么数量加1
item.setNumber(item.getNumber()+1);
} //4:考虑如何把购物车项(即挑选的书籍是哪一个和书本的数量)放到购物车中
cart.put(book.getBookid(),item); //5:将购物车放到session中,方便后面取出来
session.setAttribute("cart", cart); response.sendRedirect("book.jsp");
%>
</body>
</html>

11:写完上面的就可以查看我的购物车了,在book.jsp页面和detail.jsp页面都有可以点击查看我的购物车的连接,然后就可以查看我的购物车,完成购物车功能。

 <%@page import="com.bie.po.CartItem"%>
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>我的购物车的页面</title>
</head>
<body>
<table width="100%" align="center" border="1px">
<tr>
<th>书本编号</th>
<th>书本名称</th>
<th>书本单价</th>
<th>书本数量</th>
<th>书本小计</th>
</tr>
<%
//1:将添加到购物车里面的物品显示出来
Map<Integer,CartItem> map=(Map<Integer,CartItem>)session.getAttribute("cart");
//2:将购物车里面的内容遍历出来
double count=0;//显示出总价格
for(Map.Entry<Integer,CartItem> entry : map.entrySet()){
//计算出每一样的书籍一共花了多少钱
double price=entry.getValue().getBook().getPrice() * entry.getValue().getNumber();
//计算出一共花了多少钱
count=count+price;
%>
<tr align="center">
<td><%=entry.getKey() %></td>
<td><%=entry.getValue().getBook().getBookname() %></td>
<td><%=entry.getValue().getBook().getPrice() %></td>
<td><%=entry.getValue().getNumber() %></td>
<td><%=entry.getValue().getBook().getPrice() * entry.getValue().getNumber()%></td> </tr>
<%} %>
<tr>
<td colspan="4" align="right">价格总计</td>
<td><%=count %></td>
</tr>
</table>
<div style="text-align:center;font-size:36px;">
<a href="book.jsp">图书列表</a>
</div>
</body>
</html>

效果如下所示:

购物车的实现(jsp的session+Java的Map的结合)

虽然简陋,没有完全实现完,还待改善,继续加油!!!