本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用
内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系。
本人互联网技术爱好者,互联网技术发烧友
微博:伊直都在0221
QQ:951226918
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1.面向接口编程的优势
1)增加了程序的课扩展性,降低耦合度。即,只需要知道方法就好了,具体的实现不关注。如果需要新的功能,添加在接口中添加方法的声明,还有具体的实现类,这就是可扩展性。
2)程序的可配置性。通过一个配置的修改,就可以达到不同的实现的目的。
2.面向接口编程的实例。结合上mvc综合实践
需求:通过MVC设计模式,实现对用户的增删改查操作。提供两种实现方式:jdbc,xml ; 通过工场模式 和 MVC设计模式 实现对实现方式的切换。
代码:① CustomerDAOFactory: 单例的 CustomerDAO 工场类。采用饿汉式,线程安全。返回一个CustomerDAO 对象的工厂。
② InitServlet: 一个Servlet 类,实现了init() 方法,读取 实现方式 配置文件 switch.properties , 获取 设置的 type。
③ CustomerServlet2: 前台请求的Servlet, 其中有一个CutomerDAO 的私有属性。可以由CustomerDAOFactory 创建。
④ CustomerDAOXMLImpl: CustomerDAO 接口的XML 形式的实现类。
⑤ CustomerDAOJdbcImpl: CustomerDAO 接口的JDBC实现类。
⑥ switch.properties: 实现方式 type 的配置文件。
⑦ customer.xml: customer 的xml 存储文件
⑧ web.xml: web的配置文件。此处只需配置 InitServlet的加载时间。而Servlet 的url-parttern 则由系统通过注解的方式实现配置
⑨ CustomerDAO : 操作 customer的 DAO接口
接口的关系图:
3.具体代码的实现:
1)CustomerDAOFactory.java
1 package com.jason.mvcapp.dao.factory; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 import com.jason.mvcapp.dao.CustomerDAO; 7 import com.jason.mvcapp.dao.impl.CustomerDAOJdbcImpl; 8 import com.jason.mvcapp.dao.impl.CustomerDAOXMLImpl; 9 10 /*** 11 * 12 * @author: jason 13 * @time:2016年5月28日下午5:37:39 14 * @description:单例的 CustomerDAO 工场类。采用饿汉式,线程安全 15 */ 16 public class CustomerDAOFactory { 17 18 private Map<String , CustomerDAO> daos = new HashMap<String, CustomerDAO>(); 19 20 //1.私有化构造器 21 private CustomerDAOFactory(){ 22 23 daos.put("jdbc", new CustomerDAOJdbcImpl()); 24 daos.put("xml", new CustomerDAOXMLImpl()); 25 26 } 27 //2.创建一个静态的实例 28 private static CustomerDAOFactory instance = new CustomerDAOFactory(); 29 //3.提供获取实例的方法 30 public static CustomerDAOFactory getInstance() { 31 return instance; 32 } 33 34 private static String type = null; 35 36 public void setType(String type) { 37 this.type = type; 38 } 39 40 public static String getType() { 41 return type; 42 } 43 public CustomerDAO getCustomerDAO(){ 44 45 return daos.get(type); 46 } 47 48 }
2)InitServlet.java
1 package com.jason.mvcapp.servlet; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.util.Properties; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.annotation.WebServlet; 9 import javax.servlet.http.HttpServlet; 10 11 import com.jason.mvcapp.dao.factory.CustomerDAOFactory; 12 13 /** 14 * Servlet implementation class InitServlet 15 */ 16 @WebServlet("/InitServlet") 17 public class InitServlet extends HttpServlet { 18 19 private static final long serialVersionUID = 1L; 20 21 @Override 22 public void init() throws ServletException { 23 CustomerDAOFactory.getInstance().setType("jdbc"); 24 25 //1.读取类路径下的switch.properties 配置文件 26 InputStream is = getServletContext().getResourceAsStream("/WEB-INF/classes/switch.properties"); 27 28 Properties properties = new Properties(); 29 try { 30 properties.load(is); 31 32 //2.获取switch.properties 的type 值 33 String type = properties.getProperty("type"); 34 35 //3.赋值给CustomerDAOFactory 的type 属性 36 CustomerDAOFactory.getInstance().setType(type); 37 38 } catch (IOException e) { 39 e.printStackTrace(); 40 } 41 } 42 43 }
3)CustomerServlet2.java
1 package com.jason.mvcapp.servlet; 2 3 import java.io.IOException; 4 import java.lang.reflect.Method; 5 import java.util.List; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.annotation.WebServlet; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 import com.jason.mvcapp.dao.CustomerDAO; 14 import com.jason.mvcapp.dao.factory.CustomerDAOFactory; 15 import com.jason.mvcapp.dao.impl.CustomerDAOJdbcImpl; 16 import com.jsaon.mvcapp.domain.CriteriaCustomer; 17 import com.jsaon.mvcapp.domain.Customer; 18 19 /** 20 * Servlet implementation class CustomerServlet2 21 */ 22 @WebServlet("*.do") 23 public class CustomerServlet2 extends HttpServlet { 24 private static final long serialVersionUID = 1L; 25 26 // 创建一个CustomerDAO对象,多态 27 private CustomerDAO customerDAO = CustomerDAOFactory.getInstance().getCustomerDAO(); 28 29 protected void doGet(HttpServletRequest request, 30 HttpServletResponse response) throws ServletException, IOException { 31 doPost(request, response); 32 } 33 34 protected void doPost(HttpServletRequest request, 35 HttpServletResponse response) throws ServletException, IOException { 36 // 1.获取servletPath:/add.do 或者 query.do 37 String serveltPath = request.getServletPath(); 38 39 // System.out.println(serveltPath); 40 // 2.去除/ 和 .do 得到对应的方法,如 add query 41 String methodName = serveltPath.substring(1); 42 methodName = methodName.substring(0, methodName.length() - 3); 43 // System.out.println(methodName); 44 45 try { 46 // 3.利用反射获取methodName对应的方法 47 Method method = getClass().getDeclaredMethod(methodName, 48 HttpServletRequest.class, HttpServletResponse.class); 49 50 // 4.利用反射调用方法 51 method.invoke(this, request, response); 52 } catch (Exception e) { 53 54 e.printStackTrace(); 55 } 56 } 57 58 private void updateCustomer(HttpServletRequest request, HttpServletResponse response) 59 throws ServletException, IOException { 60 System.out.println("update"); 61 request.setCharacterEncoding("UTF-8"); 62 63 //1.获取请求信息:id,name,address,phone,oldName 64 65 //1.1 隐藏域的 值 66 String idStr = request.getParameter("id"); 67 String oldNameStr = request.getParameter("oldName"); 68 69 //1.2 提交的值 70 String nameStr = request.getParameter("name"); 71 String addressStr = request.getParameter("address"); 72 String phoneStr = request.getParameter("phone"); 73 74 //2.验证name 是否可用 75 //通过equalsIgnoreCase() 方式 避免了 大小写的问题。equals 方法区分大小写, 而数据库SQL 不区分大小写 76 if(!oldNameStr.equalsIgnoreCase(nameStr)){ 77 //2.1 先比较name 和 oldName 是否相同,若相同,说明name 可用 78 //2.2 若不相同,则调用CustomerDAO 的getCostomerWithName(String name) 获取 name 在数据库中是否存在 79 long rel = customerDAO.getCountWithName(nameStr); 80 //2.2.1 若存在,则返回值大于 0,则响应 updatecustomer.jsp 页面:通过转发的方式 81 if(rel > 0){ 82 // 进行回显字符串,在request 中放入一个属性 message:用户名 name 83 // 回显:updatecustomer.jsp 的表单值可以回显 84 // value="<%= request.getParameter("name") == null ? "" : request.getParameter("name") %>" 进行回显 85 // 注意:name 显示的是 oldName,而address 和 phone 显示的是新的 86 request.setAttribute("message", "用户名 " + nameStr + " 已经被占用了,请重新选择!"); 87 //2.2.2 存在,要求在updatecustomer.jsp 页面显示一条消息:用户名 name 已经被占用了,请重新选择 88 request.getRequestDispatcher("/updatecustomer.jsp").forward(request,response); 89 // 2.2.3 结束方法:return 90 return; 91 } 92 } 93 94 //3.通过验证后,则将表单封装为一个Customer 对象 customer 95 Customer customer = new Customer(nameStr, addressStr, phoneStr); 96 customer.setId(Integer.parseInt(idStr)); 97 98 //4.调用CustomerDAO 的save(Customer customer) 执行更新操作 99 customerDAO.update(customer); 100 101 //5.重定向到 query.do 102 response.sendRedirect("query.do"); 103 104 } 105 106 private void editeCustomer(HttpServletRequest request, 107 HttpServletResponse response) throws ServletException, IOException { 108 System.out.println("edit"); 109 String forwardPath = "/error.jsp"; 110 //1. 获取请求参数id 111 String idStr = request.getParameter("id"); 112 try { 113 //2. 调用CustomerDAO 的get(id) 方法,获取 和id 对应的Customer 对象 114 Customer customer = customerDAO.get(Integer.parseInt(idStr)); 115 if(customer != null){ 116 forwardPath ="/updatecustomer.jsp"; 117 //3. 将 customer 放入 request 中 118 request.setAttribute("customer", customer); 119 } 120 } catch (Exception e) {} 121 //4. 响应updatecustomer.jsp 页面: 转发的形式 122 request.getRequestDispatcher(forwardPath).forward(request, response); 123 124 } 125 126 private void deleteCustomer(HttpServletRequest request, 127 HttpServletResponse response) throws ServletException, IOException { 128 // 1.获取请求删除的 id 为 String 类型 129 String idStr = request.getParameter("id"); 130 // try{}catch{} 的作用:方式idStr 不能转化为 int 类型,若不能转则 id = 0,无法进行任何删除 131 int id = 0; 132 try { 133 // 2.将idStr 解析为int 型 134 id = Integer.parseInt(idStr); 135 // 3.调用dao方法 删除数据 136 customerDAO.delete(id); 137 } catch (Exception e) { 138 e.printStackTrace(); 139 } 140 response.sendRedirect("query.do"); 141 142 } 143 144 private void query(HttpServletRequest request, HttpServletResponse response) 145 throws ServletException, IOException { 146 request.setCharacterEncoding("UTF-8"); 147 String name = request.getParameter("name"); 148 String address = request.getParameter("address"); 149 String phone = request.getParameter("phone"); 150 151 CriteriaCustomer criteriaCustomer = new CriteriaCustomer(name, address, 152 phone); 153 List<Customer> lists = customerDAO 154 .getForListWithCriteriaCustomer(criteriaCustomer); 155 156 // //1.调用CustomerDAO 的getAll()方法的到Customer 集合 157 // List<Customer> lists = customerDAO.getAll(); 158 // 2.把Customer 集合放入request 159 request.setAttribute("list", lists); 160 // 3.转发页面到index.jsp 161 request.getRequestDispatcher("/index.jsp").forward(request, response); 162 163 } 164 165 private void addCustomer(HttpServletRequest request, 166 HttpServletResponse response) throws ServletException, IOException { 167 168 System.out.println("add function"); 169 request.setCharacterEncoding("UTF-8"); 170 // 1.获取表单参数:name,address,phone 171 String name = request.getParameter("name"); 172 String address = request.getParameter("address"); 173 String phone = request.getParameter("phone"); 174 175 // 2.检验 name 是否已经被占用 176 // 2.1调用 CustomerDAO 的 getCountWithName(String name) 获取 name 在数据库中是否存在 177 178 long rel = customerDAO.getCountWithName(name); 179 // 2.2 若返回值大于0,则响应newcustomer.jsp 页面: 180 if (rel > 0) { 181 // 2.2.1 要求在newcustomer.jsp 页面显示一条消息:用户名 name 已经被占用了,请重新选择 182 // 在request 中放入一个属性 message:用户名 name 183 // 已经被占用,请重新选择!在页面通过request.getAttribute("message") 的方式来显示 184 // 2.2.2 newcustomer.jsp 的表单值可以回显 185 // value="<%= request.getParameter("name") == null ? "" : request.getParameter("name") %>" 186 // 进行回显 187 request.setAttribute("message", "用户名 " + name + " 已经被占用了,请重新选择!"); 188 // 通过转发的方式来响应 newcustomer.jsp 189 request.getRequestDispatcher("/newcustomer.jsp").forward(request, 190 response); 191 // 2.2.3 结束方法:return 192 return; 193 } 194 // 3.把表单参数封装为一个Customer 对象 195 Customer customer = new Customer(name, address, phone); 196 197 // 4.调用 customerDAO 的 save(Customer customer) 方法执行保存 198 customerDAO.save(customer); 199 200 // 5.重定向到success.jsp 页面:使用重定向可以避免出现表单的重复提交 201 response.sendRedirect("success.jsp"); 202 } 203 }
4)CustomerDAOXMLImpl.java
1 package com.jason.mvcapp.dao.impl; 2 3 import java.util.List; 4 5 import com.jason.mvcapp.dao.CustomerDAO; 6 import com.jsaon.mvcapp.domain.CriteriaCustomer; 7 import com.jsaon.mvcapp.domain.Customer; 8 9 public class CustomerDAOXMLImpl implements CustomerDAO { 10 11 @Override 12 public List<Customer> getForListWithCriteriaCustomer( 13 CriteriaCustomer criteriaCustomer) { 14 System.out.println("CustomerDAOXMLImpl's getForListWithCriteriaCustomer"); 15 return null; 16 } 17 18 @Override 19 public List<Customer> getAll() { 20 System.out.println("CustomerDAOXMLImpl's getAll"); 21 return null; 22 } 23 24 @Override 25 public void save(Customer coustomer) { 26 System.out.println("CustomerDAOXMLImpl's save"); 27 } 28 29 @Override 30 public Customer get(Integer id) { 31 System.out.println("CustomerDAOXMLImpl's get"); 32 return null; 33 } 34 35 @Override 36 public void delete(Integer id) { 37 System.out.println("CustomerDAOXMLImpl's get"); 38 39 } 40 41 @Override 42 public long getCountWithName(String name) { 43 System.out.println("CustomerDAOXMLImpl's getCountWithName"); 44 return 0; 45 } 46 47 @Override 48 public void update(Customer customer) { 49 System.out.println("CustomerDAOXMLImpl's update"); 50 51 } 52 53 }
5)CustomerDAOJdbcImpl.java
1 package com.jason.mvcapp.dao.impl; 2 3 import java.util.List; 4 5 import com.jason.mvcapp.dao.CustomerDAO; 6 import com.jason.mvcapp.dao.DAO; 7 import com.jsaon.mvcapp.domain.CriteriaCustomer; 8 import com.jsaon.mvcapp.domain.Customer; 9 10 /** 11 * @author: jason 12 * @time:2016年5月25日下午3:45:06 13 * @description:对CustomerDAO 的实现 14 */ 15 public class CustomerDAOJdbcImpl extends DAO<Customer> implements CustomerDAO { 16 17 @Override 18 public List<Customer> getAll() { 19 String sql = "SELECT * FROM customers"; 20 return getForList(sql); 21 } 22 23 @Override 24 public void save(Customer customer) { 25 String sql = "INSERT INTO customers(name, address, phone) VALUES(?,?,? )"; 26 update(sql,customer.getName(),customer.getAddress(),customer.getPhone()); 27 } 28 29 30 @Override 31 public Customer get(Integer id) { 32 String sql = "SELECT id, name, address, phone FROM customers WHERE id = ?"; 33 return get(sql,id); 34 35 } 36 37 @Override 38 public void delete(Integer id) { 39 String sql = "DELETE FROM customers WHERE id = ?"; 40 update(sql, id); 41 } 42 43 @Override 44 public long getCountWithName(String name) { 45 String sql = "SELECT count(id) FROM customers WHERE name = ?"; 46 return getForValue(sql, name); 47 } 48 49 @Override 50 public List<Customer> getForListWithCriteriaCustomer( 51 CriteriaCustomer criteriaCustomer) { 52 //sql语句 53 String sql = "SELECT id,name,address,phone FROM customers WHERE name LIKE ? AND address LIKE ? AND phone LIKE ?"; 54 //调用DAO<T> 中的方法getForList(),并且为占位符设置 55 return getForList(sql, criteriaCustomer.getName(),criteriaCustomer.getAddress(),criteriaCustomer.getPhone()); 56 } 57 58 @Override 59 public void update(Customer customer) { 60 String sql = "UPDATE customers SET name = ?, address = ?, phone = ? WHERE id = ?"; 61 update(sql, customer.getName(), customer.getAddress(), customer.getPhone(), customer.getId()); 62 } 63 64 }
6)switch.properties
1 type=jdbc 2 #type=xml
7)customer.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <customers> 4 <customer id ="1001"> 5 <name>tom</name> 6 <address>beijing</address> 7 <phone>123156456</phone> 8 </customer> 9 10 </customers>
8)web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> 3 <display-name>mvc</display-name> 4 5 <servlet> 6 <servlet-name>InitServlet</servlet-name> 7 <servlet-class>com.jason.mvcapp.servlet.InitServlet</servlet-class> 8 <load-on-startup>1</load-on-startup> 9 </servlet> 10 11 12 13 </web-app>
⑨)CustomerDAO.java
1 package com.jason.mvcapp.dao; 2 3 import java.util.List; 4 5 import com.jsaon.mvcapp.domain.CriteriaCustomer; 6 import com.jsaon.mvcapp.domain.Customer; 7 8 9 /** 10 * @author: jason 11 * @time:2016年5月25日下午3:28:00 12 * @description: 13 */ 14 15 public interface CustomerDAO { 16 17 //带参数的模糊查询 18 public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer criteriaCustomer); 19 //查询所有 20 public List<Customer> getAll(); 21 22 //保存操作 23 public void save(Customer coustomer); 24 25 //更新前,先查询 26 public Customer get(Integer id); 27 28 //删除用户 29 public void delete(Integer id); 30 31 //查看与参数相同的名字有多少个记录数 32 public long getCountWithName(String name); 33 34 //更新操作 35 public void update(Customer customer); 36 37 }
3.总结:
1)从代码层次理解面向接口编程的优势
来源:https://www.cnblogs.com/jasonHome/p/5540664.html