纯Servlet实现学生信息系统 -----理解项目的基本流程和设计思路

本文详述了一个基于JavaWeb的学生信息管理系统实现过程,包括数据库表的创建、前端页面设计、Servlet实现各功能,如查看学生列表、详情、添加、删除和修改。讨论了项目的功能分析、开发环境搭建、项目架构模式以及代码实现中的问题和优化方向。
摘要由CSDN通过智能技术生成

Java打卡:第102、3天

javaWeb

Java EE


综合分析 — web版学生信息管理系统;简单的增删改


昨天分享了Servlet的请求和响应,并分析了线程安全问题

Servlet实例

前面已经分享了Servlet的基本的内容,包括各种方法,请求和重定向以及线程安全。接下来就使用Servlet简单完成数据库的增删改查

准备数据库表

首先就是准备一个数据库表

#学生简单信息表
USE cfengbase;
DROP TABLE IF EXISTS student;
CREATE TABLE student(
	stuno INT PRIMARY KEY AUTO_INCREMENT,
    stuname VARCHAR(255),
    stuclass VARCHAR(255)
);
INSERT INTO student(stuno,stuname,stuclass) VALUES (1,"张三","HC2001");
INSERT INTO student(stuname,stuclass) VALUES ("李四","HC2002");
INSERT INTO student(stuname,stuclass) VALUES ("Cfeng","HC2002");
INSERT INTO student(stuname,stuclass) VALUES ("王五","HC2001");
INSERT INTO student(stuname,stuclass) VALUES ("Jning","HC2001");
COMMIT;
SELECT * FROM student;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-56oIDQWK-1640345892066)(C:\Users\OMEY-PC\AppData\Roaming\Typora\typora-user-images\image-20211223164710511.png)]

这里直接将文件放到workbench中就可以产生数据库表

mysql> USE cfengbase;
Database changed
mysql> SHOW TABLES;
+---------------------+
| Tables_in_cfengbase |
+---------------------+
| class               |
| fruits              |
| student             |
| t_student           |
| use_account         |
+---------------------+
5 rows in set (0.00 sec)

mysql> SELECT * FROM student;
+-------+---------+----------+
| stuno | stuname | stuclass |
+-------+---------+----------+
|     1 | 张三    | HC2001   |
|     2 | 李四    | HC2002   |
|     3 | Cfeng   | HC2002   |
|     4 | 王五    | HC2001   |
|     5 | Jning   | HC2001   |
+-------+---------+----------+
5 rows in set (0.00 sec)

制作前端页面

这里就是一个简单的项目操作,看着简单,但是设计的页面不止一个,包括增加页面add.html;修改页面edit.html;详情页面detail.html;列表页面list.html【可以显示所有的学生的信息】—这是核心; 还有欢迎页面就是index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>修改学生信息</title>
	</head>
	<body>
		<h1 align="center">修改学生信息</h1>
		<hr color="aquamarine"/>
		<form action="list.html" method="get">
			学生学号<input type="text" name="no" readonly"/><br/> <!-- 主键不修改,只读-->
			学生姓名<input type="text" name="name" value=""/><br/>
			学生班级<input type="text" name="class" value=""/><br/>
			<input type="submit" value="修改"/>
		</form>
	</body>
</html>

分析项目功能

什么叫做一个功能?

要知道,开发的一个重要的基础就是数据库,所以如果一个操作需要使用到数据库就叫做一个功能

比如简单的超链接页面跳转【跳转到新增学生页面】就不是一个功能,这里的功能有

  • 查看学生列表
  • 新增学生
  • 删除学生
  • 修改学生
  • 跳转到修改页面【因为要显示对应列的数据到表单中供修改】
  • 查看学生详细信息

在开发工具中搭建开发环境

创建webapp;向webapp中添加连接数据库的jar包【mysql驱动】,编写JDBC工具类

注意:必须在WEB-INF目录下新建lib目录,然后将mysql驱动jar包拷贝到这个目录下,这个目录名必须为lib;

  • 将所有的页面放到WEB-INF下

