天天看點

初學Java Web(9)——學生管理系統(簡易版)總結

項目開始時間:2018年4月8日14:37:47

項目完成時間:2018年4月9日10:03:30

技術準備

這個項目是自己用于鞏固 J2EE 相關知識的練手項目,非常簡單,但是相關的功能卻非常實用,是以在這裡分享一下

為了完成這個項目,需要掌握如下技術:

  • Java

    基礎知識

  • 前端:

    HTML, CSS, JAVASCRIPT, JQUERY

  • J2EE:

    Tomcat, Servlet, JSP, Filter

  • 資料庫:

    MySQL

開發流程

項目雖然很簡單,很小,但是為了開發的有條不紊,還是按照商業項目的開發來完成。

① 需求分析

首先要确定要做哪些功能

  • 使用資料庫來儲存資料
  • 能增删改查學生的資訊(學号,名稱,年齡,性别,出生日期)

② 表結構設計

根據需求,那麼隻需要一個 student 表就能夠完成功能了。

  • 建立資料庫:student

    将資料庫編碼格式設定為 UTF-8 ,便于存取中文資料

DROP DATABASE IF EXISTS student;
CREATE DATABASE student DEFAULT CHARACTER SET utf8;
           
  • 建立學生表:student

    不用學生學号(studentID)作為主鍵的原因是:不友善操作,例如在更新資料的時候,同時也要更改學号,那這樣的操作怎麼辦呢?

    是以我們加了一個 id 用來唯一表示目前資料。

