首页 > 代码库 > 带条件的分页

带条件的分页


一、后台

    ①分类的list .jsp中的流程控制改成JSTL实现

         <script type ="text/javascript" src="script/jquery-1.7.2.js"></script>
         <script type ="text/javascript">
            $ (function (){   
                $ (".del").click(function(){         
                    var $td = $(this). parents("tr").children("td:eq(1)" );         
                    var flag = confirm ("你真的要删除"+$td.text()+"的信息吗?" );     
                     if(!flag) {
                         return false;
                     }           
                 });     
             });
         </script >
         </head >
         <body >  
             <h1 >$ {message }</h1 >    
             <table >
                 <tr >
                     <th >ID </th >
                     <th >NAME </th >
                     <th >AUTHOR </th >
                     <th >PRICE </th >
                     <th >STORENUM </th >
                     <th >SALSEAMOUNT </th >
                     <th >IMG </th >
                     <th >更新 </th >
                     <th >删除 </th >
                 </tr >
                 <c :if test="${empty bookList }" >
                     <tr ><td colspan ="3"> 没有任何数据可以显示 </td ></tr >
                 </c :if>
                 <c :if test="${!empty bookList }" >
                     <c :forEach items ="${bookList }" var ="book">
                         <tr >
                             <td >$ {book .bookId }</td >
                             <td >$ {book .bookName }</td >
                             <td >$ {book .author }</td >
                             <td >$ {book .price }</td >
                             <td >$ {book .storeNum }</td >
                             <td >$ {book .salseAmount }</td >
                             <td ><a href ="${book.imgPath }">查看图片</a></td >
                             <td ><a href="manager/BookManagerServlet?method=toEditUI&bookId=${book.bookId }">更新 </a ></td >
                             <td ><a class="del" href="manager/BookManagerServlet?method=delBook&bookId=${book.bookId }">删除 </a ></td >
                         </tr >
                     </c :forEach >
                 </c :if>
             </table >
         </body >
        

    ②实现图书的CRUD ----> BookManagerServlet

    
    [1 ]添加:前往添加的表单页面时,必须携带cateList数据,在下拉列表中显示
         protected void toAddUI (HttpServletRequest request ,
            HttpServletResponse response ) throws ServletException, IOException {
         //前往“添加图书”的表单界面之前,必须携带“分类列表”数据
        List <Category > cateList = cateService .getCateList ();
        WebUtils .myForward (request , response , "/manager/book/add.jsp" , "cateList", cateList);
         }
            
    [2 ]更新:前台更新的表单页面是,必须携带cateList数据,且在下拉列表中显示当前记录的分类
         protected void toEditUI (HttpServletRequest request ,
            HttpServletResponse response ) throws ServletException, IOException {
            
        String bookId = request .getParameter ("bookId");
         //携带cateList数据和Book对象
        Book book = bookService .getBookById (bookId );
        
        List <Category > cateList = cateService .getCateList ();
        
        Map <String , Object > attrMap = new HashMap <>();
        attrMap .put ("book", book);
        attrMap .put ("cateList", cateList);
        
        WebUtils .myForwardSuper (request , response , "/manager/book/edit.jsp" , attrMap );
        
         }
        
        
        ★在edit .jsp中接收,关键代码如下:
         <form action="manager/BookManagerServlet?method=updateBook" method="post">
    
         <input type ="hidden" name ="bookId" value ="${book.bookId }" />
    
         <table >
             <tr ><td >图书名称 </td ><td ><input type ="text" name="bookName" value ="${book.bookName }" /></td ></tr >
             <tr ><td >作者 </td ><td ><input type ="text" name="author" value ="${book.author }" /></td ></tr >
             <tr ><td >价格 </td ><td ><input type ="text" name ="price" value="${book.price }" /></td ></tr >
             <tr ><td >库存 </td ><td ><input type ="text" name="storeNum" value ="${book.storeNum }" /></td ></tr >
             <tr ><td >销量 </td ><td ><input type ="text" name="salseAmount" value ="${book.salseAmount }" /></td ></tr >
             <tr >
                 <td >分类 </td >
                 <td >
                     <select name ="cateId">
                         <c :forEach items ="${cateList }" var="categroy">
                             <c :if test="${book.cateId == categroy.cateId }">
                                 <option value ="${categroy.cateId }" selected="selected" >$ {categroy .cateName }</option >
                             </c :if>
                             <c :if test="${book.cateId != categroy.cateId }">
                                 <option value ="${categroy.cateId }">${ categroy.cateName }</option >
                             </c :if>
                         </c :forEach >
                     </select >
                 </td >
             </tr >
             <tr ><td colspan ="2">< input type="submit" value= "更新" /></ td></tr>
         </table >
    
         </form >
                