java项目架构的模式

java的项目基本的分层,action层,service层,model层,dao层 一个action就是一个业务代理,action是用户请求和业务逻辑之间的桥梁

img

  • model层 — domain,entity层【模型】就是对应的数据库表的实体类,比如学生,教师,管理员

  • dao – mapper层使用hibernate连接数据库,操作数据库【增删改查】

  • service【服务】层:引用对应的Dao数据库操作,可以编写简单代码完成服务,比如判断

  • action【处理,行为】层:引用对应的Service层,结合Structs中的配置文件,跳转到指定的页面,接收页面的请求,所以和界面直接交接的应该是在action包下 hibernate和struts都是注入到Spring中进行整合【action是属于MVC中的control层】

    form表单中的跳转就是action,就是将数据交给下一个action或者页面,action就相当于一个管理器,作用是取掉转,取出前端界面的数据,调用biz----business service逻辑处理的方法,转发给下一个action或者页面,model就是实体类,就是之前命名的作用域domain,entity

表示层调用控制层,控制层调用业务层,业务层调用数据访问层;

业务层为核心,所以业务层要面向扩展,不能出现具体的对象,不要轻易new Dao();正确的操作是将功能给封装为工具类,然后在Service中调用【前期的小项目因为基本上取出数据就完了,所以操作无Service】

比如现在做一个用户模块,假如一个功能需要使用user表和permission表,那么就是前台的界面访问action,action取调用service,service判断使用哪个表,然后service的实现类就调用比如userDao

JSP----》Action—》Service–》Dao–》hibernate–》DB 【Service分为Service接口和ServiceImpl;Dao也分为Dao接口和DaoImpl】 — 面向接口,解耦;Dao和数据库表是一一对应的,但是Service却不是

实现功能

实现功能:查看部门列表【从后端一步一步向前端写,或者从前端一步一步向后端写,但是不能随意些,过程最好是程序执行过程,程序执行到哪里,就写到哪里【这里就有一个流程图】事先给画出来,设计好,这样一个顺序流下来,基本上没有错误

查看学生列表【欢迎页面跳转】功能

  • 假如从前端开始,那么就是从用户点击按钮开始,就是点击超链接【点击之后就会连接数据库】

之前设计的前端只是让界面能够很好的显示,并且正常跳转,实现功能就要具体设计了

<!--修改前端界面的超链接-->
<a href="/StudentSystem/student/list">查看学生列表</a>  <!--使用/开始,是前台路径,参照路径为服务器路径,所以加上项目名-->
  • 之后就是将这个路径/student/list给配置到文件中

  • 编写类继承HttpServlet,重写Doget方法【超链接是Get请求】

  • 之后在这个doGet方法中连接数据库,查询出所有的数据;放到页面中

  • 动态展示页面的信息【这里就直接使用respnse的输出即可,但是这里要将之前页面中的所有双引号变为单引号,避免截断】使用工具就可以了

功能就是点击链接,会发出请求给一个action,action就从数据库中取出数据,并展示到界面上

从这个功能就可以大概看出一个web功能的执行流程

客户在浏览器中点击相关的位置,比如按钮,超链接;之后发出请求给web服务器,web服务器接收请求之后【因为动态资源和路径一一绑定】,就会将请求交给相关的Servlet;Servlet接收到的请求的所有的信息封装在ServletRequest中,【如果请求中有parameter,就从请求中取出数据】,这个直接接收请求的servlet一般是位于action层,MVC中的控制层,在复杂业务中,action调用service层,service层调用Dao层,Dao层通过hibernate与数据库通信;数据库返回数据,遵守的规范为JDBC;

简单来说线路就是3协议4对象; 浏览器到服务器遵守Http协议;web服务器到服务端程序遵守Servlet规范;服务端程序到数据库为JDBC规范; JDBC的实现是厂家实现;Servlet的实现是Programmer;形成一个层次化结构;用户只需要简单操作;就可以给通过HTTP的规范给服务器请求;服务器调用Servet等资源;servlet遵守JDBC的规范操作数据库

