热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

javamvc_【JAVA】基于MVC架构Java技术荟萃案例演练

2016年6月9日22:47:08阅读前瞻:本文源于对javaweb相关技术和资料汇总,涉及大量javaweb基础技术诸如:Servlet

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下

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

root

root

com.mysql.jdbc.Driver

jdbc:mysql:///test

5

10

10

50

20

5

View Code

2、 数据层配置

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

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.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实体类的封装

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.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源码:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.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&#61;JdbcUtils.getConnection();return queryRunner.query(connection,sql,new BeanListHandler<>(clazz),args);

}catch(Exception e){

e.printStackTrace();

}finally{

JdbcUtils.releaseConnection(connection);

}return null;

}/**

* 返回对应T的一个实体类对象

* &#64;param sql&#xff1a;SQL语句

* &#64;param args&#xff1a;填充SQL语句的占位符

* &#64;return*/

public T get(String sql,Object ... args){

Connection connection&#61;null;try{

connection&#61;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操作

* &#64;param sql&#xff1a;SQL语句

* &#64;param args&#xff1a;填充SQL语句的占位符*/

public voidupdate(String sql,Object ... args){

Connection connection&#61;null;try{

connection&#61;JdbcUtils.getConnection();

queryRunner.update(connection,sql,args);

}catch(Exception e){

e.printStackTrace();

}finally{

JdbcUtils.releaseConnection(connection);

}

}

}

View Code

CustomerDAO源码&#xff1a;

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.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 List getAll();//获取Customer列表信息

public void save(Customer customer);//对Customer的添加,通过CTRL&#43;T转到定义

public void update(Customer customer);//对Customer的更新,通过CTRL&#43;T转到定义

public Customer get(int id);//获取Customer实体

public void delete(int id);//根据id进行删除

public long getCountWithName(String name);//返回name相等的记录数//cc封装了查询条件&#xff0c;返回查询条件的list

public ListgetForListWithCriteriaCustomer(CriteriaCustomer cc);

}

View Code

com.cuit.mvc.dao.impl包&#xff1a;CustomerDAOJdbcImpl.java&#xff1a;Customer对CustomerDAO具体方法的实现

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.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&#61;"select * from customers where name like ? and address like ?"

&#43; "and phone like ?";//修改了CriteriaCustomer的getter方法:使其返回字符串中有%%//若返回值为null返回%%&#xff0c;若不返回null则返回&#xff1a;"%"&#43;字段本身的值&#43;"%"//如上效果如&#xff1a;cc.getName()&#61;&#61;null&#xff1f;%%:%&#43;name&#43;%

System.out.println(sql);returngetForList(sql,cc.getName(),cc.getAddress(),cc.getPhone());

}

&#64;Overridepublic ListgetAll() {

String sql&#61;"select * from customers";returngetForList(sql);

}

&#64;Overridepublic voidsave(Customer customer) {

String sql&#61;"insert customers(name,address,phone) values(?,?,?)";

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

}

&#64;Overridepublic Customer get(intid) {

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

}

&#64;Overridepublic void delete(intid) {

String sql&#61;"delete from customers where id&#61;?";

update(sql, id);

}

&#64;Overridepublic longgetCountWithName(String name) {

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

}

&#64;Overridepublic voidupdate(Customer customer) {

String sql&#61;"update customers set name&#61;?,address&#61;?,phone&#61;? where id&#61;?";

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

}

}

View Code

3 业务逻辑层

com.cuit.mvc.dao.servlet包&#xff1a;CustomerServlet.java对CustomerDAO公共方法具体实现&#xff0c;以及页面显示的控制

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.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&#61;new CustomerDAOJdbcImpl();//private CustomerDAO customerDAO&#61;new CustomerDAOXMLImpl();

private CustomerDAO customerDAO&#61;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&#61;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;

}

}*/&#64;Overrideprotected voiddoPost(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {//1 获取servlet路径 诸如&#xff1a;/add.do

String servletPath&#61;req.getServletPath().substring(1);//去除/和.do得到类似于add这样字符串

String methodName&#61;servletPath.substring(0,servletPath.length()-3);//System.out.println(methodName);

try{//利用反射获取获取methodName对应的方法

Method method &#61; 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&#61;"/error.jsp";//1 获取请求参数id

String idstr&#61;request.getParameter("id");//2 调用CustomeDAO的customerDAO.get(id)获取和id对应的Customer对象customer

try{

Customer customer&#61;customerDAO.get(Integer.parseInt(idstr));if(customer!&#61;null){

forwordPath&#61;"/updatecustomer.jsp";//3 将customer放在request中

request.setAttribute("customer", customer);

}

}catch(Exception e){}//4 响应updatecustomer.jsp页面&#xff1a;转发