二、前台

1、不带条件的查询

    [1 ]实现Dao方法:getPageList ()、getTotalItemNum ()
    ◆在BookDao中写接口方法
    /**
     * 获取在指定条件下的分页数据
     * @param pageNo 不能使用pageCondition返回的pageNoStr,要使用经过Page对象纠正的
     * @param pageSize
     * @param pageCondition
     * @return
     */
    List<Book> getPageList (int pageNo, int pageSize, PageCondition pageCondition);
    
    /**
     * 带条件的查询
     * @param pageCondition
     * @return 返回在指定的条件下一共有多少条记录
     */
    int getTotalItemNum (PageCondition pageCondition );
    
    
    ◇此时需要更改Dao :
         /**
         * 获取单一值的接口方法
         * @param connection
         * @param sql
         * @param params
         * @return
         */
         <V > V getSingleValue (Connection connection , String sql , Object ... params);
    
    ◇DaoImpi中实现该接口方法:
        @Override
         public <V > V getSingleValue (Connection connection , String sql,
                Object ... params ) {
            V v = null;
             try {
                v = (V ) runner .query (connection , sql , new ScalarHandler(), params);
             } catch (SQLException e ) {
                 // TODO Auto-generated catch block
                e .printStackTrace ();
             }
             return v ;
         }
    
    [2 ]实现Page类
    package com.atguigu.bookstore.fun;
    import java .util .List ;

    /**
     * 封装分页信息的类
     * @author Phenix
     *
     * @param <T>对应具体的实体类
     */
    public class Page<T> {
        
         //代表当前页码
         private int pageNo ;
        
         //页面上的数据
         private List <T > list ;
        
         //每页显示的数据数量
         public static final int PAGE_SIZE = 3;
        
         //总记录数
         private int totalItemNum ;
        
         //总页数
         private int totalPageNum ;
        
        
         public Page (String pageNoStr , int totalItemNum ) {
            
             //先获取总记录数,以计算总页数
             this.totalItemNum = totalItemNum ;
            
             //计算总页数
             this.totalPageNum = (totalItemNum % PAGE_SIZE == 0) ? totalItemNum/ PAGE_SIZE : totalItemNum/PAGE_SIZE + 1 ;
            
             //对pageNoStr进行类型转换
            pageNo = 1;
             try {
                pageNo = Integer .parseInt (pageNoStr );
             } catch (NumberFormatException e ) {/*如果转换失败则保持默认值*/ }

             //限定pageNo的有效范围
             if(pageNo < 1) {
                pageNo = 1;
             }
            
             if(pageNo > totalPageNum ) {
                pageNo = totalPageNum ;
             }
            
         }

         public List <T > getList () {
             return list ;
         }

         public void setList (List <T > list ) {
             this.list = list;
         }

         public int getPageNo () {
             return pageNo ;
         }

         public int getTotalItemNum () {
             return totalItemNum ;
         }

         public int getTotalPageNum () {
             return totalPageNum ;
         }

         public boolean isHasPrev () {
             return pageNo > 1;
         }
        
         public boolean isHasNext () {
             return pageNo < totalPageNum ;
         }
        
         public int getPrevNo () {
             return pageNo - 1;
         }
        
         public int getNextNo () {
             return pageNo + 1;
         }
        
    }
    
    [3 ]实现与分页相关的Service层代码
    ◇BookService中添加如下接口方法:获取book类的分页信息
        Page <Book > getBookPage (String pageNoStr );
    ◇在BookServiceImpi中实现该方法
        @Override
         public Page <Book > getBookPage (PageCondition pageCondition) {
         int totalItemNum = bookDao.getTotalItemNum( pageCondition);
        
        Page <Book > page = new Page<>(pageCondition. getPageNoStr(), totalItemNum);
        
         //这里,pageNo必须使用Page类纠正过的,不能使用pageCondition中的pageNoStr
        List <Book > list = bookDao .getPageList (page .getPageNo (), Page.PAGE_SIZE, pageCondition);
        
        page .setList (list );
        
         return page ;//返回book类的分页信息
    }

    ◆在client .jsp请求
    <iframe src ="client/BookClientServlet?method=getPage" name="targetFrame"></iframe>
    ◆BookClientServlet中进行转发
         protected void getPage (HttpServletRequest request ,
            HttpServletResponse response ) throws ServletException, IOException {
        
        String pageNoStr = request .getParameter ("pageNo");  
        Page <Book > page = bookService .getBookPage (pageNoStr );   
        WebUtils .myForward (request , response , "/client/book/bookList.jsp" , "page", page);
        
    }
    ◆在bookList .jsp中接收数据
        $ {page .list }
    
    

    [4 ]页面 (文本框输入数字跳转页面 )
        ① 给文本框加一个Id 属性: <input id ="pageCode" class="inpType" type="text" name= "pageNo" />
        ②导入jquery: <script type ="text/javascript" src="script/jquery-1.7.2.js"></script>【已经加过base标签】
        ③书写JS代码:
        版本一:可以容错,因为Page类内置了容错校验
         <script type ="text/javascript">
            $ (function (){
                $ ("#pageCode").change(function(){
                     //去掉前后空格
                    var pageCode =$ .trim (this. value);
                     //判断用户输入的页码是否为数字
                     if(isNaN(pageCode)){
                         //如果不是将文本框置空,并停止函数的执行
                         this.value="" ;
                         return false;
                     }
                     //如果是数字,则跳转到指定的页码
                    var url ="${pageContext.request.contextPath }/"+
                     "client/BookClientServlet?method=getPage&pageNo=" +pageCode ; 
                    window .location .href =url ;
                 });
             });
         </script >
    

    
