一:高级查询+分页查询

操作步骤:0):把pageSize和currentPage封装到QueryObject对象中(任何查询对象都得接受用户传入的这两个数据).1):在IProductDAO接口中定义高级查询+分页查询方法.2):在ProductDAOImpl中实现该方法.3):测试代码.解决翻页是丢失高级查询数据的问题:造成的原因:翻页时,会重新发一次请求,该请求和高级查询表单没有关系.解决方案:使用JS解决:在翻页的时候:同时提交高级查询表单参数 和 当前第几页(currentPage).<a href="javascript:go(${1})">首页</a><a href="javascript:go(${pageResult.prevPage})">上页</a><a href="javascript:go(${pageResult.nextPage})">下页</a><a href="javascript:go(${pageResult.totalPage})">末页</a>跳转的函数:<script type="text/javascript">//提交表单function go(pageNo){//把需要跳转的页码设置到<input type="number" name="currentPage"/>上document.getElementById("currentPage").value = pageNo;//提交表单document.forms[0].submit();}</script>

DAO

public interface IProductdirDAO {List<Productdir> list();
}
public interface IProductDAO {PageResult query(ProductQueryObject qo);
}

Impl

public class BaseDAO {public PageResult query(Class<?> calssType,IQuery qo) {//默认把类名作为表名String tableName = calssType.getSimpleName();Table table = calssType.getAnnotation(Table.class);if(table!=null){tableName = table.value();}//查询结果总数String sqlCount = "SELECT count(*) from  " + tableName + qo.getQuery();Integer totalCount = JdbcTemplate.query(sqlCount, new ResultSetHandler<Long>() {public Long handle(ResultSet rs) throws Exception {if (rs.next()) {return rs.getLong(1);}return 0L;}},qo.getParameters().toArray()).intValue();if(totalCount == 0){return PageResult.empty(qo.getPageSize());}System.out.println("sqlCount:"+sqlCount);System.out.println("参数="+qo.getParameters());//====================================================================================//查询结果集String sqlList = "SELECT * from  " + tableName + qo.getQuery()+ " LIMIT ?,?";qo.getParameters().add((qo.getCurrentPage() -1)*qo.getPageSize());qo.getParameters().add(qo.getPageSize());List listdata = JdbcTemplate.query(sqlList, new BeanListHandler<>(calssType), qo.getParameters().toArray());System.out.println("sqlList:"+sqlList);System.out.println("参数="+qo.getParameters());return new PageResult(qo.getCurrentPage(),qo.getPageSize(),listdata,totalCount);}
}
public class ProductDAOImpl extends BaseDAO implements IProductDAO {public PageResult query(ProductQueryObject qo) {return super.query(Product.class, qo);}
}

query

//表示查询对象的规范,约束查询对象应该具有的方法
public interface IQuery {String getQuery();List<Object> getParameters();Integer getPageSize();Integer getCurrentPage();}
//封装了结果集的对象
@Getter
public class PageResult {private List listData;//结果集数据;通过SQL查询private Integer totalCount;//结果总条数;通过SQL查询private Integer currentPage = 1;//当前页;用户传入private Integer pageSize = 5;//每页条数;用户传入private Integer beginPage = 1;//首页 private Integer prevPage;//上页private Integer nextPage;//下页private Integer totalPage;//末页private List<Integer> pageItems = Arrays.asList(3,5,8,10);public static PageResult empty(Integer pageSize){return new PageResult(1,pageSize,Collections.EMPTY_LIST,0);}public PageResult( Integer currentPage, Integer pageSize,List listData, Integer totalCount) {this.listData = listData;this.totalCount = totalCount;this.currentPage = currentPage;this.pageSize = pageSize;//-------------------------------------this.totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;this.prevPage = currentPage - 1 >= 1 ? currentPage - 1 : 1;this.nextPage = currentPage + 1 <= totalPage ? currentPage + 1 : totalPage;}
}
//封装了商品对象的查询条件,并且它继承了currentPage,pageSize的封装
@Getter
@Setter
public class ProductQueryObject extends QueryObject{private String name;private BigDecimal minSalePrice; private BigDecimal maxSalePrice;private Long dir_id = -1L;private String keyword;protected void customizedQuery() {if(StringUtils.isNotBlank(name)){super.addQuery("productName LIKE ?", "%"+name+"%");}//最低价格if(minSalePrice != null){super.addQuery("salePrice >= ?", minSalePrice);}//最高价格if(maxSalePrice != null){super.addQuery("salePrice <= ?", maxSalePrice);}if(dir_id != -1){super.addQuery("dir_id = ?", dir_id);}if(StringUtils.isNotBlank(keyword)){//因为AND优先级大于OR,得使用()括起来super.addQuery(" (productName LIKE ? OR brand LIKE ? )", "%"+keyword+"%","%"+keyword+"%");}}
}
//封装了商品对象的查询条件
@Getter
@Setter
public class ProductdirQueryObject extends QueryObject{private String name;private Long parent_id = -1L;//自身的订制查询public void customizedQuery() {//商品分类名称if (StringUtils.isNotBlank(name)) {super.addQuery("productdir LIKE ?", "%" + name + "%");}//父分类if (parent_id != -1) {super.addQuery(" parent_id = ?", parent_id);}}
}
public class QueryObject implements IQuery{@Getter@Setterprivate Integer currentPage = 1;//当前页;用户传入@Getter@Setterprivate Integer pageSize = 5;//每页条数;用户传入private List<String> conditions = new ArrayList<>();//封装占位符参数private List<Object> parameters = new ArrayList<>();private boolean isBuild = false;//是否已经构建SQL/封装参数//初始化操作public void init(){if(!isBuild){isBuild = true;this.customizedQuery();}}//返回查询条件,如:WHERE productName LIKE ? AND salePrice >= ?public String getQuery() {this.init();StringBuilder sql = new StringBuilder();if (conditions.size() == 0) {return "";}String queryString = StringUtils.join(conditions, " AND ");return sql.append(" Where ").append(queryString).toString();}//返回查询条件中的占位符参数值public List<Object> getParameters() {this.init();return parameters;}//暴露给子类,让子类编写自个的查询方式protected void customizedQuery(){}//暴露给子类:让子类在customizedQuery中调用,添加自己的查询条件和参数protected void addQuery(String condition,Object...param){this.conditions.add(condition);this.parameters.addAll(Arrays.asList(param));}
}

Servlet

@WebServlet("/product")
public class ProductServlet extends HttpServlet {private static final long serialVersionUID = 1L;private IProductDAO dao;private IProductdirDAO dao_dir;public void init() throws ServletException {dao = new ProductDAOImpl();dao_dir = new ProductdirDAOImpl();}//列表操作protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("UTF-8");//1:接受请求参数,封装对象//2:调用业务方法处理请求ProductQueryObject qo = new ProductQueryObject();this.request2Object(req,qo);req.setAttribute("qo",qo);PageResult pageResult = dao.query(qo);req.setAttribute("pageResult", pageResult);req.setAttribute("dir", dao_dir.list());//3:控制界面跳转req.getRequestDispatcher("/WEB-INF/views/product/product.jsp").forward(req, resp);}//下面这段代码可以用commons-beanUtils 可以实现对象拷贝private void request2Object(HttpServletRequest req, ProductQueryObject qo) {String name = req.getParameter("name");String minSalePrice = req.getParameter("minSalePrice");String maxSalePrice = req.getParameter("maxSalePrice");String dir_id = req.getParameter("dir_id");String keyword = req.getParameter("keyword");String currentPage = req.getParameter("currentPage");String pageSize = req.getParameter("pageSize");if(StringUtils.isNotBlank(name)){qo.setName(name);}if(StringUtils.isNotBlank(minSalePrice)){qo.setMinSalePrice(new BigDecimal(minSalePrice));}if(StringUtils.isNotBlank(maxSalePrice)){qo.setMaxSalePrice(new BigDecimal(maxSalePrice));}if(StringUtils.isNotBlank(dir_id)){qo.setDir_id(Long.valueOf(dir_id));}if(StringUtils.isNotBlank(keyword)){qo.setKeyword(keyword);}if(StringUtils.isNotBlank(currentPage)){qo.setCurrentPage(Integer.valueOf(currentPage));}if(StringUtils.isNotBlank(pageSize)){qo.setPageSize(Integer.valueOf(pageSize));}}
}

jsp前端页面

<form action="/product" method="post">商品名称:<input type="text" name="name" value="${qo.name}"/>商品价格:<input type="text" name="minSalePrice" value="${qo.minSalePrice}"/>到<input type="text" name="maxSalePrice" value="${qo.maxSalePrice}"/>商品种类:<select name="dir_id"><option value="-1">全部商品</option><c:forEach items="${dir}" var="d"><option value="${d.id}" ${d.id == qo.dir_id? "selected":""} >${d.name}</option></c:forEach></select>关键字查询:<input type="text" name="keyword" placeholder="商品名称或商品品牌" value="${qo.keyword}"/><input type="submit" value=" 提交  " style="background-color: orange;"/>  <table border="1" width="80%" cellpadding="0" cellspacing="0"><tr style="background-color: orange"><th>id</th><th>productName</th><th>brand</th><th>supplier</th><th>salePrice</th><th>costPrice</th><th>cutoff</th><th>dir_id</th></tr><c:forEach items="${pageResult.listData}" var="p" varStatus="s"><tr style='background-color:${s.count % 2 == 0? "gray":""}'><td>${p.id}</td><td>${p.productName}</td><td>${p.brand}</td><td>${p.supplier}</td><td>${p.salePrice}</td><td>${p.costPrice}</td><td>${p.cutoff}</td><td><c:choose><c:when test="${p.dir_id == 1}">无线手机</c:when><c:when test="${p.dir_id == 3}">游戏手机</c:when><c:when test="${p.dir_id == 5}">有线手机</c:when></c:choose></td></tr></c:forEach><tr ><td colspan="8" align="center"><%@include file="/WEB-INF/views/commons/commons_page.jsp" %></td></tr></table>
</form>

这段代码是重构出来的代码,可以重复利用

