MVC初步学习

MVC思想

M:model        模型

V:view           视图

C:control       控制器

用户(客户端或浏览器)向服务端发送请求,控制器(control)接收请求,并进行处理,选择对应的模型(model),模型(model)与数据库进行数据交互等操作,交互完成后,模型(model)将数据发送到控制器(control),控制器(model)进行处理,选择相应的视图(view)来展示这些数据,并呈现到浏览器上,形成最终的显示页面。

使用MVC的思想,结合servlet和jsp进行数据库的查询操作

1.实体类Hero

实体类Hero是一个由普通Java代码编写的类

将其实例化为对象后,可调用其内部编写的各种方法实现与数据库之间的交互操作

其代码如下:
 

package bean;

public class Hero {
    
    // 定义数据库中表的字段名
    //成员变量
	public int id;
	public String name;
	public float hp;
	public int damage;



    //这个方法的作用是获取数据库中表的 字段为id 的数据
	public int getId() {
		return id;
	}

    //这个方法的作用是设置表中字段为id 的数据
	public void setId(int id) {
		this.id = id;
	}
    


    //获取字段名为name的数据
	public String getName() {
		return name;
	}

    //设置字段名为name的数据
	public void setName(String name) {
		this.name = name;
	}




    //获取字段名为hp的数据
	public float getHp() {
		return hp;
	}

    //设置字段名为 hp 的数据
	public void setHp(float hp) {
		this.hp = hp;
	}






    //获取字段名为damage的数据
	public int getDamage() {
		return damage;
	}
    
    设置字段名为damage的数据
	public void setDamage(int damage) {
		this.damage = damage;
	}

}

2.HeroDAO

package dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import bean.Hero; // 导入了编写的 实体类 Hero

public class HeroDAO {

    //HeroDAO类的构造方法,
	public HeroDAO() {
        
        //创建驱动程序
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

    //方法名是getConnection()    返回类型是Connection
	public Connection getConnection() throws SQLException {
		return DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/db_database24", "root", "914717"); //连接数据库
	}


    


    //获取表中一共有多少数据的方法

	public int getTotal() {
		int total = 0;
        
        //进行数据库连接
		try (Connection c = getConnection(); Statement s = c.createStatement();) {
            
            //编写sql语句
			String sql = "select count(*) from hero";

            //执行查询语句,并返回结果集合
			ResultSet rs = s.executeQuery(sql);

			while (rs.next()) {
				total = rs.getInt(1);//获取第一个字段 id
                
                //每个next是指向的下一个元组,该语句获取的是这个元组的 第一个字段 id 的值
			}

			System.out.println("total:" + total);    //输出最后total的值,就代表表中一共有多少条数据
    

		} catch (SQLException e) {

			e.printStackTrace();
		}
		return total;        //返回结果
	}





    //向数据库表中添加数据
    //传入参数为Hero类实例化的hero对象
	public void add(Hero hero) {

        //编写sql语句
		String sql = "insert into hero values(null,?,?,?)";
        
        //连接数据库
		try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {

			ps.setString(1, hero.name);
			ps.setFloat(2, hero.hp);
			ps.setInt(3, hero.damage);

			ps.execute();

			ResultSet rs = ps.getGeneratedKeys();
			if (rs.next()) {
				int id = rs.getInt(1);
				hero.id = id;
			}
		} catch (SQLException e) {

			e.printStackTrace();
		}
	}


    
    //修改数据库表中的数据
	public void update(Hero hero) {
        

        //编写sql语句
		String sql = "update hero set name= ?, hp = ? , damage = ? where id = ?";
        //连接数据库
		try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {

			ps.setString(1, hero.name);
			ps.setFloat(2, hero.hp);
			ps.setInt(3, hero.damage);
			ps.setInt(4, hero.id);

			ps.execute();

		} catch (SQLException e) {

			e.printStackTrace();
		}

	}



    //修改数据库表中的数据
	public void delete(int id) {
        //连接数据库
		try (Connection c = getConnection(); Statement s = c.createStatement();) {
            //编写sql语句
			String sql = "delete from hero where id = " + id;

			s.execute(sql);

		} catch (SQLException e) {

			e.printStackTrace();
		}
	}




    //方法名为 get(),返回类型为Hero
	public Hero get(int id) {
        //实例化对象为空
		Hero hero = null;

        //连接数据库
		try (Connection c = getConnection(); Statement s = c.createStatement();) {
            //编写sql语句
			String sql = "select * from hero where id = " + id;
            //执行查询语句
			ResultSet rs = s.executeQuery(sql);

			if (rs.next()) {

                //将表中的数据都赋值给hero对象
				hero = new Hero();
				String name = rs.getString(2);
				float hp = rs.getFloat("hp");
				int damage = rs.getInt(4);
				hero.name = name;
				hero.hp = hp;
				hero.damage = damage;
				hero.id = id;
			}

		} catch (SQLException e) {

			e.printStackTrace();
		}
		return hero;
	}



    //返回类型为List<Hero>  方法名为list
	public List<Hero> list() {
		return list(0, Short.MAX_VALUE);
	}


    
	public List<Hero> list(int start, int count) {
		List<Hero> heros = new ArrayList<Hero>();
        
        //编写sql语句
		String sql = "select * from hero order by id desc limit ?,? ";

        //连接数据库
		try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {

			ps.setInt(1, start);
			ps.setInt(2, count);

			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				Hero hero = new Hero();
				int id = rs.getInt(1);
				String name = rs.getString(2);
				float hp = rs.getFloat("hp");
				int damage = rs.getInt(4);
				hero.id = id;
				hero.name = name;
				hero.hp = hp;
				hero.damage = damage;
                //将hero对象添加到列表中去
				heros.add(hero);
			}
		} catch (SQLException e) {

			e.printStackTrace();
		}
		return heros;
	}

}

