当前位置: 首页 > 图灵资讯 > 技术篇> 单表的CRUD操作改造

单表的CRUD操作改造

来源:图灵教育
时间:2023-06-01 09:48:29

1.分析使用纯Servlet开发web应用的缺陷351.1在Servlet中编写HTML//CSS/JavaScript等前端代码。有什么问题?35

-java程序中很难编写前端代码。麻烦。

-在java程序中编写前端代码,显然程序的耦合度很高。

-在java程序中编写前端代码,代码非常难看。

-在java程序中编写前端代码,维护成本过高。(维护非常困难)

-修改一个小的前端代码,只要有变化,就需要重新编译java代码,生成新的class文件,打一个新的war包重新发布。

1.2想想,如果是你,你打算如何解决这个问题?35

-想法很重要。用什么样的想法去做,去解决这个问题?

-上面的Servlet(Java程序)能不能不写,让机器自动生成?我们的程序员只需要在Servlet程序中编写“前端代码”,然后让机器自动翻译我们编写的“前端代码”,生成“Servletjava程序”。然后机器会自动“java“程序编译生成”class"文件。然后用JVM调用class中的方法。

2.知识点2.1思考一个问题:如果只使用JSP技术,能否开发web应用?39

-当然,JSP可以用来完成所有的功能。因为JSP是Servlet,在JSP<%%>写在service方法中的代码,所以在<%%>可以编写JDBC代码,连接数据库,查询数据,也可以编写业务逻辑代码,处理业务,所以使用单独的JSP开发web应用程序没有问题。

-虽然JSP可以通过技术完成web应用程序,但不建议使用servlet+jsp进行开发。这可以充分发挥各自的优势。JSP是为了显示数据。servlet是为了收集数据。(JSP中编写的Java代码越少越好。)必须有明确的职责。

2.2JSP文件的扩展名必须是xxx.jsp吗?39

-可配置jsp文件的扩展名。不是固定的。

-CATALINA_HOME/conf/web.xml,jsp文件的扩展名配置在本文件中。

        <servlet-mapping>            <servlet-name>jsp</servlet-name>            <url-pattern>*.jsp</url-pattern>            <url-pattern>*.jspx</url-pattern>        </servlet-mapping>

-xxx.jsp文件只是小猫的一个普通文本文件,web容器将xxxx.jsp文件最终生成java程序,最终调用java对象相关方法,实际执行时,与jsp文件无关。

-提示:JSP如果看不懂,建议将JSP翻译成java代码,就能看懂。

2.3包名bean是什么意思?39

-javabean(javalogo是一杯热气腾腾的咖啡。javabean翻译成咖啡豆)

-java是一杯咖啡,咖啡是由一粒咖啡豆研磨而成。

-在整个java程序中有许多bean的存在。由许多bean组成。

2.3.Javabean是什么?

实际上,javabean您可以理解为符合某一规范的java类别,例如:

-是否有参数结构方法

-属性私有化

-为外界提供开放的set和get方法

-实现java.io.Serializable接口

-tostring重写tostring

-hashCode重写hashCode+equals

-...

-javabean实际上是java中的实体类。负责数据的包装。

-由于javabean符合javabean规范,具有较强的通用性。

4.Oa项目改造采用Servlet+JSP完成。384.1使用Servlet处理业务收集数据。使用JSP显示数据。38.

-将原型中的html文件全部修改为jsp,然后在jsp文件头部添加page指令(指定contenttype防止中文乱码),直接将所有jsp复制到web目录中。

-完成所有页面的正常流通。(页面仍能正常跳转。修改超链接的请求路径。)

-<%=request.getContextPath()%>动态获取JSP应用的根路径。

在Servlet中连接数据库,查询所有部门,遍历结果集。39

-在通历结果集的过程中,取出部门编号、部门名称、位置等信息,封装成java对象。

-将java对象存储在List集合中。

-将List集合存储在request域中。

