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是用户请求和业务逻辑之间的桥梁
-
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>");