高级查询

作者: superNeil | 来源:发表于2020-05-22 11:26 被阅读0次

    分页和过滤查询

    流程图 :

    高级查询.jpg
    1 设计和原理分析
    image-20200521230058307.png
    前面我们已经讲过分页查询了 , 接下来我们讲讲 过滤查询 .

    思路 : 从后台开始写 , 写好测试 , 测试成功 ; 开始写前台 .

    这里我们需要 MyBatis动态sql语句

    为了解决在 xml 中拼接 SQL 的问题,此处需要来学习 MyBatis 的动态 SQL

    <where> 和<if> 标签的配合使用

    <select id="queryCount" resultType="int">
            SELECT count(*) FROM t_armoire
            <where>
                <if test="keyword!=null and keyword!=''">
                    AND supplier LIKE concat('%',#{keyword},'%')
                </if>
                <if test="minPrice!=null">
                    AND price >= #{minPrice}
                </if>
                <if test="maxPrice!=null">
                    AND price &lt;= #{maxPrice}
                </if>
            </where>
        </select>
        <select id="queryResult" resultType="armoire">
            SELECT * FROM t_armoire
            <where>
                <if test="keyword!=null and keyword!=''">
                    AND supplier LIKE concat('%',#{keyword},'%')
                </if>
                <if test="minPrice!=null">
                    AND price >= #{minPrice}
                </if>
                <if test="maxPrice!=null">
                    AND price &lt;= #{maxPrice}
                </if>
            </where>
            limit #{beginIndex},#{pageSize}
        </select>
    

    首先 , 我们现在需要用户传入的 过滤条件封装成对象 ArmoireQueryObject, 去继承 QueryObject ,这样我们通过 ArmoireQueryObject就可以获取用户传来的所有参数 .

    @ToString
    @AllArgsConstructor
    @NoArgsConstructor
    @Getter
    @Setter
    public class ArmoireQueryObject extends QueryObject {
        //用户传来   高级查询 的参数
        //1. 关键字  2. 最小值  3. 最大值
        private String keyword;
        private Integer minPrice;
        private Integer maxPrice;
        //继承  这样 其实已经有  5+2 + getBegin 数据了
    }
    

    list.jsp 操作步骤 添加在 form标签中

    <p align="center">                               //这里是value 是回显,可以先不管
            关键字:<input type="text" name="keyword" value="${aq.keyword}">
            价格:<input type="number" name="minPrice" value="${aq.minPrice}"> ~ <input type="number" name="maxPrice" value="${aq.maxPrice}">
            <input type="submit" value="提交"></p>
    

    注意:一般的,为了避免不必要的麻烦,让字段名称和表单中的请求参数名称相同 .

    DAO

    public interface IArmoireDAO {
        //高级查询 总条数
        int queryCount(ArmoireQueryObject aq);
        //高级查询 页面结果集
        List<?>queryResult(ArmoireQueryObject aq);
    }
    
    public class ArmoireDAOImpl implements IArmoireDAO {
        @Override
        public int queryCount(ArmoireQueryObject aq) {
            SqlSession sqlSession = MyBatisUtil.getSqlSession();
            int count = sqlSession.selectOne("cn.wolfcode.amis.mapper.ArmoireMapper.queryCount", aq);
            sqlSession.close();
            return count;
        }
    
        @Override
        public List<?> queryResult(ArmoireQueryObject aq) {
            SqlSession sqlSession = MyBatisUtil.getSqlSession();
            List<?>list = sqlSession.selectList("cn.wolfcode.amis.mapper.ArmoireMapper.queryResult", aq);
            sqlSession.close();
            return list;
        }
    }
    

    注意 ; MyBatisUtil 自己去拿 . 算了 还是写给你吧 (这是我封装好的工具类 , 拿去用吧 害 !)

    public class MyBatisUtil {
        private MyBatisUtil() {
            //私有化构造器
        }
        static SqlSessionFactory factory = null;
        static {
            try {
                factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public static SqlSession getSqlSession() {
            return factory.openSession();
        }
    }
    

    还有后面 service要用的工具类 , 方便点 , 统统给你. StringUtil

    public class StringUtil {
        private StringUtil(){
            //私有化构造器
        }
        //判空
        public static boolean hasLength(String str){
            return str!=null && !"".equals(str.trim());
        }
    }
    

    后台这样其实就已经写好了 , 测试下吧 . 成功继续...

    想想我们 需要给前台 返回什么数据 ??? 之前分页查询已经说过了 .

    两输 , 两查 , 三计算 封装成对象 .

    @NoArgsConstructor
    @AllArgsConstructor
    @Getter
    @Setter
    @ToString
    public class PageResult {
        //存 2输  2查 3计算
        private int currentPage;
        private int pageSize;
        //2查
        private int totalCount;
        private List<?> listResult;
        //3 计算  上一页 下一页 总页数
        private int totalPage;
        private int prevPage;
        private int nextPage;
        //自定义构造器
        public PageResult(int currentPage,int pageSize,int totalCount,List<?> listResult){
            this.currentPage=currentPage;
            this.pageSize=pageSize;
            this.totalCount=totalCount;
            this.listResult=listResult;
            this.totalPage=totalCount%pageSize==0?totalCount/pageSize:totalCount/pageSize+1;
            this.prevPage=currentPage>1?currentPage-1:1;
            this.nextPage=currentPage<totalPage?currentPage+1:totalPage;
        }
    }
    

    我们看看service 层 (调用方法: 参数: 前台的数据传来封装到 ArmoireQueryObject 对象中)返回一个前台需要的 所有数据 PageResult对象过去 .

    public interface IArmoireService {
        //业务层
        PageResult query(ArmoireQueryObject aq);
    }
    

    简单吧 ! ! !

    有了接口 , 就要去实现吧 , 不然要它何用 ?

    实现 :

    public class ArmoireServiceImpl implements IArmoireService {
        @Override
        public PageResult query(ArmoireQueryObject aq) {
            IArmoireDAO dao=new ArmoireDAOImpl();
            List<?> list = dao.queryResult(aq);
            int count = dao.queryCount(aq);
            if(count==0){
                //如果为0 , 返回空集
                return new PageResult(aq.getCurrentPage(),aq.getPageSize(),0,new ArrayList<>());
            }
            return new PageResult(aq.getCurrentPage(),aq.getPageSize(),count,list);
        }
    }
    

    真棒 , 都看到这里了 , 那我们是不是应该做啥事呢 ? 肯定是测试呀 !(还用想吗, 一天天的啥也不是啊哈! ! !)

    测试成功 ...

    我们开始写 servlet吧 快结束了 .

    @WebServlet("/arm")
    public class ArmoireServlet extends HttpServlet {
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            IArmoireService service=new ArmoireServiceImpl();
            ArmoireQueryObject aq = new ArmoireQueryObject();
    
            //分页查询 : 用户输入
            String strCurrentPage = req.getParameter("currentPage");
            if(StringUtil.hasLength(strCurrentPage)){
                Integer currentPage = Integer.valueOf(strCurrentPage);
                aq.setCurrentPage(currentPage);
            }
            String strPageSize = req.getParameter("pageSize");
            if(StringUtil.hasLength(strPageSize)){
                Integer pageSize = Integer.valueOf(strPageSize);
                aq.setPageSize(pageSize);
            }
    
            //过滤查询
            String keyword = req.getParameter("keyword");
            aq.setKeyword(keyword);
            String strMinPrice = req.getParameter("minPrice");
            if(StringUtil.hasLength(strMinPrice)){
                Integer minPrice = Integer.valueOf(strMinPrice);
                aq.setMinPrice(minPrice);
            }
            String strMaxPrice = req.getParameter("maxPrice");
            if(StringUtil.hasLength(strMaxPrice)){
                Integer maxPrice = Integer.valueOf(strMaxPrice);
                aq.setMaxPrice(maxPrice);
            }
    
    
            PageResult list = service.query(aq);
            //共享
            req.setAttribute("aq",aq);//回显数据 这里有 关键字 最大 最小 +2
            req.setAttribute("list",list);//返回 页面需要的 结果数据
            //跳转
            req.getRequestDispatcher("/list.jsp").forward(req,resp);
        }
    }
    

    总算写好了 , 那我们要干啥啊 , 问我 ? ? ? 把它装上 jsp页面上 .

    看着有点复杂 , 其实静下心来 , 看看 , 其实 JAVA 也就那样 . 其实 学习 JAVA 也是一种修行哈 , 越努力越幸运 , 加油 !

    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>信息管理系统</title>
        <script>
            function onChange() {
                document.forms[0].submit();
            }
    
            function goPage(pageNum) {
                document.getElementById("currentPageId").value = pageNum;
                document.forms[0].submit();
            }
        </script>
    </head>
    <body>
    <h3 align="center">货品信息查询系统</h3>
    <form action="/arm">
        <p align="center">
            关键字:<input type="text" name="keyword" value="${aq.keyword}">
            价格:<input type="number" name="minPrice" value="${aq.minPrice}"> ~ <input type="number" name="maxPrice" value="${aq.maxPrice}">
            <input type="submit" value="提交"></p>
        <table border="1" cellpadding="0" cellspacing="0" style="width: 80%" align="center">
            <tr>
                <th>序号</th>
                <th>出产商</th>
                <th>类型</th>
                <th>价格</th>
            </tr>
            <c:forEach items="${list.listResult}" var="arm" varStatus="vs">
                <tr>
                    <td>${vs.count}</td>
                    <td>${arm.supplier}</td>
                    <td>${arm.type}</td>
                    <td>${arm.price}</td>
                </tr>
            </c:forEach>
            <tr align="center">
                <td colspan="4">
                    <a href="#" onclick="goPage(1)">首页</a>
                    <a href="#" onclick="goPage(${list.prevPage})">上一页</a>
                    <a href="#" onclick="goPage(${list.nextPage})">下一页</a>
                    <a href="#" onclick="goPage(${list.totalPage})">末页</a>
                    当前${list.currentPage}页
                    共${list.totalPage}页
                    跳转<input type="number" name="currentPage" onchange="onChange()" style="width: 60px"
                             value="${list.currentPage}" id="currentPageId">页
                    每页显示
                    <select name="pageSize">
                        <option value="3" ${list.pageSize==3?'selected':''}> 3</option>
                        <option value="5" ${list.pageSize==5?'selected':''}> 5</option>
                        <option value="8" ${list.pageSize==8?'selected':''}> 8</option>
                    </select>
                    条数据
                </td>
            </tr>
        </table>
    </form>
    </body>
    </html>
    

    相关文章

      网友评论

        本文标题:高级查询

        本文链接:https://www.haomeiwen.com/subject/eifqahtx.html