        <script type="text/javascript">//提交表单function go(pageNo){//把需要跳转的页码设置到<input type="number" name="currentPage"/>上document.getElementById("currentPage").value = pageNo;//提交表单document.forms[0].submit();}</script><a href="javascript:go(${1})">首页</a><a href="javascript:go(${pageResult.prevPage})">上页</a><a href="javascript:go(${pageResult.nextPage})">下页</a><a href="javascript:go(${pageResult.totalPage})">末页</a>当前第${pageResult.currentPage}/${pageResult.totalPage}页,一共${pageResult.totalCount}条数据,跳转到<input type="number" min="1" max="${pageResult.totalPage}" id="currentPage" style="width: 50px" name="currentPage" value="${pageResult.currentPage}"/>页<input type="button" value="GO" onclick="go()"/>每页<select name="pageSize" onchange="go();"><c:forEach items="${pageResult.pageItems}" var="item"><option ${item == pageResult.pageSize? "selected":""}>${item}</option></c:forEach></select>条数据

domain

 * 商品对象
@Data
@Table("product")
public class Product {private Long id;//@Comlumn("name2")当列名是name2的时候private String productName;private String brand;private String supplier;private BigDecimal salePrice;private BigDecimal costPrice;private Double cutoff;private Long dir_id;//分类编号
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Table {String value() default "";
}
@Data
public class Productdir {private String name;private Long id;private Long parent_id;
}   

JDBC重构设计类

public class JdbcTemplate {private JdbcTemplate() {}/*** *@param sql   DML各自的SQL,由调用者决定*@param params      DML操作需要的参数,由调用者决定*@return     受影响的行数*/public static int update(String sql, Object... params) {Connection conn = null;PreparedStatement ps = null;try {conn = JdbcUtil.INSTANCE.getConn();ps = conn.prepareStatement(sql);for (int i = 0; i < params.length; i++) {ps.setObject(i + 1, params[i]);}return ps.executeUpdate();} catch (SQLException e) {e.printStackTrace();} finally {JdbcUtil.INSTANCE.close(conn, ps, null);}return 0;}public static <T>T query(String sql, ResultSetHandler<T> rsh ,Object... params) {Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {conn = JdbcUtil.INSTANCE.getConn();ps = conn.prepareStatement(sql);for (int i = 0; i < params.length; i++) {ps.setObject(i + 1, params[i]);}rs = ps.executeQuery();return rsh.handle(rs);} catch (Exception e) {e.printStackTrace();} finally {JdbcUtil.INSTANCE.close(conn, ps, rs);}return null;}
}
//表示结果集中的一行数据,封装成一个对象,专门针对结果集中只有一行数据的情况.
public class BeanHandler<T> implements ResultSetHandler<T>{private Class<T> classType;public BeanHandler(Class<T> classType){this.classType = classType;}/*** 规范:*      1:规定表中的列名必须和对象中的属性名相同.*      2:规定表中列名的类型必须和java中的类型要匹配. decimal  --->BigDecimal/bigint --->Long */public T handle(ResultSet rs) throws Exception {//1):创建对应的一个对象T obj = classType.newInstance();//2):取出结果集中当前光标所在行的某一列的数据.BeanInfo beanInfo = Introspector.getBeanInfo(classType,Object.class);   PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();if(rs.next()){for (PropertyDescriptor pd : pds) {String columnName = pd.getName();//获取对象的属性名称,属性名和列名相同Object val = rs.getObject(columnName);//3):调用该对象的setter方法,把某一列的数据,设置进去.pd.getWriteMethod().invoke(obj, val);}}return obj;}}
//表示把结果集中的多行数据,封装成一个对象的集合(List<xx>),针对于结果集中有多行数据的.
public class BeanListHandler<T> implements ResultSetHandler<List<T>> {private Class<T> classType;public BeanListHandler(Class<T> classType) {this.classType = classType;}public List<T> handle(ResultSet rs) throws Exception {List<T> list = new ArrayList<>();while(rs.next()) {//每一行封装成一个对象T obj = classType.newInstance();BeanInfo beanInfo = Introspector.getBeanInfo(classType, Object.class);PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();for (PropertyDescriptor pd : pds) {//获取对象的属性名称,属性名和列名相同String columnName = pd.getName();Object val = rs.getObject(columnName);//3):调用该对象的setter方法,把某一列的数据,设置进去.pd.getWriteMethod().invoke(obj, val);//把每一行对应的对象,存储到List集合中.}list.add(obj);}return list;}
}
//定义一个专门的约束处理结果集的接口:ResultSetHandler:结果集处理器
public interface ResultSetHandler<T> {T handle(ResultSet rs) throws Exception;
}

分页设计 与 高级查询 的 结合设计相关推荐