request.getRequestDispatcher(forwordPath).forward(request, response);

}private voidupdate(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{//1 获取请求参数:id,name,address,phone,oldname

String id&#61;request.getParameter("id");

String name&#61;request.getParameter("name");

String oldname&#61;request.getParameter("oldname");

String address&#61;request.getParameter("address");

String phone&#61;request.getParameter("phone");//2 检验name是否被占用//2.1 比较name和oldname是否相同&#xff0c;若相同name可用&#xff0c;oldname.equals(name)不如equalsIgnoreCase&#xff0c;数据库默认大小写一致的&#xff0c;而equals忽略大小写

if(!oldname.equalsIgnoreCase(name)){//不相同&#xff0c;调用CustomerDAO的getCountWithName(String name)获取name在数据库中是否存在

long count&#61;customerDAO.getCountWithName(name);//大于0&#xff0c; 响应updatecustomer.jsp页面&#xff1a;通过转发响应newcustomer.jsp

if(count>0){//通过request.getAttribute("message")显示信息&#xff0c;在页面上request.getAttribute("message")的方式显示//表单据回显。address,phone显示提交的新值&#xff0c; name显示oldname&#xff0c;而不是新值

request.setAttribute("message", "用户名["&#43;name&#43;"]已经被占用&#xff0c;请重新填写&#xff01;");//方法结束

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

}

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

Customer customer&#61;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&#61;request.getParameter("name");

String address&#61;request.getParameter("address");

String phone&#61;request.getParameter("phone");

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

List customers&#61;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&#61;request.getParameter("id").trim();int id&#61;0;try{

id&#61;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 获取表单参数&#xff1a;name&#xff0c;address&#xff0c;phone

String name&#61;request.getParameter("name");

String address&#61;request.getParameter("address");

String phone&#61;request.getParameter("phone");//2 检验name是否被占用//2.1 调用CustomerDAO的getCountWithName(String name)获取name在数据库中是否存在

long count&#61;customerDAO.getCountWithName(name);if(count>0){//2.2 若返回值大于0&#xff0c;则相应newcustomer.jsp页面&#xff1a;①在此页面显示一个错误信息②此表单值可以回显//通过request.getAttribute("message")显示信息//通过value&#61;""回显

request.setAttribute("message", "用户名["&#43;name&#43;"]已经被占用&#xff0c;请重新填写&#xff01;");

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

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

Customer customer&#61;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包&#xff1a;JdbcUtilsTest.java对CustomerServlet.java各个方法单元测试

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.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&#61;newCustomerDAOJdbcImpl();

&#64;Testpublic voidgetForListWithCriteriaCustomer(){

CriteriaCustomer cc&#61;new CriteriaCustomer("Tom", null, null);

List customers&#61;customerDAO.getForListWithCriteriaCustomer(cc);

System.out.println(customers);

}

&#64;Testpublic voidtestGetAll() {

List customers&#61;customerDAO.getAll();

System.out.println(customers);

}

&#64;Testpublic voidtestSaveCustomer() {

Customer customer&#61;new Customer("Baijing","Shanghai","134-2345-9086");

customerDAO.save(customer);

}

&#64;Testpublic voidtestGetInt() {

Customer cust&#61;customerDAO.get(0);

System.out.println(cust);

}

&#64;Testpublic voidtestDelete() {

customerDAO.delete(2);

}

&#64;Testpublic voidtestGetCountWithName() {long count&#61;customerDAO.getCountWithName("Tom");

System.out.println(count);

}

}

View Code

5 视图显示页面层

index.jsp&#xff1a;显示顾客信息&#xff0c;并支持回显

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

String basePath&#61; request.getScheme()&#43;"://"&#43;request.getServerName()&#43;":"&#43;request.getServerPort()&#43;path&#43;"/";%>

My JSP &#39;index.jsp&#39; starting page

$(&#39;.delete&#39;).click(function(){var content&#61;$(this).parent().parent().find("td:eq(1)").text();var flag&#61;confirm("确定要删除此"&#43;content&#43;"信息&#xff1f;");returnflag;

});

});

CustomerName:
CustomerAddress:
CustomerPhone:
Create New Customer

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


IDCustomerNameCustomerAddressCustomerPhoneUpdate/Delete

