天天看点

学生管理系统(JSP+Servlet+MySQL+BootStrap)1.缘起2. 使用的技术3.实现的功能以及截图4.核心步骤4.页面跳转的一些问题5.总结

1.缘起

刚刚接触一点JavaWeb,会一点Servlet和JSP,所以想写点东西,巩固一下知识。因为刚刚入门,本着能做出来就行的目标完成了这个《学生管理系统》小项目。写博客就是想梳理一下流程,回顾一下,大佬请绕道。

2. 使用的技术

前端:HTML+CSS+Bootstrap

后台:JSP+Servlet

数据库:MySQL(JDBC)

3.实现的功能以及截图

  1. Bootstrap实现具有轮播背景的登陆页面
  2. 学生信息的增删改查(可以根据学生id或学生name查询)
  3. 实现了分页
  4. 修改管理员信息
  5. 退出系统

1.登陆页面

学生管理系统(JSP+Servlet+MySQL+BootStrap)1.缘起2. 使用的技术3.实现的功能以及截图4.核心步骤4.页面跳转的一些问题5.总结

2.主页面

学生管理系统(JSP+Servlet+MySQL+BootStrap)1.缘起2. 使用的技术3.实现的功能以及截图4.核心步骤4.页面跳转的一些问题5.总结

3.添加学生信息页面

学生管理系统(JSP+Servlet+MySQL+BootStrap)1.缘起2. 使用的技术3.实现的功能以及截图4.核心步骤4.页面跳转的一些问题5.总结

4.更新学生信息页面

学生管理系统(JSP+Servlet+MySQL+BootStrap)1.缘起2. 使用的技术3.实现的功能以及截图4.核心步骤4.页面跳转的一些问题5.总结

5.修改管理员信息页面

学生管理系统(JSP+Servlet+MySQL+BootStrap)1.缘起2. 使用的技术3.实现的功能以及截图4.核心步骤4.页面跳转的一些问题5.总结

4.核心步骤

1.JDBC的封装,因为在进行数据库的操作中,有很多步骤是重复的,而且一些步骤和sql语句无关,我们可以将其封装成一个工具类,这将大大减小代码量,更便于维护。

DBUtil

package cn.yf.util;

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

public class DBUtil {
	
	private static final String URL = "jdbc:mysql://127.0.0.1:3306/sms?characterEncoding=UTF-8";
	private static final String NAME = "root";
	private static final String PASSWORD="admin";
	public static Connection connection = null;
	public static PreparedStatement ps = null;
	public static ResultSet rs = null;
	
	//获得连接
	public static Connection getConnection(){
		try{
			Class.forName("com.mysql.jdbc.Driver");
			connection = DriverManager.getConnection(URL, NAME, PASSWORD);
		}catch(ClassNotFoundException e){
			e.printStackTrace();
		}catch(SQLException e){
			e.printStackTrace();
		}
		return connection;
	}
	
	//获得PreparedStatement
	public static PreparedStatement getPreparedStatement(String sql,Object[] params){
		try{
			ps = DBUtil.getConnection().prepareStatement(sql);
			if(params != null){
				for(int i=0; i<params.length; i++){
					//这里是从1开始的
					ps.setObject(i+1, params[i]);
				}
			}
		}catch(SQLException e){
			e.printStackTrace();
		}
		return ps;
	}
	
	//关闭
	public static void close(Connection c, PreparedStatement ps, ResultSet rs){
		try{
			if(rs != null) rs.close();
			if(ps != null) ps.close();
			if(rs != null) rs.close();
		}catch(SQLException e){
			e.printStackTrace();
		}
	}
	
