1.使用模板设计模式优化oa项目344
-以上注释解决了配置文件的问题。但是oa项目还是有一个臃肿的问题。
-一个单标的CRUD写了六个Servlet。如果是复杂的业务系统,这种开发方法显然会导致类爆炸。(类数太大。)
1.1如何解决这类爆炸问题?34可采用模板方法设计模式。
如何解决类爆炸问题?
-以前的设计是要求一个Servlet类。1000个请求对应1000个Servlet类。导致类爆炸。
-可以这样做:一个请求对应一个方法。一个业务对应一个Servlet类。
-处理部门相关业务对应的Deptservlet。处理用户相关业务对应的Userservlet。处理银行卡卡业务对应的Cardservlet。
com中的代码.bjpowernode.oa.utils工具类DBUtilpackage 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(); } } }}
com中的代码.bjpowernode.oa.web.actionDeptServletpackage 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.io.PrintWriter;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;///使用模板改造的单表CRUD操作 34// 模板类@WebServlet({"/dept/list", "/dept/save", "/dept/edit", "/dept/detail", "/dept/delete", "/dept/modify"})// 模糊匹配//// 只要请求路径是“//”dept“一开始,都走这个Servlet。//@WebServlet("/dept/*")public class DeptServlet extends HttpServlet { // 模板方法 // 重写service方法(不重写doget或dopost) @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取servlet path String servletPath = request.getServletPath(); if("/dept/list".equals(servletPath)){ doList(request, response); } else if("/dept/save".equals(servletPath)){ doSave(request, response); } else if("/dept/edit".equals(servletPath)){ doEdit(request, response); } else if("/dept/detail".equals(servletPath)){ doDetail(request, response); } else if("/dept/delete".equals(servletPath)){ doDel(request, response); } else if("/dept/modify".equals(servletPath)){ doModify(request, response); } } private void doList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ ///获取应用程序的根路径 String contextPath = request.getContextPath(); //设置项响应的内容类型和字符集,防止中文乱码问题 response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.print("<!DOCTYPE html>"); out.print("<html>"); out.print("<head>"); out.print("<meta charset='utf-8'>"); out.print("<title>部门列表页面</title>"); ///这部分删除了操作 28 out.print("<script type='text/javascript'>"); out.print(" function del(dno) {"); out.print(" if(window.confirm('请,删除后无法恢复哦){"; out.print(" document.location.href='"+contextPath+"/dept/delete?deptno='+dno"); out.print(" }"); out.print(" }"); out.print("</script>"); out.print("</head>"); out.print("<body>"); out.print("<h1 align='center'>部门列表</h1>"); out.print("<hr>"); out.print("<table border='1px' align='center' width='50%'>"); out.print("<tr>"); out.print("<th>序号</th>"); out.print("<th>部门编号</th>"); out.print("<th>部门名称</th>"); out.print("<th>操作</th>"); out.print("</tr>"); ///上一部分是死的 //连接数据库,查询所有部门 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { //获取连接 conn = DBUtil.getConnection(); //编写sql语句 String sql = "select deptno as a,dname,loc from dept"; ///获取预编译数据库操作对象 ps = conn.prepareStatement(sql); //执行sql语句 rs = ps.executeQuery(); ///处理结果集 int i = 0; while(rs.next()){ String deptno = rs.getString("a"); String dname = rs.getString("dname"); String loc = rs.getString("loc"); ////这部分是动态的 out.print("<tr>"); out.print("<td>"+(++i)+"</td>"); out.print("<td>"+deptno+"</td>"); out.print("<td>"+dname+"</td>"); out.print("<td>"); out.print("<a href" + "='javascript:void(0)' onclick='del("+deptno+")'>删除</a>"); out.print("<a href" + "='"+contextPath+"/dept/edit?deptno="+deptno+"'>修改</a>"); out.print("<a href" + "='"+contextPath+"/dept/detail?deptno="+deptno+"'>详情</a>"); out.print("</td>"); out.print("</tr>"); } } catch (SQLException e) { e.printStackTrace(); } finally { //关闭,释放资源 DBUtil.close(conn,ps,rs); } ////以下部分是死亡的 out.print("</table>"); out.print("<hr>"); out.print("<a href='"+contextPath+"/add.html'>新增部门</a>"); out.print("</body>"); out.print("</html>"); } 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) { ///保存成功跳转到列表页面 //request.getRequestDispatcher("/dept/list").forward(request,response); // 最好在这里使用重定向(浏览器会发送一个全新的请求。) // 浏览器在地址栏上发送请求,即get请求。 response.sendRedirect(request.getContextPath()+"/dept/list"); }else{ ///保存失败跳转到错误页面 //request.getRequestDispatcher("/error.html").forward(request,response); ///这里也建议使用重定向 response.sendRedirect(request.getContextPath()+"/error.html"); } } private void doEdit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ ///获取根路径 String contextPath = request.getContextPath(); response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.print("<!DOCTYPE html>"); out.print("<html>"); out.print("<head>"); out.print("<meta charset='utf-8'>"); out.print("<title>修改部门</title>"); out.print("</head>"); out.print("<body>"); out.print("<h1>修改部门</h1>"); out.print("<hr>"); out.print("<form action='"+contextPath+"/dept/modify' method='post'>"); //获取部门编号 String deptno = request.getParameter("deptno"); //连接数据库,根据部门编号查询部门信息 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,deptno); rs = ps.executeQuery(); while(rs.next()){ String dname = rs.getString("dname"); String loc = rs.getString("loc"); //输出动态网页 out.print(部门编号<input type='text' name='deptno' value='"+deptno+"' readonly /><br> <!-- readonly代表部门编号不能修改 -->"); out.print(部门名称<input type='text' name='dname' value='"+dname+"'/><br>"); out.print(部门位置<input type='text' name='loc' value='"+loc+"'/><br>"); } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(conn,ps,rs); } out.print("<input type='submit' value='修改' /><br>"); out.print("</form>"); out.print("</body>"); out.print("</html>"); } private void doDetail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ //设置项响应的内容类型和字符集,防止中文乱码问题 response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.print(" <!DOCTYPE html>"); out.print("<html>"); out.print("<head>"); out.print("<meta charset='utf-8'>"); out.print("<title>部门详情</title>"); out.print("</head>"); out.print("<body>"); out.print("<h1>部门详情</h1>"); out.print("<hr>"); ///上部是死的 // 获取部门号 // /oa/dept/detail?fdsafdsas=30 // 虽然提交了30,但服务器获得了字符串“30”。 String deptno = request.getParameter("deptno"); Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { //连接数据库,根部部门编号查询部门信息 conn = DBUtil.getConnection(); //编写sql语句 ///获取预编译数据库操作对象 String sql = "select deptno,dname,loc from dept where deptno=?"; ps = conn.prepareStatement(sql); ps.setString(1,deptno); //执行 rs = ps.executeQuery(); //处理结果集,这个结果集只有一个记录 while(rs.next()){ String dname = rs.getString("dname"); String loc = rs.getString("loc"); ///这部分是动态的 out.print(" 门编号:"+deptno+" <br>"); out.print(" 部门名称:“+dname+" <br>"); out.print(" 部门位置:“+loc+" <br>"); } } catch (SQLException e) { e.printStackTrace(); } finally { ///关闭资源 DBUtil.close(conn,ps,rs); } ///下部死亡 out.print("<input type='button' value='后退' onclick='window.history.back()' />"); out.print("</body>"); out.print("</html>"); } private void doDel(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ ///根据部门编号删除部门编号 //设置项响应的内容类型和字符集,防止中文乱码问题 response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); // 获取部门号 String deptno = request.getParameter("deptno"); Connection conn = null; PreparedStatement ps = null; int count = 0; try { //获取数据库连接 conn = DBUtil.getConnection(); ///开启事务(关闭自动提交机制) conn.setAutoCommit(false); //编写sql语句 ///获取预编译数据库操作对象 String sql = "delete from dept where deptno = ?"; ps = conn.prepareStatement(sql); ps.setString(1,deptno); // 返回值是:影响数据库表中有多少条记录。 count = ps.executeUpdate(); //事务提交 conn.commit(); } catch (SQLException e) { ///遇到异常要回滚 if(conn!=null){ try { conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } e.printStackTrace(); } finally { DBUtil.close(conn,ps,null); } ///判断删除是否成功或失败 if (count == 1){ ///成功删除 //仍然跳转到部门列表页面 //部门列表页面的显示需要执行另一个Servlet。怎么办?怎么办?转发。 //request.getRequestDispatcher("/dept/list").forward(request,response); //重定向 response.sendRedirect(request.getContextPath()+"/dept/list"); }else{ ///删除失败 //request.getRequestDispatcher("/error.html").forward(request,response); //重定向 response.sendRedirect(request.getContextPath()+"/error.html"); } } 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){ ///成功更新 // 跳转到部门列表页面(部门列表页面通过Java程序动态生成,因此,还需要再次执行另一个Servlet) //request.getRequestDispatcher("/dept/list").forward(request,response); //重定向 response.sendRedirect(request.getContextPath()+"/dept/list"); }else{ ///更新失败 //request.getRequestDispatcher("/error.html").forward(request,response); //重定向 response.sendRedirect(request.getContextPath()+"/error.html"); } }}
SRC配置文件.resourcesjdbc.propertiesdriver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/bjpowernodeuser=rootpassword=lzl
index.html<!-- 单表CRUD操作 欢迎页面 26 --><!DOCTYPE html><html><head><meta charset="utf-8"><title>oa系统欢迎使用</title></head><body><!--当前端超链接发送请求时,请求路径从“/”开始,并带有项目名称 27--><a href="/oa/dept/list">查看部门列表</a></body></html>
add.html
<!-- 单表CRUD操作 新增页面 26 --><!DOCTYPE html><html><head><meta charset="utf-8"><title>新增部门</title></head><body><h1>新增部门</h1><hr><form action="/oa/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>
errot.html
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>error</title></head><body><h1>操作失败,<a href="javascript:void(0)" onclick="window.history.back()">返回</a></h1></body></html>
edit.html
<!-- 单表CRUD操作 修改页面 26 --><!DOCTYPE html><html><head><meta charset="utf-8"><title>修改部门</title></head><body><h1>修改部门</h1><hr><form action="list.html" method="get">部门编号<input type="text" name="deptno" value="20" readonly /><br> <!-- readonly代表部门编号不能修改 -->部门名称<input type="text" name="dname" value=“销售部”/><br>部门位置<input type="text" name="loc" value="北京"/><br><input type="submit" value="修改" /><br></form></body></html>