for(Customer customer:customers){%>

Update

Delete

View Code

error.jsp&#xff1a;异常或者报错页面跳转

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

String basePath&#61; request.getScheme()&#43;"://"&#43;request.getServerName()&#43;":"&#43;request.getServerPort()&#43;path&#43;"/";%>

My JSP &#39;error.jsp&#39; starting page

对不起没有您请求的页面

error.jpg

对不起访问失败&#xff01;

View Code

newcustomer.jsp&#xff1a;添加顾客信息页面&#xff0c;支持回显&#xff0c;控制name不能重复

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

Insert title here

");out.print(mes);out.print("
");out.print("
");

}%>

添加一条新的customer信息
CustomerName:"/>
CustomerAddress:"/>
CustomerPhone:"/>

View Code

success.jsp&#xff1a;添加新信息成功跳转页面

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

Insert title here

成功添加&#xff0c;保存成功&#xff01;

Back Index

View Code

updatecustomer.jsp&#xff1a;更新信息页面&#xff0c;支持回显&#xff0c;回显显示的是name旧值

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

Insert title here

");out.print(mes);out.print("
");out.print("
");

}

String id&#61;null;

String name&#61;null;

String oldname&#61;null;

String address&#61;null;

String phone&#61;null;

Customer customer&#61;(Customer)request.getAttribute("customer");if(customer!&#61;null){

id&#61;customer.getId()&#43;"";

address&#61;customer.getAddress();

name&#61;customer.getName();

oldname&#61;customer.getName();

phone&#61;customer.getPhone();

}else{

id&#61;request.getParameter("id");

name&#61;request.getParameter("oldname");

oldname&#61;request.getParameter("oldname");

address&#61;request.getParameter("address");

phone&#61;request.getParameter("phone");

}%>

更新一条新的customer信息
CustomerName:
CustomerAddress:
CustomerPhone:

View Code

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

1) 项目设计分析&#xff1a; 实现name&#xff0c;address&#xff0c;phone联合模糊查询

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

2、 把customer的集合放入request

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

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

2)项目源码实现

1 DAO数据操作

public List getForListWithCriteriaCustomer(CriteriaCustomer cc) {

String sql&#61;"select * from customers where name like ? and address like ? "

&#43; "and phone like ?";

//修改了CriteriaCustomer的getter方法:使其返回字符串中有%%

//若返回值为null返回%%&#xff0c;若不返回null则返回&#xff1a;"%"&#43;字段本身的值&#43;"%"

//如上效果如&#xff1a;cc.getName()&#61;&#61;null&#xff1f;%%:%&#43;name&#43;%

System.out.println(sql);

return getForList(sql,cc.getName(),cc.getAddress(),cc.getPhone());

}

2、servlet控制源码&#xff1a;

//模糊查询

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

String name&#61;request.getParameter("name");

String address&#61;request.getParameter("address");

String phone&#61;request.getParameter("phone");

CriteriaCustomer cc&#61;new CriteriaCustomer(name,address,phone);

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

//List sustomers&#61;customerDAO.getAll();获取所有信息列表

List customers&#61;customerDAO.getForListWithCriteriaCustomer(cc);

//2 把customer的集合放入request

request.setAttribute("customers", customers);

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

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

}

3、index页面显示

List customers&#61;(List)request.getAttribute("customers");

if(customers!&#61;null && customers.size()>0){

%>


IDCustomerNameCustomerAddressCustomerPhoneUpdate/Delete

for(Customer customer:customers){

%>

Update

Delete

}

%>

}

%>

3)项目单元测试

&#64;Test

public void getForListWithCriteriaCustomer(){

CriteriaCustomer cc&#61;new CriteriaCustomer("Tom", null, null);

List customers&#61;customerDAO.getForListWithCriteriaCustomer(cc);

System.out.println(customers);

}

4)项目运行效果

982e1c0e30bf74fbc37bfb9a6d4f45d2.png

4 顾客信息添加设计与实现

1) 项目设计分析&#xff1a;name唯一&#xff0c;新添加信息需要验证错误提示

1、获取表单参数&#xff1a;name、address、phone

2、检验name是否被占用

3、若验证通过&#xff0c;把表单参数封装为一个Customer对象customer

4、调用CustomerDAO的save(Customer customer)执行保存操作

5、重定向到success.jsp页面

2)项目源码实现

1、DAO操作源码

&#64;Override

public void save(Customer customer) {

String sql&#61;"insert customers(name,address,phone) values(?,?,?)";

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

}