2、在首页显示真实的分类数据
    ①创建ClientServlet ,用于跳转到前台页面 ,跟实体类无关,和前台页面相关
    ②修改index .jsp中的代码
             <jsp :forward page="client/ClientServlet?method=toClientUI"></jsp :forward >
    ③在toClientUI ()方法中获取数据库分类列表数据,跳转到client .jsp显示
         public class ClientServlet extends BaseServlet {
         private static final long serialVersionUID = 1L;
        
         private CateService cateService =new CateServiceImpl ();
        
         protected void toClientUI (HttpServletRequest request , HttpServletResponse response) throws ServletException, IOException {
            List <Category > cateList = cateService .getCateList ();
            
            WebUtils .myForward (request , response , "/client/client.jsp", "cateList", cateList);
         }

         }
    
    注意:修改web .xml将ClientServlet注册一下。
    <servlet >
         <display -name >ClientServlet </display -name >
         <servlet -name >ClientServlet </servlet -name >
         <servlet -class> com.atguigu.bookstore.servlet.client.ClientServlet </servlet -class>
    </servlet >
    <servlet -mapping >
      <servlet -name >ClientServlet </servlet -name >
      <url-pattern>/client /ClientServlet </url -pattern >
    </servlet -mapping >
      
    ④修改client .jsp 中的分类列表
        <li>全部分类 </li >
         <c :forEach items ="${cateList }" var ="category" >
             <li ><a href ="#"> ${category.cateName }</a></li >
         </c :forEach >
      
    ⑤后台中跳转到前台页面的超链接也要跟着修改
    <a href="client/ClientServlet?method=toClientUI" >进入前台 </a >
    