CREATE TABLE student(
  id int(11) NOT NULL AUTO_INCREMENT,
  studentID int(11) NOT NULL UNIQUE,
  name varchar(255) NOT NULL,
  age int(11) NOT NULL,
  sex varchar(255) NOT NULL,
  birthday date DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
           

③ 原型設計

就是設計界面,在商業項目中,這是很重要的一步,我們可以解除界面原型,低成本、高效率的與客戶達成需求的一緻性。

這個項目一共就分為兩個頁面:

  • 首頁面:
  • 學生編輯頁面:

④ 實體類的設計

實體類僅僅是對資料庫中表的一一映射,同時可能還需要兼顧對業務能力的支援。

  • 在 Packge[bean]下建立 Student 類:
package bean;

import java.util.Date;

public class Student {

	private int id;				// 在資料庫中的ID
	private int studentID;      // 學号,跟ID區分開為了友善資料庫操作
	private String name;		// 姓名
	private int age;			// 年齡
	private String sex;			// 性别
	private Date birthday;		// 出生日期

    // setter 和 getter (為節約篇幅沒列出來)
}
           

⑤ DAO 類的設計

DAO,即 Date Access Object,資料庫通路對象,就是對資料庫相關操作的封裝,讓其他地方看不到 JDBC 的代碼。

首先我們先建立一個資料庫操作的工具類:

  • 在 Packge[util]下建立 DBUtil 類:
/**
 * 資料庫工具類,這個類的作用是初始化驅動,并且提供一個getConnection用于擷取連接配接。
 */
package util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBUtil {

	static String ip = "127.0.0.1";
	static int port = 3306;
	static String database = "student";
	static String encoding = "UTF-8";
	static String loginName = "root";
	static String password = "root";

	static {

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

	public static Connection getConnection() throws SQLException {
		String url = String.format("jdbc:mysql://%s:%d/%s?characterEncoding=%s", ip, port, database, encoding);
		return DriverManager.getConnection(url, loginName, password);
	}

	public static void main(String[] args) throws SQLException {
		System.out.println(getConnection());

	}

}
           
  • 寫工具類的好處:

    便于統一維護,降低維護成本

然後是 DAO 類,除了進行典型的 ORM 支援功能之外,也需要提供各種業務方法。

  • 在 Packge[dao]下建立 StudentDAO 類:
package dao;

import bean.Student;
import util.DBUtil;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class StudentDAO {

	public int getTotal() {

		int total = 0;

		String sql = "SELECT COUNT(*) FROM student";
		try (Connection c = DBUtil.getConnection(); Statement st = c.createStatement()) {

			ResultSet rs = st.executeQuery(sql);
			while (rs.next()) {
				total = rs.getInt(1);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return total;
	}

	public void add(Student student) {

		String sql = "INSERT INTO student VALUES(NULL,?,?,?,?,?)";
		try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql)) {

			ps.setInt(1, student.getStudentID());
			ps.setString(2, student.getName());
			ps.setInt(3, student.getAge());
			ps.setString(4, student.getSex());
			ps.setDate(5, new java.sql.Date(student.getBirthday().getTime()));

			ps.execute();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public void delete(int id) {

		String sql = "DELETE FROM student WHERE ID = ?";
		try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql)) {

			ps.setInt(1, id);

			ps.execute();

		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public void update(Student student) {

		String sql = "update student set student_id = ?, name = ?, age = ?, sex = ?, birthday = ? where id = ? ";
		try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql)) {

			ps.setInt(1, student.getStudentID());
			ps.setString(2, student.getName());
			ps.setInt(3, student.getAge());
			ps.setString(4, student.getSex());
			ps.setDate(5, new java.sql.Date(student.getBirthday().getTime()));
			ps.setInt(6, student.getId());

			ps.execute();

		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public Student get(int id) {

		Student student = new Student();

		String sql = "SELECT * FROM student WHERE ID = " + id;
		try (Connection c = DBUtil.getConnection(); Statement st = c.createStatement()) {

			ResultSet rs = st.executeQuery(sql);

			if (rs.next()) {

				int student_id = rs.getInt("student_id");
				String name = rs.getString("name");
				int age = rs.getInt("age");
				String sex = rs.getString("sex");
				Date birthday = rs.getDate("birthday");
				student.setStudentID(student_id);
				student.setName(name);
				student.setAge(age);
				student.setSex(sex);
				student.setBirthday(birthday);
				student.setId(id);
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}

		return student;
	}

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

	public List<Student> list(int start, int count) {

		List<Student> students = new ArrayList<>();

		String sql = "SELECT * FROM student ORDER BY student_id desc limit ?,?";

		try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql)) {

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

			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				Student student = new Student();
				int id = rs.getInt("id");
				int studentID = rs.getInt("student_id");
				String name = rs.getString("name");
				int age = rs.getInt("age");
				String sex = rs.getString("sex");
				Date birthday = rs.getDate("birthday");
				student.setId(id);
				student.setStudentID(studentID);
				student.setName(name);
				student.setAge(age);
				student.setSex(sex);
				student.setBirthday(birthday);

				students.add(student);
			}

			rs.close();

		} catch (SQLException e) {
			e.printStackTrace();
		}

		return students;
	}

}
           
  • 該類中,既提供了增删改查這些基本的 CRUD 操作

    1.增加:

    public void add(Student student)

    2.删除:

    public void delete(int id)

    3.修改:

    public void update(Student student)

    4.查詢所有:

    public List<Student> list()

  • 又提供了一些非 CRUD 方法

    1.擷取總數:

    public int getTotal()

    2.根據 id 擷取:

    public Student get(int id)

⑥ 業務類介紹

作為 J2EE Web 應用,一般都會按照如圖所示的設計流程進行:

Servlet -> Service(業務類) -> DAO -> database

當浏覽器送出請求到 Tomcat Web 伺服器的時候,對應的 Servlet 的doGet/doPost 方法會被調用,接着在 Servlet 中調用 Service類,然後在 Service 類中調用DAO類,最後在 DAO 中通路資料庫擷取相應的資料。

單本項目沒有使用 Service 這一層,原因是在對 DAO 類進行開發中,已經提供了很好的支援業務的方法,沒有必要再包括上一層 Service 業務類。

參考連結:這裡

⑦ 功能開發

需要按照子產品之間的依賴關系,順序開發。

  • 首先為項目添加必要的 jar 包:

    jstl.jar

    mysql-connector-java-5.0.8-bin.jar

    servlet-api.jar

    standard.jar

    這也是 Web 開發中最基本的 4 個包

——【1.編寫 Filter】——

由于項目中設計表單 POST 方式的送出,是以我們先來編寫好相關編碼的過濾器,好支援中文的存取

  • 在 Packge[filter] 下編寫 EncodingFilter 類:
package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter("/*")
public class EncodingFilter implements Filter {

	public void destroy() {
	}

	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {

		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;

        // 設定編碼格式為 UTF-8
		request.setCharacterEncoding("UTF-8");

		chain.doFilter(request, response);
	}

	public void init(FilterConfig config) throws ServletException {
	}

}
           

——【2. 編寫 Servlet 】——

按照傳統的方式,我們項目的業務為增删改查,是以對應四個路徑,也就是需要編寫四個 Servlet 才可以

  • AddServlet:
package servlet;

import bean.Student;
import dao.StudentDAO;

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 java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

@WebServlet("/addStudent")
public class AddServlet extends HttpServlet {

	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		Student student = new Student();

        // 直接從表單中擷取資料
		int studentID = Integer.parseInt(req.getParameter("studentID"));
		String name = req.getParameter("name");
		int age = Integer.parseInt(req.getParameter("age"));
		String sex = req.getParameter("radio");
		Date birthday = null;

		// String 類型按照 yyyy-MM-dd 的格式轉換為 java.util.Date 類
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		try {
			birthday = simpleDateFormat.parse(req.getParameter("birthday"));
		} catch (ParseException e) {
			e.printStackTrace();
		}

		student.setStudentID(studentID);
		student.setName(name);
		student.setAge(age);
		student.setSex(sex);
		student.setBirthday(birthday);

		new StudentDAO().add(student);

		resp.sendRedirect("/listStudent");  // 這裡可以了解為重新整理,重新請求
	}
}
           
  • DeleteServlet:
package servlet;

import dao.StudentDAO;

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 java.io.IOException;

@WebServlet("/deleteStudent")
public class DeleteServlet extends HttpServlet {

	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		int id = Integer.parseInt(req.getParameter("id"));
		new StudentDAO().delete(id);

		resp.sendRedirect("/listStudent");
	}
}
           
  • EditServlet:
