单据上百位模糊java_【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下

b9225abb6630a343fb8f48ae09f5e1a8.png

46246f9871f5327e9a9d2002a2d32474.png

"1.0" encoding="UTF-8"?>

"mvcapp">

"user">root

"password">root

"driverClass">com.mysql.jdbc.Driver

"jdbcUrl">jdbc:mysql:///test

"acquireIncrement">5

"initialPoolSize">10

"minPoolSize">10

"maxPoolSize">50

"maxStatements">20

"maxStatementsPerConnection">5

View Code

2、 数据层配置

com.cuit.mvc.db包:JdbcUtils.java数据库连接和释放方法的封装

b9225abb6630a343fb8f48ae09f5e1a8.png

46246f9871f5327e9a9d2002a2d32474.png

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 classJdbcUtils {/**

* 释放Connection链接

* @param connection*/

public static voidreleaseConnection(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 staticConnection getConnection() throws SQLException{returndataSource.getConnection();

}

}

View Code

com.cuit.mvc.model包:Customer.java实体类的封装

b9225abb6630a343fb8f48ae09f5e1a8.png

46246f9871f5327e9a9d2002a2d32474.png

package com.cuit.mvc.model;public classCustomer {private intid;privateString name;privateString address;privateString phone;public intgetId() {returnid;

}publicCustomer() {

}publicCustomer(String name, String address, String phone) {this.name =name;this.address =address;this.phone =phone;

}public void setId(intid) {this.id =id;

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}publicString getAddress() {returnaddress;

}public voidsetAddress(String address) {this.address =address;

}publicString getPhone() {returnphone;

}public voidsetPhone(String phone) {this.phone =phone;

}

@OverridepublicString toString(){return "Customer [id="+id+",name="+name+",address"+address+

",phone="+phone+"]";

}

}

View Code

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

DAO源码:

b9225abb6630a343fb8f48ae09f5e1a8.png

46246f9871f5327e9a9d2002a2d32474.png

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 :当前DAO处理实体的类型是什么

* @author 白宁超http://www.cnblogs.com/baiboy/**/

public class DAO{//此步骤前需要/lib加入commons-dbutils-xx.jar

private QueryRunner queryRunner=newQueryRunner();private Classclazz;publicDAO(){//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)typeArgs[0];

}

}

}/**

* 返回某一个字段的值,或者返回数据表中有多少条记录等。

* @param sql:SQL语句

* @param args:填充SQL语句的占位符

* @return*/

public 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

* @param sql:SQL语句

* @param args:填充SQL语句的占位符

* @return*/