3.HeroListServlet

这是一个Servlet文件

package servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import bean.Hero;
import dao.HeroDAO;

/**
 * Servlet implementation class HeroListServlet
 */
@WebServlet("/HeroListServlet")
public class HeroListServlet extends HttpServlet {
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		List<Hero> heros = new HeroDAO().list();
        //设置属性
		request.setAttribute("heros", heros);
        
        //呈现视图的页面
		request.getRequestDispatcher("listhero.jsp").forward(request, response);

	}

}

4.listHero.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
 
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
 
<table align='center' border='1' cellspacing='0'>
    <tr>
        <td>id</td>
        <td>name</td>
        <td>hp</td>
        <td>damage</td>
        <td>edit</td>
        <td>delete</td>
    </tr>
    <c:forEach items="${heros}" var="hero" varStatus="st">
        <tr>
            <td>${hero.id}</td>
            <td>${hero.name}</td>
            <td>${hero.hp}</td>
            <td>${hero.damage}</td>
            <td><a href="editHero?id=${hero.id}">edit</a></td>
            <td><a href="deleteHero?id=${hero.id}">delete</a></td>
        </tr>
    </c:forEach>
</table>

运行HeroListServlet,结果为

分析查询过程中的MVC(以下观点仅为个人看法)

下面来分析一下这个过程中的MVC分别是什么:
M(模型):模型是用来与数据库进行交互操作(增、删、改、查)的,那上述文件中,发挥此作用的是HeroDAO,HeroDAO在其内部封装了与数据库进行交互操作的方法

V(视图):视图是用来在浏览器中展示的,在上述文件中,listHero发挥了这种作用,在浏览器上呈现最终的数据

C(控制器):控制器是用来处理请求的,将模型与视图连接在一起的,上述文件中HeroListServlet就发挥了这种作用。

以MVC思想实现数据的增删改

接下来我们在上述步骤的基础上完成对数据的增、删、改,并将其显示在页面上。

那我们就要分类好谁是M、谁是V、谁是C;

V的话很简单,就是jsp文件,我们用上面查询所用的代码就可以;

M的话就是与数据库进行交互的HeroDAO;

