高級查詢

分頁和過濾查詢

流程圖 :

高級查詢.jpg

1 設(shè)計(jì)和原理分析
image-20200521230058307.png

前面我們已經(jīng)講過分頁查詢了 , 接下來我們講講 過濾查詢 .

思路 : 從后臺開始寫 , 寫好測試 , 測試成功 ; 開始寫前臺 .

這里我們需要 MyBatis動態(tài)sql語句

為了解決在 xml 中拼接 SQL 的問題,此處需要來學(xué)習(xí) MyBatis 的動態(tài) SQL

<where> 和<if> 標(biāo)簽的配合使用

<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>

首先 , 我們現(xiàn)在需要用戶傳入的 過濾條件封裝成對象 ArmoireQueryObject, 去繼承 QueryObject ,這樣我們通過 ArmoireQueryObject就可以獲取用戶傳來的所有參數(shù) .

@ToString
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class ArmoireQueryObject extends QueryObject {
    //用戶傳來   高級查詢 的參數(shù)
    //1. 關(guān)鍵字  2. 最小值  3. 最大值
    private String keyword;
    private Integer minPrice;
    private Integer maxPrice;
    //繼承  這樣 其實(shí)已經(jīng)有  5+2 + getBegin 數(shù)據(jù)了
}

list.jsp 操作步驟 添加在 form標(biāo)簽中

<p align="center">                               //這里是value 是回顯,可以先不管
        關(guān)鍵字:<input type="text" name="keyword" value="${aq.keyword}">
        價(jià)格:<input type="number" name="minPrice" value="${aq.minPrice}"> ~ <input type="number" name="maxPrice" value="${aq.maxPrice}">
        <input type="submit" value="提交"></p>

注意:一般的,為了避免不必要的麻煩,讓字段名稱和表單中的請求參數(shù)名稱相同 .

DAO

public interface IArmoireDAO {
    //高級查詢 總條數(shù)
    int queryCount(ArmoireQueryObject aq);
    //高級查詢 頁面結(jié)果集
    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() {
        //私有化構(gòu)造器
    }
    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要用的工具類 , 方便點(diǎn) , 統(tǒng)統(tǒng)給你. StringUtil

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

后臺這樣其實(shí)就已經(jīng)寫好了 , 測試下吧 . 成功繼續(xù)...

想想我們 需要給前臺 返回什么數(shù)據(jù) ??? 之前分頁查詢已經(jīng)說過了 .

兩輸 , 兩查 , 三計(jì)算 封裝成對象 .

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
public class PageResult {
    //存 2輸  2查 3計(jì)算
    private int currentPage;
    private int pageSize;
    //2查
    private int totalCount;
    private List<?> listResult;
    //3 計(jì)算  上一頁 下一頁 總頁數(shù)
    private int totalPage;
    private int prevPage;
    private int nextPage;
    //自定義構(gòu)造器
    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 層 (調(diào)用方法: 參數(shù): 前臺的數(shù)據(jù)傳來封裝到 ArmoireQueryObject 對象中)返回一個前臺需要的 所有數(shù)據(jù) PageResult對象過去 .

public interface IArmoireService {
    //業(yè)務(wù)層
    PageResult query(ArmoireQueryObject aq);
}

簡單吧 ! ! !

有了接口 , 就要去實(shí)現(xiàn)吧 , 不然要它何用 ?

實(shí)現(xiàn) :

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);
    }
}

真棒 , 都看到這里了 , 那我們是不是應(yīng)該做啥事呢 ? 肯定是測試呀 !(還用想嗎, 一天天的啥也不是啊哈! ! !)

測試成功 ...

我們開始寫 servlet吧 快結(jié)束了 .

@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);//回顯數(shù)據(jù) 這里有 關(guān)鍵字 最大 最小 +2
        req.setAttribute("list",list);//返回 頁面需要的 結(jié)果數(shù)據(jù)
        //跳轉(zhuǎn)
        req.getRequestDispatcher("/list.jsp").forward(req,resp);
    }
}

總算寫好了 , 那我們要干啥啊 , 問我 ? ? ? 把它裝上 jsp頁面上 .

看著有點(diǎn)復(fù)雜 , 其實(shí)靜下心來 , 看看 , 其實(shí) JAVA 也就那樣 . 其實(shí) 學(xué)習(xí) JAVA 也是一種修行哈 , 越努力越幸運(yùn) , 加油 !

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>信息管理系統(tǒng)</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">貨品信息查詢系統(tǒng)</h3>
<form action="/arm">
    <p align="center">
        關(guān)鍵字:<input type="text" name="keyword" value="${aq.keyword}">
        價(jià)格:<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>出產(chǎn)商</th>
            <th>類型</th>
            <th>價(jià)格</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>
                當(dāng)前${list.currentPage}頁
                共${list.totalPage}頁
                跳轉(zhuǎn)<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>
                條數(shù)據(jù)
            </td>
        </tr>
    </table>
</form>
</body>
</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容