3、★带条件的查询★重点★

    难点:查询条件时有时无,要做到适配不同的情况
    ①查询条件包括
        pageNo页码
        minPrice 价格区间最小值
        maxPrice 价格区间最大值
        cateId   分类Id
    ②将查询条件封装为PageCondition类
         (1) 为每个查询条件设置默认值
                pageNo 页码,默认值:1,最终还是交给Page类纠正
                minPrice 默认值:0
                maxPrice 默认值:Integer .MAX_VALUE
                cateId 默认值:null为了避免有可能产生的歧义,所以应声明为Integer类型
         (2) 在构造器中,获取String类型的参数,进行类型转换,若任何一个条件数据转换失败则保持默认值
         (3) 提供getXxx()方法
        代码如下:
         public class PageCondition {
            
         //  (1)pageNo 页码 声明为String类型是为了直接交给Page类的构造器
             private String pageNoStr = "1";
            
         //  (2)minPrice 价格区间的最小值 默认值的作用是在页面没有传入该参数时仍然可以查询
             private int minPrice = 0;
            
         //  (3)maxPrice 价格区间的最大值
             private int maxPrice = Integer .MAX_VALUE ;
            
         //  (4)cateId   分类ID
             private Integer cateId = null;
            
             public PageCondition (String pageNoStr , String minPriceStr, String maxPriceStr, String cateIdStr) {
                
                 this.pageNoStr = pageNoStr ;
                
                 //转换失败,使用默认值
                 try {
                     this.minPrice = Integer.parseInt( minPriceStr);
                 } catch (NumberFormatException e ) {/*保持默认值*/}
                
                 try {
                     this.maxPrice = Integer.parseInt( maxPriceStr);
                 } catch (NumberFormatException e ) {/*保持默认值*/}
                
                 try {
                     this.cateId = Integer.parseInt(cateIdStr);
                 } catch (NumberFormatException e ) {/*保持默认值*/}
                
             }

             public String getPageNoStr () {
                 return pageNoStr ;
             }

             public int getMinPrice () {
                 return minPrice ;
             }

             public int getMaxPrice () {
                 return maxPrice ;
             }

             public Integer getCateId () {
                 return cateId ;
             }

            @Override
             public String toString () {
                 return "PageCondition [pageNoStr=" + pageNoStr + ", minPrice="
                         + minPrice + ", maxPrice=" + maxPrice + ", cateId=" + cateId
                         + "]";
             }
            
         }
    ③在Dao中升级原有的分页方法
         (1) int getTotalItemNum (PageCondition pageCondition ),根据相关条件进行相关查询
        ·原本不带条件的SQL语句:SELECT COUNT (*) FROM book
        ·带全部条件的SQL语句
            SELECT
              COUNT (*)
            FROM
              book
            WHERE price <= 10000
              AND price >= 0
              AND cate_id = 1
        ·适配具体情况的SQL语句
            pageCondition .getCateId ()的返回值是否为null,决定是否附加“AND cate_id = 1 
            ○第一部分
            SELECT
              `book_id` bookId ,
              `book_name` bookName ,
              `author` author ,
              `price` price ,
              `store_num` storeNum ,
              `salse_amount` salseAmount ,
              `imp_path` imgPath ,
              `cate_id` cateId
            FROM
              book
            WHERE price >= 0
              AND price <= 10000
            ○第二部分
              AND cate_id = 1
              根据pageCondition .getCateId ()的返回值是否为null,决定是否附加
            ○第三部分
              LIMIT ?, ?
            
            
        ◆具体更改如下:

        ★1、在BookDao .java中重载两个方法

         /**
         * 获取在指定条件下的分页数据
         * @param pageNo 表示当前页,不能使用pageCondition返回的pageNoStr,要使用经过Page对象纠正的
         * @param pageSize 页面显示的条目数
         * @param pageCondition
         * @return
         */
        List <Book > getPageList (int pageNo, int pageSize, PageCondition pageCondition);
        
         /**
         * 带条件的查询
         * @param pageCondition
         * @return 返回在指定的条件下一共有多少条记录
         */
         int getTotalItemNum (PageCondition pageCondition );
    

        ★2、在BookDaoImpl .java中实现上述两个方法

        @Override
         public List <Book > getPageList (int pageNo, int pageSize,
                PageCondition pageCondition ) {
            
            Connection connection = JDBCUtils .getConnection ();
            
            String sql = "SELECT `book_id` bookId,"
                     + "`book_name` bookName,"
                     + "`author` author,"
                     + "`price` price,"
                     + "`store_num` storeNum,"
                     + "`salse_amount` salseAmount,"
                     + "`imp_path` imgPath,`cate_id` cateId "
                     + "FROM book WHERE price>=? and price<=?" ;
            
            Integer cateId = pageCondition .getCateId ();
            
             //根据实际情况决定是否加入这个条件
             if(cateId != null) sql = sql + " and `cate_id`=" + cateId;
            
            sql = sql + " LIMIT ?,?";
            
            List <Book > list = this.getBeanList (connection , sql ,
                    pageCondition .getMinPrice (),
                    pageCondition .getMaxPrice (),
                     (pageNo -1)* pageSize,
                    pageSize );
            
            JDBCUtils .releaseConnection (connection );
            
             return list ;
            
         }
         //获取总记录数
        @Override
         public int getTotalItemNum (PageCondition pageCondition ) {
            
            Connection connection = JDBCUtils .getConnection ();
            
            String sql = "SELECT COUNT(*) FROM book WHERE price >= ? AND price <= ?";
            
            Integer cateId = pageCondition .getCateId ();
            
             if(cateId != null) sql = sql + " AND cate_id = " + cateId;
            
             long itemNum = this.getSingleValue (connection , sql , pageCondition.getMinPrice(), pageCondition.getMaxPrice());
            
            JDBCUtils .releaseConnection (connection );
            
             return (int) itemNum;
         }
    
        ☆对以上更改进行单元测试
         private BookDao bookDao = new BookDaoImpl ();
        @Test
         public void testGetPageListInCon () {

            PageCondition pageCondition = new PageCondition ("1", null, null, null);
            
            List <Book > list = bookDao .getPageList (1, 3 , pageCondition);
            
             for (Iterator iterator = list .iterator (); iterator.hasNext();) {
                Book book = (Book ) iterator .next ();
                System .out .println (book );
             }
            
         }
        @Test
         public void testGetItemNumInCon () {
            
            PageCondition pageCondition = new PageCondition ("1", "30", "50", "2" );
            
             int totalItemNum = bookDao.getTotalItemNum( pageCondition);
            
            System .out .println (totalItemNum );
            
         }
    

        ★3、在BookService中对该方法重载

        Page <Book > getBookPage (PageCondition pageCondition );
        

        ★4、在BookServiceImpl实现该接口

        @Override
         public Page <Book > getBookPage (PageCondition pageCondition) {
         //总记录数从Dao中获取,先获取总记录数,以计算总页数
         int totalItemNum = bookDao.getTotalItemNum( pageCondition);
         //创建分页类对象,并在构造器中对传入的当前页和总记录数进行校验
        Page <Book > page = new Page<Book>( pageCondition.getPageNoStr(), totalItemNum );
        
         //这里pageNo必须使用Page类纠正过的,不能使用PageCondition中的pageNoStr,它不具备纠正能力
         //getPageList()获取在指定条件下的分页数据
        List <Book > list = bookDao .getPageList (page .getPageNo (), Page.PAGE_SIZE, pageCondition);
         //将page对象设置到list集合当中
        page .setList (list );
        
         return page ;
         }
        

        ☆对该接口实行单元测试:

        @Test
         public void testGetPageInCon () {
             //查询第一页,价格在30-77之间,书的分类Id是5的有记录
            PageCondition pageCondition = new PageCondition ("1", "30", "77", "5" );   
            Page <Book > page = bookService.getBookPage( pageCondition);     
             int totalItemNum = page .getTotalItemNum ();  
             int totalPageNum = page .getTotalPageNum ();
             int pageNo = page .getPageNo ();  
            Iterator <Book > iterator = page .getList ().iterator ();
            
             while (iterator .hasNext ()) {            
                Book book = (Book ) iterator .next ();         
                System .out .println (book .getBookId ());
                 //5 7 18
             }
            
            System .out .println ("总记录数:"+totalItemNum );   //总记录数:3
            System .out .println ("总页数:"+totalPageNum);     //总页数:1
            System .out .println ("当前页:"+pageNo);//    当前页:1   
         }
    

        ★5、在BookClientServlet中增加getPageInCondition ()方法

         protected void getPageInCondition (HttpServletRequest request,
            HttpServletResponse response ) throws ServletException, IOException {
        
         //获取请求参数
        String pageNoStr = request .getParameter ("pageNo");
        String minPriceStr = request .getParameter ("minPrice");
        String maxPriceStr = request .getParameter ("maxPrice");
        String cateIdStr = request .getParameter ("cateId");
        
         //封装条件对象
        PageCondition pageCondition = new PageCondition(pageNoStr, minPriceStr, maxPriceStr, cateIdStr );
        
        Page <Book > page = bookService.getBookPage( pageCondition);
        
        WebUtils .myForward (request , response , "/client/book/bookList.jsp" , "page", page);
        
         }
        

        ★6、在bookList .jsp中更改价格查询的提交地址

         <form action="client/BookClientServlet?method=getPageInCondition" method="post">
            价格
             <input type ="text" class= "inpType" name ="minPrice" />-
             <input type ="text" class= "inpType" name ="maxPrice" />
             <input type ="submit" value ="查询" />
         </form >
        

        ★7、在client .jsp中做同样更改

         <li >全部分类 </li >
         <c :forEach items ="${cateList }" var ="category" >
         <li ><a href="client/BookClientServlet?method=getPageInCondition&cateId=${category.cateId }" >$ {category .cateName }</a ></li >
         </c :forEach >
        
        

        ★8、给分类信息加入target属性使其在mainContent中显示

         <li >全部分类 </li >
         <c :forEach items ="${cateList }" var ="category" >
         <li ><a target ="targetFrame" href="client/BookClientServlet?method=getPageInCondition&cateId=${category.cateId }" >$ {category .cateName }</a ></li >
         </c :forEach >
    
    
        

4、在页面上保持查询条件

    [1 ]会导致“丢失”查询条件的行为

         (1) 翻页的超链接
            ·能够保持的条件:pageNo
            ○分类、价格会丢失
            →可将以下条件附着在超链接之后
             &cateId =$ {param .cateId }&minPrice =$ {param .minPrice }&maxPrice= ${param.maxPrice }
            例如:
             <a href="client/BookClientServlet?method=getPageInCondition&pageNo=${page.prevNo }
             &cateId =$ {param .cateId }&minPrice =$ {param .minPrice }&maxPrice= ${param.maxPrice }">上一页</a>

            
    ·改进:对超链接进行批量操作
    <script type ="text/javascript">
    $(function(){
        var conditonStr ="&cateId=${param.cateId }&minPrice=${param.minPrice }&maxPrice=${param.maxPrice }";
        $ ("a"). each(function(){
             this.href=this .href +conditonStr ;
         });
        
        $ ("#pageCode").change(function(){
             //去掉前后空格
            var pageCode =$ .trim (this. value);
             //判断用户输入的页码是否为数字
             if(isNaN(pageCode)){
                 //如果不是将文本框置空,并停止函数的执行
                 this.value="" ;
                 return false;
             }
             //如果是数字,则跳转到指定的页码
            var url ="${pageContext.request.contextPath }/"+
             "client/BookClientServlet?method=getPageInCondition&pageNo=" +pageCode +conditonStr ;  
            window .location .href =url ;
         });
    });
    </script >
    
    
         (2) 跳转页面的文本框
            ·能够保持的条件:pageNo
            ○分类、价格会丢失
            
        ◇在bookList .jsp中修改JS代码中的URL地址
         <script type ="text/javascript">
        $ (function (){
            $ ("#pageCode").change(function(){
                 //去掉前后空格
                var pageCode =$ .trim (this. value);
                 //判断用户输入的页码是否为数字
                 if(isNaN(pageCode)){
                     //如果不是将文本框置空,并停止函数的执行
                     this.value="" ;
                     return false;
                 }
                 //如果是数字,则跳转到指定的页码
                var url ="${pageContext.request.contextPath }/"+
                 "client/BookClientServlet?method=getPageInCondition&pageNo=" +pageCode +
                 "&cateId=${param.cateId }&minPrice=${param.minPrice }&maxPrice=${param.maxPrice }"; 
                window .location .href =url ;
             });
         });
        </script >
        注意:方法名要更改为:getPageInCondition    
        疑问?EL表达式能写在JS里面吗?
        解答:可以的,因为Jsp页面的翻译和运行先于JS ,浏览器取得该超链接地址是被翻译过的。
        
         (3) 查询价格的表单提交
            ·能够保持价格信息
            ○会丢失pageNo和分类
            因此要附着: &pageNo =$ {param .pageNo }&cateId= ${param.cateId }
            
        ◇将其附着在表单提交的地址后面
         <form action="client/BookClientServlet?method=getPageInCondition&pageNo=${param.pageNo }&cateId=${param.cateId }" method="post">
            价格
             <input type ="text" class= "inpType" name ="minPrice" value="${param.minPrice }"/>-
             <input type ="text" class= "inpType" name ="maxPrice" value="${param.maxPrice }" />
             <input type ="submit" value ="查询" />
         </form >
            
            
         (4) 点击分类超链接【会话控制可以解决】
            分类信息client .jsp和bookList .jsp非同一个页面在bookList .jsp中即使用param对象,在client .jsp中也获取不到它的值
            因此暂时先不动分类Client .jsp,之后可以将pageCondition放到session里面,那么这两个页面就可以协同工作了。
            ·能够保持分类
            ○丢失分类、价格、页码
                
            

    [2 ]保持查询条件

         (1) 在跳转页面时将已存在的查询条件携带提交
         (2) ${param.xxx }
        翻页的超链接:自己发出的不存在保持查询条件的问题,可以将查询条件附着在超链接上面,
         <a href ="...let?method=getPageInCondition&pageNo=${num }&minPrice=${param.minPrice }"> ${num }</a>
         <a href ="...let?method=getPageInCondition&pageNo=${num }&minPrice=30"> ${num }</a>
         (3) 注意:Servlet方法的名字要改成getPageInCondition
    
    
    
    [3 ]在bookList .jsp中显示当前的分类名称
    ◇在client .jsp中将每一个分类都附着cateName信息
    <li>全部分类 </li >
    <c:forEach items ="${cateList }" var ="category" >
         <li ><a target ="targetFrame" href="client/BookClientServlet?method=getPageInCondition&cateId=${category.cateId }&cateName=${category.cateName }">${ category.cateName }</a></li >
    </c:forEach>
    
    ◇在bookList .jsp中获取cateName
    //<td colspan="2">当前分类:${param.cateName }</td>
    <td colspan ="2"> 当前分类:${param.cateName==null ? ‘全部分类‘:param.cateName }</td>
    
    ◆当点击全部分类的时候显示空白,现在要给全部分类也加上超链接以便于用户能回到全部分类
    <li><a target ="targetFrame" href="client/BookClientServlet?method=getPageInCondition&cateName=全部分类" >全部分类 </a ></li >
    

    目前的局限性:

    只能在当前分类下保持查询(先点击“科学”再点击价格可以保持,但是再次点击别的分类就保持不了)
    
    

    

