JavaEE学习日志(五十八)

  • JavaWeb案例
  • 展示所有商品数据
  • 删除商品
  • 条件查询
  • 分页查询


JavaWeb案例

展示所有商品数据

管理员后台展示所有商品

JAVAee实验总结与心得体会_删除商品

数据库表

JAVAee实验总结与心得体会_条件查询_02

代码实现
前端关键代码一:左侧那部分

<script type="text/javascript">
	
		d = new dTree('d');
		d.add('01',-1,'系统菜单树');
		d.add('0102','01','分类管理','','','mainFrame');
		d.add('010201','0102','分类管理','${pageContext.request.contextPath}/admin/category/list.jsp','','mainFrame');
		d.add('0104','01','商品管理');
		//修改商品管理菜单,超链接改变,到达获取所有数据的servlet
		d.add('010401','0104','商品管理','${pageContext.request.contextPath}/findAll','','mainFrame');
		document.write(d);
		
	</script>

前端关键代码二:商品展示

<%--
	商品展示
	forEach标签属性 varStatus循环变量状态
--%>
<c:forEach items="${list}" var="product" varStatus="vs">
<tr onmouseover="this.style.backgroundColor = '#CCCCCC'"
	onmouseout="this.style.backgroundColor = '#F5FAFE';">
	<td style="CURSOR: hand; HEIGHT: 22px" align="center"
		width="18%">${vs.count}</td>
	<td style="CURSOR: hand; HEIGHT: 22px" align="center"
		width="17%"><img width="40" height="45" src="${product.pimage}"></td>
	<td style="CURSOR: hand; HEIGHT: 22px" align="center"
		width="17%">${product.pname}</td>
	<td style="CURSOR: hand; HEIGHT: 22px" align="center"
		width="17%">${product.shop_price}</td>
	<%--数据表当中,1表示热门,0表示非热门--%>
	<td style="CURSOR: hand; HEIGHT: 22px" align="center"
		width="17%">${product.is_hot==1?"是":"不是"}</td>
	<td align="center" style="HEIGHT: 22px"><a
		href="${ pageContext.request.contextPath }/admin/product/edit.jsp">
			<img
			src="${pageContext.request.contextPath}/images/i_edit.gif"
			border="0" style="CURSOR: hand">
	</a></td>

	<td align="center" style="HEIGHT: 22px"><a href="#"> <img
			src="${pageContext.request.contextPath}/images/i_del.gif"
			width="16" height="16" border="0" style="CURSOR: hand">
	</a></td>
</tr>
</c:forEach>
<%--商品展示结束--%>

dao层

public class ProductDao {
    private QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
    /*
      方法 findAll()
    * 查询所有商品数据
    * 返回集合
    * */
    public List<Product> findAll() throws SQLException {
        String sql = "select * from product";
        return qr.query(sql,new BeanListHandler<Product>(Product.class));


    }
}

service层

public class ProductService {
    private ProductDao dao = new ProductDao();
    /*
        方法findAll
        调用dao层方法findAll()
        获取所有的数据,返回web层
     */
    public List<Product> findAll(){
        List<Product> list = null;
        try {
            list = dao.findAll();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }
}

web层

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
            调用业务层方法findAll
            获取集合,存储域对象
            转发到页面
         */
        ProductService service = new ProductService();
        List<Product> list = service.findAll();
        request.setAttribute("list",list);
        request.getRequestDispatcher("/admin/product/list.jsp").forward(request,response);
	}

删除商品

  • 点击删除图片,出现提示框(JS函数 confirm)
  • 获取点击商品的主键数据
  • 主键提交服务器的Servlet,然后通过三层架构传递到dao层
  • dao层执行sql语句,删除数据
  • Servlet为客户端作出响应,重新展示所有数据

代码实现
前端页面:在删除图片,添加一个点击事件
注意:

  • '${product.pid}',加单引号是因为主键为字符串类型
<td align="center" style="HEIGHT: 22px"><a href="#"> 
<img
		src="${pageContext.request.contextPath}/images/i_del.gif"
		width="16" height="16" border="0" style="CURSOR: hand"
		onclick="delProduct('${product.pid}')">
</a></td>
function delProduct(pid) {
	if(confirm("确定要删除吗")){
		//获取点击的商品主键
		//主键数据提交到服务器Servlet
		location.href="${pageContext.request.contextPath}/delProduct?pid="+pid;
	}
}

dao层

/*
        方法delProduct()
        用于删除指定的商品数据
        业务层传递商品主键
     */
    public void delProduct(String pid) throws SQLException {
        String sql = "delete from product where pid=?";
        qr.update(sql,pid);
    }

service层