package servlet;

import bean.Student;
import dao.StudentDAO;

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 java.io.IOException;

@WebServlet("/editStudent")
public class EditServlet extends HttpServlet {

	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		int id = Integer.parseInt(req.getParameter("id"));
		Student student = new StudentDAO().get(id);

		req.setAttribute("student", student);

		req.getRequestDispatcher("/editStudent.jsp").forward(req, resp);
	}
}
           
  • ListServlet:
package servlet;

import bean.Student;
import dao.StudentDAO;
import util.Page;

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 java.io.IOException;
import java.util.List;

@WebServlet("/listStudent")
public class ListServlet extends HttpServlet {

	private StudentDAO studentDAO = new StudentDAO();

	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 擷取分頁參數
		int start = 0;
		int count = 10;

		try {
			start = Integer.parseInt(req.getParameter("page.start"));
			count = Integer.parseInt(req.getParameter("page.count"));
		} catch (Exception e) {
		}

		Page page = new Page(start, count);

		List<Student> students = studentDAO.list(page.getStart(), page.getCount());
		int total = studentDAO.getTotal();
		page.setTotal(total);

		req.setAttribute("students", students);
		req.setAttribute("page", page);

		req.getRequestDispatcher("/listStudent.jsp").forward(req, resp);
	}
}
           
  • UpdateServlet:
package servlet;

import bean.Student;
import dao.StudentDAO;

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 java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

@WebServlet("/updateStudent")
public class UpdateServlet extends HttpServlet {

	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		Student student = new Student();

		int id = Integer.parseInt(req.getParameter("id"));
		int studentID = Integer.parseInt(req.getParameter("studentID"));
		String name = req.getParameter("name");
		int age = Integer.parseInt(req.getParameter("age"));
		String sex = req.getParameter("radio");

		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		Date birthday = null;
		try {
			birthday = simpleDateFormat.parse(req.getParameter("birthday"));
		} catch (ParseException e) {
			e.printStackTrace();
		}

		student.setId(id);
		student.setStudentID(studentID);
		student.setName(name);
		student.setAge(age);
		student.setSex(sex);
		student.setBirthday(birthday);

		new StudentDAO().update(student);

		resp.sendRedirect("/listStudent");
	}
}
           

——【3. JSP 的編寫】——

我們把預設的 index.jsp 修改成如下代碼:

<%
    request.getRequestDispatcher("/listStudent").forward(request, response);
%>
           
  • 引入 JQ 和 Bootstrap

    為了簡化操作,引入了 JQuery 和 Bootstrap

  • 編寫 listStudent.jsp

    其實主要還是利用 Bootstrap 編寫好整個頁面,我寫的時候也是對照這裡寫的

<!DOCTYPE html>
<%@ page contentType="text/html;charset=UTF-8" language="java"
         pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<html>