而这个简单功能,基本没有业务逻辑,不需要复杂分层,这里的过程就是用户点击超链接,发出get请求给web服务器;服务器将这个请求封装成Request对象和一个可以返回数据的响应对象Response传给StudentListAction这个servlet;Servlet程序是为了将所有的数据给返回,这里因为传入的没有数据,不需要使用request;可以使用其查看根路径;然后就使用工具类进行数据库操作,获取出数据库中的数据,然后通过Response将数据给返回给浏览器

功能的实现就从前端向后端写;首先明白用户点击的是什么,在哪里  ---- 设置路径
之后就是将这个路径配置到项目中,在web.xml中,这里就不用注解,因为放在一个文件中方便操作 -----配置路径和Servlet
编写Servlet类继承HTTPServlet类,看请求类型重写相关的方法------ 编写Servlet
编写响应的doGET方法,可以先写伪代码,清楚操作的流程 ----- 实现方法
这里的目的是为了动态的页面,所以就分析之前编写的前端页面哪里是动态的,哪里是静态的

所以需要一个DButil工具类,之前的页面只是为了大概展示前台的效果

package cfeng.oa.actions;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

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

import cfeng.oa.utils.DBUtil;
/**
 * @author OMEY-PC
 * 这里的操作很简单,就取出数据,所以就没有业务逻辑
 * action收集页面的数据,转发给下一个action,调用service层
 * 这里为了简化,就不使用JS了,直接输出页面
 */
public class StudentListAction extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html;charset=UTF-8");
		PrintWriter out = resp.getWriter();
		//list上方的静态界面
		out.println("<!DOCTYPE html>");
		out.println("<html>");
		out.println("<head>");
		out.println("<meta charset='utf-8'>");
		out.println("<title>学生信息表</title>");
		out.println("</head>");
		out.println("<body>");
		out.println("<h1 align='center'>学生列表</h1>");
		out.println("<hr color='aquamarine'/>");
		out.println("<table border='1px' align='center' width='50%'>");
		out.println("<tr>");
		out.println("<th>学号</th>");
		out.println("<th>姓名</th>");
		out.println("<th>班级</th>");
		out.println("<th>操作</th>");
		out.println("</tr>");

		
		//连接数据库,查询所有的数据
		Connection conn = null;
		PreparedStatement state = null;
		ResultSet result = null;
		//JDBC编程六步
		String sql = "SELECT stuno,stuname,stuclass FROM student";
		try {
			conn = DBUtil.getConnection();//注册驱动获得数据库连接
			conn.setAutoCommit(false); //开启事务
			state = conn.prepareStatement(sql);
			result = state.executeQuery();
			while(result.next()) {
				String stuno = result.getString("stuno");
				String stuname = result.getString("stuname");
				String stuclass = result.getString("stuclass");
				//测试一下是否有效;有效
//				System.out.println(stuno + " " + stuname + " " + stuclass);
				
				out.println("<tr>");
				out.println("<td>"+ stuno +"</td>");
				out.println("<td>"+ stuname +"</td>");
				out.println("<td>"+ stuclass +"</td>");
				out.println("<td>");
				out.println("<a href=''>删除</a>");
				out.println("<a href='edit.html'>修改</a>");
				out.println("<a href='"+req.getContextPath()+"/student/detail?stuno="+ stuno + "'>详情</a>");
				out.println("</td>");
				out.println("</tr>");
			}
		} catch (SQLException e) {
			if(conn!=null) {
				try {
					conn.rollback();
				} catch (SQLException e1) {
					e1.printStackTrace();
				}
			}
			e.printStackTrace();
		}finally {
			DBUtil.close(conn, state, result);
		}
		
		//表下方的也是静态的页面
		out.println("<tr>");
		out.println("<td colspan='4' align='center'>");
		out.println("<a href='add.html'>添加学生</a>");
		out.println("</td>");
		out.println("</tr>");
		out.println("</table>");
		out.println("</body>");
		out.println("</html>");
	}
}

