基於JSP的學生管理系統
一、摘要
本系統前端是基於HTML+CSS+Bootstrap,後端基於純JSP製作而成。由於是新手學習,當中的程式碼格式不夠規範,還請各位多多包含。本專案已經在Github中開源,請各位大佬Star,Folk,Issue。
專案的總結構如圖
資料庫表:
所有表:
login表結構:
studentinfo表結構:
二、安裝環境
- 作業系統:MicroSoft Windows 10 1709
- JAVA版本:1.8.0_172
- 前端:HTML+CSS+JavaScript+BootStrap 4.0
- 後端:Tomcat 8.5+JSP
三、實現功能和部分介面預覽
- 管理員登入系統
- 學生資料的增加、修改、刪除、查詢
- 管理員賬號密碼重置
- 管理員退出系統
- 登入介面
- 主介面
- 新增學生資料
- 查詢介面
- 密碼重置介面
四、安裝方法
- 方法一:
- 訪問我的GitHub:點選開啟連結
- 下載我的專案(Down Zip)
- 解壓後開啟eclipse,File->Open Projects From File System,點選Directory選擇剛剛解壓出來的資料夾,點選finsh就行了。
- 使用Mysql命令執行我專案下MySQL資料夾裡面的StudentManagementByWeb.sql指令碼檔案,還原資料庫。
- 修改我專案下所有訪問資料庫的賬號和密碼的java語句,root改為自己的Mysql賬戶名,123456改為自己的Mysql相對應的密碼。如這樣的
- 看看專案環境是失效,如果失效通常專案都會有個紅色小X的,只需要右鍵專案->Build Path->configure Build Path修復相對於失效的環境就行了。
- 執行TomCat,專案搭建完畢(賬號和密碼都是:admin)。
- 如果出現登入了正確的賬號和密碼後跳轉的頁面是空白,請按照第七點的第四小點進行操作。
方法二:
- 複製圈中的地址
- 開啟Eclipse,File->Import,選擇如圖,然後按next
- 選擇 clone URI,點選next
- 把複製的地址貼上到URI欄,eclipse會自動補全下面的資訊,然後不斷點選next或Finsh直到專案匯入。
- 執行方法一的步驟4~8
- 完成專案搭建。
五、關鍵程式碼段和思想
1.如何連線MySQL資料庫?
如DAOCheckLogin.jsp中的部分程式碼
request.setCharacterEncoding("UTF-8");
String user = request.getParameter("user");
String password = request.getParameter("password");
String sqlQuery = "SELECT * FROM stumanagementbyweb.login WHERE user='"+user+"'AND password='"+password+"'";
try{
Class.forName("com.mysql.cj.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/stumanagementbyweb","root","123456");//建立一個Connection物件,DriverManager.getConnection("MySQL地址","MySQL賬戶名","MySQL密碼");
Statement sql = con.createStatement();//建立一個動作
ResultSet rs = sql.executeQuery(sqlQuery);//把執行的結果放入到結果集中
if(rs.next()){//遍歷整個結果集,如果有下一行返回TRUE,沒有則返回false
session.setAttribute("user", user);
session.setAttribute("id", rs.getString(1));
response.sendRedirect("frame.jsp");
}else{
out.print("<script language='JavaScript'>alert('您的使用者名稱或密碼有誤,請重新輸入或者註冊');window.location.href='Login.html'</script>");
}
con.close();
}catch(SQLException e){
e.printStackTrace();
}
2.如何把資料庫所有的資料顯示在表格中?
思想:先遍歷學生資訊資料表的每一行,然後使用JSP中的out.print()。
做法:在Contain.jsp中有如下的程式碼段:
while(rs.next()){
out.print("<tr>");
out.print("<td>"+rs.getString(1)+"</td>");
out.print("<td>"+rs.getString(2)+"</td>");
out.print("<td>"+rs.getString(3)+"</td>");
out.print("<td>"+rs.getString(4)+"</td>");
out.print("<td>"+rs.getString(5)+"</td>");
out.print("<td>"+rs.getString(6)+"</td>");
out.print("<td>"+rs.getString(7)+"</td>");
out.print("<td><a href='AlertStudent.jsp?id="+rs.getString(1)+"'><button class='btn btn-primary'>修改</button></a><a href='DaoDelete.jsp?id="+rs.getString(1)+"' onclick='javascript:return del();'><button class='btn btn-danger'>刪除</button></a></td>");
out.print("</tr>");
}
當中的while(rs.next())就是遍歷了學生資訊表的每一行,所以利用rs.getString()來獲取當前行的某一列,如第一列為rs.getString(1)如此類推。由於我在插入JSP程式碼是在HTML的表格<table></table>的範圍中,所以能把所有資訊以表格的形式列出來。
3.如何做到按一下修改按鈕能夠跳轉到相應的頁面並且顯示修改的資訊?
思想:在Contain.jsp中在遍歷每一行資料時我都在超連結處留下一個相對應的id,讓每一行的id通過URL進行傳值,然後在DaoAlertStudent.jsp獲取到相應的id,再進行資料庫查詢,從而得出當前行的資訊。
做法:
out.print("<td><a href='AlertStudent.jsp?id="+rs.getString(1)+"'><button class='btn btn-primary'>修改</button></a><a href='DaoDelete.jsp?id="+rs.getString(1)+"' onclick='javascript:return del();'><button class='btn btn-danger'>刪除</button></a></td>");
在此行程式碼中,我做了一個有超連結的按鈕,超連結的地址指向AlertStudent.jsp,但是我在地址的後面還寫了?id="+rs.getString(1),這樣一來可以把當前行的id傳給AlertStudent.jsp,只要在AlertStudent.jsp中寫request.getParameter("id");就能夠獲得當前行的id。利用id進行資料庫查詢,得出當前行的資訊,再把各個資訊放在相對應的表單控制元件中就可以完成資訊展示。
4.如何做到選擇院部的時候專業的內容相對應會改變?
這種功能是通過JavaScript實現的,這樣能減少訪問資料庫的次數。
這裡要感謝以下文章地址的作者,我是仿照他的程式碼進行修改
我仿照的程式碼,出自AddStudent.jsp
var librarians = ['機電工程學院', '電子資訊學院', '工商管理學院', '財經管理學院', '汽車工程學院'];
var choice = ['---請選擇---'];
var electromeChanical = ['數控技術', '模具設計與製造', '機械製造與自動化', '機電裝置維修與管理', '工業機器人', '電氣自動化', '機械設計與製造'];
var electronicInformation = ['工業設計', '藝術設計', '光伏工程技術', '光伏發電技術與應用', '物聯網應用技術', '計算機應用技術', '通訊技術', '電子資訊工程技術'];
var businessCircles = ['物流管理', '電子商務', '市場營銷', '國際貿易實務', '工商企業管理', '商務管理'];
var financialManagement = ['會計', '金融管理與實務', '財務管理', '酒店管理', '旅遊管理'];
var automobileEngineering = ['食品營養與檢測', '汽車技術服務與營銷', '汽車檢測與維修技術'];
var professional = new Array;
professional[0] = choice;
professional[1] = electromeChanical;
professional[2] = financialManagement;
professional[3] = businessCircles;
professional[4] = electronicInformation;
professional[5] = automobileEngineering;
function add_option(select, option) {
var target = document.getElementById(select);
for(var i = option.length - 1; i >= 0; i--) {
var add_option = document.createElement("option");
add_option.text = option[i];
target.add(add_option, null);
target.lastChild.setAttribute("value", option[i]);
}
}
add_option("college", librarians);
document.getElementById("college").addEventListener("change", function() {
var selevted_college = document.getElementById("college");
var selected_major = document.getElementById("major");
for(var i = selected_major.length - 1; i >= 0; i--) {
selected_major.remove(i);
}
var selected = selevted_college.selectedIndex;
if(selected == 0) {
add_option("major", professional[0]);
} else {
add_option("major", professional[selected]);
}
})
5.如何防止訪問者繞過登入介面訪問其他頁面?
思想:在一開始登入的時候檢查使用者是否正確,如果正確就建立一個session的會話,每個頁面在進行操作之前都需要檢查session會話是否為空,若為空則使用JavaScript提示需要登入並且強制跳轉回登入介面。
做法:在DaoCheckLogin.jsp中檢查輸入的賬號和密碼是否正確,如果正確就執行一條語句session.setAttribute("user", user);,這條語句的意思是將user這個物件儲存在session作用域中,而Session的生命週期是Session會話域,開啟一個瀏覽器請求一個網站的頁面後,Session開始,當Session超過時間限制後,Session登出而失效。
然後在每個頁面的在執行JSP語句之前先檢查user這個物件是否為空
if((String)session.getAttribute("user")==null){
out.print("<script language='JavaScript'>alert('請先登入!');window.location.href='Login.html'</script>");
}
如果user為空則輸出一個JavaScript語句,彈出視窗說“請先登入!”並且強制跳轉回登入頁面。
附上DaoCheckLogin.jsp程式碼:
<%@page import="java.sql.SQLException"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.Connection"%>
<%@ 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>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String user = request.getParameter("user");
String password = request.getParameter("password");
String sqlQuery = "SELECT * FROM stumanagementbyweb.login WHERE user='"+user+"'AND password='"+password+"'";
try{
Class.forName("com.mysql.cj.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/stumanagementbyweb","root","123456");
Statement sql = con.createStatement();
ResultSet rs = sql.executeQuery(sqlQuery);
if(rs.next()){
session.setAttribute("user", user);
session.setAttribute("id", rs.getString(1));
response.sendRedirect("frame.jsp");
}else{
out.print("<script language='JavaScript'>alert('您的使用者名稱或密碼有誤,請重新輸入或者註冊');window.location.href='Login.html'</script>");
}
con.close();
}catch(SQLException e){
e.printStackTrace();
}
%>
</body>
</html>
6.如何做到按左側的側邊導航欄,網頁能夠在導航欄的右側顯示(如主介面)?
思想:這裡涉及到了HTML的框架佈局,可以點選此超連結檢視相關內容 點選開啟連結,設計好框架後把相應的網頁放進框架中,導航欄那裡的超連結的target屬性記得是要填你想要顯示框架的name屬性的屬性值。不然他會預設重新整理超連結所在的當前框架。
做法:下面是我的frame.html程式碼(注意在框架頁裡面,框架不能在body元素中,必須要刪除body元素,不然會不顯示):
<%@ 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>
</head>
<%
if((String)session.getAttribute("user")==null){
out.print("<script language='JavaScript'>alert('請先登入!');window.location.href='Login.html'</script>");
}
%>
<frameset rows="10%,*" frameborder="0" framespacing="10">
<frame src="Top.jsp" noresize="noresize" scrolling="yes" />
<frameset cols="30%,*">
<frame src="Left_nav.html" noresize="noresize" />
<frame src="Contain.jsp" name="contain" />
</frameset>
</frameset>
</html>
大概的佈局圖就是這樣:
我的Left_nav.html程式碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="http://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style type="text/css">
ul{
width: 200px;
height: 200px;
float: right;
margin-top: 30px;
}
</style>
</head>
<body>
<ul class="nav nav-pills nav-stacked">
<li><a href="Contain.jsp" target="contain">學生管理</a></li>
<li><a href="AdminPasswordReset.jsp" target="contain">賬號密碼重置</a></li>
<li><a href="SystemExit.jsp" target="_parent">退出系統</a></li>
</ul>
</body>
</html>
我的超連結的target屬性都是指向了contain,跳轉的時候只有contain這個框架映象重新整理,這樣就能做到問題的效果。
7.如果我的元素在框架中,但是我需要實現整個頁面進行重新整理或者跳轉,我該怎樣實現?
做法:一般來說,如果元素在框架中,如果不設定某些屬性,當超連結跳轉的時候只會在當前框架重新整理,不會整個頁面重新整理,如果需要實現整個網頁重新整理,對應不同的情況有不同方法。
超連結:
<a href="SystemExit.jsp" target="_parent">退出系統</a>
target的屬性值必須是“_parent”,屬性解釋請看下圖或點選超連結 點選開啟連結
JavaScript:
<script type='text/javascript'>window.parent.frames.location.href='Login.html';</script>
詳細解釋可以看這位作者的文章:點選開啟連結
8.如何實現類似於百度分頁的分頁效果?
思想:首先得要有兩個概念,最大頁和最小頁,這個最小頁(minPages)和最大頁(maxPages)是用於接下來迴圈的邊界(以下的什麼當前頁(pagesNo)-3,當前頁(pagesNo)+3中的數字可以任意設定,看你分頁需要有多長的需求,數字越大,分頁顯示的數字就越多)。最小頁需要判斷當瀏覽的當前頁(pagesNo)-3頁的時候是否小於0時,如果小於0便會越界,因為沒有頁數是負數的,所以需要檢查當前頁(pagesNo)-3頁的時候如果小於0時,就需要把最小頁變為1,如果不是小於0,則最小頁為當前頁-3頁。最大頁同理,如果當前頁(pagesNo)+3頁如果越過資料庫所有資料所呈現的頁數(pagesCount),則最大頁只能是等於資料庫所能所能提供的最大頁數,否則最大頁就是當前頁+3。最後迴圈顯示頁數就能得到這樣的效果。
做法:
程式碼出自Contain.jsp,可以對應上面的思想進行分析,下面有判斷是否是當前頁,如果是當前頁則新增高亮css的class屬性。
pagesCount = (lastRow % pageSize == 0) ? (lastRow / pageSize) : (lastRow / pageSize +1);
int minpages = (pagesNo - 3 >0) ? (pagesNo - 3) : 1;//使用了三目運算子
int maxpages = (pagesNo + 3 >= pagesCount) ? (pagesCount) : (pagesNo+3);
for(int i = minpages;i <=maxpages ;i++){
if(i == pagesNo){//判斷是否是當前頁
out.print("<li class='page-item active'>");
out.print("<a class='page-link' href='Contain.jsp?pages="+i+"'>"+i+"</a>");
out.print("</li>");
}else{
out.print("<li class='page-item'>");
out.print("<a class='page-link' href='Contain.jsp?pages="+i+"'>"+i+"</a>");
out.print("</li>");
}
}
9.如何實現分頁當前頁高亮效果?
由於我是使用BootStrap,裡面有一個class屬性:.active,把這個屬性放到相對應的class中就可以了,詳情可以參考程式碼Contain.jsph和上面的第八點。也可以參考以下網址六、關於程式設計過程遇到的坑
1.明明html頁面修改後提交到Tomcat,但是頁面還是沒有改變?
答:這是由於瀏覽器裡面優先讀取了快取,即記錄下你之前登入過這個系統的樣式,瀏覽器這樣做是為了能讓網頁訪問速度更快,但是在這裡卻變成了絆腳石。解決方法有兩個
(1)設定HTML頁面不快取
可以在HTML開頭使用以下語句使HTML不快取
<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-control" content="no-cache">
<meta http-equiv="Cache" content="no-cache">
(2)每次進入更新HTML頁面的時候使用CTRL+F5進行重新整理,這樣能不通過快取進行重新整理。
七、不足之處
1.沒有實現將所有查詢到的資料分頁顯示,如果沒有分頁顯示,現在資料庫的資料量少還可以,但是一旦資料庫有上千條資料,在顯示的時候會導致一頁往下拉全是資料,這樣使用者用起來體驗就不好了。<-------------------------------------------------2018年6月4日更新--------------------------------------------->
分頁查詢已經實現,請示通過資料庫指定行數查詢+id傳值的方法就能夠實現,詳情看我GitHub原始碼的Contain.jsp。
改動後發現了新的Bug:
如果我的資料庫有上千行語句,以每頁顯示10行來計算,需要100頁,也就是100格,可是螢幕的空間根本不能夠容下一行1000格的空間,所以分頁元素極有可能會溢位。所以現在的解決思路是像百度那樣分頁,按下第10頁,然後第10頁移到中間,如此類推。
選中第10頁前:
選中第10頁後:
<-------------------------------------------------2018年6月7日更新--------------------------------------------->
修復了了上面分頁的Bug,能夠像百度的分頁那樣自動擴充套件頁數並且增添了當前頁高亮的效果。效果圖如下:
第一頁
第四頁
第八頁
2.介面比較簡單,畢竟理科生沒有藝術細胞。
在這裡打個廣告需要前端美工一名,沒有工資3.開發過於隨意,沒有計劃性。
不管三七二十一先寫了再說4.在登入介面第一次輸入正確密碼的時候,跳轉時網頁空白,控制檯報錯。
頁面:
控制檯:
解決方法:我參考的方法:點選開啟連結 這個是因為我選的JDBC版本太高(8.0),所以導致資料庫的時區出錯。解決方法可以在命令列登入了MySQL資料庫,輸入一下命令列:
set global time_zone='+8:00';
八、總結
最近的JSP課程講到了資料庫的連線,然後我就試著用單純的JSP來寫這個學生資料管理系統,怎麼說呢,我在以前有用過Java+Swing的形式做過一個學生管理系統的經驗,專案地址:點選開啟連結。所以這一次的專案我是按照上一次的經驗做成的。雖然說程式碼量不大,估計前端+後端就700~800行,
可是一個人兼顧前端和後端是真的累,以後要找個會前端的幫忙背鍋(笑),花了大概3~4天的空閒時間,這次的開發也挺隨性的,想到什麼就寫什麼,完全沒有開發流程的規範,在實現點選修改按鈕就能修改當前行的功能時,還想了一早上都不知怎樣實現,然後突然靈感一來,想到<form></form>能通過get方法讓URL來傳值,超連結也可以仿照get方法來傳學號的值,再通過查詢資料庫就能獲得當前的值了(其實直接把所有的內容通過傳值獲得,那就能減輕資料庫的負擔,這種方法更好,但是安全性不高),所以有時程式設計知識面和靈感也很重要。這一次的開發雖然是按照舊的經驗做的,但是也學到很多東西,如BootStrap框架的使用,JavaScript的使用,等等。鞏固了上課的內容,充實了自己,自己親手把東西做出來後也是挺有成就感的,可能下次的作品還是學生管理系統,只是程式設計了使用各種框架,實現前端和後端分離的學生管理系統,還敬請期待。