/*
        方法delProduct
        用于删除指定的商品数据
        Web层调用方法,传递主键
        主键传递到dao层
     */
    public void delProduct(String pid){
        try {
            dao.delProduct(pid);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

web层

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
            获取客户端提交的商品主键
            调用业务层方法,传递主键
            响应不要直接回到页面
            转发到查询所有数据的servlet
         */
        String pid = request.getParameter("pid");
        ProductService service = new ProductService();
        service.delProduct(pid);
        request.getRequestDispatcher("/findAll").forward(request,response);
    }

条件查询

由于是案例练习,不做验证

JAVAee实验总结与心得体会_条件查询_03


前端:添加查询的部分

<tr>
					<td class="ta_01" align="center" bgColor="#afd1f3">
						商品名称<input type="text" name="pname">
						价格区间<input type="text" name="min_price">-<input type="text" name="max_price">
						是否热门<select name="is_hot">
							<option value="">不限</option>
							<option value="1">是</option>
							<option value="0">不是</option>
					</select>
						<input type="submit" value="查询">
					</td>
				</tr>

JAVAee实验总结与心得体会_web_04


实现步骤:

  • 客户端填写数据,提交服务器
  • Servlet获取客户端提交的数据,需要进行中文处理
  • 提交的数据存储到JavaBean中(Search)
  • JavaBean通过三层架构,传递到dao层
  • 取出JavaBean中存储的查询条件;根据条件内容,动态地拼接处需要的SQL;查询结果返回到业务层
  • Servlet获取结果集存储到域对象,转发页面

dao层(关键)
注意

  • 使用动态sql语句拼接,即在where后加上一个结果为true的判断,然后就可以使用and进行查询条件的拼接。需要注意and前加上空格
  • 模糊查询时的问号占位符的实际参数写法:
    "%"+search.getPname() +"%"注意不能写成
    "'%"+search.getPname() +"%'"
  • 需要使用list集合存储问号占位符的实际参数,并在传递时将集合转为数组
public List<Product> findProduct(Search search) throws SQLException {
        //定义查询的sql语句
        String sql = "select * from product where 1=1";
        //创建集合,存储?占位符的实际参数
        List<Object> list = new ArrayList<Object>();


        //取出Search对象的数据,判断结果,拼接sql
        //判断pname商品名
        if (search.getPname() != null && !"".equals(search.getPname())) {
            sql += " and pname like ?";
            //向集合中添加商品名
            list.add("%"+search.getPname() +"%");
        }
        //判断min_price
        if (search.getMin_price() != null && !"".equals(search.getMin_price())) {
            sql += " and shop_price >= ?";
            list.add(search.getMin_price());
        }
        //判断max_price
        if (search.getMax_price() != null && !"".equals(search.getMax_price())) {
            sql += " and shop_price <= ?";
            list.add(search.getMax_price());
        }
        //判断is_hot
        if (search.getIs_hot() != null && !"".equals(search.getIs_hot())) {
            sql += " and is_hot = ?";
            list.add(search.getIs_hot());
        }
        return qr.query(sql,new BeanListHandler<Product>(Product.class),list.toArray());
    }

service层

/*
        方法findProduct()
        WEB层调用,传递封装好的Search对象
        调用dao层方法,传递Search对象
        返回结果集list
     */
    public List<Product> findProduct(Search search){
        List<Product> list = null;
        try {
            list = dao.findProduct(search);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

web层

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
            获取客户端提交的查询参数
            封装到JavaBean
            调用业务层方法,传递JavaBean
            返回结果list集合
            存储到域对象request
            转发页面list.jsp
         */
        request.setCharacterEncoding("utf-8");
        Map<String, String[]> map = request.getParameterMap();
        Search search = new Search();
        try {
            BeanUtils.populate(search,map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        ProductService service = new ProductService();
        List<Product> list = service.findProduct(search);
        request.setAttribute("list",list);
        request.getRequestDispatcher("/admin/product/list.jsp").forward(request,response);

    }

结果

JAVAee实验总结与心得体会_java_05


JAVAee实验总结与心得体会_删除商品_06

分页查询

JAVAee实验总结与心得体会_JAVAee实验总结与心得体会_07


首先,找出分页查询需要的五个数据,封装到一个JavaBean中

JAVAee实验总结与心得体会_java_08


分页的三层架构

JAVAee实验总结与心得体会_java_09


代码实现

PageBean:封装实现分页查询的数据

package com.itheima.domain;

import java.util.List;

/*
    封装实现分页查询的数据
    private List<Product>分页只能显示商品数据,不好
    适合所有的数据集合-->变成泛型
 */
public class PageBean<T> {
    //当前页数
    private int currentPage;
    //总数量
    private long totalCount;
    //总页数
    private int totalPage;
    //每页显示的条数
    private int pageSize;
    //分页中的数据,集合的数据类型,写成泛型
    private List<T> list;

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public long getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(long totalCount) {
        this.totalCount = totalCount;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }
}

web层

package com.itheima.web;

import com.itheima.domain.PageBean;
import com.itheima.domain.Product;
import com.itheima.service.ProductService;

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;

@WebServlet(urlPatterns = "/page")
public class PageServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
            获取客户端提交的当前页
            当前页传递业务层
            接收业务层返回PageBean
            存储到request域对象,转发回页码
         */
        String currentPage = request.getParameter("currentPage");
        if(currentPage == null){
            currentPage="1";
        }
        //调用业务层,传递当前页
        ProductService service = new ProductService();
        PageBean<Product> pageBean = service.getPageBean(Integer.parseInt(currentPage));
        request.setAttribute("pb",pageBean);
        request.getRequestDispatcher("/product_list.jsp").forward(request,response);

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

service层

package com.itheima.service;

import com.itheima.dao.ProductDao;
import com.itheima.domain.PageBean;
import com.itheima.domain.Product;
import com.itheima.domain.Search;

import java.sql.SQLException;
import java.util.List;

public class ProductService {
    private ProductDao dao = new ProductDao();

    /*
        定义方法,封装PageBean对象
        接收web层传递的当前页数
     */
    public PageBean<Product> getPageBean(int currentPage) {
        PageBean<Product> pb = new PageBean<>();
        //封装PageBean对象的数据
        try {
            //封装当前页
            pb.setCurrentPage(currentPage);
            //封装每页个数
            pb.setPageSize(12);
            //封装需要的商品数据
            //dao层查询,需要当前页和每页条数
            List<Product> list = dao.findByPage(currentPage, 12);
            pb.setList(list);
            //封装总数量
            long totalCount = dao.getTotalCount();
            pb.setTotalCount(totalCount);
            //封装总页数
            int totalPage = (int) Math.ceil(totalCount * 1.0 / 12);
            pb.setTotalPage(totalPage);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return pb;
    }

    /*
        方法findProduct()
        WEB层调用,传递封装好的Search对象
        调用dao层方法,传递Search对象
        返回结果集list
     */
    public List<Product> findProduct(Search search) {
        List<Product> list = null;
        try {
            list = dao.findProduct(search);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    /*
        方法delProduct
        用于删除指定的商品数据
        Web层调用方法,传递主键
        主键传递到dao层
     */
    public void delProduct(String pid) {
        try {
            dao.delProduct(pid);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /*
        方法findAll
        调用dao层方法findAll()
        获取所有的数据,返回web层
     */
    public List<Product> findAll() {
        List<Product> list = null;
        try {
            list = dao.findAll();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }
}

dao层

package com.itheima.dao;

import com.itheima.domain.Product;
import com.itheima.domain.Search;
import com.itheima.utils.C3P0UtilsXML;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ProductDao {
    private QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
    /*
        方法获取所有商品的总数量
        返回long
        查询的结果一个值
        结果集使用ScalarHandler
     */
    public long getTotalCount() throws SQLException {
        String sql = "select count(*) from product";
        return (long) qr.query(sql, new ScalarHandler());
    }
    /*
        方法获取分页查询的商品
        参数传递当前页,每页条数
        返回集合list
     */
    public List<Product> findByPage(int currentPage, int pageSize) throws SQLException {
        //拼写分页查询的sql
        String sql = "select * from product limit ?,?";
        return qr.query(sql,new BeanListHandler<Product>(Product.class),(currentPage-1)*pageSize,pageSize);

    }
    /*
        方法:findProduct()
        传递封装了查询条件的JavaBean
        查询后,返回结果list
     */
    public List<Product> findProduct(Search search) throws SQLException {
        //定义查询的sql语句
        String sql = "select * from product where 1=1";
        //创建集合,存储?占位符的实际参数
        List<Object> list = new ArrayList<Object>();


        //取出Search对象的数据,判断结果,拼接sql
        //判断pname商品名
        if (search.getPname() != null && !"".equals(search.getPname())) {
            sql += " and pname like ?";
            //向集合中添加商品名
            list.add("%"+search.getPname() +"%");
        }
        //判断min_price
        if (search.getMin_price() != null && !"".equals(search.getMin_price())) {
            sql += " and shop_price >= ?";
            list.add(search.getMin_price());
        }
        //判断max_price
        if (search.getMax_price() != null && !"".equals(search.getMax_price())) {
            sql += " and shop_price <= ?";
            list.add(search.getMax_price());
        }
        //判断is_hot
        if (search.getIs_hot() != null && !"".equals(search.getIs_hot())) {
            sql += " and is_hot = ?";
            list.add(search.getIs_hot());
        }
        return qr.query(sql,new BeanListHandler<Product>(Product.class),list.toArray());
    }

    /*
        方法delProduct()
        用于删除指定的商品数据
        业务层传递商品主键
     */
    public void delProduct(String pid) throws SQLException {
        String sql = "delete from product where pid=?";
        qr.update(sql, pid);
    }

    /*
      方法 findAll()
    * 查询所有商品数据
    * 返回集合
    * */
    public List<Product> findAll() throws SQLException {
        String sql = "select * from product";
        return qr.query(sql, new BeanListHandler<Product>(Product.class));


    }
}

前端显示

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>会员登录</title>
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />
<script src="js/jquery-1.11.3.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<!-- 引入自定义css文件 style.css -->
<link rel="stylesheet" href="css/style.css" type="text/css" />

<style>
body {
	margin-top: 20px;
	margin: 0 auto;
	width: 100%;
}

.carousel-inner .item img {
	width: 100%;
	height: 300px;
}
</style>
</head>

<body>


	<!-- 引入header.jsp -->
	<jsp:include page="/header.jsp"></jsp:include>


	<div class="row" style="width: 1210px; margin: 0 auto;">
		<div class="col-md-12">
			<ol class="breadcrumb">
				<li><a href="#">首页</a></li>
			</ol>
		</div>
		<%--
			遍历标签,取出域对象中的商品
			pb取出的是pageBean对象,pb对象的属性list才能拿到商品
		--%>
		<c:forEach items="${pb.list}" var="product">
		<div class="col-md-2" style="height: 240px">
			<a href="product_info.htm"> <img src="${product.pimage}"
				width="170" height="170" style="display: inline-block;">
			</a>
			<p>
				<a href="product_info.html" style='color: green'>${product.pname}</a>
			</p>
			<p>
				<font color="#FF0000">商城价:¥${product.shop_price}</font>
			</p>
		</div>
		</c:forEach>
		<%--遍历标签,取出域对象中的商品--%>


	</div>

	<!--分页 -->
	<div style="width: 380px; margin: 0 auto; margin-top: 50px;">
		<ul class="pagination" style="text-align: center; margin-top: 10px;">
			<%--
				上一页=当前页-1
				如果已经是第一页,不能点击
			--%>
			<c:if test="${pb.currentPage==1}">
				<li class="disabled"><a aria-label="Previous"><span
						aria-hidden="true">«</span></a></li>
			</c:if>
			<c:if test="${pb.currentPage!=1}">
				<li><a href="${pageContext.request.contextPath}/page?currentPage=${pb.currentPage-1}" aria-label="Previous"><span
						aria-hidden="true">«</span></a></li>
			</c:if>
			<%--
				页码:不是死的,而是循环出来的
				开始循环变量是1,循环到总页数结束
			--%>
			<c:forEach begin="1" end="${pb.totalPage}" var="i">
				<%--超链接:连接到分页Servlet,传递页码参数--%>
				<%--当前页数,页码不能点击,背景样式--%>
				<c:if test="${i==pb.currentPage}">
					<li class="active"><a>${i}</a></li>
				</c:if>
				<c:if test="${i!=pb.currentPage}">
					<li><a href="${pageContext.request.contextPath}/page?currentPage=${i}">${i}</a></li>
				</c:if>
			</c:forEach>

			<%--
				下一页=当前页+1
				如果是最后一页,不能点击
			--%>
			<c:if test="${pb.currentPage==pb.totalPage}">
				<li class="disabled"><a aria-label="Next"> <span aria-hidden="true">»</span></a></li>
			</c:if>
			<c:if test="${pb.currentPage!=pb.totalPage}">
				<li><a href="${pageContext.request.contextPath}/page?currentPage=${pb.currentPage+1}" aria-label="Next"> <span aria-hidden="true">»</span>
			</c:if>
			</a></li>
		</ul>
	</div>
	<!-- 分页结束 -->

	<!--商品浏览记录-->
	<div
		style="width: 1210px; margin: 0 auto; padding: 0 9px; border: 1px solid #ddd; border-top: 2px solid #999; height: 246px;">

		<h4 style="width: 50%; float: left; font: 14px/30px 微软雅黑">浏览记录</h4>
		<div style="width: 50%; float: right; text-align: right;">
			<a href="">more</a>
		</div>
		<div style="clear: both;"></div>

		<div style="overflow: hidden;">

			<ul style="list-style: none;">
				<li
					style="width: 150px; height: 216; float: left; margin: 0 8px 0 0; padding: 0 18px 15px; text-align: center;"><img
					src="products/1/cs10001.jpg" width="130px" height="130px" /></li>
			</ul>

		</div>
	</div>


	<!-- 引入footer.jsp -->
	<jsp:include page="/footer.jsp"></jsp:include>

</body>

</html>