查看学生详情功能【数据的传输依靠get地址栏传输】

功能就是点击相应的学生的详情就会链接相应的数据库,之后展示信息

从前端向后端一步一步实现;首先就是考虑用户点击的是什么,用户点击的在哪里?像上面的功能,用户点击的超链接在欢迎页面,所以就是修改index.html中的href;

查看学生详情,点击的是list页面的表格中的超链接;所以就是修改listaction中的查询代码中的href为一个servlet;所以创建一个详情页面

这里要显示详情,显示的是对应学生的详情,因为这里的主键是studentno;所以将这个数据传递给下一个action;注意这里类似于重定向;要想携带数据,使用?name=value; 创建servlet;这里的路径虽然放在java代码中,但是解释执行的是浏览器,所以使用/就要加上项目名;但是为了易于维护,不要将路径写死;使用request的方法getContextPath就可以获取项目的根路径

out.println("<a href='detail.html'>详情</a>");
//修改
out.println("<a href='/StudentSystem/student/detail?studentno=20'>详情</a>")

//转化为动态的界面
out.println("<a href='"+req.getContextPath()+"/student/detail?stuno="+ stuno + "'>详情</a>");

修改之后点击路径【get请求传输数据的格式就是name=value&name=value;HTTP协议规定的】

http://localhost:8080/StudentSystem/student/detail?stuno=1

可以看到成功将数据传输了

配置web.xml;并且要创建一个DetailAction类

package cfeng.oa.actions;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

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

import cfeng.oa.utils.DBUtil;

public class StudentDetailAction extends HttpServlet {
	//超链接请求,所以重写doget
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//获取传输的数据
		String stuno = req.getParameter("stuno");
//		System.out.println(stuno);   测试数据是否成功传输
		
		resp.setContentType("text/html;charset=UTF-8");
		PrintWriter out = resp.getWriter();
		
		out.println("<!DOCTYPE html>");
		out.println("<html>");
		out.println("<head>");
		out.println("<meta charset='utf-8'>");
		out.println("<title>学生信息</title>");
		out.println("</head>");
		out.println("<body>");
		out.println("<h1 align='center'>学生详细信息</h1>");
		out.println("<hr color='aquamarine'/>");
		
		Connection conn = null;
		PreparedStatement state = null;
		ResultSet result = null;
		//连接数据库,展示学生的信息;因为开发中的信息可能会有很多,所以就不会直接传输过来显示,而是传输主键值即可
		try {
			conn = DBUtil.getConnection();
			conn.setAutoCommit(false);
			String sql = "Select * FROM student WHERE stuno = ?"; //防止SQL注入
			state = conn.prepareStatement(sql);//预编译SQL
			state.setString(1, stuno);
			result = state.executeQuery();
			if(result.next()) {//这里的主键查询,一定最多一条记录
				String stuname = result.getString("stuname");
				String stuclass = result.getString("stuclass");
				
				//动态界面
				out.println("学生学号:"+stuno +"<br>");
				out.println("学生姓名:"+ stuname +"<br>");
				out.println("学生班级:"+ stuclass +"<br>");
			}
			conn.commit();
		} catch (SQLException e) {
			if(conn != null) {
				try {
					conn.rollback();
				} catch (SQLException e1) {
					e1.printStackTrace();
				}
			}
			e.printStackTrace();
		}finally {
			DBUtil.close(conn, state, result);
		}
		
		//静态界面
		out.println("<input type='button' value='后退' οnclick='window.history.back()'/>");
		out.println("</body>");
		out.println("</html>");
		
	}
}

实现部门的删除功能

删除部门的步骤:

用户点击页面按钮之后,会提示用户是否删除数据,因为删除操作时危险的,很多时候可能是用户误操作,所以必须给用户提示,是否删除【这里的界面不需要跳转,所以超链接不能起作用,那么就要删除时使用void(0)】

