MVC

前言

  • MVC 是一种分层的设计模式,通过控制器 (C),让不同的视图 (V),显示不同的数据 (M)。

  • MVC 模式

  • MVC 快速入门

1、MVC

  • MVC 设计模式

    • M 代表 模型(Model):就是数据,就是 dao,bean。
    • V 代表 视图(View):就是网页,JSP,用来展示模型中的数据。
    • C 代表 控制器(controller):用来把不同的数据,显示在不同的视图上。

  • MVC 思想

    • 仅仅使用 Servlet,可以看到 Servlet 不仅要准备数据,还要准备 html。尤其是准备 html,可读性非常差,维护起来也很麻烦。
    • 仅仅使用 JSP,会发现,虽然编写 html 方便了,但是写 Java 代码不如在 Servlet 中那么方便。
    • 结合 Servlet 和 JSP,Servlet 只用来从数据库中查询对象,然后跳转到 JSP 页面。
    • JSP 不做查询数据库的事情,直接获取从 Servlet 传过来的对象,通过 EL 表达式把 request 中的内容显示出来。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      /* HeroEditServlet.java */

      import java.io.IOException;

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

      import bean.Hero;
      import dao.HeroDAO;

      public class HeroEditServlet extends HttpServlet {

      protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      int id = Integer.parseInt(request.getParameter("id"));
      Hero hero = new HeroDAO().get(id);
      request.setAttribute("hero", hero);
      request.getRequestDispatcher("editHero.jsp").forward(request, response);
      }
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      /* editHero.jsp */

      <%@ page language="java" contentType="text/html; charset=UTF-8"
      pageEncoding="UTF-8" import="java.util.*,bean.*,java.sql.*"%>

      <form action='updateHero' method='post'>
      名字:<input type='text' name='name' value='${hero.name}'> <br>
      血量:<input type='text' name='hp' value='${hero.hp}'> <br>
      伤害:<input type='text' name='damage' value='${hero.damage}'> <br>
      <input type='hidden' name='id' value='${hero.id}'>
      <input type='submit' value='更新'>
      </form>

2、查询

  • 使用 MVC 的思想,结合 Servlet 和 JSP 进行查询操作

  • 实体类 Hero.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    public class Hero {
    public int id;
    public String name;
    public float hp;
    public int damage;

    public int getId() {
    return id;
    }
    public void setId(int id) {
    this.id = id;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public float getHp() {
    return hp;
    }
    public void setHp(float hp) {
    this.hp = hp;
    }
    public int getDamage() {
    return damage;
    }
    public void setDamage(int damage) {
    this.damage = damage;
    }
    }
  • 使用 HeroDAO.java 从数据库查询数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    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;

    public class HeroDAO {

    public HeroDAO() {
    try {
    Class.forName("com.mysql.jdbc.Driver");
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
    }

    public Connection getConnection() throws SQLException {
    return DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8", "root", "admin");
    }

    public int getTotal() {
    int total = 0;
    try (Connection c = getConnection(); Statement s = c.createStatement();) {
    String sql = "select count(*) from hero";
    ResultSet rs = s.executeQuery(sql);
    while (rs.next()) {
    total = rs.getInt(1);
    }
    System.out.println("total:" + total);
    } catch (SQLException e) {
    e.printStackTrace();
    }
    return total;
    }

    public void add(Hero hero) {

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

    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();) {
    String sql = "delete from hero where id = " + id;
    s.execute(sql);
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }

    public Hero get(int id) {
    Hero hero = null;

    try (Connection c = getConnection(); Statement s = c.createStatement();) {
    String sql = "select * from hero where id = " + id;

    ResultSet rs = s.executeQuery(sql);
    if (rs.next()) {
    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;
    }

    public List<Hero> list() {
    return list(0, Short.MAX_VALUE);
    }

    public List<Hero> list(int start, int count) {
    List<Hero> heros = new ArrayList<Hero>();
    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;
    heros.add(hero);
    }
    } catch (SQLException e) {
    e.printStackTrace();
    }
    return heros;
    }
    }
  • 控制器的 HeroListServlet.java,其作用就是通过 dao 获取所有的 heros 对象,然后放在 request 中,跳转到 listHero.jsp。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import java.io.IOException;
    import java.util.List;

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

    import bean.Hero;
    import dao.HeroDAO;

    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);
    }
    }
  • web.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <web-app>
    <servlet>
    <servlet-name>HeroListServlet</servlet-name>
    <servlet-class>servlet.HeroListServlet</servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>HeroListServlet</servlet-name>
    <url-pattern>/listHero</url-pattern>
    </servlet-mapping>
    </web-app>
  • 作为视图的 listHero.jsp,其作用就是把控制器传过来的数据显示出来。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <%@ 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>

3、分页

  • 随着数据中记录的增多,网页上显示的数据会越来越多。当多到一定程度的时候,就会影响用户的体验。

  • 解决办法是通过分页技术,一次只显示数据库中的部分数据,如果要看其他数据,可以通过 “下一页” “最后一页” 等翻页操作实现。

4、登陆验证

  • 用户是否登陆

    • 比如网站提供 Hero 查询服务,但是前提是用户要登录过才能使用。
    • 如果用户登陆过了,访问 listHero,就让用户正常访问,否则就跳转到登陆界面。
  • 这是非常常见的场景,通过使用 session 来实现这个功能。

    • 在处理登录的 loginServlet 中使用将用户名保存在 session 中。
    • 在 HeroListServlet 中查看 session 中是否为空。如果为空,就表示用户没有登陆过,或者登录已经超过了30分钟,就跳转到登陆页面。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      private static final long serialVersionUID = 1L;

      protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      String name = request.getParameter("name");
      String password = request.getParameter("password");

      if ("admin".equals(name) && "123".equals(password)) {
      request.getSession().setAttribute("userName", name); // 设置 Session
      response.sendRedirect("listHero");
      } else {
      response.sendRedirect("login.html");
      }
      }
      1
      2
      3
      4
      5
      6
      7
      protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      String userName = (String) request.getSession().getAttribute("userName"); // 获取 Session
      if (null == userName) {
      response.sendRedirect("login.html");
      return;
      }
      }

5、CRUD

文章目录
  1. 1. 前言
  2. 2. 1、MVC
  3. 3. 2、查询
  4. 4. 3、分页
  5. 5. 4、登陆验证
  6. 6. 5、CRUD
隐藏目录