  1. SQL Server高级查询之数据库设计(E-R模型图)

    1.E-R模型(entity relationship) 实际就是利用E-R模型去绘制程序的执行流程图和程序决策图 以下就是一个简单的E-R模型图

  2. MYSQL之数据库设计范式和高级查询

    文章目录 1 数据库设计范式 范式一 范式二 范式三 反范式 高级查询 基础查询 条件查询 范围查询 判空查询 模糊查询 分页查询 查询后排序 聚合查询 分组查询 1 数据库设计范式 为了建立冗余较小 ...

  3. html条件查询,高级查询条件设置- 通用查询-报表设计初级教程

    普通布局下,多个查询条件之间是"AND"并且的关系.当多个条件之间存在着复杂的逻辑关系时,可以切换至高级布局面板,高级布局提供了括号和逻辑值的设置框,来完成条件之间逻辑关系的设置, ...

  4. ABP +VUE Elment 通用高级查询(右键菜单)设计+LINQ通用类Expression<Func<TFields, bool>>方法

    ABP +VUE Elment 通用高级查询(右键菜单)设计+LINQ通用类Expression 1. 目前需要用VUE实现源cs系统报表的右键菜单所有和自定义查询功能. 1.1 CS端的右键菜单效果 ...

  5. 基于javaweb的公交查询系统的设计与实现(含源文件)