2、servlet操作源码

//1 获取表单参数&#xff1a;name&#xff0c;address&#xff0c;phone

String name&#61;request.getParameter("name");

String address&#61;request.getParameter("address");

String phone&#61;request.getParameter("phone");

//2 检验name是否被占用

//2.1 调用CustomerDAO的getCountWithName(String name)获取name在数据库中是否存在

long count&#61;customerDAO.getCountWithName(name);

if(count>0){

//2.2 若返回值大于0&#xff0c;则相应newcustomer.jsp页面&#xff1a;①在此页面显示一个错误信息②此表单值可以回显

// 通过request.getAttribute("message")显示信息

// 通过value&#61;""回显

request.setAttribute("message", "用户名["&#43;name&#43;"]已经被占用&#xff0c;请重新填写&#xff01;");

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

return;

}

//3 若验证通过&#xff0c;把表单参数封装为一个Customer对象customer

Customer customer&#61;new Customer(name,address,phone);

//4 调用CustomerDAO的save(Customer customer)执行保存操作

customerDAO.save(customer);

//5 重定向到success.jsp页面

response.sendRedirect("success.jsp");

3、 视图页面显示源码

Object mes&#61;request.getAttribute("message");

if(mes!&#61;null){

out.print("
");

out.print(mes);

out.print("
");

out.print("
");

}

%>

添加一条新的customer信息
CustomerName:

value&#61;""/>

CustomerAddress:

value&#61;""/>

CustomerPhone:

value&#61;""/>

3)项目单元测试

&#64;Test

public void testSaveCustomer() {

Customer customer&#61;new Customer("Baijing","Shanghai","134-2345-9086");

customerDAO.save(customer);

}

4)项目运行效果

4c2afd7632df01f5ef0f20730a33726b.png

5 顾客信息更新设计与实现

1) 项目设计分析

1、 编辑操作&#xff1a;①获取请求参数id&#xff1b;②调用CustomeDAO的customerDAO.get(id)获取和id对应的Customer对象customer&#xff1b;③若验证通过&#xff0c;把表单参数封装为一个Customer对象customer&#xff1b;④ 调用CustomerDAO的update(Customer customer)执行更新操作&#xff1b;⑤重定向到query.do

2、更新操作&#xff1a;①获取请求参数:id,name,address,phone,oldname&#xff1b;②检验name是否被占用&#xff1b;③若验证通过&#xff0c;把表单参数封装为一个Customer对象customer&#xff1b;④调用CustomerDAO的update(Customer customer)执行更新操作&#xff1b;⑤重定向到query.do&#xff1b;

2)项目源码实现

1、DAO操作源码&#xff1a;

&#64;Override

public void save(Customer customer) {

String sql&#61;"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&#61;"/error.jsp";

//1 获取请求参数id

String idstr&#61;request.getParameter("id");

//2 调用CustomeDAO的customerDAO.get(id)获取和id对应的Customer对象customer

try{

Customer customer&#61;customerDAO.get(Integer.parseInt(idstr));

if(customer!&#61;null){

forwordPath&#61;"/updatecustomer.jsp";

//3 将customer放在request中

request.setAttribute("customer", customer);

}

}catch(Exception e){}

//4 响应updatecustomer.jsp页面&#xff1a;转发

request.getRequestDispatcher(forwordPath).forward(request, response);

}

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

//1 获取请求参数:id,name,address,phone,oldname

String id&#61;request.getParameter("id");

String name&#61;request.getParameter("name");

String oldname&#61;request.getParameter("oldname");

String address&#61;request.getParameter("address");

String phone&#61;request.getParameter("phone");

//2 检验name是否被占用

//2.1 比较name和oldname是否相同&#xff0c;若相同name可用&#xff0c;oldname.equals(name)不如equalsIgnoreCase&#xff0c;数据库默认大小写一致的&#xff0c;而equals忽略大小写