<head>

    <%-- 引入JQ和Bootstrap --%>
    <script src="js/jquery/2.0.0/jquery.min.js"></script>
    <link href="css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
    <script src="js/bootstrap/3.3.6/bootstrap.min.js"></script>
    <link href="css/style.css" rel="stylesheet">

    <title>學生管理頁面 - 首頁</title>

    <script>
        $(function () {
            $("ul.pagination li.disabled a").click(function () {
                return false;
            });
        });
    </script>
</head>

<body>

<div class="listDIV">
    <table class="table table-striped table-bordered table-hover table-condensed">

        <caption>學生清單 - 共${page.total}人</caption>
        <thead>
        <tr class="success">
            <th>學号</th>
            <th>姓名</th>
            <th>年齡</th>
            <th>性别</th>
            <th>出生日期</th>

            <th>編輯</th>
            <th>删除</th>
        </tr>
        </thead>

        <tbody>
        <c:forEach items="${students}" var="s" varStatus="status">
            <tr>
                <td>${s.studentID}</td>
                <td>${s.name}</td>
                <td>${s.age}</td>
                <td>${s.sex}</td>
                <td>${s.birthday}</td>

                <td><a href="/editStudent?id=${s.id}"><span class="glyphicon glyphicon-edit"></span> </a></td>
                <td><a href="/deleteStudent?id=${s.id}"><span class="glyphicon glyphicon-trash"></span> </a></td>
            </tr>
        </c:forEach>

        </tbody>
    </table>
</div>

<nav class="pageDIV">
    <ul class="pagination">
        <li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
            <a href="?page.start=0">
                <span>«</span>
            </a>
        </li>

        <li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
            <a href="?page.start=${page.start-page.count}">
                <span>‹</span>
            </a>
        </li>

        <c:forEach begin="0" end="${page.totalPage-1}" varStatus="status">

            <c:if test="${status.count*page.count-page.start<=30 && status.count*page.count-page.start>=-10}">
                <li <c:if test="${status.index*page.count==page.start}">class="disabled"</c:if>>
                    <a
                            href="?page.start=${status.index*page.count}"
                            <c:if test="${status.index*page.count==page.start}">class="current"</c:if>
                    >${status.count}</a>
                </li>
            </c:if>
        </c:forEach>

        <li <c:if test="${!page.hasNext}">class="disabled"</c:if>>
            <a href="?page.start=${page.start+page.count}">
                <span>›</span>
            </a>
        </li>
        <li <c:if test="${!page.hasNext}">class="disabled"</c:if>>
            <a href="?page.start=${page.last}">
                <span>»</span>
            </a>
        </li>
    </ul>
</nav>

<div class="addDIV">

    <div class="panel panel-success">
        <div class="panel-heading">
            <h3 class="panel-title">增加學生</h3>
        </div>
        <div class="panel-body">

            <form method="post" action="/addStudent" role="form">
                <table class="addTable">
                    <tr>
                        <td>學号:</td>
                        <td><input type="text" name="studentID" id="studentID" placeholder="請在這裡輸入學号"></td>
                    </tr>
                    <tr>
                        <td>姓名:</td>
                        <td><input type="text" name="name" id="name" placeholder="請在這裡輸入名字"></td>
                    </tr>
                    <tr>
                        <td>年齡:</td>
                        <td><input type="text" name="age" id="age" placeholder="請在這裡輸入年齡"></td>
                    </tr>
                    <tr>
                        <td>性别:</td>
                        <td><input type="radio" class="radio radio-inline" name="radio" value="男"> 男
                            <input type="radio" class="radio radio-inline" name="radio" value="女"> 女
                        </td>
                    </tr>
                    <tr>
                        <td>出生日期:</td>
                        <td><input type="date" name="birthday" id="birthday" placeholder="請在這裡輸入出生日期"></td>
                    </tr>
                    <tr class="submitTR">
                        <td colspan="2" align="center">
                            <button type="submit" class="btn btn-success">提 交</button>
                        </td>

                    </tr>

                </table>
            </form>
        </div>
    </div>

</div>

</body>
</html>
           
  • eidtStudent.jsp

    編輯表單對照着首頁的增加表單稍微改一改參數就好了