    欢迎添加微信互相交流学习哦! 项目源码:https://gitee.com/oklongmm/biye 基于J2EE的公交查询系统的设计与实现 摘  要 公交查询系统是城市道路交通的重要组成部分,是城 ...

  6. 基于SSM框架的公交车查询系统的设计与实现

    源码获取:私聊回复[SpringBoot.公交查询]获取 更多选题参考: 计算机毕业设计.三级项目.五级项目.期末大作业.参赛作品等选题参考 文章目录 前言 一.背景及意义 选题背景 选题目的 二.系 ...

  7. MySQL数据库性能优化由浅入深(表设计、慢查询、SQL索引优化、Explain分析、Show Profile分析、配置优化)

    文章目录 0 SQL性能分析 1 表的设计合理化 1.1 为什么需要范式 1.2 三范式原理 1.3 什么样的表才满足三范式 2 慢查询 2.1 慢查询介绍 2.2 慢查询步骤 3 添加适当索引 3. ...

  8. java城市公交查询系统案例,城市公交查询系统的设计与实现(SQLServer)

    城市公交查询系统的设计与实现(SQLServer)(任务书,外文翻译,毕业论文19500字,程序代码,SQLServer数据库,答辩PPT) 摘    要 随着计算机技术的不断发展,计算机应用于各大领 ...