所以给超链接< a>加上一个JavaScript:void(0)取消跳转但是保留样式;之后使用onclick加上事件句柄,这里就使用行间事件就可;这里使用js

<a href="javascript:void(0)" onclick="del(" + stuno +")">删除</a>
    
    
<script>
	del = function(stuno){
				if(confirm("真的要删除该学生的信息吗,删除后不可恢复")) {//可以加上window
				//发送请求给服务器
					document.location.href = "/StudentSystem/student/delete?stuno=" + stuno;
		}
</script>

确定删除时,将删除的数据的主键传给下一个servlet程序,该程序会获取到主键,连接数据库,通过主键值为约束条件删除数据,并提示删除成功

删除操作需要使用js代码,弹出确认框 ,在js中进行操作,那么如何将请求如何传递给相应的Servlet程序?

这里之前js中提到过,有很多方式可以提交请求,js中使用window或者document.location.href就可以传递一个Get请求给相应的地址

使用out.println将上面的代码打到浏览器中

http://localhost:8080/StudentSystem/student/+%20%22req.getContextPath%28%29%22%20+/student/delete?stuno=1

后端代码中不要将项目名写死,所以使用contextPahth;上面出现的问题是因为没有拼接成功

out.println(“document.location.href = '” + req.getContextPath() + “/student/delete?stuno=’ + stuno;”);//自动使用了\转义

  • 接下里就是配置路径,创建servlet进行操作

使用web.xml进行配置的缺点就是写一个就要配置一个,如果写了无数个,那么web.xml就爆炸了;之后就直接使用注解webServlet就可以了

package cfeng.oa.actions;

import java.awt.image.DataBuffer;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

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

import cfeng.oa.utils.DBUtil;

public class StudentDeleteAction extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//获取传入的主键
		String stuno = req.getParameter("stuno");
		//连接数据库删除数据
		Connection conn = null;
		PreparedStatement state = null;
		ResultSet result = null;
		int count = 0;
		
		try {
			conn =  DBUtil.getConnection();
			conn.setAutoCommit(false);//关闭事务自动提交
			String sql = "DELETE FROM student WHERE stuno = ?";
			state = conn.prepareStatement(sql);
			state.setString(1, stuno);
			//删除操作,不需要处理查询结果
			count = state.executeUpdate(); //删除的条数
			conn.commit();
		} catch (SQLException e) {
			if(conn != null) {
				try {
					conn.rollback();
				} catch (SQLException e1) {
					e1.printStackTrace();
				}
			}
			e.printStackTrace();
		}finally {
			DBUtil.close(conn, state, result);
		}
		//删除成功,回到list页面,删除之后要重新查数据库;那就需要跳转执行listServlet;怎么让其执行?这里就使用重定向就行
		if(count == 1) {
			//只会有一条记录
			resp.sendRedirect(req.getContextPath() + "/student/list"); //重定向的时候路径要加上根路径;特例
		}else{
            //删除失败
            resp.sendRedirect(req.getContextPath() + "/deleteError.html");
        }
	}
}

Servlet之间的互相调用,只能是tomcat来操作,所以使用请求转发或者重定向

新增部门

这个功能的流程应该是,用户点击list页面的新增的超链接,进入到一个页面【这个页面跳转不是一个功能】,填入相关的信息,提交给新增学生的Servlet,该Servlet将信息插入到数据库中;添加成功就返回列表页面【重新查数据库,所以重定向到list】

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>新增学生</title>
	</head>
	<body>
		<h1 align="center">新增学生信息</h1>
		<hr color="aquamarine"/>
		<form action="list.html" method="post">
			学生学号<input type="text" name="no"/><br/>
			学生姓名<input type="text" name="name"/><br/>
			学生班级<input type="text" name="class"/><br/>
			<input type="submit" value="保存"/>
		</form>
	</body>