if(!oldname.equalsIgnoreCase(name)){

//不相同&#xff0c;调用CustomerDAO的getCountWithName(String name)获取name在数据库中是否存在

long count&#61;customerDAO.getCountWithName(name);

//大于0&#xff0c; 响应updatecustomer.jsp页面&#xff1a;通过转发响应newcustomer.jsp

if(count>0){

// 通过request.getAttribute("message")显示信息&#xff0c;在页面上request.getAttribute("message")的方式显示

// 表单据回显。address,phone显示提交的新值&#xff0c; name显示oldname&#xff0c;而不是新值

request.setAttribute("message", "用户名["&#43;name&#43;"]已经被占用&#xff0c;请重新填写&#xff01;");

// 方法结束

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

return;

}

}

//3 若验证通过&#xff0c;把表单参数封装为一个Customer对象customer

Customer customer&#61;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、视图显示操作源码

Object mes&#61;request.getAttribute("message");

if(mes!&#61;null){

out.print("
");

out.print(mes);

out.print("
");

out.print("
");

}

String id&#61;null;

String name&#61;null;

String oldname&#61;null;

String address&#61;null;

String phone&#61;null;

Customer customer&#61;(Customer)request.getAttribute("customer");

if(customer!&#61;null){

id&#61;customer.getId()&#43;"";

address&#61;customer.getAddress();

name&#61;customer.getName();

oldname&#61;customer.getName();

phone&#61;customer.getPhone();

}else{

id&#61;request.getParameter("id");

name&#61;request.getParameter("oldname");

oldname&#61;request.getParameter("oldname");

address&#61;request.getParameter("address");

phone&#61;request.getParameter("phone");

}

%>

更新一条新的customer信息
CustomerName:
CustomerAddress:
CustomerPhone:

3)项目单元测试

&#64;Test

public void testSaveCustomer() {

Customer customer&#61;new Customer("Baijing","Shanghai","134-2345-9086");

customerDAO.save(customer);

}

4)项目运行效果

7d3d98e4b6a57191fae4b5cc194acaa8.png

06ccd1db11123364510aaa9e8a5d6746.png

6 顾客信息删除设计与实现

1) 项目设计分析

1、获取id的值

2、调用DAO的删除方法

3、执行提示是否删除

4、删除成功跳转刷新

2)项目源码实现

1、DAO源码&#xff1a;

&#64;Override

public void delete(int id) {

String sql&#61;"delete from customers where id&#61;?";

update(sql, id);

}

2、servlet源码&#xff1a;

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

String idstr&#61;request.getParameter("id").trim();

int id&#61;0;

try{

id&#61;Integer.parseInt(idstr);

customerDAO.delete(id);

}catch(Exception e){}

response.sendRedirect("query.do");

}

3、页面显示源码&#xff1a;

$(function(){

$(&#39;.delete&#39;).click(function(){

var content&#61;$(this).parent().parent().find("td:eq(1)").text();

var flag&#61;confirm("确定要删除此"&#43;content&#43;"信息&#xff1f;");

return flag;

});

});

Update

Delete

3)项目单元测试

&#64;Test

public void testDelete() {

customerDAO.delete(2);

}

4)项目运行效果

0722d9e43e5f4ddaa90d7ef421922498.png

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

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

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

//单例工厂

public class CustomerDAOFactory {

private Map daos&#61;new HashMap();

private static CustomerDAOFactory instance&#61;new CustomerDAOFactory();

public static CustomerDAOFactory getInstance(){

return instance;

}

private String type&#61;null;

public void setType(String type) {

this.type&#61;type;

}

private CustomerDAOFactory() {

daos.put("jdbc", new CustomerDAOJdbcImpl());

daos.put("xml", new CustomerDAOXMLImpl());

}

public CustomerDAO getCustomerDAO(){

return daos.get(type);

}

}

2、type值放在switch.properties用于切换&#xff0c;如下是该文件的内容

#type&#61;xml

type&#61;jdbc

3、初始化servlet&#xff0c;创建InitServlet.java文件&#xff0c;并控制type值传递CustomerDAOFactory工厂用来切换数据源

public class InitServlet extends HttpServlet {

&#64;Override

public void init() throws ServletException {

CustomerDAOFactory.getInstance().setType("jdbc");

//读取类路径switch.properties文件

InputStream in&#61;getServletContext().getResourceAsStream("/WEB-INF/classes/switch.properties");

Properties properties&#61;new Properties();

try {

properties.load(in);

//获取switch.properties的type值

String type&#61;properties.getProperty("type");

//赋给了CustomerDAOFactory的type属性

CustomerDAOFactory.getInstance().setType(type);

} catch (Exception e) {

e.printStackTrace();

}

}

}

4、配置web.xml文件&#xff0c;使InitServlet.java在项目启动时即运行

CustomerServlet

com.cuit.mvc.servlet.CustomerServlet

InitServlet

com.cuit.mvc.servlet.InitServlet

1

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

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

1 Tomcat目录结构图

9422ee585f35c9137db1ea4f5a4f33a5.png

2 Tomcat配置&#xff0c;MyEclipse2015默认集成了&#xff0c;不需要配置

