java web基础之mvc模式设计(一)--使用httpservlet实现mvc分层设计,DAO层使用的是dbutils实现与数据库的链接
一:1.最终的实现效果图:
2.案例的目录结构:
3.案例中使用到的jar包:
二:案例的链接数据库的层次结构关系:数据库是:mysql ,数据库名字:dsm,表格名字:customers
数据库表格的样子是:
数据库实现中用到的各个类的层次关系:
上述java类中的源代码:
Dao.java:
package com.guodiantong.mvc.dao; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.sql.Connection; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import com.guodiantong.mvc.db.JdbcUtils; public class Dao<T> { private QueryRunner queryRunner=new QueryRunner(); private Class<T> clazz; public Dao(){ Type superClass=getClass().getGenericSuperclass(); if(superClass instanceof ParameterizedType){ ParameterizedType parameterizedType= (ParameterizedType) superClass; Type[] typeArgs=parameterizedType.getActualTypeArguments(); if(typeArgs!=null&&typeArgs.length>0){ if(typeArgs[0] instanceof Class){ clazz=(Class<T>) typeArgs[0]; } } } } /* * 这个方法是只获取,表格中的某一行属性中的某一个属性值,就是返回某一个字段的值,例如返回某一条记录的customerName,或者返回数据表中有多少条记录等。 */ public <E> E getForValue(String sql,Object ... args){ Connection connection=null; try {connection=JdbcUtils.getConnection(); return (E) queryRunner.query(connection, sql, new ScalarHandler(), args); } catch (Exception e) { e.printStackTrace(); }finally{ JdbcUtils.releaseConnection(connection); } return null; } /* * 该方法是返回一组数据对象实体类,返回T所对应的List,其实质就是查询 */ public List<T> getForList(String sql,Object ... agrs ){ Connection connection=null; try {connection=JdbcUtils.getConnection(); return queryRunner.query(connection, sql, new BeanListHandler<T>(clazz), agrs); } catch (Exception e) { e.printStackTrace(); }finally{ JdbcUtils.releaseConnection(connection); } return null; } /* * 执行查询的语句,结果是返回数据表中的一个对象(一条记录)其实质就是查询! */ public T get(String sql,Object ... agrs){ Connection connection=null; try {connection=JdbcUtils.getConnection(); return queryRunner.query(connection, sql, new BeanHandler<T>(clazz), agrs); } catch (Exception e) { e.printStackTrace(); }finally{ JdbcUtils.releaseConnection(connection); } return null; } /* * 该方法封装了INSERT、UPDATE、DELETE操作 * sql是sql语句 * args是占位符 */ public void update(String sql,Object ... args){ Connection connection=null; try {connection=JdbcUtils.getConnection(); queryRunner.update(connection, sql, args); } catch (Exception e) { e.printStackTrace(); }finally{ JdbcUtils.releaseConnection(connection); } } }
JdbcUtils.java
package com.guodiantong.mvc.db;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class JdbcUtils {
/*
*释放数据库的连接
*
*/
public static void releaseConnection(Connection connection){
try {
if(connection !=null){
connection.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static DataSource dataSource=null;
static {
/*
* 数据源只能被创建一次
*/
dataSource=new ComboPooledDataSource("mvcapp");
}
public static Connection getConnection() throws SQLException{
//dataSource=new ComboPooledDataSource("mvcapp");若要是放在这里就说明,获得一次就创建一下,比较耗费内存
return dataSource.getConnection();
}
}
说明一下这里的 “mvcapp”参数,这个参数是在c3p0-config.xml文件中的一项配置(<named-config name="mvcapp">)
Customer.java:
package com.guodiantong.mvc.domain; public class Customer { private Integer id; private String name; private String address; private String phone; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public Customer(Integer id, String name, String address, String phone) { super(); this.id = id; this.name = name; this.address = address; this.phone = phone; } public Customer() { super(); } @Override public String toString() { return "Customer [id=" + id + ", name=" + name + ", address=" + address + ", phone=" + phone + "]"; } }
CustomerDao.java:
package com.guodiantong.mvc.dao; import java.util.List; import com.guodiantong.mvc.domain.CriteriaCustomer; import com.guodiantong.mvc.domain.Customer; public interface CustomerDao { public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc); public List<Customer> getAll(); public void save(Customer customer); public Customer get(Integer id); public void delete(Integer id); /* * 根据查询的名字,返回使用该名字的数据条数 */ public long getCountWithName(String name); public void update(Customer customer); }
CustomerDaoJdbcImpl.java:
package com.guodiantong.mvc.impl; import java.util.List; import com.guodiantong.mvc.dao.CustomerDao; import com.guodiantong.mvc.dao.Dao; import com.guodiantong.mvc.domain.CriteriaCustomer; import com.guodiantong.mvc.domain.Customer; public class CustomerDaoJdbcImpl extends Dao<Customer>implements CustomerDao { public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc){ String sql="SELECT id ,name,address,phone FROM customers WHERE "+ "name LIKE ? AND address LIKE ? AND phone LIKE ?"; return getForList(sql, cc.getName(),cc.getAddress(),cc.getPhone()); } @Override public List<Customer> getAll() { String sql="SELECT id,name,address,phone FROM customers"; return getForList(sql); } @Override public void save(Customer customer) { String sql="INSERT INTO customers(name,address,phone) VALUES(?,?,?)"; update(sql, customer.getName(),customer.getAddress(),customer.getPhone());; } @Override public Customer get(Integer id) { String sql="SELECT id,name,address,phone FROM customers WHERE id=?"; return get(sql, id); } @Override public void delete(Integer id) { String sql="DELETE FROM customers WHERE id=?"; update(sql, id); } @Override public long getCountWithName(String name) { String sql="SELECT count(id) FROM customers WHERE name=?"; return getForValue(sql, name); } @Override public void update(Customer customer) { String sql="UPDATE customers SET name=?, address=?, phone=? WHERE id=?"; update(sql, customer.getName(),customer.getAddress(),customer.getPhone(),customer.getId()); } }
说明:Dao.java 和JdbcUtils.java具有可移植性,在哪个工程项目中都能用,CustomerDao.java和CustomerDaoImpl.java 是根据具体的项目抽象出可能用到的方法,然后让底层Dao.java最基础的增删改查等功能来拼凑出项目中页面中抽象的方法
三:项目中jsp文件的编写(jsp实质上就是一个servlet)
案例中用到最多的无非是HttpServletRequest request,HttpServletResponse response这两个参数结合页面中的表单form以及转发方式等在页面和后台servlet之间传递数据
开始页面的jsp:index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.util.List" %> <%@ page import="com.guodiantong.mvc.domain.Customer" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript" src="script/jquery-1.7.2.js"></script> <script type="text/javascript"> $(function(){ $(".delete").click(function(){ var content=$(this).parent().parent().find("td:eq(1)").text(); var flag =confirm("确定要删除" + content + "的信息吗?"); return flag; }); }); </script> </head> <body> <form action="query.do" method="post"> <table> <tr> <td>CustomerName:</td> <td><input type="text" name=name></td> </tr> <tr> <td>Address:</td> <td><input type="text" name="address"></td> </tr> <tr> <td>Phone:</td> <td><input type="text" name="phone"></td> </tr> <tr> <td><input type="submit" value="Query"></td> <td><a href="addCustomer.jsp">Add Customer123</a></td> </tr> </table> </form> <hr> <br> <% List<Customer> customer=(List<Customer>)request.getAttribute("customers"); if(customer!=null && customer.size()>0){ %> <table border="1" cellspacing="0" cellpadding="10"> <tr> <th>id</th> <th>name</th> <th>address</th> <th>phone</th> <th>delete</th> <th>edit</th> </tr> <% for(Customer cust:customer) { %> <tr> <td><%=cust.getId() %></td> <td><%=cust.getName() %></td> <td><%=cust.getAddress() %></td> <td><%=cust.getPhone() %></td> <td><a class="delete" href="delete.do?id=<%=cust.getId()%>">delete</a></td> <td><a class="edit" href="edit.do?id=<%=cust.getId() %>">edit</a></td> </tr> <% } %> <% } %> </table> </body> </html>
新增页面的jsp:addCustomer.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% Object msg=request.getAttribute("message"); if(msg!=null){ %> <%=request.getAttribute("message")%> <% } %> <form action="addCustomer.do" method="post"> <table> <tr> <td>customerName:<input type="text" name="name" value="<%=request.getAttribute("name")==null? "":request.getAttribute("name") %>"></td> </tr> <tr> <td>address:<input type="text" name="address" value="<%=request.getAttribute("address")==null? "":request.getAttribute("address") %>"></td> </tr> <tr> <td>phone:<input type="text" name="phone" value="<%=request.getAttribute("phone")==null? "":request.getAttribute("phone") %>"></td> </tr> <tr> <td><input type="submit" value="submit"></td> </tr> </table> </form> </body> </html>
编辑页面的jsp:edit.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="com.guodiantong.mvc.domain.Customer" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <% Object msg = request.getAttribute("message"); if(msg != null){ %> <br> <font color="red"><%= msg %></font> <br> <br> <% } String id = null; String oldName = null; String name = null; String address = null; String phone = null; Customer customer = (Customer)request.getAttribute("customer"); if(customer != null){ id = customer.getId() + ""; oldName = customer.getName(); name = customer.getName(); address = customer.getAddress(); phone = customer.getPhone(); }else{ id = request.getParameter("id"); oldName = request.getParameter("oldName"); name = request.getParameter("oldName"); address = request.getParameter("address"); phone = request.getParameter("phone"); } %> <form action="update.do" method="post"> <input type="hidden" name="id" value="<%= id %>"/> <input type="hidden" name="oldName" value="<%= oldName %>"/> <table> <tr> <td>CustomerName:</td> <td><input type="text" name="name" value="<%= name %>"/></td> </tr> <tr> <td>Address:</td> <td><input type="text" name="address" value="<%= address %>"/></td> </tr> <tr> <td>Phone:</td> <td><input type="text" name="phone" value="<%= phone %>"/></td> </tr> <tr> <td colspan="2"><input type="submit" value="Submit"/></td> </tr> </table> </form> </body> </html>
四.后台中的控制类Servlet CustomerServlet.java
package com.guodiantong.mvc.servlet; import java.io.IOException; import java.lang.reflect.Method; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.guodiantong.mvc.dao.CustomerDao; import com.guodiantong.mvc.domain.CriteriaCustomer; import com.guodiantong.mvc.domain.Customer; import com.guodiantong.mvc.impl.CustomerDaoJdbcImpl; public class CustomerServlet extends HttpServlet { CustomerDao customerDao=new CustomerDaoJdbcImpl(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String servletPath=req.getServletPath(); System.out.println(servletPath); String methodName=servletPath.substring(1); methodName=methodName.substring(0, methodName.length()-3); /* * 利用反射获取methodName对应的方法 */ try { Method method=getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class); //利用反射调用对应的方法 method.invoke(this, req,resp); } catch (Exception e) { e.printStackTrace(); resp.sendRedirect("error.jsp"); } } private void query(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{ String name=request.getParameter("name"); String address=request.getParameter("address"); String phone=request.getParameter("phone"); CriteriaCustomer criteriaCustomer=new CriteriaCustomer(name, address, phone); List<Customer> customers=customerDao.getForListWithCriteriaCustomer(criteriaCustomer); System.out.println(customers); request.setAttribute("customers", customers); request.getRequestDispatcher("/index.jsp").forward(request, response); } private void delete(HttpServletRequest request,HttpServletResponse response) throws IOException{ String idstr=request.getParameter("id"); int id=0; try { id=Integer.parseInt(idstr); System.out.println(id); customerDao.delete(id); } catch (Exception e) { } response.sendRedirect("query.do"); } private void addCustomer(HttpServletRequest resquest,HttpServletResponse response) throws IOException, ServletException{ String name=resquest.getParameter("name"); String address=resquest.getParameter("address"); String phone=resquest.getParameter("phone"); //String message="用户" + name + "已经注册过了"; long count=customerDao.getCountWithName(name); if(count>0){ //resquest.setAttribute("count", count); resquest.setAttribute("message","用户" + name + "已经注册过了"); resquest.setAttribute("address", address); resquest.setAttribute("phone", phone); resquest.getRequestDispatcher("/addCustomer.jsp").forward(resquest, response); } else{ Customer customer=new Customer(null, name, address, phone); customerDao.save(customer); response.sendRedirect("query.do");} } private void edit(HttpServletRequest request,HttpServletResponse response){ String idstr=request.getParameter("id"); int id=0; try { id=Integer.parseInt(idstr); Customer cus=customerDao.get(id); // String name=cus.getName(); // String address=cus.getAddress(); // String phone=cus.getPhone(); // request.setAttribute("name", name); // request.setAttribute("address", address); request.setAttribute("customer", cus); request.getRequestDispatcher("/edit.jsp").forward(request, response); } catch (Exception e) { // TODO: handle exception } } private void update(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{ //1. 获取表单参数: id, name, address, phone, oldName String id = request.getParameter("id"); String name = request.getParameter("name"); String phone = request.getParameter("phone"); String address = request.getParameter("address"); String oldName = request.getParameter("oldName"); //2. 检验 name 是否已经被占用: //2.1 比较 name 和 oldName 是否相同, 若相同说明 name 可用. //2.1 若不相同, 则调用 CustomerDAO 的 getCountWithName(String name) 获取 name 在数据库中是否存在 if(!oldName.equalsIgnoreCase(name)){ long count = customerDao.getCountWithName(name); //2.2 若返回值大于 0, 则响应 updatecustomer.jsp 页面: 通过转发的方式来响应 newcustomer.jsp if(count > 0){ //2.2.1 在 updatecustomer.jsp 页面显示一个错误消息: 用户名 name 已经被占用, 请重新选择! //在 request 中放入一个属性 message: 用户名 name 已经被占用, 请重新选择!, //在页面上通过 request.getAttribute("message") 的方式来显示 request.setAttribute("message", "用户名" + name + "已经被占用, 请重新选择!"); //2.2.2 newcustomer.jsp 的表单值可以回显. //address, phone 显示提交表单的新的值, 而 name 显示 oldName, 而不是新提交的 name //2.2.3 结束方法: return request.getRequestDispatcher("/updatecustomer.jsp").forward(request, response); return; } } //3. 若验证通过, 则把表单参数封装为一个 Customer 对象 customer Customer customer = new Customer(null, name, address, phone); customer.setId(Integer.parseInt(id)); //4. 调用 CustomerDAO 的 update(Customer customer) 执行更新操作 customerDao.update(customer); //5. 重定向到 query.do response.sendRedirect("query.do"); } }