<!DOCTYPE html>
<%@ page contentType="text/html;charset=UTF-8" language="java"
         pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>

    <%-- 引入JQ和Bootstrap --%>
    <script src="js/jquery/2.0.0/jquery.min.js"></script>
    <link href="css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">
    <script src="js/bootstrap/3.3.6/bootstrap.min.js"></script>
    <link href="css/style.css" rel="stylesheet">

    <title>學生管理頁面 - 編輯頁面</title>
</head>

<body>

<div class="editDIV">

    <div class="panel panel-success">
        <div class="panel-heading">
            <h3 class="panel-title">編輯學生</h3>
        </div>
        <div class="panel-body">

            <form method="post" action="/updateStudent" role="form">
                <table class="editTable">
                    <tr>
                        <td>學号:</td>
                        <td><input type="text" name="studentID" id="studentID" value="${student.studentID}"
                                   placeholder="請在這裡輸入學号"></td>
                    </tr>
                    <tr>
                        <td>姓名:</td>
                        <td><input type="text" name="name" id="name" value="${student.name}" placeholder="請在這裡輸入名字">
                        </td>
                    </tr>
                    <tr>
                        <td>年齡:</td>
                        <td><input type="text" name="age" id="age" value="${student.age}" placeholder="請在這裡輸入年齡"></td>
                    </tr>
                    <tr>
                        <td>性别:</td>
                        <td><input type="radio" class="radio radio-inline" name="radio" value="男"> 男
                            <input type="radio" class="radio radio-inline" name="radio" value="女"> 女
                        </td>
                    </tr>
                    <tr>
                        <td>出生日期:</td>
                        <td><input type="date" name="birthday" id="birthday" value="${student.birthday}"
                                   placeholder="請在這裡輸入出生日期"></td>
                    </tr>
                    <tr class="submitTR">
                        <td colspan="2" align="center">
                            <input type="hidden" name="id" value="${student.id}">
                            <button type="submit" class="btn btn-success">提 交</button>
                        </td>

                    </tr>

                </table>
            </form>
        </div>
    </div>

</div>

</body>
</html>
           
  • style.css 檔案:
body {
    padding-top: 60px;
}

div.listDIV {
    width: 600px;
    margin: 0 auto;
}

div.editDIV {
    width: 400px;
    margin: 0 auto;
}

nav.pageDIV {
    text-align: center;
}

div.addDIV {
    width: 300px;
    margin: 0 auto;
}

table.addTable {
    width: 100%;
    padding: 5px;
}

table.addTable td {
    padding: 5px;
}

table.editTable {
    width: 100%;
    padding: 5px;
}

table.editTable td {
    padding: 5px;
}
           

——【4. 項目細節】——

  • 項目的整理結構:

分頁功能

  • 首頁在 Packge[util] 下建立一個 Page 工具類:
package util;

public class Page {

	int start;		// 開始資料
	int count;		// 每一頁的數量
	int total;		// 總共的資料量

	public Page(int start, int count) {
		super();
		this.start = start;
		this.count = count;
	}

	public boolean isHasPreviouse(){
		if(start==0)
			return false;
		return true;

	}
	public boolean isHasNext(){
		if(start==getLast())
			return false;
		return true;
	}

	public int getTotalPage(){
		int totalPage;
		// 假設總數是50,是能夠被5整除的,那麼就有10頁
		if (0 == total % count)
			totalPage = total /count;
			// 假設總數是51,不能夠被5整除的,那麼就有11頁
		else
			totalPage = total / count + 1;

		if(0==totalPage)
			totalPage = 1;
		return totalPage;

	}

	public int getLast(){
		int last;
		// 假設總數是50,是能夠被5整除的,那麼最後一頁的開始就是40
		if (0 == total % count)
			last = total - count;
			// 假設總數是51,不能夠被5整除的,那麼最後一頁的開始就是50
		else
			last = total - total % count;

		last = last<0?0:last;
		return last;
	}

    // 各種 setter 和 getter
}
           
  • totalPage 是計算得來的數,用來表示頁碼一共的數量

在首頁顯示的 StudentList 用 page 的參數來擷取:

List<Student> students = studentDAO.list(page.getStart(), page.getCount());
           

并且在 DAO 類中用 LIMIT 關鍵字:

String sql = "SELECT * FROM student ORDER BY student_id desc limit ?,?";
           
  • 第一個參數為 start,第二個參數為 count

    這樣就能根據分頁的資訊來擷取到響應的資料

  • 編寫分頁欄:

1.寫好頭和尾

<nav class="pageDIV">
    <ul class="pagination">
    .....
    </ul>
</nav>
           

2.寫好

«

這兩個功能按鈕

使用

<c:if>

标簽來增加邊界判斷,如果沒有前面的頁碼了則設定為disable狀态

<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
            <a href="?page.start=0">
                <span>«</span>
            </a>
        </li>

        <li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
            <a href="?page.start=${page.start-page.count}">
                <span>‹</span>
            </a>
        </li>
           

再通過 JavaScrip 代碼來完成禁用功能:

<script>
    $(function () {
        $("ul.pagination li.disabled a").click(function () {
            return false;
        });
    });
</script>
           

3.完成中間頁碼的編寫

循環到

page.totalPage - 1

varStatus

相當于是循環變量

  • status.count 是從1開始周遊
  • status.index 是從0開始周遊
  • 要求:顯示目前頁碼的前兩個和後兩個就可,例如目前頁碼為3的時候,就顯示 1 2 3(目前頁) 4 5 的頁碼
  • 了解測試條件:

    -10 <= 目前頁*每一頁顯示的數目 - 目前頁開始的資料編号 <= 30

  • 隻要了解了這個判斷條件,其他的就都好了解了
<c:forEach begin="0" end="${page.totalPage-1}" varStatus="status">

    <c:if test="${status.count*page.count-page.start<=30 && status.count*page.count-page.start>=-10}">
        <li <c:if test="${status.index*page.count==page.start}">class="disabled"</c:if>>
            <a
                    href="?page.start=${status.index*page.count}"
                    <c:if test="${status.index*page.count==page.start}">class="current"</c:if>
            >${status.count}</a>
        </li>
    </c:if>
</c:forEach>
           

4.在 Servlet 中擷取參數

// 擷取分頁參數
int start = 0;
int count = 10;

try {
	start = Integer.parseInt(req.getParameter("page.start"));
	count = Integer.parseInt(req.getParameter("page.count"));
} catch (Exception e) {
}

....

// 共享 page 資料
req.setAttribute("page", page);
           

Date 轉換的問題

/**
     * Date類型轉為指定格式的String類型
     * 
     * @param source
     * @param pattern
     * @return
     */
    public static String DateToString(Date source, String pattern) {
        simpleDateFormat = new SimpleDateFormat(pattern);
        return simpleDateFormat.format(source);
    }
           
/**
     * 
     * 字元串轉換為對應日期
     * 
     * @param source
     * @param pattern
     * @return
     */
    public static Date stringToDate(String source, String pattern) {
        simpleDateFormat = new SimpleDateFormat(pattern);
        Date date = null;
        try {
            date = simpleDateFormat.parse(source);
        } catch (Exception e) {
        }
        return date;
    }
           

項目總結

這一個項目實在有些太簡單了,可能最需要了解的一個功能就屬于【分頁功能】了吧

不過還是借助這個項目,進一步鞏固了 J2EE 開發的相關知識,也對開發的流程愈發熟悉,整個項目編寫時間不超過 8 個小時,對于我自己來說,不算快,但還算比較順暢的

需要改進的地方:

  1. 登入驗證

    本項目沒有增加登入驗證,可以增加一個登入頁面并結合 session 來完成驗證

  2. 代碼重構

    本項目僅僅完成的是一個學生表的增删改查,卻有以下的五個 Servlet :

如果項目大起來,那可想而知,Servlet 有多臃腫,維護成本有多高

  • 改進方法:用一個 StudentServlet 代替
  • 具體做法:使用 Filter + Servlet 完成
① 首先編寫一個過濾所有位址的 Filter,并解析位址欄的位址,提取出其中的方法傳遞給 StudentServlet (這個時候需要統一的位址,如:

student_list

student_edit

student_delete

student_update

request.setAttribute("method", method);
           
② 在 Servlet 中擷取 method 方法,并調用
// 擷取到對應的方法
String method = (String) request.getAttribute("method");
// 對 method 作判斷,調用對應的方法
           
  1. 沒有對輸入的資料的正确性進行驗證

    這顯然會導緻許多問題,可以通過 js 代碼來完成驗證

歡迎轉載,轉載請注明出處!

簡書ID:@我沒有三顆心髒

github:wmyskxz

歡迎關注公衆微信号:wmyskxz_javaweb

分享自己的Java Web學習之路以及各種Java學習資料

繼續閱讀