-将forward转发到jsp。

4.2.在JSP中:39

-从request域中取出List集合。

-遍历List集合,取出各部门对象。动态生成tr。

4.3目前oa应用存在的问题:41

-任何用户都可以访问该系统,并添加、删除和更改该系统中的数据。我只想让合法用户使用该系统。非法用户无法访问该系统。我该怎么办?

-添加一个登录功能。如果登录成功,可以访问该系统,如果登录失败,则无法访问。

4.3.1实现登录功能:414.3.1.1步骤1:在数据库中添加用户表:t_user41

-t用户的登录信息存储在user表中,最基本的还包括:登录用户名和密码。

-密码通常存储在数据库表中。一般不以明文的形式存储。(这里先用明文。)

-将数据插入T_user表中。

4.3.1.2步骤2:再次实现登录页面。41

-登录页面上应该有登录表。有用户名和密码输入框。

-用户点击登录,提交表格,提交用户名和密码。form通过post提交。

4.3.1.3步骤3:后台应有相应的Servlet来处理登录请求。41

-成功登录:跳转到部门列表页面。

-登录失败:跳转到失败页面。

4.3.1.4步骤4:提供另一个登录失败的页面。41

-登录功能已经实现,目前最大的问题是:

-这个登录功能目前只是一个装饰,没有任何效果。只要用户知道后端的请求路径,他们仍然可以访问而不登录。

-这个登录并没有真正起到拦截作用。怎么解决?

-JSP指令

-指令的作用:指导JSP翻译引擎如何工作(指导JSP翻译引擎如何翻译JSP文件)。

-指令包括什么?

-include指令:包含指令,在JSP中完成静态包含,很少使用。

-taglib指令:引入标签库的指令。到JJSTL标签库时再学习。现在就不管了。

-page指令:目前重点学习page指令。

-指令的什么是语法?

-<%@指令名属性名=属性值属性名=属性值属性名=属性值属性名=属性值...%>

com中的代码.bjpowernode.oa.web.actionDeptServlet

package com.bjpowernode.oa.web.action;import com.bjpowernode.oa.bean.Dept;import com.bjpowernode.oa.utils.DBUtil;import jakarta.servlet.ServletException;import jakarta.servlet.annotation.WebServlet;import jakarta.servlet.http.HttpServlet;import jakarta.servlet.http.HttpServletRequest;import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;///使用jsp改造单表的CRUD操作  38@WebServlet({"/dept/list","/dept/detail","/dept/delete","/dept/save","/dept/modify"})public class DeptServlet extends HttpServlet {    @Override    protected void service(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        String servletPath = request.getServletPath();//得到路径        if("/dept/list".equals(servletPath)){            doList(request,response);        }else if("/dept/detail".equals(servletPath)){            doDetail(request,response);        }else if("/dept/delete".equals(servletPath)){            doDel(request,response);        }else if("/dept/save".equals(servletPath)){            doSave(request, response);        }else if("/dept/modify".equals(servletPath)){            doModify(request,response);        }    }    //保存部门信息   40    private void doSave(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException{        //获取部门信息        // 注意乱码问题(Tomcat10不会出现这个问题)        request.setCharacterEncoding("UTF-8");        String deptno = request.getParameter("deptno");        String dname = request.getParameter("dname");        String loc = request.getParameter("loc");        ///连接数据库执行insert语句        Connection conn = null;        PreparedStatement ps = null;        int count = 0;        try {            conn = DBUtil.getConnection();            String sql = "insert into dept(deptno, dname, loc) values(?,?,?,?)";            ps = conn.prepareStatement(sql);            ps.setString(1,deptno);            ps.setString(2,dname);            ps.setString(3,loc);            count = ps.executeUpdate();        } catch (SQLException e) {            e.printStackTrace();        } finally {            DBUtil.close(conn,ps,null);        }        if(count==1) {            // 最好在这里使用重定向(浏览器会发送一个全新的请求。)            // 浏览器在地址栏上发送请求,即get请求。            response.sendRedirect(request.getContextPath()+"/dept/list");        }    }    ////根据部门编号删除相应的部门  40    private void doDel(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException{        //获取部门编号        String deptno = request.getParameter("deptno");        //连接数据库,查询部门信息        Connection conn = null;        PreparedStatement ps = null;        int count = 0;        try {            conn = DBUtil.getConnection();            String sql = "delete from dept where deptno = ?";            ps = conn.prepareStatement(sql);            ps.setString(1,deptno);            count = ps.executeUpdate();///返回删除受影响的条数        } catch (SQLException e) {            e.printStackTrace();        } finally {            DBUtil.close(conn,ps,null);        }        if(count == 1){            ///成功删除            ////重定向列表页面            String contextPath = request.getContextPath();///获取应用程序的根路径            response.sendRedirect(contextPath+"/dept/list");        }    }    ///根据部门编号获取部门信息   39    private void doDetail(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException{        ///创建部门对象        Dept dept = new Dept();        //获取部门编号        String dno = request.getParameter("dno");        ///根据部门编号获取部门信息 将部门信息封装成咖啡豆(即javabean)        //连接数据库,查询部门信息        Connection conn = null;        PreparedStatement ps = null;        ResultSet rs = null;        try {            conn = DBUtil.getConnection();            String sql = "select dname,loc from dept where deptno=?";            ps = conn.prepareStatement(sql);            ps.setString(1,dno);            rs = ps.executeQuery();            ///这个结果只集中了一个数据,所以不需要while循环,只需要if            if(rs.next()){                String dname = rs.getString("dname");                String loc = rs.getString("loc");                ///包装对象(创建豆子javabean)                dept.setDeptno(dno);                dept.setDname(dname);                dept.setLoc(loc);            }        } catch (SQLException e) {            e.printStackTrace();        } finally {            DBUtil.close(conn,ps,rs);        }        ///这个豆子只有一个,所以不需要袋子(也就是不需要集合),只需要把袋子放在request域        request.setAttribute("dept",dept);        //转发(不是重定向,因为跳转数据显示到JSP)        //request.getRequestDispatcher("/detail.jsp").forward(request,response);        ///获得不同的标志(这个标志是我们的listt.自己添加jsp修改和细节,用于区分修改和细节的操作)        //因为我们可以根据不同的标记转发到不同的页面  40       /* String f = request.getParameter("f");        if("m".equals(f)){            //转发到修改页面            request.getRequestDispatcher("/edit.jsp").forward(request,response);        }else if("d".equals(f)){            //转发到详细页面            request.getRequestDispatcher("/detail.jsp").forward(request,response);        }*/        //我们将简化上述代码 这是路径拼接 getParameter("f")得到标记  40        String forward = "/"+request.getParameter("f")+".jsp";        ///根据获得的拼接路径转发        request.getRequestDispatcher(forward).forward(request,response);    }    //连接数据库,查询所有部门信息,收集部门信息,然后跳转到JSP进行页面显示。38    private void doList(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException{        //准备一个容器,专门用于存储部门        List depts = new ArrayList<>();        //连接数据库,查询所有部门信息        Connection conn = null;        PreparedStatement ps = null;        ResultSet rs = null;        try {            //获取连接            conn = DBUtil.getConnection();            String sql = "select deptno,dname,loc from dept";            ps = conn.prepareStatement(sql);            rs = ps.executeQuery();            ///遍历结果集            while(rs.next()){                ///集中从结果中取出                String deptno = rs.getString("deptno");                String dname = rs.getString("dname");                String loc = rs.getString("loc");                ///将上述分散的数据封装成java对象                Dept dept = new Dept();                dept.setDeptno(deptno);                dept.setDname(dname);                dept.setLoc(loc);                ////将部门对象放入list集中                depts.add(dept);            }        } catch (SQLException e) {            e.printStackTrace();        } finally {            ///关闭连接            DBUtil.close(conn,ps,rs);        }        ///将一个集合放入请求域        request.setAttribute("depList",depts);        ///转发不要重定向        request.getRequestDispatcher("/list.jsp").forward(request,response);    }    ///修改操作   40    private void doModify(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        ////解决请求体中文乱码问题        request.setCharacterEncoding("UTF-8");        //获取表单数据        String deptno = request.getParameter("deptno");        String dname = request.getParameter("dname");        String loc = request.getParameter("loc");        ////连接数据库执行更新语句        Connection conn = null;        ;        PreparedStatement ps = null;        int count = 0;        try {            conn = DBUtil.getConnection();            String sql = "update dept set dname = ?,loc = ?,loc = ? where deptno = ?";            ps = conn.prepareStatement(sql);            ps.setString(1, dname);            ps.setString(2, loc);            ps.setString(3, deptno);            count = ps.executeUpdate();        } catch (SQLException e) {            e.printStackTrace();        } finally {            DBUtil.close(conn, ps, null);        }        if (count == 1) {            ///成功更新            //重定向            response.sendRedirect(request.getContextPath() + "/dept/list");        }     }}

UserServlet

package com.bjpowernode.oa.web.action;import com.bjpowernode.oa.utils.DBUtil;import jakarta.servlet.ServletException;import jakarta.servlet.annotation.WebServlet;import jakarta.servlet.http.HttpServlet;import jakarta.servlet.http.HttpServletRequest;import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;///专门处理用户登录  41//Servlet负责业务处理//JSP负责页面显示@WebServlet("/user/login")public class UserServlet extends HttpServlet {    @Override    protected void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        boolean success = false;///登录成功标志        ////验证用户名和密码是否正确        ///获取用户名和密码        // 您是这样提交前端的:username=admin&password=123        String username = request.getParameter("username");        String password = request.getParameter("password");        ////连接数据库验证用户名和密码        Connection conn = null;        PreparedStatement ps = null;        ResultSet rs = null;        try {            conn = DBUtil.getConnection();            String sql = "select * from t_user where username=? and password=? and password=?";            ///编译sql            ps = conn.prepareStatement(sql);            //给?赋值            ps.setString(1,username);            ps.setString(2,password);            //执行sql            rs = ps.executeQuery();            ///这个结果只集中了一个数据            if (rs.next()) {                ///成功登录                success = true;            }        } catch (SQLException e) {            e.printStackTrace();        }finally {            DBUtil.close(conn,ps,rs);        }        if(success){            ///成功登录,跳转到用户列表页面            response.sendRedirect(request.getContextPath()+"/dept/list");        }else{            ///登录失败,跳转到失败页面            response.sendRedirect(request.getContextPath()+"/error.jsp");        }    }}

javabeancom.bjpowernode.oa.beanDept

package com.bjpowernode.oa.bean;import java.util.Objects;//这是一个普通的java类,可以包装分散的数据,代表部门对象public class Dept {    private String deptno;    private String dname;    private String loc;    public Dept() {    }    public String getDeptno() {        return deptno;    }    public void setDeptno(String deptno) {        this.deptno = deptno;    }    public String getDname() {        return dname;    }    public void setDname(String dname) {        this.dname = dname;    }    public String getLoc() {        return loc;    }    public void setLoc(String loc) {        this.loc = loc;    }    @Override    public String toString() {        return "Dept{" +                "deptno='" + deptno + '\'' +                ", dname='" + dname + '\'' +                ", loc='" + loc + '\'' +                '}';    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        Dept dept = (Dept) o;        return Objects.equals(deptno, dept.deptno) &&                Objects.equals(dname, dept.dname) &&                Objects.equals(loc, dept.loc);    }    @Override    public int hashCode() {        return Objects.hash(deptno, dname, loc);    }}

工具com.bjpowernode.oa.utilsDBUtil

package com.bjpowernode.oa.utils;import java.sql.*;import java.util.ResourceBundle;/** * JDBC工具类   27 */public class DBUtil {    // 静态变量:在类加载过程中执行。    // 而且有序。自上而下的顺序。    // 绑定属性资源文件    private static ResourceBundle bundle = ResourceBundle.getBundle("resources.jdbc");    // key根据属性配置文件获得value    private static String driver = bundle.getString("driver");    private static String url = bundle.getString("url");    private static String user = bundle.getString("user");    private static String password = bundle.getString("password");    static {        // 注册驱动(注册驱动只需注册一次,放置在静态代码块中。加载DBUTil类时执行。加载DBUTil类时执行。)        try {            // "com.mysql.jdbc.Driver" 是连接数据库的驱动,不能写死。因为Oracle数据库将来可能会连接起来。            // 在连接oracle数据库时,还需要修改java代码,这显然违反了OCP开关的原则。            // OCP开关原则:对扩展开放,对修改关闭。(什么是符合OCP?不需要修改java源代码进行功能扩展。)            //Class.forName("com.mysql.jdbc.Driver");            Class.forName(driver);        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }    /**     * 获取数据库连接对象     * @return conn 连接对象     * @throws SQLException     */    public static Connection getConnection() throws SQLException {        // 获取连接        Connection conn = DriverManager.getConnection(url, user, password);        return conn;    }    /**     * 释放资源     * @param conn 连接对象     * @param ps 数据库操作对象     * @param rs 结果集对象     */    public static void close(Connection conn, Statement ps, ResultSet rs){        if (rs != null) {            try {                rs.close();            } catch (SQLException e) {                e.printStackTrace();            }        }        if (ps != null) {            try {                ps.close();            } catch (SQLException e) {                e.printStackTrace();            }        }        if (conn != null) {            try {                conn.close();            } catch (SQLException e) {                e.printStackTrace();            }        }    }}

SRC配置文件.resourcesjdbc.properties

driver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/bjpowernodeuser=rootpassword=lzl

index.jsp

<%@page contentType="text/html;charset=UTF-8"%><%--更改jsp   38   将此页面改为登录页面   41--%><!DOCTYPE html><html>  <head>    <meta charset="utf-8">    <title>OA系统欢迎使用</title>  </head>  <body>    <%-- 当前端发送请求路径时,如果要求路径是绝对路径,则应使用 / 开始,添加项目名称。--%>    <%-- 这样写代码,oa项目名写死了。--%>    <%-- 这样写代码,oa项目名写死了。这种设计显然不好。--%>    <%--    <a href="/oa/list.jsp">查看部门列表</a>--%>    <%--  <a href="<%=request.getContextPath()%>/list.jsp">查看部门列表</a>--%>    <%--  执行Servlet,查询数据库,收集数据--%>    <%--  <a href="<%=request.getContextPath() %>/dept/list">查看部门列表</a>--%>    <%--  <hr>--%>    <%--  调用方法获取应用的根路径-%>    <%--  <%=request.getContextPath()%>  <%–类似out.print(request.getContextPath());   –%>--%><%--    绘制用户登录页面   41--%>    <h1>用户登录</h1>    <hr>    <form action = "<%=request.getContextPath()%>/user/login" method="post">        username:<input type="text" name="username"/><br>        password:<input type="password" name="password"/><br>        <input type="submit" value="login"/>    </form>  </body></html>

list.jsp

<%@ page import="com.bjpowernode.oa.bean.Dept" %><%@ page import="java.util.List" %><%@page contentType="text/html;charset=UTF-8"%><!DOCTYPE html><html><head><meta charset="utf-8"><title>部门列表页面</title></head><body><script type="text/javascript">function del(dno){//弹出确认框,用户点击确定,返回true,点击取消返回falsevarr ok = window.confirm("亲,删除不可恢复哦”);if(ok)如何在js代码中向服务器发送请求///发送请求进行删除数据操作////document.location.href = “请求路径”//document.location = “请求路径”//window.location.href = “请求路径”//window.location = “请求路径”document.location.href="<%=request.getContextPath()%>/dept/delete?deptno="+dno}}</script><h1 align="center">部门列表</h1><hr ><table border="1px" align="center" width="50%"><tr><th>序号</th><th>部门编号</th><th>部门名称</th><th>操作</th></tr><%///从request域中取出数据Listt<Dept> deptList = (List<Dept>)request.getAttribute("depList");///循环遍历int i = 0;for(Dept dept:deptList)后台输出System{/.out.println(dept.getDname());////输出部名称到浏览器////out.write(dept.getDname());///以下红线报错是idea没事就别出来了。不影响%><tr><td><%=++i%></td><td><%=dept.getDeptno()%></td><td><%=dept.getDname()%></td><td><a href="javascript:void(0)" onclick="del(<%=dept.getDeptno()%>)">删除</a><a href="<%=request.getContextPath()%>/dept/detail?f=edit&dno=<%=dept.getDeptno()%>">修改</a><a href="<%=request.getContextPath()%>/dept/detail?f=detail&dno=<%=dept.getDeptno()%>">详情</a></td></tr><%}%></table><hr ><a href="<%=request.getContextPath()%>/add.jsp">新增部门</a></body></html>

add.jsp

<%@page contentType="text/html;charset=UTF-8"%><!DOCTYPE html><html><head><meta charset="utf-8"><title>新增部门</title></head><body><h1>新增部门</h1><hr ><form action="<%=request.getContextPath()%>/dept/save" method="post">部门编号<input type="text" name="deptno"/><br>部门名称<input type="text" name="dname"/><br>部门位置<input type="text" name="loc"/><br><input type="submit" value="保存"/><br></form></body></html>

detail.jsp

<%@ page import="com.bjpowernode.oa.bean.Dept" %><%@page contentType="text/html;charset=UTF-8"%><%///从request域中取出数据   39Dept d = (Dept) request.getAttribute("dept");%><!DOCTYPE html><html><head><meta charset="utf-8"><title>部门详情</title></head><body><h1>部门详情</h1><hr >部门编号:<%=d.getDeptno()%> <br>部门名称:<%=d.getDname()%><br>部门位置:<%=d.getLoc()%><br><input type="button" value="后退" onclick="window.history.back()"/></body></html>

error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head>    <title>登录失败</title></head><body><%--登录失败页面  41--%>登陆失败,请<a href="<%=request.getContextPath()%>/index.jsp">重新登录</a></body></html>

edit.jsp

<%@ page import="com.bjpowernode.oa.bean.Dept" %><%@page contentType="text/html;charset=UTF-8"%><%///从request域中取出数据  40Dept d = (Dept) request.getAttribute("dept");%><!DOCTYPE html><html><head><meta charset="utf-8"><title>修改部门</title></head><body><h1>修改部门</h1><hr ><form action="<%=request.getContextPath()%>/dept/modify" method="post">部门编号<input type="text" name="deptno" value="<%=d.getDeptno()%>" readonly /><br>部门名称<input type="text" name="dname" value="<%=d.getDname()%>"/><br>部门位置<input type="text" name="loc" value="<%=d.getLoc()%>"/><br><input type="submit" value="修改"/><br></form></body></html>

T_user的sql脚本添加到数据库中:\java\course19t_user41t_user.sql

drop table if exists t_user;CREATE TABLE t_user(id INT PRIMARY KEY auto_increment,username VARCHAR(255),password VARCHAR(255));INSERT INTO t_user(username,password) VALUES('admin','123456');INSERT INTO t_user(username,password) VALUES('zhangsan','123456');commit;SELECT *FROM t_user;