45dd99292f6c329ec2feacb37858e895.png

3 web程序结构图

5f6e6396181c360e5d6a5bcaaac0de88.png

4 Servlet简介

2a32d8003e05c3977119d67a2813edad.png

5 servlet运行交互图

5af964a1d674fb28de934081c20533e9.png

fa051f4852a9188220e010b1455a99ea.png

6 servlet运行原理

b589769195b39ec9a1f5e66d14afae08.png

7 jsp运行原理

04b19b6fe4da94b4eac49d3d612c6ab1.png

8 jsp的9大隐含对象

cfd7420ca355ddd4d2e0e454ae10cc1a.png

bc36972c54a5e06a9010e9ab68fff966.png

9 jsp注释与声明

e51a7a00d37a7ec53504165eb871d4da.png

05f94e25c93d5a7583cf9f42917386d1.png

10 jsp和属性相关的方法

93b765c10e56e6aea50a0b930598bc9f.png

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

76facdc238d19a4c54f36508fb0b15a6.png

48837dd41a9f371ebc3357680cf06926.png

fc9235d194dda9332d9839438214ac4f.png

219a4ce0808f467cedb95842653b3fcb.png

12 page指令

7d5fbe5c19dd1bfe247a5e4e0a27b016.png

12 errorPage和isErrorPage

c6e5679cb2e7f90c70c96517cd24ca59.png

e8caca4c9e71c467978ed39bdb118f38.png

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

1aa70ea2a60f3a81423207d4c0ba1533.png

14 MVC简介

4aa75a68ff8915cccc1a8384334d03f0.png

15 MVC原理图

e971adfe194ab2ee271fd4edf1f685fd.png

16 多页面向单个servlet发送请求控制&#xff1a;方法1

6c6ec91378e6dcbe4a450b37b29df59e.png

17 多页面向单个servlet发送请求控制&#xff1a;方法2

908a41e5a8f6ac428501757e80ccf001.png

94cf6f68a4dacc41eb64698a1a297cb7.png

18 更新操作原理示意图

17d7c65844309b2ff6dd03e582081237.png

19 查询设计思路

6e399354f1374cfbcfb5e8ab68b589f8.png

27d14db33bd20bd7f70fe73125226c82.png

9202d846e24831b6f48f4c5d539dbdae.png

31267876feda3f51ea98b6517f3d2265.png

20 MVC案例需求设计

a5c92483cb36982c18ac71486c45131d.png

21 jsp页面请求遍历数据

0e6f4e9491e50395ae82b23d93bdeaa8.png

22 修改更新设计思路

147ed70e3e5e98fc523796c00aca48a9.png

23 面向接口编程

c9da22d4480f3776758b9e54ed25d44a.png

3b3b7cf1af485c897f8d52bd5bcec356.png

24 表单请求和回显图示

a4e07b2c41e46f24ff57c223dff60a69.png

da69f6b36e12d7af5e923c49065d155f.png



推荐阅读
  • 开发笔记:spring boot项目打成war包部署到服务器的步骤与注意事项
    本文介绍了将spring boot项目打成war包并部署到服务器的步骤与注意事项。通过本文的学习,读者可以了解到如何将spring boot项目打包成war包,并成功地部署到服务器上。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 如何实现JDK版本的切换功能,解决开发环境冲突问题
    本文介绍了在开发过程中遇到JDK版本冲突的情况,以及如何通过修改环境变量实现JDK版本的切换功能,解决开发环境冲突的问题。通过合理的切换环境,可以更好地进行项目开发。同时,提醒读者注意不仅限于1.7和1.8版本的转换,还要适应不同项目和个人开发习惯的需求。 ... [详细]
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 集成电路企业在进行跨隔离网数据交换时面临着安全性问题,传统的数据交换方式存在安全性堪忧、效率低下等问题。本文以《Ftrans跨网文件安全交换系统》为例,介绍了如何通过丰富的审批流程来满足企业的合规要求,保障数据交换的安全性。 ... [详细]
  • 阿里云虚拟主机安装多个织梦系统的方法
    本文介绍了在阿里云虚拟主机上安装多个织梦系统的方法。通过创建不同名称的文件夹并将不同的域名解析到对应的目录,可以实现多个系统的安装。在安装过程中需要注意修改数据库前缀,并在系统设置中还原数据库。同时还介绍了阿里云虚拟主机二级域名绑定二级目录和域名重定向的用法。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
author-avatar
清晨竹林9_877
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有