电商网站搭建(四)
4 商城页面和商品详情页面设计
4.1 超链接传值
由于商城页面也是为了显示数据库中保存的商品信息,因此和之前的后台查询代码基本相似,但是这里要实现一个特殊功能就是商品名称是一个超链接。
由于每个商品详情页内容均不同,但是又不能每次新增商品就新建一个 jsp 文件,因此这里使用超链接传值的方式,将商品代码传递过去,再通过查询语句将该代码对应的商品信息取出。
对应代码如下,传递参数为 detailid
。
out.print("<td><a href=\"shopdetail.jsp?detailid=" + rs.getString(1) + "\">" + rs.getString(2) + "</a></td>");
同时在 shopdetail.jsp
页面使用如下代码接收值:
String dbid = request.getParameter("detailid");
连接数据库时查询语句如下:
String SQL = "SELECT * FROM shopProducts where proid = " + dbid;
核心代码如下:
try{
con = DriverManager.getConnection(url, user, password);
sql = con.createStatement();
String SQL = "SELECT * FROM shopProducts where proid = " + dbid;
rs = sql.executeQuery(SQL);
while(rs.next()){
out.print("<img src=\"images/" + rs.getString(1) + ".jpg\" height=\"200px\">");
out.print("<p>商品名称:" + rs.getString(2) + "</p>");
out.print("<p>商品价格:" + rs.getString(3) + "元</p>");
out.print("<p>店铺:" + rs.getString(4) + "</p>");
if(rs.getString(5) == null){
out.print("<p>详细信息:暂无</p>");
}
else{
out.print("<p>详细信息:" + rs.getString(5) + "</p>");
}
}
con.close();
}
catch(SQLException e){
out.print("<h1>"+e);
}
商城页面显示结果如下:
商品详情页面显示结果如下:
4.2 购物车页面设计
4.2.1 初步显示
详情页面除了要显示对应的商品信息,还要提供加入购物车等功能。
购物车这里设想就是一张大表,这张表中存储所有用户的订单信息,主键由用户号和商品号组成。
先创建表 userProd
,代码如下:
create table userProd(
usrid int,
proid int,
pronum int NOT NULL,
PRIMARY KEY (`usrid`, `proid`)
);
商品加入购物车时将用户号、商品号和数量传递到购物车页,在购物车页将这些数据插入表中,并且通过 SQL 语句,将该用户的订单信息从订单表中取出,代码如下:
String SQL = "SELECT proname,proprice,stoname,pronum FROM userProd as s1 " +
"left join shopproducts as s2 on s1.proid = s2.proid " +
"where usrid = " + session.getAttribute("userID");
可以看出,以上 SQL 语句进行了表连接,并且是按照用户号取出数据。
以上就完成了不同用户取出其对应的要购买的商品的功能。
4.2.2 更改数量
这一步如果不使用 js 实现,在我入门 jsp 之后来实现起来相当困难,下面将详细解释我是如何通过繁琐的步骤实现的更改数量。
首先我们要明确,我们更改数量之后,是希望同时将数据库表中的数据进行更新的。
以下将表单部分分成三部分,层层递进解析结构。
- 第一层:
<!-- 这个表单把整个购物车包住 -->
<form action="" method="post">
<!-- Java代码片 -->
<input type="submit" />
</form>
使用 form
表单将其完全包住的原因是要一次性将里面所有的数值全部提交。
- 第二层:
// Java代码片
// 连接数据库相关操作(省略)
// 多表连接查询
try{
con = DriverManager.getConnection(url, user, password);
sql = con.createStatement();
String SQL = "SELECT s1.proid,proname,proprice,stoname,pronum FROM userProd as s1 " +
"left join shopproducts as s2 on s1.proid = s2.proid " +
"where usrid = " + session.getAttribute("userID");
rs = sql.executeQuery(SQL);
int i = 1;
while(rs.next()) {
out.print("<tr style=\"color:#333333\">");
out.print("<td>" + rs.getString(2) + "</td>");
out.print("<td>" + rs.getString(3) + "</td>");
out.print("<td>" + rs.getString(4) + "</td>");
// 循环输入框,用于修改数值
out.print("</tr>");
i = i + 1;
}
con.close();
}
catch(SQLException e) {
out.print("");
}
这里要注意的一点是使用了一个变量 i
,该变量的设置是为了下面循环给 <input>
起名。
- 第三层:
<!-- 循环输入框内容 -->
<td>
<input type="text" name="changenum<%= i %>" value="<%= rs.getString(5) %>"/>
<input type="hidden" name="changeproid<%= i %>" value="<%= rs.getString(1) %>"/>
</td>
可以看见每次循环都使用不同的命名,这样的话后续提交值的时候就可以和商品一一对应了。
以上三层完成的是将要更改的数据输入并标识出是哪里修改的,下面就要完成连接数据库进行更新的操作。
整体数据库连接代码如下:
// 加载JDBC-MySQL8.0连接器
// 插入记录
try{
con = DriverManager.getConnection(url, user, password);
sql = con.createStatement();
String SQL = "SELECT COUNT(*) FROM userProd as s1 " +
"left join shopproducts as s2 on s1.proid = s2.proid " +
"where usrid = " + session.getAttribute("userID"); // 1
rs = sql.executeQuery(SQL); // 2
String count = ""; // 3
while(rs.next()) {
count = rs.getString(1); // 4
}
int countnum = Integer.parseInt(count); // 5
for(int i=1; i<=countnum; i++){
// 6
String a = "changenum" + Integer.toString(i);
String b = "changeproid" + Integer.toString(i);
// 7
String changenumg = request.getParameter(a);
String changeproidg = request.getParameter(b);
String updateSQL = "update userProd " + "set pronum = '" + changenumg + "' where usrid='" + session.getAttribute("userID") + "' and proid='" + changeproidg + "';";
int ok = sql.executeUpdate(updateSQL);
}
con.close();
}
catch(SQLException e) {
out.print("");
}
- 1 使用
COUNT()
聚合函数得到该用户放入购物车的商品总数量。 - 2 得到结果集。
- 3 创建
count
用于存放该用户购物车商品总数量。 - 4 得到该用户购物车商品总数量。
- 5 为了做循环,将字符串转换成整型
- 6 构造上述代码中的
name
部分。 - 7 得到每条记录对应的相关数据,并进行更新操作。
4.2.3 删除商品
删除商品如果在每一个商品后都加上删除按钮,不使用 js 等代码实现起来十分困难,因此这里转换一种思路,通过选中商品,点击确认删除,连接数据库将选中项删除。
这里需要进行修改的地方首先是在每个商品最前面加上单选框,如果单选框选中则传递值 ok
否则为 null
。
<td>
<input type="radio" name="choosethis<%= i %>" value="ok"/>
</td>
然后设置提交按钮,由于一个表单中出现两个提交按钮,就需要在进行操作的时候区分这两个提交按钮。
<button type="submit" name="svch" value="1">保存修改</button>
<button type="submit" name="svdl" value="1">确认删除</button>
在下面我们可以通过一段 Java 代码检验程序是否正常运行。
String svchg = request.getParameter("svch");
String svdlg = request.getParameter("svdl");
if(svchg==null || svchg.length()==0){
svchg = "";
}
if(svdlg==null || svdlg.length()==0){
svdlg = "";
}
out.println("保存修改:" + svchg + "<br />");
out.println("确认删除:" + svdlg + "<br />");
String c = "choosethis" + "1";
String cg = request.getParameter(c);
out.println("单选框1:" + cg + "<br />");
String d = "choosethis" + "2";
String dg = request.getParameter(d);
out.println("单选框2:" + dg);
验证结果如下,程序正常运行,可以标识出选中的提交按钮以及单选框。
之后的代码基本和上面的相似,也是通过循环将每个值进行相应的操作,核心代码如下:
for(int i=1; i<=countnum; i++){
String c = "choosethis" + Integer.toString(i);
String d = "changeproid" + Integer.toString(i);
String choosethisg = request.getParameter(c);
String changeproidg = request.getParameter(d);
if(changeproidg==null || changeproidg.length()==0){
changeproidg = "";
}
if(choosethisg.equals("ok")){
String updateSQL = "delete from userProd where usrid='" + session.getAttribute("userID") + "' and proid='" + changeproidg + "';";
int ok = sql.executeUpdate(updateSQL);
}
}
此时本页面所有功能基本实现,但是会发现每次操作之后都需要进行页面的刷新才能保证伪实时更改,因此在这里设置一个标记,该标记的作用是:当表单提交时,重定向回本页面实现页面的刷新。
// 刷新页面使用,伪动态更新数据
String cont = request.getParameter("control");
if(cont==null || cont.length()==0){
cont = "";
}
if(cont.equals("1")){
response.sendRedirect("shopcart.jsp");
}
此时页面效果如下:
4.2.4 结算页面
结算页面的关键是计算消费总额,这里使用 SQL 语句进行计算:
String SQL1 = "SELECT sum(round(proprice*pronum,2)) FROM userProd as s1 " +
"left join shopproducts as s2 on s1.proid = s2.proid " +
"where usrid = " + session.getAttribute("userID");
其他部分基本上和之前一样,效果如下: