【JAVA】基於MVC架構Java技術薈萃案例演練


基於JAVA-MVC技術的顧客管理項目案例總結

作者 白寧超

2016年6月9日22:47:08

閱讀前瞻:本文源於對javaweb相關技術和資料匯總,涉及大量javaweb基礎技術諸如:Servlet運行原理、Get/Post請求的區別、jsp的基本原理和運行框架、jsp的9大隱含對象的使用、MVC開發模式的使用、構建封裝自己dao代碼庫、以及基於MVC的增刪改查操作等;小結最后還有面向接口編程的多數據源配置與存儲,以及工廠模式的使用。除此之外,后續文章會對cookie、session、JavaBean、監聽、權限管理、文件上傳與下載、分頁等諸多技術匯總。本文旨在java-web多技術貫穿於單項目中,逐漸深入的過程,使得大家既學習了java技術路線,也知道其怎么用。最后會附上源碼,最后一節重點對所有實現技術小結與匯總,此過程會使用作者項目技術理解、網絡資源資料、學習視頻和文檔截圖文件等為參考,力求簡單通俗易學。最后,作者文章布局采用:1、實驗准備;2、需求分析;3、模塊化實現;4、實驗優化;5、技術梳理的寫作思路。(本文原創,轉載標明出處基於JAVA-MVC技術的顧客管理項目案例總結

一、實驗准備階段:

1  win*系統,一般配置筆記本或者台式機

2  安裝MyEclipse開發平台,本實驗使用MyEclipse2015(點擊下載 訪問密碼 eafa

3 Mysql數據庫,本實驗采用mysql-installer-community-5.6.14.0.msi(點擊下載 訪問密碼 39bf

4 關於數據庫連接的3個JAR包

4.1 JDBC鏈接數據庫的jar包,本實驗采用mysql-connector-java-5.1.20.jar(點擊下載 訪問密碼 8bb1

4.2 dbUtils數據庫JAR包,本實驗采用commons-dbutils-1.6.jar(點擊下載 訪問密碼 535d

4.3 c3p0數據庫配置JAR包,本實驗采用c3p0-0.9.1.2.jar(點擊下載 訪問密碼 9916

5 兩個公共文件

5.1 關於編寫Jquery需要的js文件,本實驗使用jquery.min.js(點擊下載 訪問密碼 3357

5.2 關於c3p0數據庫配置xml源文件c3p0-config.xml(點擊下載 訪問密碼 33a6

二、需求分析階段

1 對MyEclipse和MySql的正確安裝,並對MyEclipse環境變量配置:(配置參考文檔

2 要求l使用mysql數據庫去創建數據庫test和表customers(id int 主鍵自增,name String 唯一約束,address String,phone String)

3 采用MVC技術開發,實現M/V/C很好的封裝與解耦,在此基礎完成對顧客表的增刪改查,其中要求數據可以回顯、模糊查詢、容錯等

4 servlet初始化啟動控制多數據源配置

5 其他諸如分頁、cookie、session、JavaBean、監聽、權限管理、文件上傳與下載等后續文章繼續完善優化。

三、數據庫創建階段

# 創建數據庫test
create database test;
use test;
#創建customer表id主鍵自增,name唯一
create table customers(
id varchar(11) primary key not null,
name varchar(70) not null unique,
address varchar(70),
phone varchar(70)
);

四、基於MVC技術開發階段

1 顧客管理項目環境配置簡介

MVC百度百科:MVC全名是Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫,一種軟件設計典范,用一種業務邏輯、數據、界面顯示分離的方法組織代碼,將業務邏輯聚集到一個部件里面,在改進和個性化定制界面及用戶交互的同時,不需要重新編寫業務邏輯。MVC被獨特的發展起來用於映射傳統的輸入、處理和輸出功能在一個邏輯的圖形化用戶界面的結構中。(注:詳細MVC可以參照官方文檔或者google

配置簡介:

1 新建java web項目,默認基礎下分別建立MVC對於的包,以及添加需要配置的jar包、js文件、xml文件、imgs等文件,打通整體開發框架。

2 創建需要完成jsp頁面

2 MVC架構搭建

1、配置文件的引用

mysql-connector-java-5.1.20.jar:連接數據庫的jar包,放於./WEB-INF/lib下

commons-dbutils-1.6.jar:dbutils的jar包,放於./WEB-INF/lib下

c3p0-0.9.1.2.jar:c3p0的jar包,放於./WEB-INF/lib下

jquery.min.js:用於編寫js的文件,放於./WebRoot/scripts下

c3p0-config.xml:用於配置數據庫,放於./src下

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>

  <named-config name="mvcapp"> 
    <property name="user">root</property>
    <property name="password">root</property>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql:///test</property>
    
    
    <property name="acquireIncrement">5</property>
    <property name="initialPoolSize">10</property>
    <property name="minPoolSize">10</property>
    <property name="maxPoolSize">50</property>

    <!-- intergalactoApp adopts a different approach to configuring statement caching -->
    <property name="maxStatements">20</property> 
    <property name="maxStatementsPerConnection">5</property>

    
  </named-config>
</c3p0-config>
View Code

2、 數據層配置

 com.cuit.mvc.db包:JdbcUtils.java數據庫連接和釋放方法的封裝

package com.cuit.mvc.db;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * JDBC操作工具
 * @author 白寧超 http://www.cnblogs.com/baiboy/
 */
public class JdbcUtils {
    /**
     * 釋放Connection鏈接
     * @param connection
     */
    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");
    }
    /**
     * 返回數據源的一個Connection對象
     * @return
     * @throws SQLException 
     */
    public static Connection getConnection() throws SQLException{
        return dataSource.getConnection();
    }

}
View Code

 com.cuit.mvc.model包:Customer.java實體類的封裝

package com.cuit.mvc.model;

public class Customer {
    
    private int  id;
    private String name;
    private String address;
    private String phone;
    public int getId() {
        return id;
    }
    public Customer() {
        
    }
    public Customer(String name, String address, String phone) {
        this.name = name;
        this.address = address;
        this.phone = phone;
    }
    public void setId(int 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;
    }
    @Override
    public String toString(){
        return "Customer [id="+id+",name="+name+",address"+address+
                ",phone="+phone+"]";
    }
}
View Code

 com.cuit.mvc.dao包:DAO.java最底層公共方法封裝;CustomerDAO提供公共方法的接口;

DAO源碼:

package com.cuit.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.cuit.mvc.db.JdbcUtils;

/**
 * 封裝了基本的CRUD的方法,以供子類繼承使用
 * 當前DAO直接在方法中獲取數據庫連接
 * @param <T> :當前DAO處理實體的類型是什么
 * @author 白寧超 http://www.cnblogs.com/baiboy/
 *
 */
public class DAO<T> {
    //此步驟前需要/lib加入commons-dbutils-xx.jar
    private QueryRunner  queryRunner=new QueryRunner();
    private Class<T> clazz;
    public DAO(){
        //Type通過Ctrl+Shift+O進行反射Type選擇
        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];
            }
        }
    }    
    /**
     * 返回某一個字段的值,或者返回數據表中有多少條記錄等。
     * @param sql:SQL語句
     * @param args:填充SQL語句的占位符
     * @return
     */
    public <E> E getForValue(String sql,Object ... args) {
        Connection connection=null;
        try{
            connection=JdbcUtils.getConnection();
            return (E) queryRunner.query(connection,sql,new ScalarHandler<T>(),args);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JdbcUtils.releaseConnection(connection);
        }
        return null;
    }
    /**
     * 返回T所對應的List
     * @param sql:SQL語句
     * @param args:填充SQL語句的占位符
     * @return
     */
    public List<T> getForList(String sql,Object ... args){
        Connection connection=null;
        try{
            connection=JdbcUtils.getConnection();
            
            return queryRunner.query(connection,sql,new BeanListHandler<>(clazz),args);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JdbcUtils.releaseConnection(connection);
        }
        return null;
    }
    /**
     * 返回對應T的一個實體類對象
     * @param sql:SQL語句
     * @param args:填充SQL語句的占位符
     * @return
     */
    public T get(String sql,Object ... args){
        Connection connection=null;
        try{
            connection=JdbcUtils.getConnection();
            return queryRunner.query(connection,sql,new BeanHandler<>(clazz),args);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JdbcUtils.releaseConnection(connection);
        }
        return null;
    }
    /**
     * 該方法封裝了INSERT、DELETE、UPDATE操作
     * @param sql:SQL語句
     * @param args:填充SQL語句的占位符
     */
    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);
        }
    }
}
View Code

CustomerDAO源碼:

package com.cuit.mvc.dao;

import java.util.List;

import com.cuit.mvc.model.CriteriaCustomer;
import com.cuit.mvc.model.Customer;

public interface CustomerDAO {
    public List<Customer> getAll();//獲取Customer列表信息
    public void save(Customer customer);//對Customer的添加,通過CTRL+T轉到定義
    public void update(Customer customer);//對Customer的更新,通過CTRL+T轉到定義
    public Customer get(int id);//獲取Customer實體
    public void delete(int id);//根據id進行刪除
    public long getCountWithName(String name);//返回name相等的記錄數
    //cc封裝了查詢條件,返回查詢條件的list
    public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc);
    
}
View Code

com.cuit.mvc.dao.impl包:CustomerDAOJdbcImpl.java:Customer對CustomerDAO具體方法的實現

package com.cuit.mvc.dao.impl;

import java.util.List;

import com.cuit.mvc.dao.CustomerDAO;
import com.cuit.mvc.dao.DAO;
import com.cuit.mvc.model.CriteriaCustomer;
import com.cuit.mvc.model.Customer;

public class CustomerDAOJdbcImpl extends DAO<Customer> implements CustomerDAO{

    public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc) {
        String sql="select * from customers where name like ? and address like ? "
                + "and phone like ?";
        //修改了CriteriaCustomer的getter方法:使其返回字符串中有%%
        //若返回值為null返回%%,若不返回null則返回:"%"+字段本身的值+"%"
        //如上效果如:cc.getName()==null?%%:%+name+%
        System.out.println(sql);
        return getForList(sql,cc.getName(),cc.getAddress(),cc.getPhone());
        
    }
    @Override
    public List<Customer> getAll() {
        String sql="select * from customers";
        return getForList(sql);
    }

    @Override
    public void save(Customer customer) {
        String sql="insert customers(name,address,phone) values(?,?,?)";
        update(sql, customer.getName(),customer.getAddress(),customer.getPhone());
    }

    @Override
    public Customer get(int id) {
        String sql="select * from customers where id=?";
        return get(sql,id);
    }

    @Override
    public void delete(int 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());
    }

}
View Code