C的话应该有多个,用户每发起一次请求,网址就会改变一次,所以我认为接收请求的控制器也应该有多种,一种网址对应一种控制器同时对应一种请求。

1.视图(view)的建立:

建立listHero.jsp文件,复制上面文件代码。

首先要构思好整个页面 该怎么实现其各自的功能 

比如说 增添数据该怎么增添  ,  删除数据该怎么删除   ,修改数据该怎么修改 

我们目前展现的页面是这样的

 

现在将进行如下思考:

怎么增添数据呢?

我们可以在页面设置一个输入框,用于输入数据,然后当我们输入数据并提交之后,这些输入的数据会添加到数据表中并在页面显示出来

怎么删除数据呢?

我们可以点击delete,使该行数据在数据表中删除,并且在页面上显示出来

怎么修改数据呢?

我们点击edit,并输入修改后的值,使数据表里的数据发生改变,并在页面上显示出来

于是我们可以书写如下代码

<%@ page language="java" import="java.sql.*"
	contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
	<table align='center' border='1' cellspacing='0'>
		<tr>
			<td>id</td>
			<td>name</td>
			<td>hp</td>
			<td>edit</td>
			<td>delete</td>
		</tr>
		<c:forEach items="${heros}" var="hero" varStatus="st">
			<tr>
				<td>${hero.id}</td>
				<td>${hero.name}</td>
				<td>${hero.hp}</td>
                
                //a标签的路径已经给出,所以我们可以想到要建立editHero和deleteHero两个servlet文件
				<td><a href="editHero?id=${hero.id}">edit</a></td>
				<td><a href="deleteHero?id=${hero.id}">delete</a></td>
			</tr>
		</c:forEach>



	</table>
    
    // 该部分用于用户输入要增加的数据
	<div style="margin: 50px auto; width: 300px">
		<form action="addHero" method=""post">
			name:&nbsp;&nbsp;<input name="name"> <br>
			<br> hp:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input
				name="hp"> <br> <input type="submit" value="提交">
		</form>

	</div>

</body>
</html>

这样网页的显示页面就完成了,下面该完成各部分功能的实现

2.控制器(controller)的建立

视图建立完成后,就建立各种控制器。由于我们只有一个视图,所以我们可以把各种控制器最后要显示的页面弄成同一个。

简单来说就是  不同的控制器接收请求  调用模型与数据库进行不同的交互操作后  选择同一个视图展现在浏览器上

以删除数据为例:

当我们点击delete时,就发送了一次请求,页面跳转到deleleHero的Servlet文件中,

在这个文件中,我们接收这次请求的id参数,并且调用HeroDAO文件中的delete()方法,与数据库进行交互操作,删除这一个元组, 

最后选择视图,返回到最初显示的页面。

要返回到最初显示的页面,我们可以回退到最初的网址。

因为HeroListServlet是查询操作,所以我们每个控制器最后返回的网址都可以是它的网址,相当于完成数据增删改操作后,对数据表进行了一次查询,并显示在jsp页面上。

清楚之后,开始建立各种控制器;

创建deleteHero

代码如下:

package servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import dao.HeroDAO;

/**
 * Servlet implementation class deleteHero
 */
@WebServlet("/deleteHero")
public class deleteHero extends HttpServlet {
	public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		// 获取网址的参数 id
		int id = Integer.parseInt(request.getParameter("id"));

		// 建一个HeroDAO对象,目的是完成与数据库的交互操作,在这个文件中是完成数据的删除操作
		HeroDAO hero = new HeroDAO();
        // 删除这个元组
		hero.delete(id);

        //响应到HeroListServlet 这个网址,相当于重新进入
		response.sendRedirect("HeroListServlet");

	}
}

显示效果如下:

 

 

创建addHero

代码如下:

package servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import bean.Hero;
import dao.HeroDAO;

/**
 * Servlet implementation class addHero
 */
@WebServlet("/addHero")
public class addHero extends HttpServlet {
	public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

        //首先接收显示页面输入框中 用户输入的值
		String name = request.getParameter("name");
		String hp = request.getParameter("hp");

		// 创建一个Hero对象
		Hero hero = new Hero();
		hero.name = name;
		hero.hp = Float.parseFloat(hp);
        
        //此时的hero是一个全新的Hero对象


        //实例化HeroDAO
		HeroDAO heros = new HeroDAO();


        //与数据库进行交互
        //调用add()方法,将hero对象加入其中
		heros.add(hero);

        //响应到初始页面
		response.sendRedirect("HeroListServlet");
	}

}

显示效果如下:

 

 

创建editHero

在修改数据时,我们发现这并不能向增删那样只通过一个文件就可以达到效果

因为我们

1.要选出要修改的元组

2.并输入他们修改后的值 

3.之后要修改数据 并显示到页面上

所以这样就要建立三个文件

第一个文件editHero用于 取出要修改的元组

第二个文件editHero.jsp文件用于展示输入框并接收用户输入的数据

第三个文件updateHero文件用于接收修改的值,并对数据进行修改

接下来代码如下:

editHero文件中:

package servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import bean.Hero;
import dao.HeroDAO;

/**
 * Servlet implementation class editHero
 */
@WebServlet("/editHero")
public class editHero extends HttpServlet {
	public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

        //获取要修改的 id 元组
		int id = Integer.parseInt(request.getParameter("id"));

        //先创建一个Hero对象,并把id为‘id’的那一行元组取出来,这样才能进行修改
		Hero hero = new HeroDAO().get(id);

        //把这个hero对象作为参数传出去
		request.setAttribute("hero", hero);

        //将参数对象发送到editHero.jsp文件中
		request.getRequestDispatcher("editHero.jsp").forward(request, response);

	}
}

editHero.jsp文件中:

<%@ page language="java" import="java.sql.*" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
    	
	    <div style="margin:50px auto; width:300px">
	    <form action="updateHero" method=""post">
            
            //存储用户输入的数据
	        name:&nbsp;&nbsp;<input name="name" > <br><br>
	        hp:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input name="hp"  >
	        <br>
	            
            //用于存储要修改的元组的id,并进行提交
	        <input type="hidden" name = "id" value="${hero.id}">
	        <input type="submit" value="提交">
	    </form>
	
	</div>
    
    </body>
</html>

updateHero文件中:

package servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import bean.Hero;
import dao.HeroDAO;

/**
 * Servlet implementation class updateHero
 */
@WebServlet("/updateHero")
public class updateHero extends HttpServlet {
	public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

        //接收要修改的元组的id ,修改后的值
		String name = request.getParameter("name");
		String hp = request.getParameter("hp");
		String id = request.getParameter("id");
        
        //创建一个hero对象
		Hero hero = new Hero();

        //对hero对象进行赋值(修改)
		hero.name = name;
		hero.hp = Float.parseFloat(hp);
		hero.id = Integer.parseInt(id);
		HeroDAO heros = new HeroDAO();

        //在数据表中实现数据的修改
		heros.update(hero);

        //响应到初始界面
		response.sendRedirect("HeroListServlet");

	}
}

显示效果如下:

 

 

 

这样,以MVC思想完成对数据的增删改 就已经完成了。

在进行上述操作的过程中,最后显示的网址是没有发生改变的,但是我们要注意,我们并不仅仅是发出了一次请求,而是发出了多次请求,它们原本的网址是不同的,只是我们让它最后显示的网址是相同的。

小结

MVC是一种思想,目前我的理解还有点肤浅,对本篇文章中的M、V是什么还有点疑惑。

现在有两种想法:
一种是M是HeroDAO,V是各种servlet文件

一种是M是除HerolistServlet之外的各种文件,V是HeroListServlet文件

目前我倾向于第一种,但是还是有点疑惑,因为它对数据的更新是在servlet文件中的,HeroDAO只是提供了方法,有点不太理解。可能这个案例本身的界限不是很明显吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值