public ListgetForList(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 voidupdate(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源码:

b9225abb6630a343fb8f48ae09f5e1a8.png

46246f9871f5327e9a9d2002a2d32474.png

package com.cuit.mvc.dao;

import java.util.List;

import com.cuit.mvc.model.CriteriaCustomer;

import com.cuit.mvc.model.Customer;public interfaceCustomerDAO {public ListgetAll();//获取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 ListgetForListWithCriteriaCustomer(CriteriaCustomer cc);

}

View Code

com.cuit.mvc.dao.impl包:CustomerDAOJdbcImpl.java:Customer对CustomerDAO具体方法的实现

b9225abb6630a343fb8f48ae09f5e1a8.png

46246f9871f5327e9a9d2002a2d32474.png

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 DAOimplements CustomerDAO{public ListgetForListWithCriteriaCustomer(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);returngetForList(sql,cc.getName(),cc.getAddress(),cc.getPhone());

}

@Overridepublic ListgetAll() {

String sql="select * from customers";returngetForList(sql);

}

@Overridepublic voidsave(Customer customer) {

String sql="insert customers(name,address,phone) values(?,?,?)";

update(sql, customer.getName(),customer.getAddress(),customer.getPhone());

}

@Overridepublic Customer get(intid) {

String sql="select * from customers where id=?";return get(sql,id);

}

@Overridepublic void delete(intid) {

String sql="delete from customers where id=?";

update(sql, id);

}

@Overridepublic longgetCountWithName(String name) {

String sql="select count(id) from customers where name=?";returngetForValue(sql, name);

}

@Overridepublic voidupdate(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公共方法具体实现,以及页面显示的控制

b9225abb6630a343fb8f48ae09f5e1a8.png

46246f9871f5327e9a9d2002a2d32474.png

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 classCustomerServlet extends HttpServlet {//private CustomerDAO customerDAO=new CustomerDAOJdbcImpl();//private CustomerDAO customerDAO=new CustomerDAOXMLImpl();

private CustomerDAO customerDAO=CustomerDAOFactory.getInstance().getCustomerDAO();public voiddoGet(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;

}

}*/@Overrideprotected voiddoPost(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 voidedit(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 voidupdate(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=newCustomer(name,address,phone);

customer.setId(Integer.parseInt(id));//4 调用CustomerDAO的update(Customer customer)执行更新操作

customerDAO.update(customer);//5 重定向到query.do

response.sendRedirect("query.do");

}//模糊查询

private voidquery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{

String name=request.getParameter("name");

String address=request.getParameter("address");

String phone=request.getParameter("phone");

CriteriaCustomer cc=newCriteriaCustomer(name,address,phone);//1 调用CustomerDAO的getALl方法得到Customer集合//Listsustomers=customerDAO.getAll();获取所有信息列表

Listcustomers=customerDAO.getForListWithCriteriaCustomer(cc);//2 把customer的集合放入request

request.setAttribute("customers", customers);//3 转发页面index.jsp(不能使用重定向)

request.getRequestDispatcher("/index.jsp").forward(request,response);

}private voiddelete(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 voidadd(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.setAttribute("message", "用户名["+name+"]已经被占用,请重新填写!");

request.getRequestDispatcher("/newcustomer.jsp").forward(request, response);return;

}//3 若验证通过,把表单参数封装为一个Customer对象customer

Customer customer=newCustomer(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各个方法单元测试

b9225abb6630a343fb8f48ae09f5e1a8.png

46246f9871f5327e9a9d2002a2d32474.png

package com.cuit.mvc.test;

importstatic 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 classCustomerDAOJdbcImplTest {private CustomerDAO customerDAO=newCustomerDAOJdbcImpl();

@Testpublic voidgetForListWithCriteriaCustomer(){

CriteriaCustomer cc=new CriteriaCustomer("Tom", null, null);

Listcustomers=customerDAO.getForListWithCriteriaCustomer(cc);

System.out.println(customers);

}

@Testpublic voidtestGetAll() {

Listcustomers=customerDAO.getAll();

System.out.println(customers);

}

@Testpublic voidtestSaveCustomer() {

Customer customer=new Customer("Baijing","Shanghai","134-2345-9086");

customerDAO.save(customer);

}

@Testpublic voidtestGetInt() {

Customer cust=customerDAO.get(0);

System.out.println(cust);

}

@Testpublic voidtestDelete() {

customerDAO.delete(2);

}

@Testpublic voidtestGetCountWithName() {long count=customerDAO.getCountWithName("Tom");

System.out.println(count);

}

}

View Code

5 视图显示页面层

index.jsp:显示顾客信息,并支持回显

b9225abb6630a343fb8f48ae09f5e1a8.png

46246f9871f5327e9a9d2002a2d32474.png

"com.cuit.mvc.model.Customer"%>

"java" import="java.util.*" pageEncoding="UTF-8"%>

String path =request.getContextPath();

String basePath= request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>

span style="color:#800000;">"-//W3C//DTD HTML 4.01 Transitional//EN">

My JSP 'index.jsp' starting page

"query.do">

CustomerName:

"text" name="name"/>

CustomerAddress:

"text" name="address"/>

CustomerPhone:

"text" name="phone"/>

Listcustomers=(List)request.getAttribute("customers");if(customers!=null && customers.size()>0){%>

"1" cellpadding="10" cellspacing="0">

ID

CustomerName

CustomerAddress

CustomerPhone

Update/Delete

for(Customer customer:customers){%>

}

%>

View Code

error.jsp:异常或者报错页面跳转

b9225abb6630a343fb8f48ae09f5e1a8.png

46246f9871f5327e9a9d2002a2d32474.png

"java" import="java.util.*" pageEncoding="UTF-8"%>

String path =request.getContextPath();

String basePath= request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>

span style="color:#800000;">"-//W3C//DTD HTML 4.01 Transitional//EN">

My JSP 'error.jsp' starting page

"pragma" content="no-cache">

"cache-control" content="no-cache">

"expires" content="0">

"keywords" content="keyword1,keyword2,keyword3">

"description" content="This is my page">

对不起没有您请求的页面

1281681819300806656.htm"height:200px; width: 200; margin: 0 auto;" src="imgs/error.jpg">

"font-size: 25px; color: red;">对不起访问失败!

View Code

newcustomer.jsp:添加顾客信息页面,支持回显,控制name不能重复

b9225abb6630a343fb8f48ae09f5e1a8.png

46246f9871f5327e9a9d2002a2d32474.png

"java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>

span style="color:#800000;">"-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

"Content-Type" content="text/html; charset=UTF-8">

Insert title here

Object mes=request.getAttribute("message");if(mes!=null){out.print("");out.print(mes);out.print("");out.print("");

}%>

添加一条新的customer信息

"add.do">

CustomerName:

"text" name="name"value=""name")==null?"":request.getParameter("name")%>"/>

CustomerAddress:

"text" name="address"value=""address")==null?"":request.getParameter("address")%>"/>

CustomerPhone:

"text" name="phone"value=""phone")==null?"":request.getParameter("phone")%>"/>

"2">"submit" value="Submit"/>

View Code

success.jsp:添加新信息成功跳转页面

b9225abb6630a343fb8f48ae09f5e1a8.png

46246f9871f5327e9a9d2002a2d32474.png

"java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>

span style="color:#800000;">"-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

"Content-Type" content="text/html; charset=UTF-8">

Insert title here

成功添加,保存成功!

View Code

updatecustomer.jsp:更新信息页面,支持回显,回显显示的是name旧值

b9225abb6630a343fb8f48ae09f5e1a8.png

46246f9871f5327e9a9d2002a2d32474.png

"com.cuit.mvc.model.Customer"%>

"java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>

span style="color:#800000;">"-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

"Content-Type" content="text/html; charset=UTF-8">

Insert title here

Object mes=request.getAttribute("message");if(mes!=null){out.print("");out.print(mes);out.print("");out.print("");

}

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");

}%>

更新一条新的customer信息

"update.do">

"hidden" name="id" value=""/>

"hidden" name="oldname" value=""/>

CustomerName:

"text" name="name" value=""/>

CustomerAddress:

"text" name="address" value=""/>

CustomerPhone:

"text" name="phone" value=""/>

"2">"submit" value="Submit"/>

View Code

3 顾客信息模糊查询设计与实现

1) 项目设计分析: 实现name,address,phone联合模糊查询

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

2、 把customer的集合放入request

3、 转发页面index.jsp(不能使用重定向)

4、 index.jsp页面循环遍历显示

2)项目源码实现

1 DAO数据操作

public ListgetForListWithCriteriaCustomer(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集合

//Listsustomers=customerDAO.getAll();获取所有信息列表

Listcustomers=customerDAO.getForListWithCriteriaCustomer(cc);

//2 把customer的集合放入request

request.setAttribute("customers", customers);

//3 转发页面index.jsp(不能使用重定向)

request.getRequestDispatcher("/index.jsp").forward(request,response);

}

3、index页面显示

customers=(List)request.getAttribute("customers");

if(customers!=null && customers.size()>0){

%>

ID

CustomerName

CustomerAddress

CustomerPhone

Update/Delete

3)项目单元测试

@Test

public void getForListWithCriteriaCustomer(){

CriteriaCustomer cc=new CriteriaCustomer("Tom", null, null);

Listcustomers=customerDAO.getForListWithCriteriaCustomer(cc);

System.out.println(customers);

}

4)项目运行效果

240cfd23eb070c682a00e81360844a12.png

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.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、 视图页面显示源码

");

out.print(mes);

out.print("

");

out.print("

");

}

%>

添加一条新的customer信息

CustomerName:

"/>

CustomerAddress:

"/>

CustomerPhone:

"/>

3)项目单元测试

@Test

public void testSaveCustomer() {

Customer customer=new Customer("Baijing","Shanghai","134-2345-9086");

customerDAO.save(customer);

}

4)项目运行效果

2ea7afe8614b2301ffb2696b95cf6364.png

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、视图显示操作源码

");

out.print(mes);

out.print("

");

out.print("

");

}

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");

}

%>

更新一条新的customer信息

CustomerName:

CustomerAddress:

CustomerPhone:

3)项目单元测试

@Test

public void testSaveCustomer() {

Customer customer=new Customer("Baijing","Shanghai","134-2345-9086");

customerDAO.save(customer);

}

4)项目运行效果

0d23c40bb344ee2ca2ae0a7e3dafe98b.png

4c9aa8ae94290c12dcab12e1aad2c1d4.png

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、页面显示源码:

3)项目单元测试

