需求:javascript
通常列表頁上面會有一個查詢框,有各類的查詢條件組合,通常都採用模糊查詢方式 ,如下以本身作的實例來講明一下實現方法:java
須要實現的界面原型:要知足條件:web
一、單選分類,點GO按扭sql
二、單獨輸入標題關鍵字,點GO按扭app
三、選擇分類,再輸入關鍵字,點GO按扭框架
我這裏用了MVC分層模式來進行的,因此一步步講解吧,上源碼:jsp
由於我一個class裏寫了不少不一樣的業務,因此帖代碼只帖當前步ide
dao層:post
1 //當前頁顯示的新聞信息pageNo 當前頁碼,pagePerCount是每頁多少條數據 2 public List<NewsDetail> getPageNewsList(int pageNo,int pagePerCount,String where);
daoImpl層:this
這裏方法中加的參數是where,由於我不肯定前臺可能有幾個模糊查詢的條件,因此這裏只能用個總體的字符串來定義,到時候用StringBuffer來拼就行
這裏注意一下字符串拼接加變量的寫法
1 public List<NewsDetail> getPageNewsList(int pageNo, int pagePerCount,String where) { 2 List<NewsDetail> newslist =new ArrayList<NewsDetail>(); 3 String sql = "select d.id,d.title,d.author,d.summary,d.content,d.picPath,d.createDate,d.modifyDate," + 4 "d.createDate,d.categoryId,c.name as categoryname from news_detail as d,news_category as c" + 5 " where c.id=d.categoryId and d.status=1 "+where+"order by d.createDate desc limit ?,?"; 6 Object[] params ={(pageNo-1)*pagePerCount,pagePerCount}; 7 if(this.getconnection()){ 8 ResultSet rs = this.executeQuery(sql, params); 9 try { 10 while(rs.next()){ 11 NewsDetail news = new NewsDetail(); 12 int id = rs.getInt("id"); 13 String title1 = rs.getString("title"); 14 String author =rs.getString("author"); 15 int categoryId = rs.getInt("categoryId"); 16 String categoryname=rs.getString("categoryname"); 17 String summary = rs.getString("summary"); 18 String content = rs.getString("content"); 19 String picPath =rs.getString("picPath"); 20 Timestamp createDate =rs.getTimestamp("createDate"); 21 Timestamp modifyDate =rs.getTimestamp("modifyDate"); 22 news.setId(id); 23 news.setCategoryId(categoryId); 24 news.setAuthor(author); 25 news.setCategoryname(categoryname); 26 news.setContent(content); 27 news.setSummary(summary); 28 news.setPicPath(picPath); 29 news.setCreateDate(createDate); 30 news.setModifyDate(modifyDate); 31 news.setTitle(title1); 32 newslist.add(news); 33 34 } 35 } catch (SQLException e) { 36 e.printStackTrace(); 37 }finally{ 38 this.clossconnection(); 39 } 40 } 41 return newslist; 42 }
service接口:
1 //當前頁顯示的新聞信息pageNo 當前頁碼,pagePerCount是每頁多少條數據 2 public List<NewsDetail> getPageNewsList(int pageNo,int pagePerCount,String where);
serviceImpl接口實現類:
由於業務比較簡單,因此代碼也很簡單哈,service只是調一下dao便可
1 public class NewsServiceImpl implements NewsService { 2 private NewsDao newsdao =null; 3 public NewsServiceImpl(){ 4 newsdao=new NewsDaoImpl(); 5 newscategory1 =new NewsCategoryDaoImpl(); 6 } 7 public int getNewsCount(String where) { 8 return newsdao.getNewsCount(where); 9 } 10 }
如下是重點,套頁面JSP+Servlet
newsDetailList.jsp:我把樣式那些都省略了,只列出總體的頁面框架元素
1 <div class="main-content-right"> 2 <!--即時新聞--> 3 <div class="main-text-box"> 4 <div class="main-text-box-tbg"> 5 <div class="main-text-box-bbg"> 6 <form name ="searchForm" id="searchForm" action="<%=request.getContextPath() %>/servlet/newsListByLikeServlet" method="post"> 7 <div> 8 新聞分類: 9 <select name="categoryId"> 10 <option value="0">所有</option><!--這裏要注意,到servlet中獲取分類的時候,值爲0要加判斷,爲0不須要加查詢,默認是所有就是不選擇分類的狀況--> 11 <c:forEach var="category" items="${categorylist }" varStatus="status"> 12 <option value='${category.id }' >${category.name }</option> 13 </c:forEach> 14 15 16 17 </select> 18 新聞標題<input type="text" name="title" id="title" value=''/> 19 <button type="submit" class="page-btn" onclick="javascript:window.location.href='<%=request.getContextPath() %>/servlet/newsListByLikeServlet'">GO</button> 20 <button type="button" onclick="addNews();" class="page-btn">增長</button> 21 <!--隱藏域,當前頁碼 --> 22 <input type="hidden" id="pageIndex" name="pageIndex" value="1"/> 23 24 <input type="hidden" name="pageSize" value="10"/> 25 26 </div> 27 </form> 28 <table cellpadding="1" cellspacing="1" class="admin-list"> 29 <thead > 30 <tr class="admin-list-head"> 31 <th align="center">新聞標題</th> 32 <th align="center">新聞類別</th> 33 <th align="center">做者</th> 34 <th align="center">建立時間</th> 35 <th align="center">操做</th> 36 </tr> 37 </thead> 38 39 <tbody> 40 <c:forEach var="news" items="${newsList}" varStatus="status"> 41 <tr <c:if test="${status.count%2==0 }"> class="admin-list-td-h2"</c:if>> 42 <td><a href='<%=request.getContextPath() %>/servlet/NewsViewServlet?id=${news.id }'>${news.title }</a></td> 43 <td>${news.categoryname }</td> 44 <td>${news.author }</td> 45 <td><fmt:formatDate value="${news.createDate}" pattern="yyyy-MM-dd"/></td> 46 <td><a href='<%=request.getContextPath() %>/servlet/EditViewServlet?id=${news.id }'>修改</a> 47 <a href="javascript:if(confirm('確認是否刪除此新聞?')) location='<%=request.getContextPath() %>/servlet/DelNewsServlet?id=${news.id }'">刪除</a> 48 </td> 49 </tr> 50 </c:forEach> 51 52 53 <input type="hidden" id="totalPageCount" name="totalPageCount" value="${totalPageCount }"/> 54 </tbody> 55 56 </table> 57 <c:import url="rollPage.jsp"> 58 <c:param name="totalCount" value="${totalCount }"></c:param> 59 <c:param name="currentPageNo" value="${currentPageNo }"></c:param> 60 <c:param name="totalPageCount" value="${totalPageCount}"></c:param> 61 62 </c:import> 63 64 </div> 65 </div> 66 </div> 67 </div>
能夠看出,我圖1中的查詢那塊是一個form,HTML框架比較清晰,那麼個人servlet要作的事就是:獲取用戶選擇的select下拉框選擇的分類和用戶輸入的title關鍵字
form表單提交的數據,咱們能夠在servlet經過getParameter方法來獲取
NewsListByLike2代碼以下:
1 public class NewsListByLike2 extends HttpServlet { 2 NewsService newsService =new NewsServiceImpl(); 3 4 @Override 5 protected void doGet(HttpServletRequest request, HttpServletResponse response) 6 throws ServletException, IOException { 7 try{ 8 //定義一個sb來接收模糊查詢的sql 9 StringBuffer sb = new StringBuffer(1024); 10 //form表單提交過來的用戶輸入的title模糊查詢關鍵字 11 String title = request.getParameter("title"); 12 //若是title有輸入的時候,才拼接sql進行查詢 13 if (title != null && !"".equals(title)) { 14 sb.append(" and d.title like '%" + title + "%'"); 15 } 16 //取模類糊查詢分類選擇,是頁面select標籤的name 17 String categoryId = request.getParameter("categoryId"); 18 //取過來是個字符串,須要轉一下int,可是必定要Try-catch一下,否則會報格式轉換錯誤 19 int categoryid = Integer.parseInt(categoryId); 20 //這裏必定要判斷一下,由於jsp頁面下拉框有一個【所有】的分類選項,value=0,因此大於零,我纔去拼接字符串查詢,=0就是查所有,不須要加分類 的條件 21 if (categoryid > 0) { 22 sb.append(" and d.categoryId=" + categoryid + " "); 23 } 24 List<NewsCategory> categorylist = newsService.getcategorylist(); 25 // 頁面容量 26 int pageSize = 5; 27 // 當前頁碼 28 int currentPageNo = 1; 29 //newsDetailList.jsp中加的隱藏域,當前頁碼是包括了下一頁上一頁或用戶本身輸入的當前頁面參數值 30 String pageNo = request.getParameter("pageIndex");// 獲取當前頁碼隱藏域1 31 //對當前頁碼進行容錯處理,噹噹前頁爲空的時候,默認顯示第1頁 32 if (pageNo == null) { 33 currentPageNo = 1; 34 } else {// 不爲空的話,就連接提交給個人當前頁碼便是用戶請求的頁碼傳給個人值,我賦予給我定的當前頁碼參數值 35 currentPageNo = Integer.parseInt(pageNo); 36 } 37 //獲取總數據量的方法,參數裏面也加了where條件,全列表和查詢後列表都可用分頁 38 int totalCount = newsService.getNewsCount(sb.toString());// 總記錄數 39 /* 總頁數 */ 40 int totalPageCount = totalCount / pageSize + 1; 41 // 首頁和尾頁的異常控制 42 if (currentPageNo <= 0) { 43 currentPageNo = 1; 44 } else if (currentPageNo > totalPageCount) { 45 currentPageNo = totalPageCount; 46 } 47 // 顯示每頁新聞信息列表 48 List<NewsDetail> newsList = newsService.getPageNewsList(currentPageNo,pageSize, sb.toString()); 49 //如下變量是要把變量值set到請求中轉發給頁面,頁面要用的 50 request.setAttribute("currentPageNo", currentPageNo); 51 request.setAttribute("pageSize", pageSize); 52 request.setAttribute("totalPageCount", totalPageCount); 53 request.setAttribute("totalCount", totalCount); 54 request.setAttribute("categorylist", categorylist); 55 request.setAttribute("newsList", newsList); 56 request.getRequestDispatcher("/jsp/admin/newsDetailList.jsp").forward(request, response); 57 }catch(Exception e){ 58 e.printStackTrace(); 59 } 60 61 } 62 63 @Override 64 protected void doPost(HttpServletRequest req, HttpServletResponse resp) 65 throws ServletException, IOException { 66 doGet(req, resp); 67 } 68 69 @Override 70 protected void service(HttpServletRequest arg0, HttpServletResponse arg1) 71 throws ServletException, IOException { 72 super.service(arg0, arg1); 73 } 74 75 }
上面的servlet可能會報錯:
int categoryid = Integer.parseInt(categoryId); 這個可能會報
緣由:首次進入首頁,是doGet請求,不會去調查詢那裏的form的doPost方法,因此咱們執行
request.getParameter("categoryId")爲空,由於這個獲取表單數據值,只有Post提交才能夠
當值爲空的時候,轉換就會出錯,Integer類中有這個異常
因此要更改代碼爲:當不爲空的時候,才轉換
1 //取模類糊查詢分類選擇,是頁面select標籤的name 2 String categoryId = request.getParameter("categoryId"); 3 System.out.println("categoryId==================="+categoryId); 4 //取過來是個字符串,須要轉一下int,可是必定要Try-catch一下,否則會報格式轉換錯誤 5 if(categoryId!=null&& !"".equals(categoryId)){ 6 int categoryid = Integer.parseInt(categoryId); 7 //這裏必定要判斷一下,由於jsp頁面下拉框有一個【所有】的分類選項,value=0,因此大於零,我纔去拼接字符串查詢,=0就是查所有,不須要加分類 的條件 8 if (categoryid > 0) { 9 sb.append(" and d.categoryId=" + categoryid + " "); 10 } 11 }
由於有上面這個問題,因此想到了就是實際上進入首頁出所有列表信息,只是select下拉列表中默認選中【所有】選項,實際上並未有所有查詢
若是這個時候也不選類型也不輸入title關鍵字點擊GO進行查詢,那麼必須加上這段,由於JSP頁面select下拉列表元素【所有】這個項value=0
<option value="0">所有</option>
(上面代碼已加上,這裏只作原理說明時使用):
if (categoryid > 0) { sb.append(" and d.categoryId=" + categoryid + " "); }
web.xml配置:
1 <!--模糊查詢多條件 --> 2 <servlet> 3 <servlet-name>newsListByLikeServlet</servlet-name> 4 <servlet-class>com.cn.pb.servlet.NewsListByLike2</servlet-class> 5 </servlet> 6 <servlet-mapping> 7 <servlet-name>newsListByLikeServlet</servlet-name> 8 <url-pattern>/servlet/newsListByLikeServlet</url-pattern> 9 </servlet-mapping>
這裏的流程我要說一下,servlet爲何寫在doGet方法中,是get請求而不是Post請求:由於頁面走向是這樣的用戶請求訪問:
一、http://localhost:8080/news/servlet/newsListByLikeServlet進來的是這個列表頁,
二、請求這個servlet會映射到朝NewsListByLike2.java,
三、而後這個servlet中把頁面中須要的各個對象和變量取到再傳給newsDetailList.jsp頁面
四、模糊查詢的form提交的action也是到NewsListByLike2.java這個servlet中去的,查出的結果也仍是要在newsDetailList.jsp頁面顯示,因此與第3步一致
五、那爲何form提交的是post,而通常頁面查詢請求是get,上面個人servlet寫在doGet方法中了,但要注意,個人doPost方法中調用了doGet方法,也就是說一進來查詢條件(分類和關鍵字)用戶沒有輸入的都爲空的,這時候我仍是要出全列表數據的,這時候是Get操做,當我用戶選擇分類和關鍵字點GO的時候,form表單進行了Post提交,仍是提交給個人這個servlet處理,這時候走doPost,但實際上方法裏仍是能夠執行的我doGet裏的代碼,代碼能夠複用的。
補:
dao+service
dao:只是定義須要的方法
package com.cn.pb.dao; import java.sql.ResultSet; import java.util.Date; import java.util.List; import com.cn.pb.dao.util.PageBase; import com.cn.pb.pojo.NewsCategory; import com.cn.pb.pojo.NewsDetail; /*使用面向對象對程序進行二次改進 * 新聞信息表操做接口:針對新聞信息單表的操做 */ public interface NewsDao { //增長數據 public boolean insert(NewsDetail news); //刪除數據 public boolean delete(NewsDetail news); //修改數據:修改標題和id public boolean update(NewsDetail news); //修改數據:全部字段 public boolean updateall(NewsDetail news); //查找全部新聞信息 public List<NewsDetail> getNewList(); //按ID查詢數據 public NewsDetail select(int id); //查詢某個新聞類別下的新聞詳細信息 public int delCategoryNewsDetail(NewsDetail news); //查詢新聞並顯示類別名稱 public List<NewsDetail> getnewslist(); //獲取NewsDetail表中總行數 public int getNewsCount(String where); /* //獲得總頁數count表明一頁多少行 public int getpageCount(int count);*/ //當前頁顯示的新聞信息pageNo 當前頁碼,pagePerCount是每頁多少條數據 public List<NewsDetail> getPageNewsList(int pageNo,int pagePerCount,String where); //模糊查詢 public List<NewsDetail> getNewsByLike(int pageNo,int pagePerCount,String title); /*//模糊查詢加上分類 public List<NewsDetail> getNewsByLikeCategory(String category,String title);*/ //最新新聞:倒序前10 public List<NewsDetail> getNewNewsList(); //查找那些被刪除的主題,查找狀態爲0的列表信息 public List<NewsDetail> delNewsList(int pageNo,int pagePerCount); //刪除後的新聞信息進行恢復 public boolean recoverNews(int id); //查找某個分類下有多少條新聞信息 public int getNewsByCategory(int categoryId); }
service:跟dao層方法同樣,只是拿過來加個殼給servlet調用而已,畢竟規範在這,不直接操做dao層,若是不加其實對實際業務並沒有多少影響
package com.cn.pb.service; import java.sql.ResultSet; import java.util.Date; import java.util.List; import com.cn.pb.dao.util.PageBase; import com.cn.pb.pojo.NewsCategory; import com.cn.pb.pojo.NewsDetail; /* * service層:放業務邏輯處理 */ public interface NewsService { //增長數據 public boolean insert(NewsDetail news); //刪除數據 public boolean delete(NewsDetail news); //修改數據 public boolean update(NewsDetail news); //按ID查詢數據 public NewsDetail select(int id); //查找全部新聞數據 public List<NewsDetail> getNewsList(); /*//刪除新聞類型 public boolean deletecategory(int id);*/ /*//刪除新聞類型,類型下面有新聞信息 public boolean deletecategory2(NewsCategory newsCategory,String title);*/ //查看新聞類別 public List<NewsCategory> getcategorylist(); //修改數據:全部字段 public boolean updateall(NewsDetail news); //查詢新聞並顯示類別名稱 public List<NewsDetail> getnewslist(); //獲取NewsDetail表中總行數 public int getNewsCount(String title); /*//獲得總頁數count表明一頁多少行 public int getpageCount(int count);*/ //當前頁顯示的新聞信息pageNo 當前頁碼,pagePerCount是每頁多少條數據 public List<NewsDetail> getPageNewsList(int pageNo,int pagePerCount,String where); //模糊查詢 public List<NewsDetail> getNewsByLike(int pageNo,int pagePerCount,String title); //最新新聞:倒序前10 public List<NewsDetail> getNewNewsList(); //查找那些被刪除的主題,查找狀態爲0的列表信息 public List<NewsDetail> delNewsList(int pageNo,int pagePerCount); //刪除後的新聞信息進行恢復 public boolean recoverNews(int id); //查找某個分類下有多少條新聞信息 public int getNewsByCategory(int categoryId); //分頁和list獨立出一個javabean public PageBase<NewsDetail> getPages(int pageNo,String where); }
準備寫一篇分離分頁,把分頁封裝到一個類中的實例