(未經容許,請勿轉載,謝謝。)javascript
本案例的處理過程:html
客戶端發送一個請求給服務器,服務器把這個請求給Servlet,Servlet 獲取請求信息,根據請求信息的狀況去調用 model (在這裏是一個普通的 Java 類),而後把返回結果給 Servlet ,而後Servlet 根據返回結果 轉向一個 JSP,JSP是用來呈現數據的 (這裏用的是Java 代碼),生成一個HTML 頁面顯給客戶。java
使用到的技術:mysql
MVC 設計模式:JSP、Servlet、POJOjquery
數據庫:MySQLweb
鏈接數據庫使用 c3p0 數據庫鏈接池sql
JDBC 工具使用 DBUtils數據庫
頁面上的提示操做使用 jQueryapache
具體實現步驟:設計模式
一、創建數據表
代碼:
Create table customer(
id int(10) primary key auto_increment,
name varchar(30) not null unique,
address varchar(30),
phone varchar(30)
);
爲 name 字段添加惟一約束:
alter table customers add constraint name_uk unique(name);
二、底層實現
①、加入c3p0 數據源:導入兩個 jar 包(c3p0 和 數據庫驅動),在 src 下新建配置文件:c3p0-config.xml ,修改一下要有鏈接數據庫的基本信息(driverClass、jdbcUrl、user、password)。
c3p0-config.xml 代碼:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <c3p0-config> 3 4 <named-config name="mvcapp"> 5 6 <!--指定鏈接數據源的基本信息 --> 7 <property name="driverClass">com.mysql.jdbc.Driver</property> 8 <property name="jdbcUrl">jdbc:mysql:///javawebdb</property> 9 <property name="user">root</property> 10 <property name="password">root</property> 11 12 <!-- 若數據庫中鏈接不足時,一次性向數據庫服務器申請多少個鏈接--> 13 <property name="acquireIncrement">5</property> 14 <!-- 初始化數據庫鏈接池時鏈接的數量--> 15 <property name="initialPoolSize">10</property> 16 <!-- 數據庫鏈接池中的最小的數據庫鏈接數--> 17 <property name="minPoolSize">10</property> 18 <!-- 數據庫鏈接池中的最大的數據庫鏈接數--> 19 <property name="maxPoolSize">50</property> 20 21 <!-- c3p0 數據庫鏈接池能夠維護的 Statement 的個數--> 22 <property name="maxStatements">20</property> 23 <!-- 每一個鏈接同時能夠使用的Statement 對象的個數--> 24 <property name="maxStatementsPerConnection">5</property> 25 26 27 </named-config> 28 </c3p0-config>
②、編寫DAO 工具類、JdbcUtils 工具類和 CustomerDao 接口(如下有具體說明和代碼)
DAO 工具類:封裝了基本的增刪改查的方法,以供子類繼承使用。當前DAO 沒有事務,直接在方法中獲取數據庫鏈接。導入了DBUtils 的 jar 包,整個 DAO 採起 DBUtils 的解決方案。
實現方法:
update(封裝了insert、delete、update)操做:public void update(String sql, Object...args){ }
查詢 返回 T 對應的實體類的對象:public T get(String sql, Object...args){ }
查詢 返回 T 對應的List :public List<T> getForList(String sql, Object...args){ }
查詢 返回一個字段的值: public <E> E getForValue(String sql, Object...args){ }
DAO.java 代碼:
1 package com.hnust.mvcapp.dao; 2 3 import java.lang.reflect.ParameterizedType; 4 import java.lang.reflect.Type; 5 import java.sql.Connection; 6 import java.sql.SQLException; 7 import java.util.List; 8 9 import org.apache.commons.dbutils.QueryRunner; 10 import org.apache.commons.dbutils.handlers.BeanHandler; 11 import org.apache.commons.dbutils.handlers.BeanListHandler; 12 import org.apache.commons.dbutils.handlers.ScalarHandler; 13 14 import com.hnust.mvcapp.utils.JdbcUtils; 15 16 /** 17 * 封裝了基本的增刪改查的方法,以供子類繼承使用。 18 * 當前DAO 直接在方法中獲取數據庫鏈接。 19 * 整個DAO 採起DBUtils 解決方案。 20 * @author User 21 * 22 * @param <T> 當前 DAO 處理的實體類的類型是什麼 23 */ 24 public class Dao<T> { 25 26 private QueryRunner queryRunner = new QueryRunner(); 27 28 private Class<T> clazz; 29 30 /** 31 * 須要肯定 clazz 32 */ 33 public Dao(){ 34 //由獲得子類的 Class獲得父類 帶泛型的那個類型。 35 Type superClass = getClass().getGenericSuperclass(); 36 //先判斷是否是那個類型 37 if(superClass instanceof ParameterizedType){ 38 //是的話,強轉一下 39 ParameterizedType parameterizedType = (ParameterizedType) superClass; 40 //獲取真正的泛型的參數 41 Type[] typeArgs = parameterizedType.getActualTypeArguments(); 42 if(typeArgs != null && typeArgs.length >0){ 43 if(typeArgs[0] instanceof Class){ 44 clazz = (Class<T>) typeArgs[0]; 45 } 46 } 47 } 48 } 49 50 51 /** 52 * 查詢,返回某一個字段的值 53 */ 54 public <E> E getForValue(String sql, Object...args){ 55 Connection connection = null; 56 try { 57 connection = JdbcUtils.getConnection(); 58 return (E) queryRunner.query(connection, sql, new ScalarHandler(), args); 59 } catch (SQLException e) { 60 e.printStackTrace(); 61 }finally{ 62 JdbcUtils.releaseConnection(connection); 63 } 64 return null; 65 } 66 67 /** 68 * 查詢,返回T 所對應的 List 69 */ 70 public List<T> getForList(String sql, Object...args){ 71 Connection connection = null; 72 try { 73 connection = JdbcUtils.getConnection(); 74 return queryRunner.query(connection, sql, new BeanListHandler<>(clazz), args); 75 } catch (SQLException e) { 76 e.printStackTrace(); 77 }finally{ 78 JdbcUtils.releaseConnection(connection); 79 } 80 return null; 81 } 82 83 /** 84 * 查詢,返回一個T 的實體類對象 85 */ 86 public T get(String sql, Object...args){ 87 Connection connection = null; 88 89 try { 90 connection = JdbcUtils.getConnection(); 91 return queryRunner.query(connection, sql, new BeanHandler<>(clazz), args); 92 } catch (SQLException e) { 93 e.printStackTrace(); 94 }finally{ 95 JdbcUtils.releaseConnection(connection); 96 } 97 return null; 98 } 99 100 /** 101 * 通用的 insert 、delete、update 方法 102 */ 103 public void update(String sql, Object...args){ 104 Connection connection = null; 105 try { 106 connection = JdbcUtils.getConnection(); 107 queryRunner.update(connection, sql, args); 108 } catch (Exception e) { 109 e.printStackTrace(); 110 }finally{ 111 JdbcUtils.releaseConnection(connection); 112 } 113 } 114 }
JdbcUtils 工具類:JDBC 操做的工具類。
實現方法:
返回數據源的一個 Connection 對象:public static Connection getConnection(){ }
釋放 Connection 的鏈接:public static void releaseConnection(Connection connection){ }
注意:數據源的初始化必定要放在靜態代碼塊中,數據源被建立一次就夠了。寫完一個能夠用單元測試檢驗如下。
JdbcUtils.java 代碼:
1 package com.hnust.mvcapp.utils; 2 3 import java.sql.Connection; 4 import java.sql.SQLException; 5 6 import javax.sql.DataSource; 7 8 import com.mchange.v2.c3p0.ComboPooledDataSource; 9 10 /** 11 * JDBC 操做的工具類 12 * @author User 13 * 14 */ 15 public class JdbcUtils { 16 17 /** 18 * 釋放鏈接 19 */ 20 public static void releaseConnection(Connection connection){ 21 22 try { 23 if(connection != null){ 24 connection.close(); 25 } 26 } catch (Exception e) { 27 e.printStackTrace(); 28 } 29 } 30 31 private static DataSource dataSource = null; 32 static{ 33 dataSource = new ComboPooledDataSource("mvcapp"); //傳入的是 configName 34 } 35 /** 36 * 獲取鏈接 37 * @throws SQLException 38 */ 39 public static Connection getConnection() throws SQLException{ 40 41 return dataSource.getConnection(); 42 } 43 }
CustomerDao 接口:
實現的方法:
模糊查詢 返回知足條件的List :public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc);
查詢 返回List:public List<Customer> getAll();
添加:poublic void save(Customer customer);
修改時要根據id 的查詢顯示:public Customer get(Inreger id);
刪除(根據 id):public void delete(Integer id);
查詢 和這個名字同樣的 記錄數(根據 name):public long getCountWithName(String name);
CustomerDao.java 代碼:
1 package com.hnust.mvcapp.dao; 2 3 import java.util.List; 4 5 import com.hnuct.mvcapp.entity.Customer; 6 7 public interface CustomerDao { 8 9 /** 10 * 模糊查詢 返回知足條件的List 11 * @param cc :封裝了查詢條件 12 * @return 13 */ 14 public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc); 15 16 /** 17 * 查詢 返回 List 18 */ 19 public List<Customer> getAll(); 20 21 /** 22 * 增長 23 */ 24 public void save(Customer customer); 25 26 /** 27 * 修改 更新時候的查詢(根據id)顯示 28 */ 29 public Customer get(Integer id); 30 31 /** 32 * 刪除 33 */ 34 public void delete(Integer id); 35 36 /** 37 * 返回和name 相同的記錄數 38 */ 39 public long getCountWithName(String name); 40 }
實體類 Customer:
Customer.java 代碼:
1 package com.hnuct.mvcapp.entity; 2 3 public class Customer { 4 5 private Integer id; 6 private String name; 7 private String address; 8 private String phone; 9 public Integer getId() { 10 return id; 11 } 12 public void setId(Integer id) { 13 this.id = id; 14 } 15 public String getName() { 16 return name; 17 } 18 public void setName(String name) { 19 this.name = name; 20 } 21 public String getAddress() { 22 return address; 23 } 24 public void setAddress(String address) { 25 this.address = address; 26 } 27 public String getPhone() { 28 return phone; 29 } 30 public void setPhone(String phone) { 31 this.phone = phone; 32 } 33 public Customer(Integer id, String name, String address, String phone) { 34 super(); 35 this.id = id; 36 this.name = name; 37 this.address = address; 38 this.phone = phone; 39 } 40 public Customer() { 41 super(); 42 } 43 44 @Override 45 public String toString() { 46 return "Customers [id=" + id + ", name=" + name + ", address=" 47 + address + ", phone=" + phone + "]"; 48 } 49 50 51 }
Dao 接口的實現:
CustomerDaoJdbcImpl.java 代碼:
1 package com.hnuct.mvcapp.dao.impl; 2 3 import java.util.List; 4 5 import com.hnuct.mvcapp.entity.Customer; 6 import com.hnust.mvcapp.dao.CriteriaCustomer; 7 import com.hnust.mvcapp.dao.CustomerDao; 8 import com.hnust.mvcapp.dao.Dao; 9 10 public class CustomerDaoJdbcImpl extends Dao<Customer> implements CustomerDao{ 11 12 @Override 13 public List<Customer> getAll() { 14 String sql = "select * from customer"; 15 return getForList(sql); 16 } 17 18 @Override 19 public void save(Customer customer) { 20 String sql = "insert into customer(name,address,phone) values (?,?,?)"; 21 update(sql, customer.getName(), customer.getAddress(), customer.getPhone()); 22 } 23 24 @Override 25 public Customer get(Integer id) { 26 String sql = "select * from customer where id = ?"; 27 return get(sql, id); 28 } 29 30 @Override 31 public void delete(Integer id) { 32 String sql = "delete from customer where id = ? "; 33 update(sql, id); 34 } 35 36 @Override 37 public long getCountWithName(String name) { 38 String sql = "select count(id) from customer where name = ?"; 39 return getForValue(sql, name); 40 } 41 42 @Override 43 public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc) { 44 String sql = "SELECT id,name,address,phone FROM customer WHERE name LIKE ? AND " 45 + "address LIKE ? AND phone LIKE ?"; 46 //注意:修改了 CriteriaCustomer 的 getter 方法,使其返回的字符串中有 "%%", 47 //若返回值爲 null 則返回 "%%" ,若不爲 null, 則返回 "% " + 字段自己的值 + " %" 48 return getForList(sql, cc.getName(), cc.getAddress(), cc.getPhone()); 49 } 50 51 }
ps:注意由於查詢條件不少時候 和 實體類 並不相同,因此要作成一個單獨的類,這裏是 CriteriaCustomer 類,其中裏面的getter 方法作了修改,是爲了正確的填充佔位符。
CriteriaCustomer.java 代碼:
1 package com.hnust.mvcapp.dao; 2 3 public class CriteriaCustomer { 4 5 private String name; 6 private String address; 7 private String phone; 8 public String getName() { 9 if(name == null) 10 name = "%%"; 11 else 12 name = "%" + name + "%"; 13 return name; 14 } 15 public void setName(String name) { 16 this.name = name; 17 } 18 public String getAddress() { 19 if(address == null) 20 address = "%%"; 21 else 22 address = "%" + address + "%"; 23 return address; 24 } 25 public void setAddress(String address) { 26 this.address = address; 27 } 28 public String getPhone() { 29 if(phone == null) 30 phone = "%%"; 31 else 32 phone = "%" + phone + "%"; 33 return phone; 34 } 35 public void setPhone(String phone) { 36 this.phone = phone; 37 } 38 39 40 41 public CriteriaCustomer() { 42 super(); 43 } 44 public CriteriaCustomer(String name, String address, String phone) { 45 super(); 46 this.name = name; 47 this.address = address; 48 this.phone = phone; 49 } 50 51 52 }
三、Servlet 的實現:獲取請求信息的參數,根據請求信息調用 DAO 的對應的方法。
先寫了一個 test.jsp 頁面 放了三個超連接。
test.jsp 代碼:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 <%-- 11 <a href="customerServlet?method=add">add</a> 12 <br><br> 13 <a href="customerServlet?method=query">query</a> 14 <br><br> 15 <a href="customerServlet?method=delete">delete</a> 16 --%> 17 18 <a href="addCustomer.do">add</a> 19 <br><br> 20 <a href="query.do">query</a> 21 <br><br> 22 <a href="delete.do">delete</a> 23 <br><br> 24 25 26 27 </body> 28 </html>
注意你的 web.xml 裏的 url-pattern:<url-pattern>*.do</url-pattern>
而後 建立了CustomerServlet :去響應服務器的請求,調用對應的model,返回結果(我這裏暫時實現了 模糊查詢和 刪除的功能)。
CustomerServlet.java 代碼:
1 package com.hnust.mvcapp.servlet; 2 3 import java.io.IOException; 4 import java.lang.reflect.InvocationTargetException; 5 import java.lang.reflect.Method; 6 import java.util.List; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 import com.hnuct.mvcapp.dao.impl.CustomerDaoJdbcImpl; 14 import com.hnuct.mvcapp.entity.Customer; 15 import com.hnust.mvcapp.dao.CriteriaCustomer; 16 import com.hnust.mvcapp.dao.CustomerDao; 17 18 19 public class CustomerServlet extends HttpServlet { 20 private static final long serialVersionUID = 1L; 21 22 private CustomerDao customerDao = new CustomerDaoJdbcImpl(); 23 24 protected void doGet(HttpServletRequest request, HttpServletResponse response) 25 throws ServletException, IOException { 26 27 this.doPost(request, response); 28 } 29 30 @Override 31 protected void doPost(HttpServletRequest req, HttpServletResponse resp) 32 throws ServletException, IOException { 33 34 //一、獲取servletPath 35 String servletPath = req.getServletPath(); 36 //System.out.println(servletPath); //獲得的是 /addCustomer.do 37 38 //二、去除 / 和 .do ,獲得 addCustomer 這樣的字符串 39 String methodName = servletPath.substring(1); 40 methodName = methodName.substring(0, methodName.length() - 3); 41 //System.out.println(methodName); // 獲得的是 addCustomer 42 43 try { 44 //三、利用反射,根據獲取的 方法名,獲取對應的方法。 45 Method method = getClass().getDeclaredMethod(methodName, HttpServletRequest.class, 46 HttpServletResponse.class); 47 //四、利用反射調用對應的方法 48 method.invoke(this, req, resp); 49 50 } catch (Exception e) { 51 e.printStackTrace(); 52 //能夠有一些響應 53 resp.sendRedirect("error.jsp"); 54 } 55 56 } 57 58 private void delete(HttpServletRequest request, HttpServletResponse response) 59 throws ServletException, IOException { 60 //一、獲取 id 61 String idStr = request.getParameter("id"); 62 int id = 0; 63 //爲了不輸入的 id 是不 合法的。 idStr 不能轉爲 int 類型。若不能轉,則 id 爲0,沒法執行任何的操做。 64 try { 65 id = Integer.parseInt(idStr); 66 //二、調用 CustomerDAO 的 delete 方法 67 customerDao.delete(id); 68 //三、頁面的重定向 69 response.sendRedirect("query.do"); 70 } catch (Exception e) { 71 e.printStackTrace(); 72 } 73 } 74 75 private void query(HttpServletRequest request, HttpServletResponse response) 76 throws ServletException, IOException { 77 //一、獲取模糊查詢的請求參數 78 String name = request.getParameter("name"); 79 String address = request.getParameter("address"); 80 String phone = request.getParameter("phone"); 81 82 //二、把請求參數封裝爲 CriteriaCustomer 對象 83 CriteriaCustomer cc = new CriteriaCustomer(name, address, phone); 84 85 //三、再調用CustomerDao 的 getForListWithCriteriaCustomer() 方法 86 List<Customer> customers = customerDao.getForListWithCriteriaCustomer(cc); 87 88 //調用CustomerDao 的 getAll() 方法 查詢。 89 //List<Customer> customers = customerDao.getAll(); 90 91 //四、把查詢到的結果集放入 request 中 92 request.setAttribute("customers", customers); 93 //五、請求的轉發 94 request.getRequestDispatcher("/index.jsp").forward(request, response); 95 96 } 97 98 private void addCustomer(HttpServletRequest request, HttpServletResponse response) 99 throws ServletException, IOException { 100 101 System.out.println("add"); 102 } 103 104 }
四、返回結果 的 JSP 頁面:獲取返回結果,遍歷顯示。
index.jsp 代碼:
1 <%@page import="com.hnuct.mvcapp.entity.Customer"%> 2 <%@page import="java.util.List"%> 3 <%@ page language="java" contentType="text/html; charset=UTF-8" 4 pageEncoding="UTF-8"%> 5 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 6 <html> 7 <head> 8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 9 <title>Insert title here</title> 10 <script type="text/javascript" src="Scripts/jquery-1.7.2.js"></script> 11 <script type="text/javascript"> 12 $(function(){ 13 $(".delete").click(function(){ 14 var content = $(this).parent().parent().find("td:eq(1)").text(); 15 var flag = confirm("肯定要刪除 " + content + " 的信息嗎?"); 16 return flag; 17 }); 18 }) 19 </script> 20 </head> 21 <body> 22 <form action="query.do" method="post"> 23 <table> 24 <tr> 25 <td>name:</td> 26 <td><input type="text" name="name"/></td> 27 </tr> 28 <tr> 29 <td>address:</td> 30 <td><input type="text" name="address"/></td> 31 </tr> 32 <tr> 33 <td>phone:</td> 34 <td><input type="text" name="phone"/></td> 35 36 <tr> 37 <td><input type="submit" value="Query"/></td> 38 <td><a href="">Add new Customer</a></td> 39 </tr> 40 </table> 41 </form> 42 <br><br> 43 44 <% 45 List<Customer> customers = (List<Customer>) request.getAttribute("customers"); 46 if(customers != null && customers.size() > 0){ 47 %> 48 <hr> 49 <br><br> 50 <table border="1" cellpadding="10" cellspacing="0"> 51 <tr> 52 <th>ID</th> 53 <th>NAME</th> 54 <th>ADDRESS</th> 55 <th>PHONE</th> 56 <th>UPDATE/DELETE</th> 57 </tr> 58 <% for(Customer cust : customers){ 59 60 %> 61 <tr> 62 <td><%= cust.getId() %></td> 63 <td><%= cust.getName() %></td> 64 <td><%= cust.getAddress() %></td> 65 <td><%= cust.getPhone() %></td> 66 <td> 67 <a href="">Update</a> 68 <a href="delete.do?id=<%=cust.getId() %>" class="delete">Delete</a> 69 </td> 70 </tr> 71 <% 72 } 73 %> 74 </table> 75 <% 76 } 77 %> 78 </body> 79 </html>
最後結果:
點擊query
能夠實現模糊查詢,和刪除的功能。
這是今天的學習內容。