JavaEE学习日志(五十八)
- JavaWeb案例
- 展示所有商品数据
- 删除商品
- 条件查询
- 分页查询
JavaWeb案例
展示所有商品数据
管理员后台展示所有商品
数据库表
代码实现
前端关键代码一:左侧那部分
<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);
}
条件查询
由于是案例练习,不做验证
前端:添加查询的部分
<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>
实现步骤:
- 客户端填写数据,提交服务器
- 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);
}
结果
分页查询
首先,找出分页查询需要的五个数据,封装到一个JavaBean中
分页的三层架构
代码实现
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>