</html>
这里用户输入的信息,最好使用post来提交数据,不然地址栏会撑爆
out.println("<a href='/add.html'>添加学生</a>"); 这里的是前台路径,该文件直接在项目下面,需要加上路径,但是不写的话,多一个student;不符合要求
所以该为
out.println("<a href='"+ req.getContextPath() +"/add.html'>添加学生</a>");

那么这里用户向服务器发送的另外的一个请求就是上传数据

因为是前台路径,所以这里的提交需要加上项目名称,这里就使用名称开头的就可,因为当前add.html直接在项目下面,直接加上即可

开启事务之后,一定要手动提交,不然就不会提交

package cfeng.oa.actions;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

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

import cfeng.oa.utils.DBUtil;

public class StudentAddAction extends HttpServlet {
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//获取数据,解决中文乱码
		req.setCharacterEncoding("UTF-8");
		String stuno = req.getParameter("stuno");
		String stuname = req.getParameter("stuname");
		String stuclass = req.getParameter("stuclass");
//		System.out.println(stuno + stuname + stuclass); 测试是否传入成功
		//连接数据库,操作数据库
		Connection conn = null;
		PreparedStatement state = null;
		ResultSet result = null;
		int count = 0; //删除记录的条数
		try {
			conn = DBUtil.getConnection();
			conn.setAutoCommit(false);
			String sql = "INSERT INTO student (stuno,stuname,stuclass) VALUES (?,?,?)";
			state = conn.prepareStatement(sql);//预编译
			state.setString(1, stuno);
			state.setString(2, stuname);
			state.setString(3, stuclass);
			//执行sql
			count = state.executeUpdate();
			//提交事务,不然就不会成功
			conn.commit();
		} catch (SQLException e) {
			if(conn!=null) {
				try {
					conn.rollback();
				} catch (SQLException e1) {
					e1.printStackTrace();
				}
			}
			e.printStackTrace();
		}finally {
			DBUtil.close(conn, state, result);//释放资源
		}
		if(count == 1) {
			//success
			resp.sendRedirect(req.getContextPath() + "/student/list");
		}else {
			//添加失败
		}
	}
}

需要注意的是,这里如果使用的请求转发就会转发的还是post,但是重写的还是doGet方法,没有doPost方法,这样就会出现问题

修改操作

该操作包括两个功能,跳转到修改页面,这需要连接数据库,后面修改的时候还是需要连接数据库

跳转到修改页面

点击修改,跳转套修改页面,点击修改按钮才会跳转到真正的修改面

这里一定要看数据是否传输成功,要及时调试,一步一步调试

这里我是因为少写了一个单引号,所以要注意细节

out.println("<a href='"+req.getContextPath() +"/student/edit?stuno="+ stuno +"'>修改</a>");
java中写前端代码真的很麻烦,所以需要改进;这里的单引号中就是href的内容

这样就可以运行跳转功能

package cfeng.oa.actions;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

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

import cfeng.oa.utils.DBUtil;

public class StudentEditAction extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//获取传输的数据
		String stuno = req.getParameter("stuno");