  9. 大数据查询——HBase读写设计与实践--转

    背景介绍 本项目主要解决 check 和 opinion2 张历史数据表(历史数据是指当业务发生过程中的完整中间流程和结果数据)的在线查询.原实现基于 Oracle 提供存储查询服务,随着数据量的不断 ...

最新文章

  1. 行为型模式之十一:备忘录模式
  2. C++中数组访问操作符的重载
  3. 《应用时间序列分析:R软件陪同》——2.3 随机游走
  4. SQL-left(right,inner) join
  5. 常用的python命令行解析库
  6. LoadRunner常用函数(转)
  7. Python 基础知识学习笔记——OpenCV(1)
  8. powerdesigner错误提示实体属性名称唯一性_SolidWorks用保存实体创建新零件与装配体...
  9. 无人编辑,人工智能编辑,AI编辑机器人-资讯频道编辑
  10. 深入剖析BIO到NIO演变史
  11. C# 汉字转拼音(支持GB2312字符集中所有汉字)
  12. Openbravo中文使用手册
  13. IPhone手机无法连接蓝牙
  14. python怎么退出全屏模式_notepad
  15. 你还相信节食能减肥?
  16. [转]从B树、B+树、B*树谈到R 树
  17. C# 根据传入的字符串生成拼音码,包含全码和简码
  18. 益智乐园——DuerOS的又一盈利之路
  19. hangye5:2345导航将出嫁史玉柱 网址站出路大盘点
  20. 一起读Java编程思想(2)---构造器的初始化与清理

热门文章

  1. windows效率工具,翻译软件QTranslate
  2. Spring框架----自动按照类型注入的Autowired注解
  3. iOS 13-Sign In with Apple
  4. 你不知道的JS之作用域和闭包(二)词法作用域
  5. java中的算术运算符、赋值运算符、比较运算符、逻辑运算符、条件运算符
  6. 《架构探险》第三章 项目核心实现
  7. IDEA下的第一个springBoot
  8. js基础之函数递传参数与作用域(5下)
  9. 【转】TYVJ 1695 计算系数(NOIP2011 TG DAY2 1)
  10. Asianux将成为最先进的安全Linux操作系统