爲了鞏固開發的流程,咱們再拿一個客戶關係管理系統來練手!javascript
咱們完成的就是下面的項目!html
CREATE TABLE customer ( id VARCHAR(40) PRIMARY KEY, name VARCHAR(20) NOT NULL, gender VARCHAR(10) NOT NULL, birthday DATE, cellphone VARCHAR(30) NOT NULL, email VARCHAR(30), preference VARCHAR(200), type VARCHAR(20), description VARCHAR(255) );
開發實體十分簡單,對照着數據庫的表就好了!java
private String id; private String name ; private String gender ; private Date birthday ; private String cellphone ; private String eamil ; private String preference ; private String type ; private String description; //....各類setter、getter
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/zhongfucheng</property> <property name="user">root</property> <property name="password">root</property> <property name="acquireIncrement">5</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">5</property> <property name="maxPoolSize">20</property> </default-config> <named-config name="mysql"> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/zhongfucheng</property> <property name="user">root</property> <property name="password">root</property> <property name="acquireIncrement">5</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">5</property> <property name="maxPoolSize">20</property> </named-config> <named-config name="oracle"> <property name="driverClass">oracle.jdbc.driver.OracleDriver</property> <property name="jdbcUrl">jdbc:oracle:thin:@//localhost:1521/事例名...</property> <property name="user">用戶名</property> <property name="password">密碼</property> <property name="acquireIncrement">5</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">5</property> <property name="maxPoolSize">20</property> </named-config> </c3p0-config>
public class Utils2DB { private static ComboPooledDataSource comboPooledDataSource = null; static { //它會自動尋找配置文件,節點爲mysql的數據庫(默認就是Mysql) comboPooledDataSource = new ComboPooledDataSource(); } public static DataSource getDataSource() { return comboPooledDataSource ; } public static Connection connection() { try { return comboPooledDataSource.getConnection(); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("數據庫初始化失敗了!"); } } }
public class WebUtils { public static String makeId() { return UUID.randomUUID().toString(); } }
DAO應該提供增長客戶和查詢用戶的功能mysql
public void addCustomer(Customer customer) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "INSERT INTO customer (id,name, gender, birthday, cellphone, preference, type, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?,?)"; //獲得用戶傳遞進來的數據 String id = customer.getId(); String name = customer.getName(); String gender = customer.getGender(); String cellphone = customer.getCellphone(); String email = customer.getEmail(); String preference = customer.getPreference(); String type = customer.getType(); String description = customer.getDescription(); //對於日期,要轉換一下 Date date = customer.getBirthday(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); String birthday = simpleDateFormat.format(date); try { //向數據庫插入數據 queryRunner.update(sql, new Object[]{id, name, gender, birthday, cellphone, email, preference, type, description}); //插入記錄成功! } catch (SQLException e) { //若是出現了異常,就拋出Dao異常吧(自定義的異常) e.printStackTrace(); throw new DaoException("添加用戶出錯了!"); } }
寫完一個功能,不要急着去寫其餘的功能,先測試一下!程序員
@Test public void add() { //爲了測試的方便,直接使用構造函數了! Customer customer = new Customer("1", "zhongfucheng", "男", new Date(), "1234", "aa@sina.com", "打代碼", "高貴的用戶", "我是個好人"); CustomerDao customerDao = new CustomerDao(); customerDao.addCustomer(customer); }
解決的辦法,看我另一篇博文:http://blog.csdn.net/hon_3y/article/details/57945418web
將全部的客戶查詢出來就好了!sql
//獲得全部的用戶 public List<Customer> getAll() { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "SELECT * FROM customer"; try { List<Customer> customers = (List<Customer>) queryRunner.query(sql, new BeanListHandler(Customer.class)); //若是集合大於個數大於0,就返回集合,不大於0,就返回null return customers.size() > 0 ? customers : null; } catch (SQLException e) { e.printStackTrace(); throw new DaoException("獲取全部的用戶出錯了!"); } }
@Test public void find() { CustomerDao customerDao = new CustomerDao(); List<Customer> customers = customerDao.getAll(); for (Customer customer : customers) { System.out.println(customer.getName()); } }
修改用戶信息首先要知道用戶的信息,在web端,只有id能惟一標識用戶,咱們須要經過id,獲取用戶所有信息(也就是Customer對象)數據庫
public Customer find(String id) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "SELECT * FROM customer WHERE id = ?"; try { Customer customer = (Customer) queryRunner.query(sql, new BeanHandler(Customer.class), new Object[]{id}); return customer; } catch (SQLException e) { e.printStackTrace(); throw new DaoException("查找用戶失敗了"); } }
修改用戶都是外邊傳遞個對象進來,Dao層取出對象的數據,從而對數據庫的數據進行修改!編程
public void update(Customer customer) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "UPDATE customer set name=?,gender=?,birthday=?,cellphone=?,email=?,preference=?,type=?,description=? WHERE id = ?"; try { queryRunner.update(sql, new Object[]{customer.getName(), customer.getGender(), customer.getBirthday(),customer.getCellphone(), customer.getEmail(), customer.getPreference(), customer.getType(), customer.getDescription(), customer.getId()}); } catch (SQLException e) { e.printStackTrace(); throw new DaoException("更新失敗"); } }
@Test public void update() { CustomerDao customerDao = new CustomerDao(); //咱們已經知道了某id,經過id獲取獲得用戶信息(Customer) String id = "043f7cce-c6f1-4155-b688-ba386cae1636"; Customer customer = customerDao.find(id); //修改用戶信息 customer.setName("看完博客要點贊"); customerDao.update(customer); }
public void delete(String id) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "DELETE from customer WHERE id = ?"; try { queryRunner.update(sql, new Object[]{id}); } catch (SQLException e) { e.printStackTrace(); throw new DaoException("刪除用戶失敗了"); } }
@Test public void delete() { CustomerDao customerDao = new CustomerDao(); //咱們已經知道了某id,經過id刪除數據庫中的記錄 String id = "043f7cce-c6f1-4155-b688-ba386cae1636"; customerDao.delete(id); }
數據庫已經查詢不到id爲043f7cce-c6f1-4155-b688-ba386cae1636的記錄了!bash
public class BusinessService { CustomerDao customerDao = new CustomerDao(); public List<Customer> getAll() { return customerDao.getAll(); } public void addCustomer(Customer customer) { customerDao.addCustomer(customer); } public void deleteCustomer(String id) { customerDao.delete(id); } public void updateCustomer(Customer customer) { customerDao.update(customer); } public Customer findCustomer(String id) { return customerDao.find(id); } }
//直接跳轉到顯示增長用戶頁面的jsp request.getRequestDispatcher("/WEB-INF/addCustomer.jsp").forward(request, response);
<form action="${pageContext.request.contextPath}/addCustomerController"> <table border="1px"> <tr> <td>用戶名:</td> <td><input type="text" name="name"></td> </tr> <tr> <td>性別:</td> <td> <input type="radio" name="gender" value="female">女 <input type="radio" name="gender" value="male">男 </td> </tr> <tr> <td>生日:</td> <td> <select id="year"> <option value="1900">1900</option> </select> <select id="month"> <option value="01">01</option> </select> <select id="day"> <option value="01">01</option> </select> </td> </tr> <tr> <td>電話號碼:</td> <td><input type="text" name="cellphone"></td> </tr> <tr> <td>郵箱:</td> <td><input type="text" name="email"></td> </tr> <tr> <td>愛好:</td> <td> <input type="checkbox" name="hobbies" value="唱歌">唱歌 <input type="checkbox" name="hobbies" value="跳舞">跳舞 <input type="checkbox" name="hobbies" value="打代碼">打代碼 </td> </tr> <tr> <td>客戶類型</td> <td> <input type="radio" name="type" value="VIP">VIP <input type="radio" name="type" value="普通客戶">普通客戶 <input type="radio" name="type" value="黑名單客戶">黑名單客戶 </td> </tr> <tr> <td>描述</td> <td> <textarea name="description" cols="30" rows="10"></textarea> </td> </tr> <tr> <td><input type="submit" value="增添客戶"></td> <td><input type="reset" value="重置"></td> </tr> </table> </form>
咱們發現,在日期的下拉框中,只有一個數據(由於咱們在value中只寫了一個數據)
要想在下拉框中能夠選擇不少的數據,那麼value的值就不能單單隻有一個。固然了,也不可能在JSP頁面中寫下面的代碼
<option value="1900">1900</option> <option value="1901">1900</option> <option value="1902">1900</option> <option value="1903">1900</option>
咱們用javaScript生成下拉框的數據就好了!!
function makeYear() { //獲得下拉框的控件 var year = document.getElementById("year"); //要想下拉框有更多的數據,就須要有更多的option控件 //js獲取獲得年份是getFullYear(),單單的getYear()只是獲取兩位數 for (var i=1901; i<= new Date().getFullYear(); i++) { //生成option控件 var option = document.createElement("option"); //option控件的值和文本內容爲循環生成的年分! option.value = i; option.innerText = i; //將生成option控件綁定到select控件上 year.appendChild(option); } }
function makeMonth() { var month = document.getElementById("month"); for (var i = 2; i <= 12; i++) { var option = document.createElement("option"); if (i < 10) { option.value = '0' + i; option.innerText = '0' + i; } else { option.value = i; option.innerText = i; } month.appendChild(option); } } function makeDay() { var day = document.getElementById("day"); for(var i=2;i<=12;i++) { var option = document.createElement("option"); if(i<10) { option.value = '0' + i; option.innerText = '0' + i; }else{ option.value = i; option.innerText = i; } day.appendChild(option); } }
在JSP頁面中導入javascript文件
注意:javasrcipt文件不能放在WEB-INF下面!!!!不然是獲取不到的!!!
<script type="text/javascript" src="${pageContext.request.contextPath}/customer.js" ></script>
function pageInit() { makeYear(); makeMonth(); makeDay(); } <body onload="pageInit()">
表單的數據很是多,毫無疑問,咱們會使用BeanUtils來將數據封裝到Bean對象中!
對於表單的數據,仍是有些雜亂的。表單中日期的年月日是分開的,咱們要麼在客戶端將年月日的數據拼湊起來,要麼在服務器端將年月日拼湊起來!同理,客戶的喜愛可能不僅僅有一個,但在Customer對象中,喜愛單單用一個String類型來表示的。咱們也要把客戶的喜愛拼湊起來。
顯然,在客戶端用javaScript作拼湊是很是方便的!
function makeBirthday() { //獲取下拉框的數據,把數據拼湊成日期字符串 var year = document.getElementById("year"); var month = document.getElementById("month"); var day = document.getElementById("day"); var birthday = year + "-" + month + "-" + day; //想要將拼湊完的字符串提交給服務器,用隱藏域就好了 var input = document.createElement("input"); input.type = "hidden"; input.value = birthday; input.name = "birthday"; //將隱藏域綁定在form下【爲了方便,在form中設置id,id名字爲form】 document.getElementById("form").appendChild(input); } function makePreference() { //獲取喜愛的控件 var hobbies = document.getElementsByName("hobbies"); //定義變量,記住用戶選中的選項 var preference = ""; //遍歷喜愛的控件,看用戶選上了什麼! for (var i = 0; i < hobbies.length; i++) { if (hobbies[i].checked == true) { preference += hobbies[i].value + ","; } } //剛纔拼湊的時候,最後一個逗號是多餘的,咱們要把它去掉 preference = preference.substr(0, preference.length - 1); //也是用隱藏域將數據帶過去給服務器 var input = document.createElement("input"); input.type = "hidden"; input.value = preference; input.name = "preference"; //將隱藏域綁定到form表單上 document.getElementById("form").appendChild(input); }
function makeForm() { makeBirthday(); makePreference(); return true; } <form action="${pageContext.request.contextPath}/addCustomerController" id="form" onsubmit=" return makeForm()" method="post">
public static <T> T request2Bean(HttpServletRequest httpServletRequest, Class<T> aClass) { try { //獲取Bean的對象 T bean = aClass.newInstance(); //獲取表單中全部的名字 Enumeration enumeration = httpServletRequest.getParameterNames(); //遍歷表單提交過來的名字 while (enumeration.hasMoreElements()) { //每一個名字 String name = (String) enumeration.nextElement(); //獲取獲得值 String value = httpServletRequest.getParameter(name); //若是用戶提交的數據不爲空,那麼將數據封裝到Bean中 if (!value.equals("") && value != null) { BeanUtils.setProperty(bean, name, value); } } return bean; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("封裝數據到Bean中,失敗了!"); } }
//將表單的數據弄到Bean對象中 Customer customer = WebUtils.request2Bean(request, Customer.class); try { //調用BusinessService層的方法,添加客戶 BusinessService businessService = new BusinessService(); businessService.addCustomer(customer); //若是執行到這裏,說明成功了,若是被catch了,說明失敗了。 request.setAttribute("message", "添加成功!"); } catch (Exception e) { e.printStackTrace(); request.setAttribute("message", "添加失敗"); } request.getRequestDispatcher("/message.jsp").forward(request, response);
//跳轉到顯示客戶界面信息的jsp request.getRequestDispatcher("/WEB-INF/lookCustomer.jsp").forward(request, response);
<c:if test="${empty(list)}"> 對不起,尚未任何客戶的信息! </c:if> <c:if test="${!empty(list)}"> <table border="1px"> <tr> <td>用戶名:</td> <td>密碼:</td> <td>性別:</td> <td>生日:</td> <td>電話號碼:</td> <td>郵箱:</td> <td>類型:</td> <td>描述:</td> </tr> <c:forEach items="${list}" var="customer"> <tr> <td>${customer.name}</td> <td>${customer.gender}</td> <td>${customer.birthday}</td> <td>${customer.cellphone}</td> <td>${customer.email}</td> <td>${customer.preference}</td> <td>${customer.type}</td> <td>${customer.description}</td> </tr> </c:forEach> </table> </c:if>
採用分貞技術,讓界面更加好看!
index頁面:
<frameset rows="25%,*"> <frame src="${pageContext.request.contextPath }/head.jsp" name="head"> <frame src="${pageContext.request.contextPath }/body.jsp" name="body"> </frameset>
head頁面:
<body style="text-align: center;"> <h1>客戶管理系統!</h1> <a href="${pageContext.request.contextPath}/AddCustomer" target="body">增添客戶</a> <a href="${pageContext.request.contextPath}/LookCustomer" target="body">查看客戶</a> </body>
body頁面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> </body> </html>
如今問題來了,若是咱們客戶信息有很是很是地多,咱們不可能把客戶信息所有都擠在同一個頁面上,若是咱們這樣作的話,網頁的長度就會很是的長!
因而乎,咱們就須要用到了分頁的技術,對於分頁技術基礎的講解,在我另外一篇博文中有介紹:http://blog.csdn.net/hon_3y/article/details/53790092
看完上篇博文,咱們知道,首先要作的就是:明確分頁技術中須要用到的4個變量的值!
查詢總記錄數也就是查詢數據庫表的記錄有多少條,這是關於對數據庫數據的操做,因此確定是在dao層作!
public Long getTotalRecord() { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "SELECT * FROM customer"; try { //獲取查詢的結果 Long l = (Long) queryRunner.query(sql, new ScalarHandler()); return l; } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("查詢總記錄數失敗了!"); } }
獲取分頁的數據也是查詢數據庫的記錄,這也是關於對數據庫的操做,因此也是在Dao層作的!
/*查詢分頁數據*/ //獲取分頁的數據是須要start和end兩個變量的【從哪條開始取,取到哪一條】 public List<Customer> getPageData(int start, int end) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "SELECT * FROM customer LIMIT ?,?"; try { List<Customer> customers = (List<Customer>) queryRunner.query(sql, new BeanListHandler(Customer.class), new Object[]{start, end}); return customers; } catch (SQLException e) { e.printStackTrace(); throw new DaoException("獲取分頁數據失敗了!"); } }
如今咱們已經能夠知道總記錄數了,對於其餘3個變量(每頁顯示記錄數【由程序員來指定】,當前是多少頁【由用戶來指定】,總頁數【由總記錄數和每頁顯示記錄數來算數來的】)
如今要分析的是,這些變量應該放在哪裏呢???所有放在Dao層??所有放在Dao層是能夠實現功能的,可是,這樣MVC結構就被破壞掉了(Dao層只用來對數據進行CRUD操做,4個變量存在Dao層,是不合理的)
最好的作法是這樣的:建立一個實體Page,將分頁用到的信息所有封裝在Page中實現!Page就表明着分頁的數據這樣就很是符合面向對象的思想了!
①:建立Page類
//保存着分頁的數據 private List<Customer> list; //總記錄數 private long totalRecord; //每頁顯示記錄數,這裏我規定每頁顯示3條 private int linesize = 3; //總頁數 private int totalPageCount; //當前顯示的頁數 private long currentPageCount; //...各類的setter、getter
②:BusinessService應該提供獲取分頁數據的服務
//既然Page對象表明是分頁數據,那麼返回Page對象便可! //web層應該傳入想要看哪一頁數據的參數! public Page getPageData(String currentPageCount) { Page page = new Page(); //獲取數據庫中有多少條記錄,並封裝到Page對象中 Long totalRecord = customerDao.getTotalRecord(); page.setTotalRecord(totalRecord); //算出總頁數,並封裝到Page對象中 int totalPagecount = (int) (totalRecord % page.getLinesize() == 0 ? totalRecord / page.getLinesize() : totalRecord / page.getLinesize() + 1); page.setTotalPageCount(totalPagecount); int start ; int end = page.getLinesize(); //如今又分兩種狀況了,若是傳遞進來的參數是null的,那麼說明外界是第一次查詢的 if (currentPageCount == null) { //第一次查詢,就應該設置當前頁數是第一頁 page.setCurrentPageCount(1); start = (int) ((page.getCurrentPageCount() - 1) * page.getLinesize()); List<Customer> customers = customerDao.getPageData(start, end); page.setList(customers); } else { //若是不是第一次,就把外界傳遞進來的頁數封裝到Page對象中 page.setCurrentPageCount(Long.parseLong(currentPageCount)); start = (int) ((page.getCurrentPageCount() - 1) * page.getLinesize()); List<Customer> customers = customerDao.getPageData(start, end); page.setList(customers); } return page; }
③:web層調用BusinessService層的功能,獲取獲得Page對象
//獲取用戶想要看的頁數,若是是第一次,那確定爲null String currentPageCount = request.getParameter("currentPageCount"); //調用BusinessService的方法,獲取獲得全部客戶信息 BusinessService businessService = new BusinessService(); Page page = businessService.getPageData(currentPageCount); //把客戶信息帶過去給jsp頁面 request.setAttribute("page", page); //跳轉到顯示客戶界面信息的jsp request.getRequestDispatcher("/WEB-INF/lookCustomer.jsp").forward(request, response);
④:在JSP頁面中,使用EL表達式獲取到Page對象,從而輸出數據
<c:forEach items="${page.list}" var="customer"> <tr> <td>${customer.name}</td> <td>${customer.gender}</td> <td>${customer.birthday}</td> <td>${customer.cellphone}</td> <td>${customer.email}</td> <td>${customer.preference}</td> <td>${customer.type}</td> <td>${customer.description}</td> </tr> </c:forEach>
⑤:在JSP頁面中顯示頁碼,同時把碼數綁定到超連接去!
<%--提供頁數的界面--%> <c:forEach var="pageNum" begin="1" end="${page.totalPageCount}"> <a href="${pageContext.request.contextPath}/LookCustomer?currentPageCount=${pageNum}"> ${pageNum} </a> </c:forEach>
通常的分頁不只僅只有頁碼給你,還有上一步和下一步。咱們在JSP頁面上也能添加這樣的功能,其實這是很是簡單的!
<%--若是當前的頁碼大於1,才顯示上一步--%> <c:if test="${page.currentPageCount>1}"> <%--把傳遞過去的頁碼-1就好了--%> <a href="${pageContext.request.contextPath}/LookCustomer?currentPageCount=${page.currentPageCount-1}"> 上一步 </a> </c:if> <%--若是當前的頁碼小於總頁數,才顯示下一步--%> <c:if test="${page.currentPageCount<page.totalPageCount}"> <%--把傳遞過去的頁碼-1就好了--%> <a href="${pageContext.request.contextPath}/LookCustomer?currentPageCount=${page.currentPageCount+1}"> 下一步 </a> </c:if>
當前頁數是:[${page.currentPageCount}] 總頁數是:${page.totalPageCount} 總記錄數是:${page.totalRecord}
<input type="text" id="currentPageCount"> <input type="button" value="跳轉">
咱們如今要作的就是:怎麼樣才能輸入框輸入內容,而後點擊跳轉按鈕,將輸入框的數據發送到Servlet上,而後實現跳轉到某頁上功能
明顯地,咱們確定要使用JavaScript代碼!
<script type="text/javascript"> /*既然寫上了JavaScript代碼了,就順便驗證輸入框輸入的數據是否合法吧*/ function goPage() { /*獲取輸入框控件*/ var input = document.getElementById("currentPageCount"); /*獲取輸入框的數據*/ var value = input.value; if(value==null || value==""){ alert("請輸入頁碼"); return false; } if(!value.match("\\d+")){ alert("請輸入數字"); return false; } if(value<1 || value>${page.totalPageCount}){ alert("請輸入合法數據"); return false ; } window.location.href="${pageContext.request.contextPath}/LookCustomer?currentPageCount="+value; } </script>
爲何咱們要記錄JSP頁面的開始頁和結束頁呢?通過上面層層地優化,咱們感受不出有什麼問題了。那是由於數據量太少!
咱們試着多添加點記錄進數據庫,再回來看看!
從上面的圖咱們能夠發現頁數有多少,JSP頁面就顯示多少!這明顯不合理的,若是有100頁也顯示100頁嗎?
咱們作一個規定,一次只能顯示10頁的數據。那麼顯示哪10頁呢?這又是一個問題了,若是咱們在看第11頁的數據,應該顯示的是第7到第16頁的數據(顯示11附近的頁數),咱們在看第2頁的數據,應該顯示第1到第10頁的數據。用戶想要看的頁數是不明確的,咱們顯示附近的頁數也是不明確的!。咱們應該把用戶想要看的頁數記錄下來,而後根據邏輯判斷,顯示附近的頁數
咱們顯示頁數的代碼是這樣的:
很明顯,咱們只要控制了begin和end中的數據,就控制顯示哪10頁了!
①在Page類中多定義兩個成員變量
//記錄JSP頁面開始的頁數和結束的頁數 private int startPage; private int endPage; //Setter,Getter方法
②開始頁數和結束頁數受用戶想看的頁數影響,在BusinessService的getPageData()加入下面的邏輯
//第一次訪問 page.setStartPage(1); page.setEndPage(10); //不是第一次訪問 if (page.getCurrentPageCount() <= 10) { page.setStartPage(1); page.setEndPage(10); } else { page.setStartPage((int) (page.getCurrentPageCount() - 4)); page.setEndPage((int) (page.getCurrentPageCount() + 5)); //若是由於加減角標越界了,那麼就設置最前10頁,或者最後10頁 if (page.getStartPage() < 1) { page.setStartPage(1); page.setEndPage(10); } if (page.getEndPage() > page.getTotalPageCount()) { page.setEndPage(page.getTotalPageCount()); page.setStartPage(page.getTotalPageCount() - 9); } }
③:在JSP顯示頁數時,獲取獲得開始頁和結束頁就好了
<%--提供頁數的界面--%> <c:forEach var="pageNum" begin="${page.startPage}" end="${page.endPage}"> <a href="${pageContext.request.contextPath}/LookCustomer?currentPageCount=${pageNum}"> [${pageNum}] </a> </c:forEach>
咱們再回頭看看BusinessService中獲取分頁數據的代碼:
//既然Page對象表明是分頁數據,那麼返回Page對象便可! //web層應該傳入想要看哪一頁數據的參數! public Page getPageData(String currentPageCount) { Page page = new Page(); //獲取數據庫中有多少條記錄,並封裝到Page對象中 Long totalRecord = customerDao.getTotalRecord(); page.setTotalRecord(totalRecord); //算出總頁數,並封裝到Page對象中 int totalPagecount = (int) (totalRecord % page.getLinesize() == 0 ? totalRecord / page.getLinesize() : totalRecord / page.getLinesize() + 1); page.setTotalPageCount(totalPagecount); int start ; int end = page.getLinesize(); //如今又分兩種狀況了,若是傳遞進來的參數是null的,那麼說明外界是第一次查詢的 if (currentPageCount == null) { //第一次查詢,就應該設置當前頁數是第一頁 page.setCurrentPageCount(1); page.setStartPage(1); page.setEndPage(10); start = (int) ((page.getCurrentPageCount() - 1) * page.getLinesize()); List<Customer> customers = customerDao.getPageData(start, end); page.setList(customers); } else { //若是不是第一次,就把外界傳遞進來的頁數封裝到Page對象中 page.setCurrentPageCount(Long.parseLong(currentPageCount)); start = (int) ((page.getCurrentPageCount() - 1) * page.getLinesize()); if (page.getCurrentPageCount() <= 10) { page.setStartPage(1); page.setEndPage(10); } else { page.setStartPage((int) (page.getCurrentPageCount() - 4)); page.setEndPage((int) (page.getCurrentPageCount() + 5)); //若是由於加減角標越界了,那麼就設置最前10頁,或者最後10頁 if (page.getStartPage() < 1) { page.setStartPage(1); page.setEndPage(10); } if (page.getEndPage() > page.getTotalPageCount()) { page.setEndPage(page.getTotalPageCount()); page.setStartPage(page.getTotalPageCount() - 9); } } List<Customer> customers = customerDao.getPageData(start, end); page.setList(customers); } return page; }
太太太太太tm複雜,太太太太tm長了!!!!!咱們BusinessService要作的僅僅是調用Dao層的功能,爲web層提供數據,但咱們在方法中使用大量了邏輯判斷,並且這些邏輯判斷都是屬於Page類的!
明確一下:只有獲取數據庫總記錄數是在BusinessService中作的,其餘的數據變量都是應該在Page類中完成!
在BusinessService獲取了總記錄數以後,咱們要對其餘變量進行初始化(根據總記錄數,用戶想要看哪一頁的數據),算出其餘的數據(JSP記錄開始頁數、結束頁數、總頁數等等),最好的辦法就是經過Page的構造函數來實現初始化!
public Page getPageData2(String currentPageCount) { //獲取獲得總記錄數 Long totalPageCount = customerDao.getTotalRecord(); if (currentPageCount == null) { //若是是第一次,那麼就將用戶想看的頁數設置爲1 Page page = new Page(1, totalPageCount); List<Customer> customers = customerDao.getPageData(page.getStartIndex(), page.getLinesize()); page.setList(customers); return page; } else { //若是不是第一次,就將獲取獲得的頁數傳遞進去 Page page = new Page(Integer.parseInt(currentPageCount), totalPageCount); List<Customer> customers = customerDao.getPageData(page.getStartIndex(), page.getLinesize()); page.setList(customers); return page; } }
public Page(int currentPageCount, long totalRecord) { //將傳遞進來的currentPageCount初始化 this.currentPageCount = currentPageCount; //總頁數 totalPageCount = (int) (totalRecord % linesize == 0 ? totalRecord / linesize : totalRecord / linesize + 1); //總記錄數 this.totalRecord = totalRecord; //開始取數據的位置 startIndex = (currentPageCount - 1) * linesize; //若是當前頁小於10,那麼開始頁爲1,結束頁爲10就好了 if (this.currentPageCount <= 10) { this.startPage = 1; this.endPage = 10; } else { startPage = this.currentPageCount - 4; endPage = this.currentPageCount + 5; //加減後頁數越界的狀況 if (startPage < 1) { this.startPage = 1; this.endPage = 10; } if (endPage > totalPageCount) { this.startPage = this.currentPageCount - 9; this.endPage = this.totalPageCount; } } }
分頁的顯示頁面都是永恆不變的,咱們能夠把代碼重構成一個jsp,須要用到分頁顯示頁面的地方,就包含進去就好了!
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%--顯示當前頁數--%> 當前頁數是:[${page.currentPageCount}] <%--若是當前的頁碼大於1,才顯示上一步--%> <c:if test="${page.currentPageCount>1}"> <%--把傳遞過去的頁碼-1就好了--%> <a href="${pageContext.request.contextPath}/LookCustomer?currentPageCount=${page.currentPageCount-1}"> 上一步 </a> </c:if> <%--提供頁數的界面--%> <c:forEach var="page" begin="${page.startPage}" end="${page.endPage}"> <a href="${pageContext.request.contextPath}/LookCustomer?currentPageCount=${page}"> [${page}] </a> </c:forEach> <%--若是當前的頁碼小於總頁數,才顯示下一步--%> <c:if test="${page.currentPageCount<page.totalPageCount}"> <%--把傳遞過去的頁碼-1就好了--%> <a href="${pageContext.request.contextPath}/LookCustomer?currentPageCount=${page.currentPageCount+1}"> 下一步 </a> </c:if> <input type="text" id="currentPageCount"> <input type="button" value="跳轉" onclick="goPage()"> 總頁數是:${page.totalPageCount} 總記錄數是:${page.totalRecord} <script type="text/javascript"> /*既然寫上了JavaScript代碼了,就順便驗證輸入框輸入的數據是否合法吧*/ function goPage() { /*獲取輸入框控件*/ var input = document.getElementById("currentPageCount"); /*獲取輸入框的數據*/ var value = input.value; if(value==null || value==""){ alert("請輸入頁碼"); return false; } if(!value.match("\\d+")){ alert("請輸入數字"); return false; } if(value<1 || value>${page.totalPageCount}){ alert("請輸入合法數據"); return false ; } window.location.href="${pageContext.request.contextPath}/LookCustomer?currentPageCount="+value; } </script>
用須要用到的地方,導入便可!
<jsp:include page="page.jsp"></jsp:include>
爲了作到更好的通用性,處理分頁數據的url應該由Servlet傳進去給Page類,讓Page類封裝起來!要使用的時候,再用Page取出來就好了。
下面寫法已經固定了,不夠靈活!也就是說,下面的url地址不該該寫死的
${pageContext.request.contextPath}/LookCustomer?currentPageCount=${page.currentPageCount+1}
咱們能夠這樣作:
String servletName = this.getServletName(); //調用BusinessService的方法,獲取獲得全部客戶信息 BusinessService businessService = new BusinessService(); //把Servlet的url也傳遞進去 Page page = businessService.getPageData2(currentPageCount, request.getContextPath() + "/" + servletName);
private String url; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; }
page.setUrl(url);
咱們在jsp頁面跳轉處處理分頁數據的Servlet上,就再不用寫死了。直接用Page對象中獲取出來就好了!
<%--把傳遞過去的頁碼-1就好了--%> <a href="${page.url}?currentPageCount=${page.currentPageCount-1}"> 上一步 </a>
在查詢jsp頁面上,增添刪除和修改的操做連接!
超連接綁定要刪除用戶的id,帶過去給Controller
<a href="${pageContext.request.contextPath}/DeleteCustomer?id=${customer.id}">刪除</a>
controller的代碼也十分簡單:
String id = request.getParameter("id"); //調用BusinessService層的功能,就能夠完成刪除操做了 BusinessService businessService = new BusinessService(); businessService.deleteCustomer(id);
刪除客戶記錄也是一件很是重要的事情,應該提供JavaSrcript代碼詢問是否要真的刪除
在超連接控件上綁定事件!
<a href="${pageContext.request.contextPath}/DeleteCustomer?id=${customer.id}" onclick=" return sureDelete()">刪除</a>
function sureDelete() { var b = window.confirm("你肯定要刪除嗎?"); if(b) { return true; }else { return false; } }
測試:
修改操做的流程是這樣的:點擊修改超連接,跳轉到該用戶的詳細信息頁面,在詳細信息頁面中修改數據,再提交修改!【跳轉到用戶詳細信息頁面時,用戶的id還在的,在提交數據的時候,記得把id也給到服務器,【id是不包含在表單中的,要咱們本身提交過去】!】
<a href="${pageContext.request.contextPath}/UpdateCustomerUI?=${customer.id}">修改</a>
String id = request.getParameter("id"); BusinessService businessService = new BusinessService(); //經過id獲取獲得用戶的詳細信息 Customer customer = businessService.findCustomer(id); request.setAttribute("customer", customer); //跳轉到顯示用戶詳細信息的jsp頁面上 request.getRequestDispatcher("/WEB-INF/customerInformation").forward(request, response);
想要日期可以選擇,記得導入JavaScript代碼,響應事件!
注意:在顯示頁面上,必定要把id傳遞過去給處理表單的Servlet,否則服務器是不知道你要修改哪一條數據的!
<head> <title>用戶詳細信息</title> <script type="text/javascript" src="${pageContext.request.contextPath}/customer.js"> </script> </head> <body onload="pageInit()"> <form action="${pageContext.request.contextPath}/updateCustomer?id=${customer.id}" method="post" onsubmit="makeForm()"> <table border="1px"> <tr> <td>用戶名:</td> <td><input type="text" name="name" value="${customer.name}"></td> </tr> <tr> <td>性別</td> <td><input type="radio" name="gender" value="male" ${customer.gender=='male'?'checked':''}>男 <input type="radio" name="gender" value="female"${customer.gender=='female'?'checked':''}>女 </td> </tr> <tr> <td>生日</td> <td> <select id="year"> <option value="${fn:split(customer.birthday,'-')[0]}">${fn:split(customer.birthday,'-')[0]}</option> </select> <select id="month"> <option value="${fn:split(customer.birthday,'-')[1]}">${fn:split(customer.birthday,'-')[1]}</option> </select> <select id="day"> <option value="${fn:split(customer.birthday,'-')[2]}">${fn:split(customer.birthday,'-')[2]}</option> </select> </td> </tr> <tr> <td>電話號碼:</td> <td><input type="text" name="cellphone" value="${customer.cellphone}"></td> </tr> <tr> <td>郵箱:</td> <td><input type="text" name="email"value="${customer.email}"></td> </tr> <tr> <td>愛好:</td> <td> <input type="checkbox" name="hobbies" value="唱歌"${fn:contains(customer.preference, '唱歌')==true?'checked':''}>唱歌 <input type="checkbox" name="hobbies" value="跳舞"${fn:contains(customer.preference, '跳舞')==true?'checked':''}>跳舞 <input type="checkbox" name="hobbies" value="打代碼"${fn:contains(customer.preference, '打代碼')==true?'checked':''}>打代碼 </td> </tr> <tr> <td>客戶類型</td> <td> <input type="radio" name="type" value="VIP" ${customer.type=='VIP'?'checked':''}>VIP <input type="radio" name="type" value="普通客戶"${customer.type=='普通客戶'?'checked':''}>普通客戶 <input type="radio" name="type" value="黑名單客戶"${customer.type=='黑名單客戶'?'checked':''}>黑名單客戶 </td> </tr> <tr> <td>描述</td> <td> <textarea name="description" cols="30" rows="10">${customer.description}</textarea> </td> </tr> <tr> <td><input type="submit" value="肯定修改"></td> <td><input type="reset" value="重置"></td> </tr> </table> </form>
//將數據封裝到Bean中 Customer customer = WebUtils.request2Bean(request, Customer.class); //將id封裝到Customer對象中!!!不要忘了id!!!在表單中獲取到的數據是沒有id的!!!!!記得!!!! customer.setId(request.getParameter("id")); //調用Service層的方法,實現修改 BusinessService businessService = new BusinessService(); businessService.updateCustomer(customer); //修改爲功就跳回查看客戶界面 request.getRequestDispatcher("/LookCustomer").forward(request, response);