//		System.out.println(stuno);   测试数据是否成功传输
				
		resp.setContentType("text/html;charset=UTF-8");
		PrintWriter out = resp.getWriter();
		//静态界面
		out.println("<!DOCTYPE html>");
		out.println("<html>");
		out.println("<head>");
		out.println("<meta charset='utf-8'>");
		out.println("<title>修改学生信息</title>");
		out.println("</head>");
		out.println("<body>");
		out.println("<h1 align=\"center\">修改学生信息</h1>");
		out.println("<hr color='aquamarine'/>");
		out.println("<form action='"+req.getContextPath() +"/student/editmodify' method='post'>");
				
		Connection conn = null;
		PreparedStatement state = null;
		ResultSet result = null;
		//连接数据库,展示学生的信息;因为开发中的信息可能会有很多,所以就不会直接传输过来显示,而是传输主键值即可
		try {
			conn = DBUtil.getConnection();
			conn.setAutoCommit(false);
			String sql = "Select * FROM student WHERE stuno = ?"; //防止SQL注入
			state = conn.prepareStatement(sql);//预编译SQL
			state.setString(1, stuno);
			result = state.executeQuery();
			if(result.next()) {//这里的主键查询,一定最多一条记录
				String stuname = result.getString("stuname");
				String stuclass = result.getString("stuclass");
				
//				System.out.println(stuname + stuclass);
				//动态界面
				out.println("学生学号<input type='text' name='stuno' value='"+ stuno+ "' readonly/><br/>");
				out.println("学生姓名<input type='text' name='stuname' value='"+ stuname +"'/><br/>");
				out.println("学生班级<input type='text' name='stuclass' value='"+ stuclass+"'/><br/>");
			}
			conn.commit();
		} catch (SQLException e) {
			if(conn != null) {
				try {
					conn.rollback();
				} catch (SQLException e1) {
					e1.printStackTrace();
				}
			}
			e.printStackTrace();
		}finally {
			DBUtil.close(conn, state, result);
		}
				
		//静态界面
		out.println("<input type='submit' value='修改'/>");
		out.println("</form>");
		out.println("</body>");
		out.println("</html>");
	}
}

最后一个功能就是修改功能,表单提交数据给editmoify这个action进行数据库的修改

package cfeng.oa.actions;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

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

import cfeng.oa.utils.DBUtil;

public class StudentEditmodifyAction extends HttpServlet {
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//请求中文乱码
		req.setCharacterEncoding("UTF-8");
		String stuno = req.getParameter("stuno");
		String stuname = req.getParameter("stuname");
		String stuclass = req.getParameter("stuclass");
		//进行数据库的操作
		Connection conn = null;
		PreparedStatement state = null;
		int count = 0;
		try {
			conn = DBUtil.getConnection();
			conn.setAutoCommit(false);
			String sql = "UPDATE student SET stuname=?,stuclass=? WHERE stuno = ?";
			state = conn.prepareStatement(sql);
			state.setString(1, stuname);
			state.setString(2, stuclass);
			state.setString(3, stuno);
			count = state.executeUpdate();
			conn.commit();
		} catch (SQLException e) {
			if(conn != null) {
				try {
					conn.rollback();
				} catch (SQLException e1) {
					e1.printStackTrace();
				}
			}
			e.printStackTrace();
		}finally {
			DBUtil.close(conn, state, null);
		}
		if(count == 1) {
			//成功
			resp.sendRedirect(req.getContextPath() + "/student/list");
		}else {
			//fail
		}
		
	}
}

这样,对于这个单表的操作的所有的功能就实现了;实现的思路就是从前端向后端写;只是用Servlet技术来写web程序真的是非常困难;主要就是前端的代码放在java中,显得臃肿

在这里插入图片描述

缺陷:

Servlet实现太繁琐

这里就只使用了Servlet和数据库的简单技术,非常繁琐,主要就是页面很繁琐

out.println("<tr>");
out.println("<td>"+ stuno +"</td>");
out.println("<td>"+ stuname +"</td>");
out.println("<td>"+ stuclass +"</td>");
out.println("<td>");
out.println("<a href=''>删除</a>");
out.println("<a href='edit.html'>修改</a>");
out.println("<a href='detail.html'>详情</a>");
out.println("</td>");
out.println("</tr>");
后端和前端的代码冗杂

这里想使用js,写到了java代码中,非常麻烦

out.println("<a href='javascript:void(0)' οnclick='del(" + stuno + ")'>删除</a>");

//js代码,没有jsp,代码冗杂
		//可以加上window
		//发送请求给服务器
		out.println("<script type=\"text/javascript\">");
		out.println("del = function(stuno){");
		out.println("if(confirm(\"真的要删除该学生的信息吗,删除后不可恢复\")) {");
		out.println("document.load.href = \"/StudentSystem/student/delete?stuno=\" + stuno;");
		out.println("}");
		out.println("}");
		out.println("</script>");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值