Java大型互联网项目-移动电子商城-商品组合查询与分页展示
商品动态条件组合分页查询
- 动态条件处理
需要使用mybatis的动态sql - 分页
Oracle的分页sql
Oracle的分页必须要使用rownum, rownum支持小于号,不支持大于号,所以分页时需要子查询来处理大于号的问题
select *
from (select rownum rw, a.*
from (
select * from eb_item
) a
where rownum < 31) b
where b.rw > 20;
分页步骤:
(1) 查询全量结果集
(2) 以全量结果集作为一张表,以rownum作为查询条件小于开始行号,以全量结果集和rownum作为结果集,给rownum个别名
(3)以第(2)步的结果集作为一张表,以第二步的结果集中的rw作为查询条件让它大于开始行号,结果集为*即可
组合查询的Mybatis_动态SQL
<select id="selectItemByCondition" parameterType="com.rl.ecps.model.QueryCondition" resultMap="BaseResultMap">
select *
from (select rownum rw, a.*
from (
select * from eb_item t
<where>
<if test="brandId != null">
t.brand_id = #{brandId}
</if>
<if test="auditStatus != null">
and t.audit_status = #{auditStatus}
</if>
<if test="showStatus != null">
and t.show_status = #{showStatus}
</if>
<if test="itemName != null and itemName != ''">
and t.item_name like '%${itemName}%'
</if>
</where>
order by t.item_id desc
<![CDATA[
) a
where rownum < #{endNum}) b
where b.rw > #{startNum}
]]>
</select>
组合+分页查询出总记录数Mybatis_动态SQL
<select id="selectItemByConditionCount" parameterType="com.rl.ecps.model.QueryCondition" resultType="int">
select count(*) from eb_item t
<where>
<if test="brandId != null">
t.brand_id = #{brandId}
</if>
<if test="auditStatus != null">
and t.audit_status = #{auditStatus}
</if>
<if test="showStatus != null">
and t.show_status = #{showStatus}
</if>
<if test="itemName != null and itemName != ''">
and t.item_name like '%${itemName}%'
</if>
</where>
</select>
传给SQL的参数为自定义对象QueryCondition
package com.rl.ecps.model;
public class QueryCondition {
private Long brandId ;
private Short auditStatus ;
private Short showStatus ;
private String itemName ;
private Integer startNum ;
private Integer endNum ;
private Integer pageNo ;
public Integer getPageNo() {
return pageNo;
}
public void setPageNo(Integer pageNo) {
this.pageNo = pageNo;
}
public Long getBrandId() {
return brandId;
}
public void setBrandId(Long brandId) {
this.brandId = brandId;
}
public Short getAuditStatus() {
return auditStatus;
}
public void setAuditStatus(Short auditStatus) {
this.auditStatus = auditStatus;
}
public Short getShowStatus() {
return showStatus;
}
public void setShowStatus(Short showStatus) {
this.showStatus = showStatus;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public Integer getStartNum() {
return startNum;
}
public void setStartNum(Integer startNum) {
this.startNum = startNum;
}
public Integer getEndNum() {
return endNum;
}
public void setEndNum(Integer endNum) {
this.endNum = endNum;
}
}
其中starNum、endNum、pageNum为分页计算必要属性
<li><a href="${path}/item/listItem.do?showStatus=1&auditStatus=1"><samp class="t05"></samp>商品录入/上下架</a></li>
Page实体
计算过程在get方法中处理
package com.rl.ecps.model;
import java.util.List;
public class Page {
/**
* 当前页码 (已知)
*/
private int pageNo = 1;
/**
* 每页记录数(已知)
*/
private int pageSize = 5;
/**
* 指定的查询条件下的总记录数
*/
private int totalCount = 0;
/**
* 指定的查询条件下的总页数
*/
private int totalPage = 1;
/**
* 查询的开始行号
*/
private int startNum = 0;
/**
* 查询的结束行号
*/
private int endNum = 0;
/**
* 查询的结果集
*/
private List<?> list;
public int getPageNo() {
return pageNo;
}
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
/**
* totalCount pageSize totalPage
* 0 10 1
* 100 10 10
* 92 10 10
* @return
*/
public int getTotalPage() {
totalPage = totalCount/pageSize;
if(totalCount == 0 || totalCount%pageSize != 0){
totalPage++;
}
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getStartNum() {
return (pageNo - 1) * pageSize;
}
public void setStartNum(int startNum) {
this.startNum = startNum;
}
public int getEndNum() {
return pageNo * pageSize + 1;
}
public void setEndNum(int endNum) {
this.endNum = endNum;
}
public List<?> getList() {
return list;
}
public void setList(List<?> list) {
this.list = list;
}
}
转发
@RequestMapping("/listItem.do")
public String listItem(QueryCondition qc, Model model){
List<EbBrand> bList = brandService.selectBrandAll();
model.addAttribute("bList", bList);
if(qc.getPageNo() == null){
qc.setPageNo(1);
}
Page page = itemService.selectItemByQC(qc);
model.addAttribute("page", page);
//把qc写回去,目的是回显
model.addAttribute("qc", qc);
return "item/list";
}
初次传递的参数不含PageNo,把它设置为1
其中,itemService具体类代码如下
public Page selectItemByQC(QueryCondition qc) {
//查询当前的查询条件下的总记录数
int totalCount = itemDao.selectItemByConditionCount(qc);
//创建page对象
Page page = new Page();
page.setPageNo(qc.getPageNo());
page.setTotalCount(totalCount);
//计算startNum和endNum
Integer startNum = page.getStartNum();
Integer endNum = page.getEndNum();
//把值设置给sql的查询对象
qc.setStartNum(startNum);
qc.setEndNum(endNum);
//查询结果集
List<EbItem> itemList = itemDao.selectItemByCondition(qc);
page.setList(itemList);
return page;
}
qc的回传是为了在前端页面做回显的
经过以上方法我们的前端页面便有了回传的qc对象做回显,Page对象里有Item商品信息
前端页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/ecps/console/common/taglibs.jsp"%>
<head>
<title>商品录入及上下架管理_商品管理</title>
<meta name="heading" content="商品录入及上下架管理"/>
<meta name="menu" content="ItemMgmtMenu"/>
<script type="text/javascript" src="<c:url value='/${system}/res/js/jquery.form.js'/>"></script>
<script type="text/javascript" src="<c:url value='/${system}/res/js/jquery.tablesorter.js'/>"></script>
<script type="text/javascript">var path = "${path}";</script>
<script type="text/javascript" src="${path }/ecps/console/res/item/js/list.js">
</script>
</head>
<body id="main">
<div class="frameL"><div class="menu icon">
<jsp:include page="/${system}/common/itemmenu.jsp"/>
</div></div>
<form action="${path }/item/showItem.do" method="post" id="showForm">
<input id="itemId" name="itemId" type="hidden">
<input id="showStatus1" name="showStatus" type="hidden">
<input id="notes" name="notes" type="hidden">
</form>
<div class="frameR"><div class="content">
<div class="loc icon"><samp class="t12"></samp>当前位置:商品管理 » <span class="gray" title="商品录入及上下架">商品录入及上下架</span></div>
<h2 class="h2_ch"><span id="tabs" class="l">
<!-- <a id="label3" href="${base}/item/listEntity.do?showStatus=2" title="待上架实体商品" class="nor">待上架</a> -->
<a id="label6" href="${path}/item/listItem.do" title="全部实体商品" class="nor">全部</a>
<a id="label4" href="${path}/item/listItem.do?showStatus=1" title="未上架实体商品" class="nor">未上架</a>
<a id="label5" href="${path}/item/listItem.do?showStatus=0" title="已上架实体商品" class="nor">已上架</a>
</span></h2>
<form id="form1" name="form1" action="${path}/item/listItem.do" method="post">
<input type="hidden" id="showStatus" value="${qc.showStatus }" name="showStatus">
<div class="sch">
<p>搜索:
<select id="brandId" name="brandId">
<option value="">全部品牌</option>
<c:forEach items="${bList }" var="brand">
<option value="${brand.brandId }" <c:if test="${qc.brandId == brand.brandId }">selected</c:if> >${brand.brandName }</option>
</c:forEach>
</select>
<select id="auditStatus" name="auditStatus" >
<option value="" selected>全部审核状态</option>
<option value="0" <c:if test="${qc.auditStatus == 0 }">selected</c:if> >待审核</option>
<option value="1" <c:if test="${qc.auditStatus == 1}">selected</c:if>>通过</option>
<option value="2" <c:if test="${qc.auditStatus == 2 }">selected</c:if>>不通过</option>
</select>
<input type="text" id="searchText" value="${qc.itemName }" name="itemName" title="请输入商品名称" class="text20 medium gray" />
<input type="submit" id="goSearch" class="hand btn60x20" value="查询" />
</p></div>
<div class="page_c">
<span class="l">
</span>
<span class="r inb_a">
<a href="${path}/item/toAddItem.do" class="btn80x20" title="添加商品">添加商品</a>
</span>
</div>
<table cellspacing="0" summary="" class="tab" id="myTable">
<thead>
<tr>
<th>商品编号</th>
<th class="wp">商品名称</th>
<th>图片</th>
<th>新品</th>
<th>推荐</th>
<th>特价</th>
<th>上下架</th>
<th>审核状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${page.list }" var="item">
<tr>
<td>${item.itemNo }</td>
<td >${item.itemName }</td>
<td><img alt="" src="${request_file_path }${item.imgs}" width="50" height="50"></td>
<td>
<c:if test="${item.isNew == 1 }"><span class="is" ></span></c:if>
<c:if test="${item.isNew == 0 }"><span class="not" ></span></c:if>
</td>
<td>
<c:if test="${item.isGood == 1 }"><span class="is" ></span></c:if>
<c:if test="${item.isGood == 0 }"><span class="not" ></span></c:if>
</td>
<td>
<c:if test="${item.isHot == 1 }"><span class="is" ></span></c:if>
<c:if test="${item.isHot == 0 }"><span class="not" ></span></c:if>
</td>
<td>
<c:if test="${item.showStatus == 1 }"><span class="not" ></span></c:if>
<c:if test="${item.showStatus == 0 }"><span class="is" ></span></c:if>
</td>
<td>
<c:if test="${item.auditStatus == 0 }">待审核</c:if>
<c:if test="${item.auditStatus == 1 }">通过</c:if>
<c:if test="${item.auditStatus == 2 }">不通过</c:if>
</td>
<td>
<a href="/ecps-console/shop/item/viewItem.jsp" title="查看">查看</a>
<c:if test="${item.showStatus == 0 }">
<a href="javascript:void(0);" onclick="isShow(${item.itemId}, 1)">下架</a>
<a href="javascript:void(0);" onclick="publish(${item.itemId})" >发布</a>
</c:if>
<c:if test="${item.showStatus == 1 }">
<a href="/ecps-console/ecps/console/item/editItem.do?type=1&itemId=2384">编辑</a>
<a href="javascript:void(0);" onclick="singleDel('2384')">删除</a>
<a href="javascript:void(0);" onclick="isShow(${item.itemId}, 0)">上架</a>
</c:if>
</td>
</tr>
</c:forEach>
</tbody>
<tr>
<td colspan="13" align="right">
选择啊:<a href="javascript:void(0);" title="全选" onclick="checkAllIds();">全选法克</a>
<samp>-</samp> <a href="javascript:void(0);" title="取消" onclick="uncheckAllIds();">取消年末</a>
</td>
</tr>
</table>
<div class="page_c">
<span class="l inb_a">
</span>
<span class="r page">
<!-- 变化后的pageNo -->
<input type="hidden" id="pageNo" name="pageNo" />
<!-- 两个隐藏域用于判断上一页和下一页的展示和隐藏 -->
<input type="hidden" value="${page.pageNo}" id="currentPageNo" name="currentPageNo" />
<input type="hidden" value="${page.totalPage}" id="totalPage" name="totalPage" />
共<var id="pagePiece" class="orange">${page.totalCount }</var>条<var id="pageTotal">${page.pageNo }/${page.totalPage }</var>
<a href="javascript:void(0);" id="firstPage" class="hidden" >首页</a>
<a href="javascript:void(0);" id="previous" class="hidden" title="上一页">上一页</a>
<a href="javascript:void(0);" id="next" class="hidden" title="下一页">下一页</a>
<select id="selectPage">
<c:forEach begin="1" end="${page.totalPage }" var="myPage">
<option value="${myPage }">第${myPage }页</option>
</c:forEach>
</select>
<a href="javascript:void(0);" id="lastPage" class="hidden">尾页</a>
</span>
</div>
</form>
</div></div>
</body>
控制的相关JS代码
$(function(){
//获得上下架状态,只要是在页面上获得值都是String类型
var showStatus = parseInt($("#showStatus").val());
if(showStatus == 1){
$("#label4").attr("class", "here");
}else if(showStatus == 0){
$("#label5").attr("class", "here");
}else{
$("#label6").attr("class", "here");
}
//获得隐藏域的值
var pageNo = parseInt($("#currentPageNo").val());
var totalPage = parseInt($("#totalPage").val());
/**
* 判断翻页按钮展示
*/
if(pageNo == 1 && pageNo == totalPage){
$("#firstPage").hide();
$("#lastPage").hide();
$("#previous").hide();
$("#next").hide();
}else if(pageNo == 1 && totalPage > pageNo){
$("#firstPage").hide();
$("#lastPage").show();
$("#previous").hide();
$("#next").show();
}else if(pageNo > 1 && totalPage > pageNo){
$("#firstPage").show();
$("#lastPage").show();
$("#previous").show();
$("#next").show();
}else if(pageNo == totalPage && totalPage > 1){
$("#firstPage").show();
$("#lastPage").hide();
$("#previous").show();
$("#next").hide();
}
/**
* 点击下一页
*/
$("#next").click(function(){
pageNo++;
$("#pageNo").val(pageNo);
$("#form1").submit();
});
$("#previous").click(function(){
pageNo--;
$("#pageNo").val(pageNo);
$("#form1").submit();
});
$("#firstPage").click(function(){
$("#pageNo").val(1);
$("#form1").submit();
});
$("#lastPage").click(function(){
$("#pageNo").val(totalPage);
$("#form1").submit();
});
$("#selectPage").change(function(){
var myPage = $(this).val();
$("#pageNo").val(myPage);
$("#form1").submit();
});
提交表单时的参数QC被框架管理了