您的位置:首页 > Web前端 > JavaScript

JSP&Servlet实现学生信息管理

2017-11-24 14:18 471 查看
首先声明,通过这个项目主要是想来学习java开发一个小项目的流程,各种包等关于后端的开发,因此对于前端的样式设计等没有介绍,不过在这个项目中关于样式之类的设计用的是EasyUI框架,现在,GO!

一、这个项目要实现什么?

要完成一个项目,你必须先知道这个项目要干什么,要完成什么样的功能,需要什么样的数据,这样我们才能一步步的进行实现。今天要学习的这个项目是学生信息管理,两个功能:班级信息管理和学生信息管理,从这两个功能应该能看到两张数据表:t_grade和t_student,还有两个界面,管理班级信息的页面:gradeInfoManage.jsp以及学生信息管理的页面:studentInfoManage.jsp;同样,我们还需要登录界面index.jsp,登陆成功会跳转到主界面main.jsp,还需要一张数据表t_user用作登录。因此本项目所需数据表3张,4个jsp页面。

二、建立工具包Util

我们会把重复使用的一些操作封装在Util中。

数据库封装:DBUtil.java

package util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DbUtil {
private String dbUrl="jdbc:mysql://127.0.0.1/db_studentsInfo";
private String dbUserName="root";
private String dbPassword="xxxxxx";
private String jdbcName="com.mysql.jdbc.Driver";
/*
* 获取数据库的连接
*/
public Connection getCon() throws ClassNotFoundException, SQLException{
Class.forName(jdbcName);
Connection conn=(Connection) DriverManager.getConnection(dbUrl,dbUserName,dbPassword);
return conn;
}
/*
* 关闭数据库连接
*/
public void close(Connection conn){
if(conn!=null){
try {
conn.close();
conn=null;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/*
* 测试
*/
public static void main(String[] args) {
DbUtil dbUtil=new DbUtil();
try {
dbUtil.getCon();
System.out.println("数据库连接成功");

} catch (ClassNotFoundException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
判断字符串就是否为空的封装:StringUtil.java
package util;
/*
* 判断空
*/
public class StringUtil {
public static boolean isEmpty(String str){
if("".equals(str)|| str==null){
return true;
}else{
return false;
}
}
public static boolean isNotEmpty(String str){
if(!"".equals(str)&&str!=null){
return true;
}else{
return false;
}
}
}


三、登录界面的实现

1.在数据库db_studentsinfo中建立第一张数据表t_user,下图是t_user的字段:



建好表以后,插入一条测试数据:



2.数据库的表建好以后紧跟着要做的就是封装数据表的字段,在src下新建model包,封装第一张数据表t_user。

User.java

package model;
public class User {
private String id;
private String userName;
private String password;
public User(String name, String password) {
this.userName=name;
this.password=password;
}
public User(){
}
public User(String id, String userName, String userPassword) {
super();
this.id = id;
this.userName = userName;
this.password = userPassword;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

3.建立index.jsp这个页面包含两个文本框:输入姓名和输入密码,以及两个按钮确定和重置。

重置按钮:

<input type="button" value="重置" onclick="resetValue()"/></td>
在点击重置时需要执行方法resetValue(),需要在这个jsp页面实现:
<script type="text/javascript">
function resetValue(){
document.getElementById("userName").value="";
document.getElementById("password").value="";
}
</script>


确定按钮:在点击确定以后,通过form表单提交就可以把我们在前台输入的内容传递到后台。





action表示你要把数据传递到哪里去,我们这里写的login是一个servlet的地址,下面再进行介绍;method表示提交方式,form有两种提交方式,post和get,get不安全,一般都选用post提交。

4.建立处理前台登录数据的Servlet:LoginServlet

(1)先建立Dao包,Dao包就是把对每个数据表的操作进行单独的封装,我们首先封装的是UserDao。

在这个dao里面,我们主要做的就是登录验证,把前台传过来的数据进行验证,如果数据库中有这个用户就允许他登录并且返回这个用户。

package dao;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.mysql.jdbc.PreparedStatement;
import model.User;

/*
* 登录验证
*/
public class UserDao {
public User login(Connection conn,User user) throws SQLException{
User resultUser=null;
String sql="select * from t_user where userName=? and password=?";
PreparedStatement pSta=(PreparedStatement) conn.prepareStatement(sql);
pSta.setString(1, user.getUserName());
pSta.setString(2, user.getPassword());
ResultSet rs=pSta.executeQuery();
if(rs.next()){
resultUser=new User();
resultUser.setUserName(rs.getString("userName"));
resultUser.setPassword(rs.getString("password"));
}
return resultUser;
}
}
(2)LoginServlet.java

建立web包,在web包下新建LoginServlet.java。写servlet都需要继承HttpServlet,重写它的两个方法,doGet()和doPost()。

这里要注意的是两个跳转:<1>服务器跳转:req.getRequestDispatcher("index.jsp").forward(req, resp);它可以携带信息传回去。

                                          <2>客户端跳转:resp.sendRedirect("main.jsp");

package web;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import model.User;
import dao.UserDao;
import util.DbUtil;
import util.StringUtil;
public class LoginServlet extends HttpServlet{
DbUtil dbUtil=new DbUtil();
UserDao userDao=new UserDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//resp.setCharacterEncoding("UTF-8");
req.setCharacterEncoding("UTF-8");
//req.getParameter("userName"),里面的userName表示的是表单name的值,这个就是从前台取数据
String name=req.getParameter("userName");
String password=req.ge
4000
tParameter("password");
req.setAttribute("userName", name);
req.setAttribute("password", password);
if(StringUtil.isEmpty(name)|| StringUtil.isEmpty(password)){
//服务器跳转,带着信息跳转
req.setAttribute("error", "用户名或者密码错误");
req.getRequestDispatcher("index.jsp").forward(req, resp);
return;//跳转结束以后就 不让往下执行了
}
User user=new User(name,password);
Connection conn=null;
try {
conn = dbUtil.getCon();
User currentUser=userDao.login(conn, user);
if(currentUser==null){
req.setAttribute("error", "用户名或者密码错误");//设置属性值,前台可以通过key得到这些数据
req.getRequestDispatcher("index.jsp").forward(req, resp);
}else{
//获取Session
HttpSession session=req.getSession();
session.setAttribute("currentUser", currentUser);//注意这里是为了下面的main.jsp,即只有登录进去了以后才能跳转到main
//客户端跳转
resp.sendRedirect("main.jsp");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
dbUtil.close(conn);
}
}
}
非常重要的不能忘记:写完了Servlet以后,必须要在web.xml中配置,否则是不会运作的,在web.xml中添加如下,我们用的时候只需要login就可,login可以找到对应的LoginServlet。



5.main.jsp

在跳转成功以后,我们就可以跳到main.jsp了,但是必须要注意的是我们在main.jsp中必须进行session验证,如果没有用户登录则会被跳转到index.jsp进行登录。



因为main里面主要是一些前台设计,所以这里不详细叙述,main的结果图如下:



四、班级信息管理的实现

1.建立数据表t_grade,表结构如下:



2.<1>封装grade字段(定义字段名,set以及get方法,这里不赘述代码)

   <2>封装一个PageBean,在页面显示的时候方便分页

PageBean.java

package model;

public class PageBean {
private int page;//第几页
private int rows;//每页的记录数
private int start;//起始页
public PageBean() {
// TODO Auto-generated constructor stub
}
public PageBean(int page, int rows) {
super();
this.page = page;
this.rows = rows;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
//起始页的处理
public int getStart() {
return (page-1)*rows;
}
}


3.<1>封装一个工具类JsonUtil.java,此工具类是把ResultSet集转化为JsonArray

package util;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Date;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class JsonUtil {
public static JSONArray formatRsToJsonArray(ResultSet rs) throws Exception{
/*
* ResultSetMetaData用于获取关于 ResultSet对象中列的类型和属性信息的对象
* rs.getMetaData()用来获取Resultset对象的列的编号类型和属性
*/
ResultSetMetaData md=rs.getMetaData();
int num=md.getColumnCount();
JSONArray jsonArray=new JSONArray();
while(rs.next()){
JSONObject object=new JSONObject();
for(int i=1;i<=num;i++){
Object o=rs.getObject(i);
if(o instanceof Date){
object.put(md.getColumnName(i), DateUtil.formatDate((Date)o, "yyyy-MM-dd"));
}else{
object.put(md.getColumnName(i),o);
}
}
jsonArray.add(object);
}
return jsonArray;
}
}
<2>封装一个输出到页面的工具类:ResponseUtil.java

package util;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;
/*
* 往页面输出的
*/
public class RseponseUtil {
public static void write(HttpServletResponse response,Object o)throws Exception{
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println(o.toString());
out.flush();
out.close();
}
}
4.封装GradeDao,我下面的代码是完整的操作grade的方法,但是这都是一步步写的,和前台相结合的写,一步步的往上加,而且工具类也是,用到什么就往里面加,切记不是一气呵成的。

GradeDao.java

package dao;
import java.sql.Connection;
import java.sql.ResultSet;
import util.StringUtil;
import com.mysql.jdbc.PreparedStatement;
import model.Grade;
import model.PageBean;
public class GradeDao {
//分页,获取查询的结果集
public ResultSet gradeList(Connection conn,PageBean pageBean,Grade grade)throws Exception{
StringBuffer sb=new StringBuffer("select * from t_grade");
//StringBuffer sb=new StringBuffer("select * from t_grade where 1=1");
if(grade!=null && StringUtil.isNotEmpty(grade.getGradeName())){
sb.append(" and gradeName like '%"+grade.getGradeName()+"%'");
}
if(pageBean!=null){
sb.append(" limit "+pageBean.getStart()+","+pageBean.getRows());
}
PreparedStatement psta=(PreparedStatement) conn.prepareStatement(sb.toString().replaceFirst("and", "where"));
//System.out.println(sb.toString().replaceFirst("and", "where"));
return psta.executeQuery();
}
//获取一共多少条记录,like进行模糊查询'%xx%'
public int gradeCount(Connection conn,Grade grade)throws Exception{
StringBuffer sb=new StringBuffer("select count(*) as total from t_grade");
if(StringUtil.isNotEmpty(grade.getGradeName())){
sb.append(" and gradeName like '%"+grade.getGradeName()+"%'");
}
PreparedStatement psta=(PreparedStatement) conn.prepareStatement(sb.toString().replaceFirst("and", "where"));
ResultSet rs=psta.executeQuery();
if(rs.next()){
return rs.getInt("total");
}else{
return 0;
}
}
/*delete from table where id in(1,3,4);删除id为1,3,4的id
*删除操作
*/
public int gradeDelete(Connection conn,String delIds) throws Exception{
String sql="delete from t_grade where id in ("+delIds+")";
// System.out.println(sql);
PreparedStatement psta=(PreparedStatement) conn.prepareStatement(sql);
return psta.executeUpdate();//成功删除了几条就返回几条数据
}
/*
* 添加操作
*/
public int gradeAdd(Connection conn,Grade grade)throws Exception{
String sql="insert into t_grade values(null,?,?)";
PreparedStatement psta=(PreparedStatement) conn.prepareStatement(sql);
psta.setString(1, grade.getGradeName());
psta.setString(2, grade.getGradeDesc());
return psta.executeUpdate();
}
public int gradeModify(Connection conn,Grade grade)throws Exception{
String sql="update t_grade set gradeName=?,gradeDesc=? where id=?";
PreparedStatement psta=(PreparedStatement) conn.prepareStatement(sql);
psta.setString(1, grade.getGradeName());
psta.setString(2, grade.getGradeDesc());
psta.setInt(3, grade.getId());
return psta.executeUpdate();

}
}
5.在点击班级信息管理时,会出现以下界面:



结果是怎么出来的呢?首先是前台页面gradeInfoManage.jsp中,调用url,这个url是一个Servlet,在下面将介绍。



实现GradeListServlet,即上面的gradeList对应的GradeListServlet,这个Servlet包含查询数据库里面所有的数据以及输入班级名进行查询的功能,当然还有显示的分页,输入班级名进行搜索的界面如下:



在jsp页面,搜索是这样定义的(没有截全):



在当前的jsp页面定义searchGrade()方法:



下面的Servlet中取到gradeName就是上面定义的gradeName的数值。

GradeListServlet.java

记得写完Servlet以后要在web.xml中进行配置,我在下面不重复了,但是一定要居住,写完servlet就要进行配置。

package web;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import dao.GradeDao;
import util.DbUtil;
import util.JsonUtil;
import util.RseponseUtil;
import model.Grade;
import model.PageBean;
public class GradeListServlet extends HttpServlet{
DbUtil dbUtil=new DbUtil();
GradeDao gradeDao=new GradeDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String page=req.getParameter("page");
String rows=req.getParameter("rows");
String gradeName=req.getParameter("gradeName");
if(gradeName==null){
gradeName="";
}
Grade grade=new Grade();
grade.setGradeName(gradeName);
PageBean pageBean=new PageBean(Integer.parseInt(page),Integer.parseInt(rows));
Connection conn=null;
try {
conn=dbUtil.getCon();
JSONObject result=new JSONObject();
JSONArray jsonArray = JsonUtil.formatRsToJsonArray(gradeDao.gradeList(conn, pageBean,grade));
int total=gradeDao.gradeCount(conn,grade);
result.put("rows", jsonArray);
result.put("total", total);
RseponseUtil.write(resp, result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
dbUtil.close(conn);
}
}

}
6.实现删除操作

先看一下前台如何定义的:



在当前页面中定义deleteGrade()方法:

function deleteGrade(){
var selectedRows=$('#dg').datagrid('getSelections');/*获取选中的哪些数据  */
if(selectedRows.length==0){
$.messager.alert("系统提示","请选择要删除的数据!");
return;
}
var strIds=[];
for(var i=0;i<selectedRows.length;i++){
strIds.push(selectedRows[i].id);
}
var ids=strIds.join(",");/*数组的join用法  */
$.messager.confirm("系统提示","您确定要删除这<font color='red'>"+selectedRows.length+"</font>条数据吗?",function(r){
if(r){
$.post("gradeDelete",{delIds:ids},function(result){
if(result.success){
$.messager.alert("系统提示","您已经成功删除<font color='red'>"+result.delNums+"</font>条数据!");
$('#dg').datagrid("reload");
}else{
$.messager.alert("系统提示","<font color='red'>"+selectedRows[result.errorIndex].gradeName+"</font>"+result.errorMsg);
}
},"json");
}
});
}
确定要删除以后,就会提交进行删除操作:



post提交的地址gradeDelete也是一个Servlet,即GradeDeleteServlet:

package web;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import dao.GradeDao;
import dao.StudentDao;
import util.DbUtil;
import util.RseponseUtil;
public class GradeDeleteServlet extends HttpServlet{
DbUtil dbUtil=new DbUtil();
GradeDao gradeDao=new GradeDao();
StudentDao studentDao=new StudentDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String delIds=req.getParameter("delIds");
Connection conn=null;
try {
conn=dbUtil.getCon();
JSONObject result=new JSONObject();
String[] str=delIds.split(",");
for(int i=0;i<str.length;i++){
boolean f=studentDao.getStudentByGradeId(conn, Integer.parseInt(str[i]));
if(f){
result.put("errorIndex", i);
result.put("errorMsg", "班级下面有学生,不能删除!");
RseponseUtil.write(resp, result);
return;
}
}
int delNums=gradeDao.gradeDelete(conn, delIds);
if(delNums>0){
result.put("success", "true");
result.put("delNums", delNums);
}else{
result.put("errorMsg", "删除失败");
}
RseponseUtil.write(resp, result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
dbUtil.close(conn);
}
}
}
7.实现添加和修改操作

前台页面定义如下:



在当前页面实现这两个方法:



这两个操作都是下先打开一个添加或者修改的文本框,把数据发送到gradeSave对应的Servlet中,可以发现的是调用url的时候add操作没有传入id参数,modify操作传入了id参数,这也是区别调用servlet中哪个方法,而且修改操作需要知道要修改哪个啊。下面看GradeSaveServlet的实现:

package web;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import dao.GradeDao;
import util.DbUtil;
import util.RseponseUtil;
import util.StringUtil;
import model.Grade;
public class GradeSaveServlet extends HttpServlet{
DbUtil dbUtil=new DbUtil();
GradeDao gradeDao=new GradeDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletRespons
c534
e resp)
throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("utf-8");//异步提交出现中文乱码的解决方法
String gradeName=req.getParameter("gradeName");
String gradeDesc=req.getParameter("gradeDesc");//接收的是前台通过form传递过来的数据
String id=req.getParameter("id");
Grade grade=new Grade(gradeName,gradeDesc);
if(StringUtil.isNotEmpty(id)){
grade.setId(Integer.parseInt(id));
}
Connection conn=null;
try {
int saveNums=0;
conn=dbUtil.getCon();
JSONObject result=new JSONObject();
if(StringUtil.isNotEmpty(id)){
saveNums=gradeDao.gradeModify(conn, grade);//id不为空则执行修改
}else{
saveNums=gradeDao.gradeAdd(conn, grade);//为空则执行添加
}
if(saveNums>0){
result.put("success", "true");
}else{
result.put("success", "true");
result.put("errorMsg", "添加失败");
}
RseponseUtil.write(resp, result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
dbUtil.close(conn);
}
}

}
前台页面中给还有关于提交操作的,这个就是用来证明你提交的结果怎么样成功还是失败或者你填写的格式对不对等,下面看一个截图:



还有关闭操作等,这里不再赘述。

五、学生信息管理

这是最后一部分了,里面基本上的操作都和班级信息管理一样,特别的我会拿出来说一下,一样的就不再说了。

1.建立t_student,表结构如下:



需要注意的是这里有一个外键,gradeId,它对应于t_grade里面的id.



2、封装Student字段

3.建立StudentDao

DAO里面的操作基本和GradeDao是一样的,需要注意的是,因为用到了外表的关联,sql语句应该写成如下:



关于生日日期查询:



当然还多了一个级联的删除,就是在要删除班级的时候,先查询这个班级下有没有学生:


4.这里新建了一个处理日期的类,即把Date转化为String以及把String转化为Date.

DateUtil.java

package util;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil {
public static String formatDate(Date date,String format) throws Exception{
String result="";
SimpleDateFormat sdf=new SimpleDateFormat(format);//以format的形式格式化
if(date!=null){
result=sdf.format(date);
}
return result;
}
public static Date formatString(String str,String format)throws Exception{
SimpleDateFormat sdf=new SimpleDateFormat(format);//以format的形式格式化,比如format是“yyyy-MM-dd”
return sdf.parse(str);
}
}
5.还有一些关于下拉框,复选框等,这里不再赘述。

六、总结

这个项目建立了4个包:

1.model:封装数据表字段的包,有几张表就需要封装几个类

2.dao:对相对应的model进行操作的,即操作数据表的,查询删除更新等

3.util:工具包,常用的操作,比如数据库的连接等

4.web:这里面主要是Servlet,切记Servlet需要在web.xml中进行配置。

脑子一定要清楚,每个模块之间是怎么联系的,前台怎么传数据给后台,后台怎么接受前台的数据,后台怎么返回数据给前台等。

<1>前台可以通过form提交表单的方式(action),把数据传输到对应的路径中去,或者在ajax或者jsp中通过url传输数据

<2>后台通过request.getParameter(“前台定义的变量名”)来获取数据

<3>$.messager.confirm(提示信息,function(r){

if(r){

//确定以后要执行的操作,可以如下进行提交,第一的参数是一个地址,第二个参数是传入地址的参数,第三个是返回结果

$.post("gradeDelete",{delIds:ids},function(result){

}

}

})

还是不够详细,因为写了太长时间有点不耐心了,如果有补充再修改,下面是整体的结构:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