3 業務邏輯層

 com.cuit.mvc.dao.servlet包:CustomerServlet.java對CustomerDAO公共方法具體實現,以及頁面顯示的控制

package com.cuit.mvc.servlet;

import java.io.IOException;
import java.io.PrintWriter;
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.cuit.mvc.dao.CustomerDAO;
import com.cuit.mvc.dao.factory.CustomerDAOFactory;
import com.cuit.mvc.dao.impl.CustomerDAOJdbcImpl;
import com.cuit.mvc.dao.impl.CustomerDAOXMLImpl;
import com.cuit.mvc.model.CriteriaCustomer;
import com.cuit.mvc.model.Customer;

public class CustomerServlet extends HttpServlet {

    //private CustomerDAO customerDAO=new CustomerDAOJdbcImpl();
    //private CustomerDAO customerDAO=new CustomerDAOXMLImpl();
    private CustomerDAO customerDAO=CustomerDAOFactory.getInstance().getCustomerDAO();
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    /*public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String method=request.getParameter("method");
        switch (method) {
        case "add":  add(request,response); break;
        case "query": query(request,response); break;
        case "delete": delete(request,response);break;
        default: break;
        }

    }*/
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        //1 獲取servlet路徑 諸如:/add.do
        String servletPath=req.getServletPath().substring(1);
        //去除/和.do得到類似於add這樣字符串
        String methodName=servletPath.substring(0,servletPath.length()-3);
        //System.out.println(methodName);
        try {
            //利用反射獲取獲取methodName對應的方法
            Method method = getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
            //利用反射獲取方法
            method.invoke(this, req,resp);
        } catch (Exception e) {
            //出錯時候響應出來
            resp.sendRedirect("error.jsp");
        }
    }
    private void edit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        String forwordPath="/error.jsp";
        //1 獲取請求參數id
        String idstr=request.getParameter("id");
        //2 調用CustomeDAO的customerDAO.get(id)獲取和id對應的Customer對象customer
        try{
            Customer customer=customerDAO.get(Integer.parseInt(idstr));
            if(customer!=null){
                forwordPath="/updatecustomer.jsp";
                //3 將customer放在request中
                request.setAttribute("customer", customer);
            }
        }catch(Exception e){}
        //4 響應updatecustomer.jsp頁面:轉發
        request.getRequestDispatcher(forwordPath).forward(request, response);
    }
    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 oldname=request.getParameter("oldname");
        String address=request.getParameter("address");
        String phone=request.getParameter("phone");
        //2  檢驗name是否被占用
        //2.1  比較name和oldname是否相同,若相同name可用,oldname.equals(name)不如equalsIgnoreCase,數據庫默認大小寫一致的,而equals忽略大小寫
        if(!oldname.equalsIgnoreCase(name)){
            //不相同,調用CustomerDAO的getCountWithName(String name)獲取name在數據庫中是否存在
            long count=customerDAO.getCountWithName(name);
            //大於0, 響應updatecustomer.jsp頁面:通過轉發響應newcustomer.jsp
            if(count>0){
                // 通過request.getAttribute("message")顯示信息,在頁面上request.getAttribute("message")的方式顯示
                // 表單據回顯。address,phone顯示提交的新值, name顯示oldname,而不是新值
                request.setAttribute("message", "用戶名["+name+"]已經被占用,請重新填寫!");
                // 方法結束
                request.getRequestDispatcher("/updatecustomer.jsp").forward(request, response);
                return;
            }
        }
        //3 若驗證通過,把表單參數封裝為一個Customer對象customer
        Customer customer=new Customer(name,address,phone);
        customer.setId(Integer.parseInt(id));
        //4 調用CustomerDAO的update(Customer customer)執行更新操作
        customerDAO.update(customer);
        //5 重定向到query.do
        response.sendRedirect("query.do");
        
    }
    //模糊查詢
    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 cc=new CriteriaCustomer(name,address,phone);
        //1 調用CustomerDAO的getALl方法得到Customer集合
        //List<Customer> sustomers=customerDAO.getAll();獲取所有信息列表
        List<Customer> customers=customerDAO.getForListWithCriteriaCustomer(cc);
        //2 把customer的集合放入request
        request.setAttribute("customers", customers);
        //3 轉發頁面index.jsp(不能使用重定向)
        request.getRequestDispatcher("/index.jsp").forward(request,response);
    }

    private void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        String idstr=request.getParameter("id").trim();
        int id=0;
        try{
            id=Integer.parseInt(idstr);
            customerDAO.delete(id);
        }catch(Exception e){}
        response.sendRedirect("query.do");
    }

    //此方法名稱跟頁面add添加的action中add.do匹配
    private void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        //1 獲取表單參數:name,address,phone
        String name=request.getParameter("name");
        String address=request.getParameter("address");
        String phone=request.getParameter("phone");
        //2  檢驗name是否被占用
        //2.1  調用CustomerDAO的getCountWithName(String name)獲取name在數據庫中是否存在
        long count=customerDAO.getCountWithName(name);
        if(count>0){
        //2.2 若返回值大於0,則相應newcustomer.jsp頁面:①在此頁面顯示一個錯誤信息②此表單值可以回顯
        //     通過request.getAttribute("message")顯示信息
        //     通過value="<%=request.getParameter("name")==null?"":request.getParameter("name")%>"回顯
            request.setAttribute("message", "用戶名["+name+"]已經被占用,請重新填寫!");
            request.getRequestDispatcher("/newcustomer.jsp").forward(request, response);
            return;
        }
        //3 若驗證通過,把表單參數封裝為一個Customer對象customer
        Customer customer=new Customer(name,address,phone);
        //4 調用CustomerDAO的save(Customer customer)執行保存操作
        customerDAO.save(customer);
        //5 重定向到success.jsp頁面
        response.sendRedirect("success.jsp");
    }

}
View Code

4 單元測試層

 com.cuit.mvc.dao.test包:JdbcUtilsTest.java對CustomerServlet.java各個方法單元測試

package com.cuit.mvc.test;

import static org.junit.Assert.*;

import java.util.List;

import org.junit.Test;

import com.cuit.mvc.dao.CustomerDAO;
import com.cuit.mvc.dao.impl.CustomerDAOJdbcImpl;
import com.cuit.mvc.model.CriteriaCustomer;
import com.cuit.mvc.model.Customer;

public class CustomerDAOJdbcImplTest {

    private  CustomerDAO customerDAO=new CustomerDAOJdbcImpl();
    @Test
    public void getForListWithCriteriaCustomer(){
        CriteriaCustomer cc=new CriteriaCustomer("Tom", null, null);
        List<Customer> customers=customerDAO.getForListWithCriteriaCustomer(cc);
        System.out.println(customers);
    }
    @Test
    public void testGetAll() {
        List<Customer> customers=customerDAO.getAll();
        System.out.println(customers);
    }

    @Test
    public void testSaveCustomer() {
        Customer customer=new Customer("Baijing","Shanghai","134-2345-9086");
        customerDAO.save(customer);
    }

    @Test
    public void testGetInt() {
        Customer cust=customerDAO.get(0);
        System.out.println(cust);
    }

    @Test
    public void testDelete() {
        customerDAO.delete(2);
    }

    @Test
    public void testGetCountWithName() {
        long count=customerDAO.getCountWithName("Tom");
        System.out.println(count);
    }

}
View Code

5 視圖顯示頁面層 

index.jsp:顯示顧客信息,並支持回顯

<%@page import="com.cuit.mvc.model.Customer"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
    
  <script type="text/javascript" src="scripts/jquery.min.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">
         <table>
             <tr>
               <td>CustomerName:</td>
               <td><input type="text" name="name"/></td>
             </tr>
             
              <tr>
               <td>CustomerAddress:</td>
               <td><input type="text" name="address"/></td>
             </tr>
             
              <tr>
               <td>CustomerPhone:</td>
               <td><input type="text" name="phone"/></td>
             </tr>
             
              <tr>
               <td><input type="submit" value="Query"/></td>
               <td><a href="newcustomer.jsp">Create New Customer</a></td>
             </tr>
         </table>
      </form>
      <br/><br/>
      <%
          List<Customer> customers=(List<Customer>)request.getAttribute("customers");
          if(customers!=null && customers.size()>0){
       %>
       <hr>
       <br/><br/>
       <table border="1" cellpadding="10" cellspacing="0">
            <tr>
               <th>ID</th>
               <th>CustomerName</th>
               <th>CustomerAddress</th>
               <th>CustomerPhone</th>
               <th>Update/Delete</th>
            </tr> 
            <% 
              for(Customer customer:customers){
            %>
            <tr>
               <td class="id"><%=customer.getId() %></td>
               <td><%=customer.getName() %></td>
               <td><%=customer.getAddress() %></td>
               <td><%=customer.getPhone() %></td>
               <td>
                   <a  href="edit.do?id=<%=customer.getId() %>">Update</a>
                   <a href="delete.do?id=<%=customer.getId() %>" class="delete">Delete</a>
               </td> 
               </tr>
               <%
                }
                %>
       </table>
       <%
          }
        %>

  </body>
</html>
View Code

error.jsp:異常或者報錯頁面跳轉

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'error.jsp' starting page</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
    <h4>對不起沒有您請求的頁面</h4>
    <img style=" height:200px; width: 200; margin: 0 auto;" src="imgs/error.jpg"></img><br/><br>
    <p style="font-size: 25px; color: red;">對不起訪問失敗!</p>
    
  </body>
</html>
View Code

newcustomer.jsp:添加顧客信息頁面,支持回顯,控制name不能重復

<%@ 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 mes=request.getAttribute("message");
        if(mes!=null){
           out.print("<br>");
           out.print(mes);
           out.print("<br>");
           out.print("<br>");
        }
     %>
    <h1>添加一條新的customer信息</h1>
     <!--此處add.do依賴於CustomerServlet中的add方法名  -->
     <form action="add.do">
         <table>
             <tr>
               <td>CustomerName:</td>
               <td><input type="text" name="name"
                    value="<%=request.getParameter("name")==null?"":request.getParameter("name")%>"/></td>
             </tr>
             
              <tr>
               <td>CustomerAddress:</td>
               <td><input type="text" name="address"
                   value="<%=request.getParameter("address")==null?"":request.getParameter("address")%>"/></td>
             </tr>
             
              <tr>
               <td>CustomerPhone:</td>
               <td><input type="text" name="phone"
                    value="<%=request.getParameter("phone")==null?"":request.getParameter("phone")%>"/></td>
             </tr>
             
              <tr>
               <td colspan="2"><input type="submit" value="Submit"/></td>
             </tr>
         </table>
      </form>
</body>
</html>
View Code

success.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>
    <h2>成功添加,保存成功!</h2><br/><br/>
    <h2><a href="index.jsp">Back Index</a></h2>
</body>
</html>
View Code

updatecustomer.jsp:更新信息頁面,支持回顯,回顯顯示的是name舊值

<%@page import="com.cuit.mvc.model.Customer"%>
<%@ 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 mes=request.getAttribute("message");
        if(mes!=null){
           out.print("<br>");
           out.print(mes);
           out.print("<br>");
           out.print("<br>");
        }
        String id=null;
        String name=null;
        String oldname=null;
        String address=null;
        String phone=null;
        Customer customer=(Customer)request.getAttribute("customer");
        if(customer!=null){
           id=customer.getId()+"";
           address=customer.getAddress();
           name=customer.getName();
           oldname=customer.getName();
           phone=customer.getPhone();
        }else{
           id=request.getParameter("id");
           name=request.getParameter("oldname");
           oldname=request.getParameter("oldname");
           address=request.getParameter("address");
           phone=request.getParameter("phone");
        }
     %>
    <h1>更新一條新的customer信息</h1>
     <!--此處add.do依賴於CustomerServlet中的add方法名  -->
     <form action="update.do">
         <input type="hidden" name="id" value="<%=customer.getId()%>"/>
         <input type="hidden" name="oldname" value="<%=oldname%>"/>
         <table>
             <tr>
               <td>CustomerName:</td>
               <td><input type="text" name="name" value="<%=name%>"/></td>
             </tr>
             
              <tr>
               <td>CustomerAddress:</td>
               <td><input type="text" name="address"  value="<%=address %>"/></td>
             </tr>
             
              <tr>
               <td>CustomerPhone:</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>
View Code

3 顧客信息模糊查詢設計與實現

1) 項目設計分析: 實現name,address,phone聯合模糊查詢

1、 調用CustomerDAO的getALl方法得到Customer集合

2、 把customer的集合放入request

3、 轉發頁面index.jsp(不能使用重定向)

4、 index.jsp頁面循環遍歷顯示

2)項目源碼實現

1 DAO數據操作

	public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc) {
		String sql="select * from customers where name like ? and address like ? "
				+ "and phone like ?";
		//修改了CriteriaCustomer的getter方法:使其返回字符串中有%%
		//若返回值為null返回%%,若不返回null則返回:"%"+字段本身的值+"%"
		//如上效果如:cc.getName()==null?%%:%+name+%
		System.out.println(sql);
		return getForList(sql,cc.getName(),cc.getAddress(),cc.getPhone());
	}

2、servlet控制源碼:

	//模糊查詢
	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 cc=new CriteriaCustomer(name,address,phone);
		//1 調用CustomerDAO的getALl方法得到Customer集合
		//List<Customer> sustomers=customerDAO.getAll();獲取所有信息列表
		List<Customer> customers=customerDAO.getForListWithCriteriaCustomer(cc);
		//2 把customer的集合放入request
		request.setAttribute("customers", customers);
		//3 轉發頁面index.jsp(不能使用重定向)
		request.getRequestDispatcher("/index.jsp").forward(request,response);
	}

3、index頁面顯示

      <%
          List<Customer> customers=(List<Customer>)request.getAttribute("customers");
          if(customers!=null && customers.size()>0){
       %>
       <hr>
       <br/><br/>
       <table border="1" cellpadding="10" cellspacing="0">
            <tr>
               <th>ID</th>
               <th>CustomerName</th>
               <th>CustomerAddress</th>
               <th>CustomerPhone</th>
               <th>Update/Delete</th>
            </tr> 
            <% 
              for(Customer customer:customers){
            %>
            <tr>
               <td class="id"><%=customer.getId() %></td>
               <td><%=customer.getName() %></td>
               <td><%=customer.getAddress() %></td>
               <td><%=customer.getPhone() %></td>
               <td>
                   <a  href="edit.do?id=<%=customer.getId() %>">Update</a>
                   <a href="delete.do?id=<%=customer.getId() %>" class="delete">Delete</a>
               </td> 
               </tr>
               <%
                }
                %>
       </table>
       <%
          }
        %>

3)項目單元測試

	@Test
	public void getForListWithCriteriaCustomer(){
		CriteriaCustomer cc=new CriteriaCustomer("Tom", null, null);
		List<Customer> customers=customerDAO.getForListWithCriteriaCustomer(cc);
		System.out.println(customers);
	}

4)項目運行效果

4 顧客信息添加設計與實現

1) 項目設計分析:name唯一,新添加信息需要驗證錯誤提示

1、獲取表單參數:name、address、phone

2、 檢驗name是否被占用

3、若驗證通過,把表單參數封裝為一個Customer對象customer

4、調用CustomerDAO的save(Customer customer)執行保存操作

5、重定向到success.jsp頁面

2)項目源碼實現

1、DAO操作源碼

	@Override
	public void save(Customer customer) {
		String sql="insert customers(name,address,phone) values(?,?,?)";
		update(sql, customer.getName(),customer.getAddress(),customer.getPhone());
	}

2、servlet操作源碼

   		//1 獲取表單參數:name,address,phone
		String name=request.getParameter("name");
		String address=request.getParameter("address");
		String phone=request.getParameter("phone");
		//2  檢驗name是否被占用
		//2.1  調用CustomerDAO的getCountWithName(String name)獲取name在數據庫中是否存在
		long count=customerDAO.getCountWithName(name);
		if(count>0){
		//2.2 若返回值大於0,則相應newcustomer.jsp頁面:①在此頁面顯示一個錯誤信息②此表單值可以回顯
		//     通過request.getAttribute("message")顯示信息
		//     通過value="<%=request.getParameter("name")==null?"":request.getParameter("name")%>"回顯
			request.setAttribute("message", "用戶名["+name+"]已經被占用,請重新填寫!");
			request.getRequestDispatcher("/newcustomer.jsp").forward(request, response);
		    return;
		}
		//3 若驗證通過,把表單參數封裝為一個Customer對象customer
		Customer customer=new Customer(name,address,phone);
		//4 調用CustomerDAO的save(Customer customer)執行保存操作
		customerDAO.save(customer);
		//5 重定向到success.jsp頁面
		response.sendRedirect("success.jsp");

3、 視圖頁面顯示源碼

<body>
    <%
        Object mes=request.getAttribute("message");
        if(mes!=null){
           out.print("<br>");
           out.print(mes);
           out.print("<br>");
           out.print("<br>");
        }
     %>
    <h1>添加一條新的customer信息</h1>
     <!--此處add.do依賴於CustomerServlet中的add方法名  -->
     <form action="add.do">
         <table>
             <tr>
               <td>CustomerName:</td>
               <td><input type="text" name="name"
                    value="<%=request.getParameter("name")==null?"":request.getParameter("name")%>"/></td>
             </tr>
             
              <tr>
               <td>CustomerAddress:</td>
               <td><input type="text" name="address"
                   value="<%=request.getParameter("address")==null?"":request.getParameter("address")%>"/></td>
             </tr>
             
              <tr>
               <td>CustomerPhone:</td>
               <td><input type="text" name="phone"
                    value="<%=request.getParameter("phone")==null?"":request.getParameter("phone")%>"/></td>
             </tr>
             
              <tr>
               <td colspan="2"><input type="submit" value="Submit"/></td>
             </tr>
         </table>
      </form>
</body>

3)項目單元測試

	@Test
	public void testSaveCustomer() {
		Customer customer=new Customer("Baijing","Shanghai","134-2345-9086");
		customerDAO.save(customer);
	}

4)項目運行效果

5 顧客信息更新設計與實現

1) 項目設計分析

1、 編輯操作:①獲取請求參數id;②調用CustomeDAO的customerDAO.get(id)獲取和id對應的Customer對象customer;③若驗證通過,把表單參數封裝為一個Customer對象customer;④ 調用CustomerDAO的update(Customer customer)執行更新操作;⑤重定向到query.do

2、更新操作:①獲取請求參數:id,name,address,phone,oldname;②檢驗name是否被占用;③若驗證通過,把表單參數封裝為一個Customer對象customer;④調用CustomerDAO的update(Customer customer)執行更新操作;⑤重定向到query.do;

2)項目源碼實現

1、DAO操作源碼:

	@Override
	public void save(Customer customer) {
		String sql="insert customers(name,address,phone) values(?,?,?)";
		update(sql, customer.getName(),customer.getAddress(),customer.getPhone());
	}

2、servlet操作源碼

	private void edit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
		String forwordPath="/error.jsp";
		//1 獲取請求參數id
		String idstr=request.getParameter("id");
		//2 調用CustomeDAO的customerDAO.get(id)獲取和id對應的Customer對象customer
		try{
			Customer customer=customerDAO.get(Integer.parseInt(idstr));
			if(customer!=null){
				forwordPath="/updatecustomer.jsp";
				//3 將customer放在request中
				request.setAttribute("customer", customer);
			}
		}catch(Exception e){}
		//4 響應updatecustomer.jsp頁面:轉發
		request.getRequestDispatcher(forwordPath).forward(request, response);
	}
	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 oldname=request.getParameter("oldname");
		String address=request.getParameter("address");
		String phone=request.getParameter("phone");
		//2  檢驗name是否被占用
		//2.1  比較name和oldname是否相同,若相同name可用,oldname.equals(name)不如equalsIgnoreCase,數據庫默認大小寫一致的,而equals忽略大小寫
		if(!oldname.equalsIgnoreCase(name)){
			//不相同,調用CustomerDAO的getCountWithName(String name)獲取name在數據庫中是否存在
			long count=customerDAO.getCountWithName(name);
			//大於0, 響應updatecustomer.jsp頁面:通過轉發響應newcustomer.jsp
			if(count>0){
				// 通過request.getAttribute("message")顯示信息,在頁面上request.getAttribute("message")的方式顯示
			    // 表單據回顯。address,phone顯示提交的新值, name顯示oldname,而不是新值
				request.setAttribute("message", "用戶名["+name+"]已經被占用,請重新填寫!");
				// 方法結束
				request.getRequestDispatcher("/updatecustomer.jsp").forward(request, response);
				return;
			}
		}
		//3 若驗證通過,把表單參數封裝為一個Customer對象customer
		Customer customer=new Customer(name,address,phone);
		customer.setId(Integer.parseInt(id));
		//4 調用CustomerDAO的update(Customer customer)執行更新操作
		customerDAO.update(customer);
		//5 重定向到query.do
		response.sendRedirect("query.do");
		
	}

3、視圖顯示操作源碼

<body>
   <%
        Object mes=request.getAttribute("message");
        if(mes!=null){
           out.print("<br>");
           out.print(mes);
           out.print("<br>");
           out.print("<br>");
        }
        String id=null;
        String name=null;
        String oldname=null;
        String address=null;
        String phone=null;
        Customer customer=(Customer)request.getAttribute("customer");
        if(customer!=null){
           id=customer.getId()+"";
           address=customer.getAddress();
           name=customer.getName();
           oldname=customer.getName();
           phone=customer.getPhone();
        }else{
           id=request.getParameter("id");
           name=request.getParameter("oldname");
           oldname=request.getParameter("oldname");
           address=request.getParameter("address");
           phone=request.getParameter("phone");
        }
     %>
    <h1>更新一條新的customer信息</h1>
     <!--此處add.do依賴於CustomerServlet中的add方法名  -->
     <form action="update.do">
         <input type="hidden" name="id" value="<%=customer.getId()%>"/>
         <input type="hidden" name="oldname" value="<%=oldname%>"/>
         <table>
             <tr>
               <td>CustomerName:</td>
               <td><input type="text" name="name" value="<%=name%>"/></td>
             </tr>
             
              <tr>
               <td>CustomerAddress:</td>
               <td><input type="text" name="address"  value="<%=address %>"/></td>
             </tr>
             
              <tr>
               <td>CustomerPhone:</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>

3)項目單元測試

	@Test
	public void testSaveCustomer() {
		Customer customer=new Customer("Baijing","Shanghai","134-2345-9086");
		customerDAO.save(customer);
	}

4)項目運行效果

6 顧客信息刪除設計與實現

1) 項目設計分析

1、獲取id的值

2、調用DAO的刪除方法

3、執行提示是否刪除

4、刪除成功跳轉刷新

2)項目源碼實現

1、DAO源碼:

	@Override
	public void delete(int id) {
		String sql="delete  from customers where id=?";
		update(sql, id);
	}

2、servlet源碼:

	private void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
		String idstr=request.getParameter("id").trim();
		int id=0;
		try{
			id=Integer.parseInt(idstr);
			customerDAO.delete(id);
		}catch(Exception e){}
		response.sendRedirect("query.do");
	}

3、頁面顯示源碼:

  <script type="text/javascript" src="scripts/jquery.min.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>
  <td>
        <a  href="edit.do?id=<%=customer.getId() %>">Update</a>
        <a href="delete.do?id=<%=customer.getId() %>" class="delete">Delete</a>
  </td> 

3)項目單元測試

	@Test
	public void testDelete() {
		customerDAO.delete(2);
	}

4)項目運行效果

7 面向接口開發的數據源配置

倘若需要操作其他數據庫或者xml數據源進行存儲,該如何操作呢?下面以jdbc和xml進行設計

1 、不修改DAO底層代碼前提下,創建工廠模式,利用tyep類型進行選擇實例創建連接模式,

//單例工廠
public class CustomerDAOFactory {
	
	private Map<String,CustomerDAO> daos=new HashMap<String,CustomerDAO>();

	private static CustomerDAOFactory instance=new CustomerDAOFactory();
	public static CustomerDAOFactory getInstance(){
		return instance;
	}
	private  String type=null;
	public  void setType(String type) {
		this.type=type;
	}
	private CustomerDAOFactory() {
		daos.put("jdbc", new CustomerDAOJdbcImpl());
		daos.put("xml", new CustomerDAOXMLImpl());
	}
	public CustomerDAO getCustomerDAO(){
		return daos.get(type);
	}
}

2、type值放在switch.properties用於切換,如下是該文件的內容

#type=xml
type=jdbc

3、初始化servlet,創建InitServlet.java文件,並控制type值傳遞CustomerDAOFactory工廠用來切換數據源

public class InitServlet extends HttpServlet {
	
	@Override
	public void init() throws ServletException {
		CustomerDAOFactory.getInstance().setType("jdbc");
		//讀取類路徑switch.properties文件
		InputStream in=getServletContext().getResourceAsStream("/WEB-INF/classes/switch.properties");
		Properties properties=new Properties();
		try {
			properties.load(in);
			//獲取switch.properties的type值
			String type=properties.getProperty("type");
			//賦給了CustomerDAOFactory的type屬性
			CustomerDAOFactory.getInstance().setType(type);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

4、配置web.xml文件,使InitServlet.java在項目啟動時即運行

  <servlet>
    <servlet-name>CustomerServlet</servlet-name>
    <servlet-class>com.cuit.mvc.servlet.CustomerServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>InitServlet</servlet-name>
    <servlet-class>com.cuit.mvc.servlet.InitServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

五、顧客管理項目完整源碼

 本項目完整源碼:(點擊下載  訪問密碼 16cf

六、顧客管理項目技術總結

1 Tomcat目錄結構圖

2 Tomcat配置,MyEclipse2015默認集成了,不需要配置

3 web程序結構圖

4 Servlet簡介

5 servlet運行交互圖

6 servlet運行原理

7 jsp運行原理

8 jsp的9大隱含對象

9 jsp注釋與聲明

10 jsp和屬性相關的方法

11 頁面請求重定向與請求轉發

12 page指令

12 errorPage和isErrorPage

13 關於中文亂碼的解決方案

 14 MVC簡介

15 MVC原理圖

16 多頁面向單個servlet發送請求控制:方法1

17 多頁面向單個servlet發送請求控制:方法2

18 更新操作原理示意圖

19 查詢設計思路

20 MVC案例需求設計

21 jsp頁面請求遍歷數據

22 修改更新設計思路

23 面向接口編程

24 表單請求和回顯圖示


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM