java mvc 案例_JavaWeb(五):MVC案例

MVC是Model-View-Controller的简称,即模型-视图-控制器。

MVC是一种设计模式,它把应用程序分成三个核心模块:模型、视图、控制器,它们各自处理自己的任务。模型是应用程序的主体部分,模型表示业务数据和业务逻辑。一个模型能为多个视图提供数据。由于应用于模型的代码只需写一次就可以被多个视图重用,所以提高了代码的可重用性。视图是用户看到并与之交互的界面,作用如下:视图向用户显示相关的数据,接受用户的输入,不进行任何实际的业务处理。控制器接受用户的输入并调用模型和视图去完成用户的需求。控制器接收请求并决定调用哪个模型组件去处理请求,然后决定调用哪个视图来显示模型处理返回的数据。

3b0cdf312087ba6d5145ad07f07354e3.png

把逻辑部分、访问数据库的部分放在Servlet,显示部分放在JSP页面。

发请求到服务器,服务器调用Servlet,Servlet做一个控制器,根据请求的情况取去调用Java类,Java类完成业务逻辑和访问数据库的操作,根据POJO的返回结果转向JSP,JSP进行显示,显示的时候可以使用一些标准标签库。

POJO里包含处理逻辑、业务逻辑,并去访问数据库。

Servlet根据不同的返回结果转向不同的JSP页面,转向的方式包括重定向和转发。

model:

e6d7c5995db6d150e01d28d4ca794b7b.png

controller:Servlet

view:JSP

一、查询和删除

1.1 查询

需求

点击超链接后在页面显示所有学生考试信息

数据库

字段

flowId

type

idCard

examCard

studentName

location

grade

数据表截图

7a60218f8bd956d40d9a90f089d1e008.png

Bean

public classStudent {privateInteger flowId;private inttype;privateString idCard;privateString examCard;privateString studentName;privateString location;private intgrade;publicInteger getFlowId() {returnflowId;

}public voidsetFlowId(Integer flowId) {this.flowId =flowId;

}public intgetType() {returntype;

}public void setType(inttype) {this.type =type;

}publicString getIdCard() {returnidCard;

}public voidsetIdCard(String idCard) {this.idCard =idCard;

}publicString getExamCard() {returnexamCard;

}public voidsetExamCard(String examCard) {this.examCard =examCard;

}publicString getStudentName() {returnstudentName;

}public voidsetStudentName(String studentName) {this.studentName =studentName;

}publicString getLocation() {returnlocation;

}public voidsetLocation(String location) {this.location =location;

}public intgetGrade() {returngrade;

}public void setGrade(intgrade) {this.grade =grade;

}public Student(Integer flowId, int type, String idCard, String examCard, String studentName, String location, intgrade) {this.flowId =flowId;this.type =type;this.idCard =idCard;this.examCard =examCard;this.studentName =studentName;this.location =location;this.grade =grade;

}//反射需要一个无参的构造器

publicStudent(){

}

}

流程

3ecaecd7578aa1897051b0d941a95411.png

页面

超链接的页面 c.jsp

Title

List All Student

c.jsp截图

2789eb4a7705d8e8414ca25854e48933.png

转发的页面 students.jsp

User: JieZhao

Date:2019/8/13Time:13:38To changethis template use File | Settings |File Templates.--%>

Title

stus = (List)request.getAttribute("students");%>

FlowIdTypeIdCardExamCardStudentNameLocationGrade

for(Student student: stus){%>

代码

Dao

public classStudentDao {public ListgetAll(){

List students = new ArrayList<>();

Connection connection= null;

PreparedStatement preparedStatement= null;

ResultSet resultSet= null;try{

String driverClass= "com.mysql.jdbc.Driver";

String url= "jdbc:mysql:///aidata";

String user= "root";

String passward= "root";

Class.forName(driverClass);

connection=DriverManager.getConnection(url, user, passward);

String sql= "SELECT flow_id, type, id_card, exam_card, sutdent_name, Location, Grade FROM examstudent";

preparedStatement=connection.prepareStatement(sql);

resultSet=preparedStatement.executeQuery();while(resultSet.next()){int flowId = resultSet.getInt(1);int type = resultSet.getInt(2);

String idCard= resultSet.getString(3);

String examCard= resultSet.getString(4);

String studentName= resultSet.getString(5);

String location= resultSet.getString(6);int grade = resultSet.getInt(7);

Student student= newStudent(flowId, type, idCard, examCard, studentName, location, grade);

students.add(student);

}

}catch(Exception e){

e.printStackTrace();

}finally{try{if(resultSet != null){

resultSet.close();

}

}catch(SQLException e){

e.printStackTrace();

}try{if(preparedStatement != null){

preparedStatement.close();

}

}catch(SQLException e){

e.printStackTrace();

}try{if(connection != null){

connection.close();

}

}catch(SQLException e){

e.printStackTrace();

}

}returnstudents;

}

}

Servlet

public class ListAllStudentsServlet extendsHttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throwsIOException, ServletException {

StudentDao studentDao= newStudentDao();

List students =studentDao.getAll();

request.setAttribute("students", students); //结果添加到students属性里,存到request里

request.getRequestDispatcher("/students.jsp").forward(request, response);//将request转发到students.jsp页面

}

}

配置web.xml

listAllStudent

com.aidata.mvc.ListAllStudentsServlet

listAllStudent

/listAllStudent

1.2 删除

students.jsp里添加删除按钮

Dao里添加删除方法

public voiddeleteByFlowId(Integer flowId){

List students = new ArrayList<>();

Connection connection= null;

PreparedStatement preparedStatement= null;try{

String driverClass= "com.mysql.jdbc.Driver";

String url= "jdbc:mysql:///aidata";

String user= "root";

String password= "root";

Class.forName(driverClass);

connection=DriverManager.getConnection(url, user, password);

String sql= "DELETE FROM examstudent WHERE flow_id = ?";

preparedStatement=connection.prepareStatement(sql);

preparedStatement.setInt(1, flowId);

preparedStatement.executeUpdate();

}catch(Exception e){

e.printStackTrace();

}finally{try{if(preparedStatement != null){

preparedStatement.close();

}

}catch(SQLException e){

e.printStackTrace();

}try{if(connection != null){

connection.close();

}

}catch(SQLException e){

e.printStackTrace();

}

}

}

Servlet添加删除的Servlet

public class DeleteStudentServlet extendsHttpServlet {protected voiddoGet(HttpServletRequest request, HttpServletResponse response)throwsIOException, ServletException {

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

StudentDao studentDao= newStudentDao();

studentDao.deleteByFlowId(Integer.parseInt(flowId));

List students =studentDao.getAll();

request.setAttribute("students", students);

request.getRequestDispatcher("/listAllStudent").forward(request, response); // 重定向到servlet

}

}

配置web.xml

deleteStudent

com.aidata.mvc.DeleteStudentServlet

deleteStudent

/deleteStudent

二、案例

2.1 架构分析

下面开始做一个小案例:利用MVC模式对数据进行增删改查

没有业务层,直接由Servlet调用DAO,所以也没有事务操作,可以在DAO中直接获取Connection对象

采取MVC设计模式

使用到的技术:

MVC设计模式:JSP、Servlet

数据库使用MySQL

连接数据库使用C3P0数据库连接池

JDBC工具采用DBUtils

页面的提示操作采用jQuery

技术难点:

多个请求如何使用一个Servlet

模糊查询

在创建或修改的情况下,验证用户名已经被使用,并给出提示信息

051b48372faccb483adf4eae49f970dd.png

2.2 DAO层

DAO 模式

DAO (DataAccessobjects 数据存取对象)是指位于业务逻辑和持久化数据之间实现对持久化数据的访问。通俗来讲,就是将数据库操作都封装起来。

对外提供相应的接口

在面向对象设计过程中,有一些"套路”用于解决特定问题称为模式。

DAO 模式提供了访问关系型数据库系统所需操作的接口,将数据访问和业务逻辑分离对上层提供面向对象的数据访问接口。

从以上 DAO 模式使用可以看出,DAO 模式的优势就在于它实现了两次隔离。

1、隔离了数据访问代码和业务逻辑代码。业务逻辑代码直接调用DAO方法即可,完全感觉不到数据库表的存在。分工明确,数据访问层代码变化不影响业务逻辑代码,这符合单一职能原则,降低了藕合性,提高了可复用性。

2、隔离了不同数据库实现。采用面向接口编程,如果底层数据库变化,如由 MySQL 变成 Oracle 只要增加 DAO 接口的新实现类即可,原有 MySQ 实现不用修改。这符合 "开-闭" 原则。该原则降低了代码的藕合性,提高了代码扩展性和系统的可移植性。

一个典型的DAO 模式主要由以下几部分组成。

1、DAO接口: 把对数据库的所有操作定义成抽象方法,可以提供多种实现。

2、DAO 实现类: 针对不同数据库给出DAO接口定义方法的具体实现。

3、实体类:用于存放与传输对象数据。

4、数据库连接和关闭工具类: 避免了数据库连接和关闭代码的重复使用,方便修改。

数据库

建立数据表

Create tablecustomers(

idint primary keyauto_increment,

namevarchar(30) not null unique,

addressvarchar(30),

phonevarchar(30)

);

# 为 name 字段添加唯一约束alter table customers add constraint name_uk unique(name);

数据表截图

1a3931fdd92536724ffbe69349b621d7.png

C3P0数据源

使用eclipse

添加c3p0的jar包和mysql驱动的jar包到根目录的lib目录中

添加commons-dbutils-1.3.jar到根目录的lib目录中

添加c3p0的配置文件到src目录

c3p0-config.xml

root

root

com.mysql.jdbc.Driver

jdbc:mysql:///aidata

5

5

5

10

20

5

实体类

Customer.java

packagecom.aidata.mvcapp.domain;public classCustomer {privateInteger id;privateString name;privateString address;privateString phone;publicInteger getId() {returnid;

}public voidsetId(Integer id) {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 + "]";

}

}

数据库连接和关闭工具类

JdbcUtils.java

packagecom.aidata.mvcapp.db;importjava.sql.Connection;importjava.sql.SQLException;importjavax.sql.DataSource;importcom.mchange.v2.c3p0.ComboPooledDataSource;/*** @ClassName JdbcUtils

* @Description JDBC操作的工具类

*@authorJZ

* @Date

*@version1.0.0*/

public classJdbcUtils {/*** @Description 释放连接

*@paramconnection*/

public static voidreleaseConnection(Connection connection) {try{if (connection != null) {

connection.close();

}

}catch(Exception e) {//TODO: handle exception

}

}private static DataSource dataSource = null;//数据源只能创建一次,所以用static

static{

dataSource= new ComboPooledDataSource("mvcapp");

}/*** @Description 返回数据源的一个Connection对象

*@return*@throwsSQLException*/

public static Connection getConnection() throwsSQLException {returndataSource.getConnection();

}

}

DAO接口

CustomerDAO.java

该接口定义了和业务相关的功能,操作customer

packagecom.aidata.mvcapp.dao;importjava.util.List;importcom.aidata.mvcapp.domain.Customer;public interfaceCustomerDAO {public ListgetAll();public voidsave(Customer customer);publicCustomer get(Integer id);public voiddelete(Integer id);/***

* @Description 返回和name相等的记录数

*@paramname

*@return

*/

public longgetCountWithName(String name);

}

DAO 实现类

DAO.java

该类不和业务相关,即和customer不相关,而是关注增删改查的功能

增删改都是update,查

packagecom.aidata.mvcapp.dao;importjava.lang.reflect.ParameterizedType;importjava.lang.reflect.Type;importjava.sql.Connection;importjava.util.List;importorg.apache.commons.dbutils.QueryRunner;importorg.apache.commons.dbutils.handlers.BeanHandler;importorg.apache.commons.dbutils.handlers.BeanListHandler;importorg.apache.commons.dbutils.handlers.ScalarHandler;importcom.aidata.mvcapp.db.JdbcUtils;/*** @ClassName DAO

* @Description 封装了CRUD的方法,以供子类继承使用 当前DAO没有事务,直接在方法中获取数据库连接 整个DAO采取DBUtils解决方案

*@authorJZ

* @Date

*@version1.0.0

*@param

* 所处理的实体类的类型*/

public class DAO{private QueryRunner queryRunner = newQueryRunner();private Classclazz;publicDAO() {

Type superClass=getClass().getGenericSuperclass();if (superClass instanceofParameterizedType) {

ParameterizedType parameterizedType=(ParameterizedType) superClass;

Type[] typeArgs=parameterizedType.getActualTypeArguments();if (typeArgs != null && typeArgs.length > 0) {

clazz= (Class) typeArgs[0];

}

}

}/*** @Description 返回某一个字段的值,例如某一天记录的customerName或 返回数据表中由多少条记录等

*@paramsql

*@paramargs

*@return

*/

public E getForValue(String sql, Object... args) {

Connection connection= null;try{

connection=JdbcUtils.getConnection();return (E) queryRunner.query(connection, sql, newScalarHandler(), args);

}catch(Exception e) {

e.printStackTrace();

}finally{

JdbcUtils.releaseConnection(connection);

}return null;

}/*** @Description 返回 T 所对应的List

*@paramsql

*@paramargs

*@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;

}/*** @Description 返回对应T的一个实例类对象

*@paramsql

*@paramargs

*@return

*/

publicT 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;

}/*** @Description 封装了INSERT、DELETE、UPDATE操作

*@paramsql

* SQL语句

*@paramargs

* 填充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);

}

}

}

CustomerDAOJdbcImpl.java

将业务和功能结合起来,实现了业务操作

packagecom.aidata.mvcapp.dao.impl;importjava.util.List;importcom.aidata.mvcapp.dao.CustomerDAO;importcom.aidata.mvcapp.dao.DAO;importcom.aidata.mvcapp.domain.Customer;public class CustomerDAOJdbcImpl extends DAO implementsCustomerDAO {

@Overridepublic ListgetAll() {

String sql= "SELECT id, name, address, phone From customers";returngetForList(sql);

}

@Overridepublic voidsave(Customer customer) {

String sql= "INSERT INTO customers(name, address, phone) VALUES(?,?,?)";

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

}

@OverridepublicCustomer get(Integer id) {

String sql= "SELECT id, name, address, phone FROM customers WHERE id = ?";returnget(sql, id);

}

@Overridepublic voiddelete(Integer id) {

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

}

}

2.3 多个请求对应一个Servlet

第一种方式:url添加参数

a9fd10788450c05fb1c454c27b195534.png

jsp

Add

Query

Delete

定义Servlet

packagecom.aidata.mvcapp.servlet;importjava.io.IOException;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;public class CustomerServlet extendsHttpServlet {private static final long serialVersionUID = 1L;publicCustomerServlet() {

}protected voiddoGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

doPost(request, response);

}protected voiddoPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, 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;

}

}private void add(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

System.out.println("add");

}private void query(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

System.out.println("query");

}private void delete(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

System.out.println("delete");

}

}

web.xml

customerServlet

com.aidata.mvcapp.servlet.CustomerServlet

customerServlet

/customerServlet

缺点:当添加一个请求时,需要在 Servlet 中修改两处代码:switch、添加方法;url 中使用 method=xxx 暴漏了要调用的方法,不私密,有安全隐患。

第二种方式:反射

f99d4a9bea961d0739b3ab189f9c83c2.png

jsp

Add

Query

Delete

web.xml

customerServlet

com.aidata.mvcapp.servlet.CustomerServlet

customerServlet

*.do

Servlet

packagecom.aidata.mvcapp.servlet;importjava.io.IOException;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;public class CustomerServlet extendsHttpServlet {private static final long serialVersionUID = 1L;publicCustomerServlet() {

}protected voiddoGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

doPost(request, response);

}protected voiddoPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

String servletPath=request.getServletPath();

String methodName= servletPath.substring(1);

methodName= methodName.substring(0, methodName.length() - 3);

System.out.println(methodName);

Method method;try{

method= getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

method.invoke(this, request, response);

}catch (NoSuchMethodException |SecurityException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalAccessException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalArgumentException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(InvocationTargetException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}private voidaddCustomer(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

System.out.println("add");

}private void query(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

System.out.println("query");

}private voiddeleteCustomer(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

System.out.println("delete");

}private void edit(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

System.out.println("edit");

}

}

流程:

8310b7bbe0a77d93356116a1c1fc345c.png

2.4 模糊查询

非模糊查询

JSP

Insert title here
CustomerName:
Address:
Phone:
Add New Customer

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


IDCustomerNameAddressPhoneUPDATE\DELETE

for(Customer customer: customers){%>

UPDATE

DELETE

Servlet

packagecom.aidata.mvcapp.servlet;importjava.io.IOException;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjava.util.List;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importcom.aidata.mvcapp.dao.CustomerDAO;importcom.aidata.mvcapp.dao.impl.CustomerDAOJdbcImpl;importcom.aidata.mvcapp.domain.Customer;public class CustomerServlet extendsHttpServlet {private static final long serialVersionUID = 1L;private CustomerDAO customerDAO = newCustomerDAOJdbcImpl();publicCustomerServlet() {

}protected voiddoGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

doPost(request, response);

}protected voiddoPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

String servletPath=request.getServletPath();

String methodName= servletPath.substring(1);

methodName= methodName.substring(0, methodName.length() - 3);

System.out.println(methodName);

Method method;try{

method= getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

method.invoke(this, request, response);

}catch (NoSuchMethodException |SecurityException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalAccessException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalArgumentException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(InvocationTargetException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}private voidaddCustomer(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

System.out.println("add");

}private void query(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {//1.调用CustomerDAO的getAll()方法,得到Customer的集合

List customers =customerDAO.getAll();//2.把customer集合放入request中

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

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

}private voiddeleteCustomer(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

System.out.println("delete");

}private void edit(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

System.out.println("edit");

}

}

模糊查询

接口添加方法,定义用于查询的类

需要在 CustomerDAO 接口中定义一个 getForListWithCriteriaCustomer(CriteriaCustomer cc)。 其中 CriteriaCustomer 用于封装查询条件:name, address, phone。因为查询条件很多时候和 domain 类并不相同,所以要做成一个单独的类

packagecom.aidata.mvcapp.dao;importjava.util.List;importcom.aidata.mvcapp.domain.Customer;public interfaceCustomerDAO {public ListgetForListWithCriteriaCustomer(CriteriaCustomer cc);public ListgetAll();public voidsave(Customer customer);publicCustomer get(Integer id);public voiddelete(Integer id);/*** @Description 返回和name相等的记录数

*@paramname

*@return

*/

public longgetCountWithName(String name);

}

CriteriaCustomer

packagecom.aidata.mvcapp.dao;public classCriteriaCustomer {privateString name;privateString address;privateString phone;publicCriteriaCustomer(String name, String address, String phone) {super();this.name =name;this.address =address;this.phone =phone;

}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;

}

}

拼 SQL

SQL: "SELECT id, name, address, phone FROM customers WHERE " +

"name LIKE ? AND address LIKE ? ANDphone LIKE ?";

packagecom.aidata.mvcapp.dao.impl;importjava.util.List;importcom.aidata.mvcapp.dao.CriteriaCustomer;importcom.aidata.mvcapp.dao.CustomerDAO;importcom.aidata.mvcapp.dao.DAO;importcom.aidata.mvcapp.domain.Customer;public class CustomerDAOJdbcImpl extends DAO implementsCustomerDAO {

@Overridepublic ListgetAll() {

String sql= "SELECT id, name, address, phone From customers";returngetForList(sql);

}

@Overridepublic voidsave(Customer customer) {

String sql= "INSERT INTO customers(name, address, phone) VALUES(?,?,?)";

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

}

@OverridepublicCustomer get(Integer id) {

String sql= "SELECT id, name, address, phone FROM customers WHERE id = ?";returnget(sql, id);

}

@Overridepublic voiddelete(Integer id) {

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 ListgetForListWithCriteriaCustomer(CriteriaCustomer cc) {

String sql= "SELECT id, name, address, phone FROM customers WHERE "

+ "name LIKE ? AND address LIKE ? AND phone LIKE ?";returngetForList(sql, cc.getName(), cc.getAddress(), cc.getPhone());

}

}

为了正确的填充占位符时,重写了 CriteriaCustomer 的 getter:

packagecom.aidata.mvcapp.dao;public classCriteriaCustomer {privateString name;privateString address;privateString phone;publicCriteriaCustomer(String name, String address, String phone) {super();this.name =name;this.address =address;this.phone =phone;

}publicString getName() {if (name == null) {

name= "%%";

}else{

name= "%" + name + "%";

}returnname;

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

}publicString getAddress() {if (address == null) {

address= "%%";

}else{

address= "%" + address + "%";

}returnaddress;

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

}publicString getPhone() {if (phone == null) {

phone= "%%";

}else{

phone= "%" + phone + "%";

}returnphone;

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

}

}

修改 Servlet

获取请求参数,把请求参数封装为CriteriaCustomer 对象,再调用 getForListWithCriteriaCustomer(CriteriaCustomer cc) 方法

packagecom.aidata.mvcapp.servlet;importjava.io.IOException;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjava.util.List;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importcom.aidata.mvcapp.dao.CriteriaCustomer;importcom.aidata.mvcapp.dao.CustomerDAO;importcom.aidata.mvcapp.dao.impl.CustomerDAOJdbcImpl;importcom.aidata.mvcapp.domain.Customer;public class CustomerServlet extendsHttpServlet {private static final long serialVersionUID = 1L;private CustomerDAO customerDAO = newCustomerDAOJdbcImpl();publicCustomerServlet() {

}protected voiddoGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

doPost(request, response);

}protected voiddoPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

String servletPath=request.getServletPath();

String methodName= servletPath.substring(1);

methodName= methodName.substring(0, methodName.length() - 3);

System.out.println(methodName);

Method method;try{

method= getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

method.invoke(this, request, response);

}catch (NoSuchMethodException |SecurityException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalAccessException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalArgumentException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(InvocationTargetException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}private voidaddCustomer(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

System.out.println("add");

}private void query(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

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

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

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

CriteriaCustomer cc= newCriteriaCustomer(name, address, phone);//1.调用CustomerDAO的getAll()方法,得到Customer的集合

List customers =customerDAO.getForListWithCriteriaCustomer(cc);//2.把customer集合放入request中

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

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

}private voiddeleteCustomer(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

System.out.println("delete");

}private void edit(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

System.out.println("edit");

}

}

2.5 删除操作

Servlet

超链接:delete.do?id=

Servlet 的 delete 方法

获取 id

调用 DAO 执行删除

重定向到 query.do(若目标页面不需要读取当前请求的 request 属性,就可以使用重定向),将显示删除后的 Customer 的 List

packagecom.aidata.mvcapp.servlet;importjava.io.IOException;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjava.util.List;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importcom.aidata.mvcapp.dao.CriteriaCustomer;importcom.aidata.mvcapp.dao.CustomerDAO;importcom.aidata.mvcapp.dao.impl.CustomerDAOJdbcImpl;importcom.aidata.mvcapp.domain.Customer;public class CustomerServlet extendsHttpServlet {private static final long serialVersionUID = 1L;private CustomerDAO customerDAO = newCustomerDAOJdbcImpl();publicCustomerServlet() {

}protected voiddoGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

doPost(request, response);

}protected voiddoPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

String servletPath=request.getServletPath();

String methodName= servletPath.substring(1);

methodName= methodName.substring(0, methodName.length() - 3);

System.out.println(methodName);

Method method;try{

method= getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

method.invoke(this, request, response);

}catch (NoSuchMethodException |SecurityException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalAccessException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalArgumentException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(InvocationTargetException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}private voidaddCustomer(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

System.out.println("add");

}private void query(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

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

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

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

CriteriaCustomer cc= newCriteriaCustomer(name, address, phone);//1.调用CustomerDAO的getAll()方法,得到Customer的集合

List customers =customerDAO.getForListWithCriteriaCustomer(cc);//2.把customer集合放入request中

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

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

}private voiddeleteCustomer(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

String idStri= request.getParameter("id");int id = 0;//try...catch... 防止idStri不能转为int类型,若不能转,id=0,不进行任何删除操作

try{

id=Integer.parseInt(idStri);

customerDAO.delete(id);

}catch(Exception e) {

}

response.sendRedirect("query.do");

System.out.println("delete");

}private void edit(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

System.out.println("edit");

}

}

JSP

jQuery 提示:

确定要删除 xx 的信息吗?

47d59109a22c4b36ecc5131045a91a7a.png

Insert title here

$(function() {

$(".delete").click(function() {varcontent=$(this).parent().parent().find("td:eq(1)").text();varflag=confirm("确定要删除"+content+"的信息吗?");returnflag;

});

});

CustomerName:
Address:
Phone:
Add New Customer

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


IDCustomerNameAddressPhoneUPDATE\DELETE

for(Customer customer: customers){%>

UPDATE

"class="delete">DELETE

request的getParameter(String name)方法获取表单里面的name信息

只有设置了 name 属性的表单元素才能在提交表单时传递它们的值,因为服务端获取表单提交的数据是通过表单元素的 name 属性的值而得到的,没有 name 属性就无法得到表单元素提交给服务端的值

2.6 新增

流程

效果:点击Add New Customer 超链接,连接到 newcustomer.jsp

e1f6e740a824ed07459354ef9dcacdad.png

创建newcustomer.jsp

83d918a956d56e27158c803912ba50e2.png

Insert title here
CustomerName:">
Address:
Phone:

success.jsp

Insert title here
操作成功!
Return...

修改addCustomer 方法

CustomerServlet 的 addCustomer 方法

packagecom.aidata.mvcapp.servlet;importjava.io.IOException;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjava.util.List;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importcom.aidata.mvcapp.dao.CriteriaCustomer;importcom.aidata.mvcapp.dao.CustomerDAO;importcom.aidata.mvcapp.dao.impl.CustomerDAOJdbcImpl;importcom.aidata.mvcapp.domain.Customer;public class CustomerServlet extendsHttpServlet {private static final long serialVersionUID = 1L;private CustomerDAO customerDAO = newCustomerDAOJdbcImpl();publicCustomerServlet() {

}protected voiddoGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

doPost(request, response);

}protected voiddoPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

String servletPath=request.getServletPath();

String methodName= servletPath.substring(1);

methodName= methodName.substring(0, methodName.length() - 3);

System.out.println(methodName);

Method method;try{

method= getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

method.invoke(this, request, response);

}catch (NoSuchMethodException |SecurityException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalAccessException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalArgumentException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(InvocationTargetException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}private voidaddCustomer(HttpServletRequest request, HttpServletResponse response)throwsServletException, 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方法获取name是否在数据库中存在

long count =customerDAO.getCountWithName(name);//2.2 若返回值大于0,则响应newcustomer.jsp页面://通过转发的方式响应newcustomer.jsp

if (count > 0) {//2.2.1 要求在newcustomer.jsp页面显示一个错误消息:用户名name已经被占用,请重新选择!//在request中放入一个属性,比如message:用户名name已经被占用,请重新选择!,//在页面上通过request.getAttribute("message")的方式显示

request.setAttribute("message", "用户名" + name + "已经被占用,请重新选择!");//2.2.2 newcustomer.jsp的表单值可以回显//jsp中,value="//2.2.3 结束方法:return

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

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

Customer customer = newCustomer(name, address, phone);//4. 调用CustomerDAO的save方法,执行保存操作

customerDAO.save(customer);//5. 重定向到success.jsp页面

response.sendRedirect("success.jsp");

}private void query(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

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

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

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

CriteriaCustomer cc= newCriteriaCustomer(name, address, phone);//1.调用CustomerDAO的getAll()方法,得到Customer的集合

List customers =customerDAO.getForListWithCriteriaCustomer(cc);//2.把customer集合放入request中

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

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

}private voiddeleteCustomer(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

String idStri= request.getParameter("id");int id = 0;//try...catch... 防止idStri不能转为int类型,若不能转,id=0,不进行任何删除操作

try{

id=Integer.parseInt(idStri);

customerDAO.delete(id);

}catch(Exception e) {

}

response.sendRedirect("query.do");

}private void edit(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

System.out.println("edit");

}

}

执行流程图

48c127c10a7ad2d342bcb81458cee8a3.png

2.7 修改

先显示(SELECT 操作)修改的页面,再进行修改(update)

显示修改页面

Update 的超链接:UPDATE

index.jsp

Insert title here

$(".delete").click(function() {

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

var flag= confirm("确定要删除"+content+"的信息吗?");returnflag;

});

});

CustomerName:
Address:
Phone:
Add New Customer

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


IDCustomerNameAddressPhoneUPDATE\DELETE

for(Customer customer: customers){%>

UPDATE

DELETE

edit 方法:

private void edit(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

String forwardPath= "/error.jsp";//1. 获取请求参数id

String idStr = request.getParameter("id");//2.调用customerDAO的customerDAO.get(id)获取和id对应的Customer对象

try{

Customer customer=customerDAO.get(Integer.parseInt(idStr));if (customer != null) {

forwardPath= "updatecustomer.jsp";//3.将customer放入request中

request.setAttribute("customer", customer);

}

}catch(Exception e) {

}//4.响应updatecustomer.jsp页面:转发

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

}

JSP 页面

获取请求域中的 Customer 对象,调用对应的字段的 get 方法来显示值。

使用隐藏域来保存要修改的 Customer 对象的 id:"/>。虽然没有修改id,当然也不能改,但依然少不了,id用来判断到底是哪个customer。

使用隐藏域来保存 oldName:"/>,oldName保存修改前的名字,name会更新为提交的名字。

关于隐藏域:和其他的表单域一样可以被提交到服务器,只不过在页面上不显示提交到 update.do

updatecustomer.jsp:

Insert title here

Objectmsg=request.getAttribute("message");if(msg != null){%>

Customer customer=(Customer)request.getAttribute("customer");if(customer != null){//如果没有出错,从edit方法过来的,customer不为空

id=customer.getId()+ "";//这里name和oldName一样,但是后面提交的时候,name会提交,即更新,而oldName保持不变,从而可以比较

oldName=customer.getName();

name=customer.getName();

address=customer.getAddress();

phone=customer.getPhone();

}else{//如果出错,即提交了重复的名字,会出现提示信息,会停留在本页面,没有edit方法了,也就没有customer属性了//只能从之前提交的request中得到id等

id=request.getParameter("id");

oldName=request.getParameter("oldName");//name=request.getParameter("oldname");

address=request.getParameter("address");

phone=request.getParameter("phone");

}%>

" />

" />

CustomerName:" />
Address:" />
Phone:" />

隐藏域的问题

回显的问题

Newcustomer.jsp 和 updateCustomer.jsp 能汇总到一个页面吗 ?

修改操作

Update 方法:

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

// 1. 获取表单参数:name,address,phone

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

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

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

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

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

// 2. 检验name是否已经被占用

// 2.1 比较name和oldName是否相同,若相同说明name可用

// 2.1 若不相同,调用customerDAO的getCountWithName方法获取name是否在数据库中存在

if (!oldName.equalsIgnoreCase(name)) {

// 如你输入了A,以前已经有了a,java的equals会认为两者不同,于是进入该if

// 但是mysql认为A和a相同,于是返回了1,即已经存在了,从而引发message

// 忽略大小写,不进入if,直接进行后面的update

long count =customerDAO.getCountWithName(name);

// 2.2 若返回值大于0,则响应updatecustomer.jsp

if (count > 0) {

// 2.2.1 在updatecustomer.jsp页面显示一个错误信息:用户名name已经被占用,请重新选择!

// 在request中放入一个属性,比如message:用户名name已经被占用,请重新选择!,

// 在页面上通过request.getAttribute("message")的方式显示

request.setAttribute("message", "用户名" + name + "已经被占用,请重新选择!");

// 2.2.2 updatecustomer.jsp的表单值可以回显

// address,phone显示提交表单的新的值,而name显示oldName,而不是新提交的name

// 2.2.3 结束方法:return

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

}

}

完整Servlet

packagecom.aidata.mvcapp.servlet;importjava.io.IOException;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjava.util.List;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importcom.aidata.mvcapp.dao.CriteriaCustomer;importcom.aidata.mvcapp.dao.CustomerDAO;importcom.aidata.mvcapp.dao.impl.CustomerDAOJdbcImpl;importcom.aidata.mvcapp.domain.Customer;public class CustomerServlet extendsHttpServlet {private static final long serialVersionUID = 1L;private CustomerDAO customerDAO = newCustomerDAOJdbcImpl();publicCustomerServlet() {

}protected voiddoGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

doPost(request, response);

}protected voiddoPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

String servletPath=request.getServletPath();

String methodName= servletPath.substring(1);

methodName= methodName.substring(0, methodName.length() - 3);

System.out.println(methodName);

Method method;try{

method= getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

method.invoke(this, request, response);

}catch (NoSuchMethodException |SecurityException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalAccessException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IllegalArgumentException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(InvocationTargetException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}private voidaddCustomer(HttpServletRequest request, HttpServletResponse response)throwsServletException, 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方法获取name是否在数据库中存在

long count =customerDAO.getCountWithName(name);//2.2 若返回值大于0,则响应newcustomer.jsp页面://通过转发的方式响应newcustomer.jsp

if (count > 0) {//2.2.1 要求在newcustomer.jsp页面显示一个错误消息:用户名name已经被占用,请重新选择!//在request中放入一个属性,比如message:用户名name已经被占用,请重新选择!,//在页面上通过request.getAttribute("message")的方式显示

request.setAttribute("message", "用户名" + name + "已经被占用,请重新选择!");//2.2.2 newcustomer.jsp的表单值可以回显//jsp中,value="//2.2.3 结束方法:return

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

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

Customer customer = newCustomer(name, address, phone);//4. 调用CustomerDAO的save方法,执行保存操作

customerDAO.save(customer);//5. 重定向到success.jsp页面

response.sendRedirect("success.jsp");

}private void query(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

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

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

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

CriteriaCustomer cc= newCriteriaCustomer(name, address, phone);//1.调用CustomerDAO的getAll()方法,得到Customer的集合

List customers =customerDAO.getForListWithCriteriaCustomer(cc);//2.把customer集合放入request中

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

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

}private voiddeleteCustomer(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {

String idStri= request.getParameter("id");int id = 0;//try...catch... 防止idStri不能转为int类型,若不能转,id=0,不进行任何删除操作

try{

id=Integer.parseInt(idStri);

customerDAO.delete(id);

}catch(Exception e) {

}

response.sendRedirect("query.do");

}private void edit(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

String forwardPath= "/error.jsp";//1. 获取请求参数id

String idStr = request.getParameter("id");//2.调用customerDAO的customerDAO.get(id)获取和id对应的Customer对象

try{

Customer customer=customerDAO.get(Integer.parseInt(idStr));if (customer != null) {

forwardPath= "updatecustomer.jsp";//3.将customer放入request中

request.setAttribute("customer", customer);

}

}catch(Exception e) {

}//4.响应updatecustomer.jsp页面:转发

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

}private void update(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {//1. 获取表单参数:name,address,phone

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

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

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

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

String oldName= request.getParameter("oldName");//2. 检验name是否已经被占用//2.1 比较name和oldName是否相同,若相同说明name可用//2.1 若不相同,调用customerDAO的getCountWithName方法获取name是否在数据库中存在

if (!oldName.equalsIgnoreCase(name)) {//如你输入了A,以前已经有了a,java的equals会认为两者不同,于是进入该if//但是mysql认为A和a相同,于是返回了1,即已经存在了,从而引发message//忽略大小写,不进入if,直接进行后面的update

long count =customerDAO.getCountWithName(name);//2.2 若返回值大于0,则响应updatecustomer.jsp

if (count > 0) {//2.2.1 在updatecustomer.jsp页面显示一个错误信息:用户名name已经被占用,请重新选择!//在request中放入一个属性,比如message:用户名name已经被占用,请重新选择!,//在页面上通过request.getAttribute("message")的方式显示

request.setAttribute("message", "用户名" + name + "已经被占用,请重新选择!");//2.2.2 updatecustomer.jsp的表单值可以回显//address,phone显示提交表单的新的值,而name显示oldName,而不是新提交的name

request.getRequestDispatcher("update.jsp").forward(request, response);

// 2.2.3 结束方法:return

return; // 重定向跳转后必须加上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");

}

}

2.8 更换底层存储源

深入理解面向接口编程:在类中调用接口的方法,而不必关心具体的实现。这将有利于代码的解耦,使程序有更好的可移植性和可扩展性。

2a98f03d2ca7488e1dc5b8fdc5fa2bd5.png

需要修改源码

src下新建customes.xml

Tom

Beijing

123

新建实现类,功能暂时省略

packagecom.aidata.mvcapp.dao.impl;importjava.util.List;importcom.aidata.mvcapp.dao.CriteriaCustomer;importcom.aidata.mvcapp.dao.CustomerDAO;importcom.aidata.mvcapp.domain.Customer;public class CustomerDAOXMLImpl implementsCustomerDAO {

@Overridepublic ListgetForListWithCriteriaCustomer(CriteriaCustomer cc) {//TODO Auto-generated method stub

return null;

}

@Overridepublic ListgetAll() {//TODO Auto-generated method stub

return null;

}

@Overridepublic voidsave(Customer customer) {//TODO Auto-generated method stub

}

@OverridepublicCustomer get(Integer id) {//TODO Auto-generated method stub

return null;

}

@Overridepublic voiddelete(Integer id) {//TODO Auto-generated method stub

}

@Overridepublic voidupdate(Customer customer) {//TODO Auto-generated method stub

}

@Overridepublic longgetCountWithName(String name) {//TODO Auto-generated method stub

return 0;

}

}

只需要在CustomerServlet中修改一行语句

private CustomerDAO customerDAO = new CustomerDAOXMLImpl();

使用工厂模式,不修改源码

如果一行语句也不用修改怎么做?

使用属性文件

动态修改 Customer 的存储方式:通过修改类路径下的 switch.properties 文件的方式来实现

src下创建switch.properties

#type=xml

type=jdbc

创建Servlet读取配置文件

当Web 应用在启动的时候,InitServlet 被创建,并由 Servlet 容器调用其 init() 方法:

InitServlet

com.aidata.mvcapp.servlet.InitServlet

1

读取类路径下的 switch.properties 文件,获取 switch.properties 的 type 属性值,赋给了 CustomerDAOFactory 的 type 属性值

packagecom.aidata.mvcapp.servlet;importjava.io.IOException;importjava.io.InputStream;importjava.util.Properties;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importcom.aidata.mvcapp.dao.factory.CustomerDAOFactory;public class InitServlet extendsHttpServlet {private static final long serialVersionUID = 1L;

@Overridepublic void init() throwsServletException {

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

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

Properties properties= newProperties();try{

properties.load(in);

String type= properties.getProperty("type");

CustomerDAOFactory.getInstance().setType(type);

}catch(IOException e) {

e.printStackTrace();

}

}}

需要通过一个类的一个方法来获取具体的实现类的对象:

packagecom.aidata.mvcapp.dao.factory;importjava.util.HashMap;importjava.util.Map;importcom.aidata.mvcapp.dao.CustomerDAO;importcom.aidata.mvcapp.dao.impl.CustomerDAOJdbcImpl;importcom.aidata.mvcapp.dao.impl.CustomerDAOXMLImpl;public classCustomerDAOFactory {private Map daos = new HashMap();privateCustomerDAOFactory() {

daos.put("jdbc", newCustomerDAOJdbcImpl());

daos.put("xml", newCustomerDAOXMLImpl());

}private static CustomerDAOFactory instance = newCustomerDAOFactory();public staticCustomerDAOFactory getInstance() {returninstance;

}private static String type = null;public voidsetType(String type) {this.type =type;

}publicCustomerDAO getCustomerDAO() {returndaos.get(type);

}

}

创建 CustomerServlet 时,为 customerDAO 属性赋值是通过 CustomerDAOFactory  的 getCustomerDAO() 方法完成的 。此时的 type 已经在 InitServlet 中被赋值了。

private CustomerDAO customerDAO = CustomerDAOFactory.getInstance().getCustomerDAO();

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java MVC三层架构是一种软件架构设计模式,它将应用程序分为三个主要的部分:模型(Model)、视图(View)和控制器(Controller)。这种架构模式的目标是实现应用程序的业务逻辑与数据展示的分离,以提高代码的可维护性和可扩展性。 在Java MVC三层架构中,模型层负责处理具体的业务逻辑和数据访问操作。它通常由JavaBean组成,用于完成与数据库的交互和数据的封装。 视图层负责展示数据给用户,并接收用户的输入。常见的视图技术包括JSP和HTML。 控制器层负责接收来自视图层的用户请求,并调用相应的模型层进行业务处理,然后将处理结果返回给视图层进行展示。在Java中,控制器通常由Servlet来实现。 Java MVC三层架构的优点包括: - 提供了良好的代码分离和模块化,使代码更易于维护和扩展。 - 支持多人协作开发,不同开发人员可以独立地开发和修改不同层的代码。 - 降低了代码的耦合性,使得代码更加灵活和可测试。 然而,也要注意到Java MVC三层架构可能存在的缺点: - 由于分层较多,可能会增加开发的复杂性和工作量。 - 如果应用程序较小,使用MVC三层架构可能会显得过于复杂,不适合所有的项目。 总之,Java MVC三层架构是一种常见的软件设计模式,通过将应用程序分为模型、视图和控制器三个部分,实现了业务逻辑和数据展示的分离,提供了可维护和可扩展的代码结构。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [mvc三层架构应用案例简单代码](https://download.csdn.net/download/weixin_59798969/86267352)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [JavaWeb(MVC模式)](https://blog.csdn.net/m0_62604616/article/details/124333865)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值