5、点击图书名称显示单本书的信息  

    ①给书名加超链接
    <li>书名: <a href="client/BookClientServlet?method=getBook&bookId=${book.bookId }">${book.bookName }</a></li >
    
    ②在BookClientServlet中写getBook ()方法
    protected void getBook(HttpServletRequest request ,
            HttpServletResponse response ) throws ServletException, IOException {
        
        String bookId = request .getParameter ("bookId");
        
        Book book = bookService .getBookById (bookId );
        
        WebUtils .myForward (request , response , "/client/book/book.jsp" , "book", book);
        
    }
        
    ③创建book .jsp页面用于显示图书信息
    注意:编码为UTF -8
    ◇导入: <base href ="http://${pageContext.request.serverName }:${pageContext.request.serverPort }${pageContext.request.contextPath }/" />
    ◇<link rel ="stylesheet" type ="text/css" href="style/css.css" />
    ◇<script type ="text/javascript" src="script/jquery-1.7.2.js"></script>
    <script type ="text/javascript">
        $ (function (){
            $ ("button").click(function(){       
                 //借助window.history.go(-1)实现后退功能
                window .history .go (-1);       
             }); 
         });
    </script >
        
    ◇在body中书写
    <body>
         <img class="bookImg" src="${book.imgPath }" >
         <p >书名:$ {book .bookName }</p >
         <p >作者:$ {book .author }</p >
         <p >价格:$ {book .price }</p >
         <p >库存:$ {book .storeNum }</p >
         <p >销量:$ {book .salseAmount }</p >
         <p ><button >回到上一页 </button ></p >
    </body> 
        

带条件的分页