	//通用的增删改
	public static boolean generalUpdate(String sql, Object[] params){
		ps = DBUtil.getPreparedStatement(sql, params);
		int count = -1;
		try {
			count = ps.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if(count>0){
			return true;
		}else{
			return false;
		}
	}
	
	//通用的查询(条件查询)
	public static ResultSet generalQuery(String sql, Object[] params){
		ps = DBUtil.getPreparedStatement(sql, params);
		try {
			rs = ps.executeQuery();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return rs;
	}
	
	//查询数据库中的所有数据个数
	public static int QueryAll(String sql){
		int count = 0;
		try {
			rs = DBUtil.generalQuery(sql, null);
			if(rs.next()){
				count = rs.getInt(1);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return count;
	}
	
	
}

           

这里需要注意的有2点:

1.对数据库的操作,整体来说分二种,第一种就是增删改也就是ps.executeUpdate(),它的返回值类型是int,代表的意思是成功操作的个数,所以这里我们只需要根据它的返回值是不是大于0即可判断是否执行成功。第二种就是查询ps.executeQuery(),因为不同的查询返回的东西不一样,我们在工具类中统一返回ResultSet。

2.因为sql语句的不同,我们需要从外面传入sql语句,而且sql语句中是有参数的,并且不知道参数的类型,这里我们用一个Object[]数组来存放这些参数。并且使用ps.setObject(i+1, params[i]);设置这些参数。这里需要注意的是PreparedStatement对象中的setObject是基于1的所有这里我们使用i+1。

到这里我们的JDBC已经封装好,对于不同的数据库操作,我们只需要准备好sql语句,以及相应的参数,调用DBUtil即可

下面是StudentDao代码

package cn.yf.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.yf.entity.Student;
import cn.yf.util.DBUtil;
import cn.yf.util.DateUtil;

public class StudentDao {
	
	//添加学生
	public boolean addStudent(Student student){
		String sql = "insert into student values(null,?,?,?,?,?,?)";
		Object params[] = {student.getName(),
		student.getSex(),student.getBirth(),student.getSchoolday(),student.getMarjor_id(),student.getCollege_id()}; 
		boolean result = DBUtil.generalUpdate(sql, params);
		return result;
	}
	
	//删除学生(根据id删除)
	public boolean deleteStudent(int id){
		String sql = "delete from student where id = ?";
		Object[] params = {id};
		boolean result = DBUtil.generalUpdate(sql, params);
		return result;
	}
	
	//根据id修改学生信息
	public boolean updateStudent(int id,Student student){
		String sql = "update student set name=?,sex=?,birth=?,schoolday=?,marjor_id=?,college_id=? where id = ?";
		Object[] params = {student.getName(),student.getSex(),student.getBirth(),student.getSchoolday(),student.getMarjor_id(),student.getCollege_id(),id};
		boolean result = DBUtil.generalUpdate(sql, params);
		return result;
	}
	
	//查询所有学生
	public List<Student> queryAllStudent(){
		List<Student> students = new ArrayList<Student>();
		Student s = null;
		try {
			String sql = "select * from student";
			ResultSet rs = DBUtil.generalQuery(sql, null);
			while(rs.next()){
				int id = rs.getInt("id");
				String name = rs.getString("name");
				int sex = rs.getInt("sex");
				Date birth = DateUtil.t2d(rs.getTimestamp("birth"));
				Date schoolday = DateUtil.t2d(rs.getTimestamp("schoolday"));
				int marjor_id = rs.getInt("marjor_id");
				int college_id = rs.getInt("college_id");
				s = new Student(id,name,sex,birth,schoolday,marjor_id,college_id);
				students.add(s);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return students;
	}
	
	//根据id查询
	public List<Student> queryStudentById(int id){
		Student s = null;
		List<Student> students = new ArrayList<Student>();
		try {
			String sql = "select * from student where id = ?";
			Object[] params = {id};
			ResultSet rs = DBUtil.generalQuery(sql, params);
			while(rs.next()){
				int id1 = rs.getInt("id");
				String name = rs.getString("name");
				int sex = rs.getInt("sex");
				Date birth = DateUtil.t2d(rs.getTimestamp("birth"));
				Date schoolday = DateUtil.t2d(rs.getTimestamp("schoolday"));
				int marjor_id = rs.getInt("marjor_id");
				int college_id = rs.getInt("college_id");
				s = new Student(id1,name,sex,birth,schoolday,marjor_id,college_id);
				students.add(s);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return students;
	}
	
	//根据姓名查询
	public List<Student> queryStudentByName(String name){
		List<Student> students = new ArrayList<Student>();
		Student s = null;
		try {
			String sql = "select * from student where name = ?";
			Object[] params = {name};
			ResultSet rs = DBUtil.generalQuery(sql, params);
			while(rs.next()){
				int id1 = rs.getInt("id");
				String name1 = rs.getString("name");
				int sex = rs.getInt("sex");
				Date birth = DateUtil.t2d(rs.getTimestamp("birth"));
				Date schoolday = DateUtil.t2d(rs.getTimestamp("schoolday"));
				int marjor_id = rs.getInt("marjor_id");
				int college_id = rs.getInt("college_id");
				s = new Student(id1,name1,sex,birth,schoolday,marjor_id,college_id);
				students.add(s);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return students;
	}
	
	//查询Student表中的数据个数
	public int QueryAll(){
		String sql = "select count(*) from student";
		return DBUtil.QueryAll(sql);
	}
	
	//查询当前页的数据
	public List<Student> queryCurrentPage(int currentPage,int pageSize){
		String sql = "SELECT * FROM STUDENT LIMIT ?,?";
		Object[] params = {(currentPage-1)*pageSize,pageSize};
		ResultSet rs = DBUtil.generalQuery(sql, params);
		Student s = null;
		List<Student> students = new ArrayList<>();
		try {
			while(rs.next()){
				int id1 = rs.getInt("id");
				String name1 = rs.getString("name");
				int sex = rs.getInt("sex");
				Date birth = DateUtil.t2d(rs.getTimestamp("birth"));
				Date schoolday = DateUtil.t2d(rs.getTimestamp("schoolday"));
				int marjor_id = rs.getInt("marjor_id");
				int college_id = rs.getInt("college_id");
				s = new Student(id1,name1,sex,birth,schoolday,marjor_id,college_id);
				students.add(s);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return students;
	}
	
		
}

           

2.前端遇到的一些问题

1.我的主页面使用的是frameset框架页面

<frameset rows="20%,*" frame framespacing="10">
	<frame src="top.jsp" noresize="noresize" scrolling="no" />
	<frameset cols="20%,*">
		<frame src="Left_nav.jsp" noresize="noresize" />
		<frame src="Page.jsp" name="contain"/>
	</frameset>
</frameset>
           

有时候很多时候要进行页面跳转,我们在跳转的时候,一定要加上target="_parent"这个属性,不然它会在子页面中跳转。

3.如何分页

我们设想一下,假如我们要进行分页,我们在页面的时候,点击下一页的时候,我们需要给后台传什么值?

当然是当前页,以及一页有多少条数据。

因为我使用的MySQL,所以首先来讲一下实现分页的sql语句,SELECT * FROM TABLE LIMIT A,B

这个sql语句的意思就是从a条数据开始,数b条数据出来。这就是我们分页的sql原理。

我们将当前页用currentPage,页面大小用pageSize表示,因为MySQL是基于0的,那么此时的sql语句是,SELECT * FROM TABLE LIMIT (currentPage-1)pageSize,pageSize。

为了帮助我们实现分页,我们需要准备一个分页帮助类Page

package cn.yf.entity;

import java.util.List;

public class Page {
	
	//当前页
	private int currentPage;
	//页面大小
	private int pageSize;
	//数据总数
	private int totalCount;
	//总页数
	private int totalPage;
	//当前页的数据集合
	private List<Student> students;
	
	public Page() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	public Page(int currentPage, int pageSize, int totalCount, int totalPage, List<Student> students) {
		super();
		this.currentPage = currentPage;
		this.pageSize = pageSize;
		this.totalCount = totalCount;
		this.totalPage = totalPage;
		this.students = students;
	}
	public int getCurrentPage() {
		return currentPage;
	}
	public void setCurrentPage(int currentPage) {
		this.currentPage = currentPage;
	}
	public int getpageSize() {
		return pageSize;
	}
	
	public void setpageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	
	public int getTotalCount() {
		return totalCount;
	}
	public void setTotalCount(int totalCount) {
		this.totalCount = totalCount;
	}
	public int getTotalPage() {
		return totalPage;
	}
	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}
	public List<Student> getStudents() {
		return students;
	}
	public void setStudents(List<Student> students) {
		this.students = students;
	}
	
	@Override
	public String toString() {
		return "Page [currentPage=" + currentPage + ", pageSize=" + pageSize + ", totalCount=" + totalCount
				+ ", totalPage=" + totalPage + ", students=" + students + "]";
	}
	
	
}

           

我们还需要知道数据总数(totalCount)以及每页的数据集合(students),这个我们可以通过封装好的DBUtil实现

//查询Student表中的数据个数
	public int QueryAll(){
		String sql = "select count(*) from student";
		return DBUtil.QueryAll(sql);
	}
	
	//查询当前页的数据
	public List<Student> queryCurrentPage(int currentPage,int pageSize){
		String sql = "SELECT * FROM STUDENT LIMIT ?,?";
		Object[] params = {(currentPage-1)*pageSize,pageSize};
		ResultSet rs = DBUtil.generalQuery(sql, params);
		Student s = null;
		List<Student> students = new ArrayList<>();
		try {
			while(rs.next()){
				int id1 = rs.getInt("id");
				String name1 = rs.getString("name");
				int sex = rs.getInt("sex");
				Date birth = DateUtil.t2d(rs.getTimestamp("birth"));
				Date schoolday = DateUtil.t2d(rs.getTimestamp("schoolday"));
				int marjor_id = rs.getInt("marjor_id");
				int college_id = rs.getInt("college_id");
				s = new Student(id1,name1,sex,birth,schoolday,marjor_id,college_id);
				students.add(s);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return students;
	}
           

当我们知道数据总数和页面大小后,页面的总数量(totalPage)就可以求出来

totalPage = totalCount%pageSize==0?totalCount/pageSize:totalCount/pageSize+1;

这样我们分页所需要的五个值,就都得到了,我们只需要将其封装成Page对象然后传到jsp页面即可

分页的Servlet

package cn.yf.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 javax.servlet.http.HttpSession;

import cn.yf.entity.Page;
import cn.yf.entity.Student;
import cn.yf.service.StudentService;

/**
 * Servlet implementation class QueryStudentByPage
 */
@WebServlet("/QueryStudentByPage")
public class QueryStudentByPage extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		StudentService service = new StudentService();
		// student表数据数总数
		int totalCount = service.QueryAll();
		// 每页的大小
		int pageSize = 10;
		// 总页数
		int totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
		// 当前页
		String passPage = request.getParameter("passPage");
		int currentPage = -1;
		if (passPage == null) {
			passPage = "1";
			currentPage = Integer.parseInt(passPage);
		}else if(Integer.parseInt(passPage)>=totalPage){
			currentPage = totalPage;
		}else if(Integer.parseInt(passPage)<=1){
			currentPage = 1;
		}else{
			currentPage = Integer.parseInt(passPage);
		}
		// 当前页的数据集合
		List<Student> students = service.queryCurrentPage(currentPage, pageSize);

		Page page = new Page();
		page.setTotalCount(totalCount);
		page.setpageSize(pageSize);
		page.setStudents(students);
		page.setCurrentPage(currentPage);
		page.setTotalPage(totalPage);
		HttpSession session = request.getSession();
		session.setAttribute("page", page);
		response.sendRedirect("main.jsp");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

           

这里我们做了一个判断,因为当我们第一次访问时,是没有当前页的值的,这个为空,所有我们设置,如果当前页为空,我们给他一个值为1,也就是第一页。

分页的jsp

<%@page import="cn.yf.entity.Page"%>
<%@page import="cn.yf.entity.Student"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/jquery/2.0.0/jquery.min.js"></script>
<link rel="stylesheet" href="css/bootstrap/3.3.6/bootstrap.min.css" target="_blank" rel="external nofollow"  />
<script type="text/javascript" src="js/bootstrap/3.3.6/bootstrap.min.js"></script>
<link rel="stylesheet" href="css/main.css" target="_blank" rel="external nofollow"  />
<script type="text/javascript">
	
	function check(){
		var idorName = document.getElementById("IdorName").value;
		if(idorName == ""){
			alert("ID不能为空!");
			return false;
		}
		return true;
	}
	
	function remove(){
		var result = confirm("请确认是否删除!");
		if(result){
			return true;
		}
		return false;
	}

</script>
</head>
<body>
	<% Page p = (Page)session.getAttribute("page"); %>
	<div id="Student">
		<div id="Student_top">
			<div id="Student_title">
				<h3>学生学籍管理</h3>
			</div>
			<div id="Student_search">
				<form action="queryByIdOrNameServlet" method="post" onsubmit="return check()" target="_parent">
					<input type="text" placeholder="请输入ID" class="form-control"
						style="width: 250px; float: left;" id="IdorName" name="IdorName" /> <input type="submit"
						value="搜索" class="btn btn-primary" style="float: right;" />
				</form>
			</div>
			<div id="Student_add">
				<input class="btn btn-success" value="添加学生" style="width: 100px;" onclick="location='addStudent.jsp?passPage=<%=p.getTotalPage() %>'"/>
			</div>
		</div>
		<div id="hr"></div>
		<div id="Student_List" style="margin-left: 20px">
			<table id="Student_table">
				<thead>
					<tr>
						<th>ID</th>
						<th>姓名</th>
						<th>性别</th>
						<th>出生日期</th>
						<th>入学日期</th>
						<th>所属专业</th>
						<th>所需学院</th>
						<th>操作</th>
					</tr>
				</thead>
				<tbody>
					<%	
						List<Student> students = p.getStudents();
						for (Student s : students) {
					%>
					<tr>
						<td><%=s.getId()%></td>
						<td><%=s.getName()%></td>
						<td><%=s.getSex()%></td>
						<td><%=s.getBirth()%></td>
						<td><%=s.getSchoolday()%></td>
						<td><%=s.getMarjor_id()%></td>
						<td><%=s.getCollege_id()%></td>
						<td>
							<button class="btn btn-primary" onclick="location='updateStudent.jsp?id=<%=s.getId() %>&passPage=<%=p.getCurrentPage() %>'">修改</button>
							<a href="deleteStudentServlet?id=<%=s.getId()%>&passPage=<%=p.getCurrentPage()%>" target="_blank" rel="external nofollow" target="_parent" onclick="return remove()"><button class="btn btn-danger">删除</button></a>
						</td>
					</tr>

					<%
						}
					%>
				</tbody>
			</table>
		</div>
		<div id="Page" style="margin-top: 40px; margin-left: 400px;">
			<a href="QueryStudentByPage?passPage=1" target="_blank" rel="external nofollow"  target="_parent"><button class="btn btn-info" >首页</button></a>
			<a style="margin: 0 10px" target="_parent" href="QueryStudentByPage?passPage=<%=p.getCurrentPage()-1%>" target="_blank" rel="external nofollow" ><button class="btn btn-info">上一页</button></a>
			<a style="margin-right: 10px" target="_parent" href="QueryStudentByPage?passPage=<%=p.getCurrentPage()+1%>" target="_blank" rel="external nofollow" ><button class="btn btn-info">下一页</button></a>
			<a href="QueryStudentByPage?passPage=<%= p.getTotalPage()	 %>" target="_blank" rel="external nofollow"  target="_parent"><button class="btn btn-info">尾页</button></a>			
		</div>
	</div>
</body>

</html>
           

4.页面跳转的一些问题

在页面跳转中有form表单跳转,也有a标签,button按钮。

当需要传值的时候,大多数是通过在url后面加上数据。也有在request,session域中设置属性。

在整个项目中设置了一个session属性,也就是管理员的姓名这个属性,一直存放在session中,因此,不管在什么页面,我们的top.jsp都可以取到当前session中的管理员姓名

login.jsp

HttpSession session = request.getSession();
session.setAttribute("name", name);
           

top.jsp

<div class="well" id="top"><h1>您好!${sessionScope.name},欢迎使用学生管理系统</h1></div>
           

但是,当我们修改管理信息后,就会将session中的name重置。

updateAdminServlet

session.setAttribute("name", name1);
           

5.总结

这个小项目花了我2,3天的空闲时间,因为前端很废时间,而且一些控件在ie上面跑不起来。做的时候也有各种各样的小问题,都是通过百度解决的。等我学习了框架,AJAX,可能还会写一个功能更加完善的学生管理系统Plus,没有使用AJAX真的很奇怪,因为点啥都会刷一下,感觉就很奇怪(主要是我还不会)。

继续阅读