@Test

public void testDelete() {

customerDAO.delete(2);

}

4)项目运行效果

15840d3f2e68d731a3e241825bb426d0.png

7 面向接口开发的数据源配置

倘若需要操作其他数据库或者xml数据源进行存储,该如何操作呢?下面以jdbc和xml进行设计

1 、不修改DAO底层代码前提下,创建工厂模式,利用tyep类型进行选择实例创建连接模式,

//单例工厂

public class CustomerDAOFactory {

private Mapdaos=new HashMap();

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在项目启动时即运行

CustomerServlet

com.cuit.mvc.servlet.CustomerServlet

InitServlet

com.cuit.mvc.servlet.InitServlet

1

五、顾客管理项目完整源码

本项目完整源码:(点击下载  访问密码 16cf)

六、顾客管理项目技术总结

1 Tomcat目录结构图

b51916ead3bfe53ce543e0bad24a2250.png

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

476122b97913c8bda8272dd458578434.png

3 web程序结构图

6838d66290b92934fccb9d12691f4630.png

4 Servlet简介

35d61141cb0f0e33845730cc37842994.png

5 servlet运行交互图

16a7190a87d9adafc6d3df2065fb24e3.png

23242accb5192b41c76b9c124a0142a4.png

6 servlet运行原理

9ab6fe353f235e7a3a47735fd535709a.png

7 jsp运行原理

17b684b6cebe7571f64bfbf6db5b173d.png

8 jsp的9大隐含对象

d2de9369d716ec0a6b53d5d5b8df2e88.png

fef343d7f3fc5132ff91a7701b5af101.png

9 jsp注释与声明

c385ba67a9eaf9074880d398a65b6fff.png

ca693909418312186cb7eb2e12325ae4.png

10 jsp和属性相关的方法

52f32807c2b5844cdc0add63d97cfaf3.png

11 页面请求重定向与请求转发

c406e12d0bd18859c0854ce02d034ec8.png

f2a5172e0f1eebbb6900a0883ef21f46.png

12 page指令

f958813ca60df373b96589bbd349c13a.png

12 errorPage和isErrorPage

c4522a6ce73247f62446a042d08b229b.png

13 关于中文乱码的解决方案

de82a80db10d3b5853ad3c57646acddc.png

14 MVC简介

eaea091e4d32680432b79ec299f1325f.png

15 MVC原理图

70d4c62fddd6d29d39bf62ca8be420de.png

16 多页面向单个servlet发送请求控制:方法1

c9683e0c3cc1a0c13e87617a61621249.png

17 多页面向单个servlet发送请求控制:方法2

32d996583cc7a8c0c77f8751dd0744c4.png

6f76cfa41174be8ef970a41f6b9a9941.png

18 更新操作原理示意图

bed4f780489013ad18dee69caf7e20d5.png

19 查询设计思路

1c91e47331f584b0fc8a23e62d53920d.png

2d0b9e9eeab039958204e96d086a6085.png

5f6fbbe5f04118236fbf67f750d1a1a2.png

b3b51b45c1156818d80dbb0ac0352eb8.png

20 MVC案例需求设计

2e32e82800843fd84fb16021ac769ce1.png

21 jsp页面请求遍历数据

c6b3e5369fecd43688dd33e83fe8ede2.png

22 修改更新设计思路

3c86222fcee8b62988011c49f44c0e89.png

23 面向接口编程

015a41a18b876e1c975eaa124081615a.png

9a6fd078b71343617dcfa92b251592ef.png

24 表单请求和回显图示

783a8ec1a154e450a59b7536f06ffe3a.png

599833f49a099b2681e0c18175f4a486.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值