前言
项目发布于半年前(2023年9月),这次是复习~来考古 =_=
点击前往 GitHub 项目页
该项目在之前的 学生管理系统 项目的基础上,增加了三层架构,对项目进行了分层
1. 三层架构
三层架构是一种分层的设计模式,将整个业务分为表示层、业务逻辑层、数据访问层(持久化层)
优点:降低了代码耦合度,层与层更方便管理,维护性和扩展性较高
缺点:开发成本高,系统性能较低(需要中间层)
具体实现如图:
- 表示层(UI)
显示数据和接受用户输入,实现用户与界面的交互
- 业务逻辑层(BLL)
表示层和数据访问层之间的桥梁,主要包含业务逻辑代码,负责数据的传递
- 数据访问层(DAL)
实现对数据库的访问和操作
2. JavaEE 设计模式之 DAO
DAO,Data Access Object(数据访问对象),是 JavaEE 的一种设计模式
只负责数据库表的 CRUD 操作,没有任何业务逻辑
3. 三层架构应用
目录结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| src |--- com.xxx.student_manage |--- bean |--- Student |--- dao 新增:数据访问层 |--- impl |--- XxxDaoImpl 实现类 |--- XxxDao 接口 |--- filter |--- LoginCheckFilter |--- service 新增:业务逻辑层 |--- impl |--- impl |--- XxxServiceImpl 实现类 |--- XxxService 接口 |--- utils |--- DBUtil |--- web 原有:表示层,代码耦合度降低 |--- StudentServlet |--- UserServlet |--- WelcomeServlet |--- resources |--- jdbc.properties
web 原有:jsp 也属于表示层 |--- ...
|
代码实现
这里列举学生信息相关
DAO 层
只完成 CRUD 操作
接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public interface StudentDao { int insert(Student student);
int deleteBySno(String sno);
int update(Student student);
Student selectBySno(String sno);
List<Student> selectAll(); }
|
实现类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
public class StudentDaoImpl implements StudentDao { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null;
int count = 0;
@Override public int insert(Student student) { try { conn = DBUtil.getConnection(); String sql = "insert into t_student(sno, sname, ssex, telephone) values (?, ?, ?, ?)"; ps = conn.prepareStatement(sql); ps.setString(1, student.getSno()); ps.setString(2, student.getSname()); ps.setString(3, student.getSsex()); ps.setString(4, student.getTelephone()); count = 0; count = ps.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); } finally { DBUtil.close(conn, ps, null); } return count; }
@Override public int deleteBySno(String sno) { try { conn = DBUtil.getConnection(); String sql = "delete from t_student where sno = ?"; ps = conn.prepareStatement(sql); ps.setString(1, sno); count = 0; count = ps.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); } finally { DBUtil.close(conn, ps, null); } return count; }
@Override public int update(Student student) { try { conn = DBUtil.getConnection(); String sql = "update t_student set sname=?, telephone=? where sno=?"; ps = conn.prepareStatement(sql); ps.setString(1, student.getSname()); ps.setString(2, student.getTelephone()); ps.setString(3, student.getSno()); count = 0; count = ps.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); } finally { DBUtil.close(conn, ps, null); } return count; }
@Override public Student selectBySno(String sno) { Student student = new Student(); try { conn = DBUtil.getConnection(); String sql = "select sno, sname, ssex, telephone from t_student where sno=?"; ps = conn.prepareStatement(sql); ps.setString(1, sno); rs = ps.executeQuery(); if (rs.next()) { String sname = rs.getString("sname"); String ssex = rs.getString("ssex"); String telephone = rs.getString("telephone");
student.setSno(sno); student.setSname(sname); student.setSsex(ssex); student.setTelephone(telephone); } } catch (SQLException e) { throw new RuntimeException(e); } finally { DBUtil.close(conn, ps, rs); } return student; }
@Override public List<Student> selectAll() { List<Student> studentList = new ArrayList<>(); try { conn = DBUtil.getConnection(); String sql = "select sno, sname, ssex, telephone from t_student"; ps = conn.prepareStatement(sql); rs = ps.executeQuery(); while (rs.next()) { String sno = rs.getString("sno"); String sname = rs.getString("sname"); String ssex = rs.getString("ssex"); String telephone = rs.getString("telephone");
Student student = new Student(); student.setSno(sno); student.setSname(sname); student.setSsex(ssex); student.setTelephone(telephone);
studentList.add(student); } } catch (SQLException e) { throw new RuntimeException(e); } finally { DBUtil.close(conn, ps, rs); } return studentList; } }
|
Service 层
实现业务逻辑,传递数据
接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
public interface StudentService { void doList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
void doDetail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
void doDel(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
void doAdd(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
void doModify(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException; }
|
实现类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
public class StudentServiceImpl implements StudentService { StudentDao studentDao = new StudentDaoImpl();
@Override public void doList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<Student> studentList = studentDao.selectAll(); request.setAttribute("stuList", studentList); request.getRequestDispatcher("/list.jsp").forward(request, response); }
@Override public void doDetail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String sno = request.getParameter("sno"); Student student = studentDao.selectBySno(sno); request.setAttribute("student", student); request.getRequestDispatcher("/" + request.getParameter("f") + ".jsp").forward(request, response); }
@Override public void doDel(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String sno = request.getParameter("sno"); if (studentDao.deleteBySno(sno) == 1) { response.sendRedirect(request.getContextPath() + "/student/list"); } }
@Override public void doAdd(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String sno = request.getParameter("sno"); String sname = request.getParameter("sname"); String ssex = request.getParameter("ssex"); String telephone = request.getParameter("telephone"); Student student = new Student(sno, sname, ssex, telephone); if (studentDao.insert(student) == 1) { response.sendRedirect(request.getContextPath() + "/student/list"); } }
@Override public void doModify(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String sno = request.getParameter("sno"); String sname = request.getParameter("sname"); String ssex = request.getParameter("ssex"); String telephone = request.getParameter("telephone");
Student student = new Student(sno, sname, ssex, telephone);
if (studentDao.update(student) == 1) { response.sendRedirect(request.getContextPath() + "/student/list"); } } }
|
Web 层
StudentServlet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
@WebServlet({"/student/list", "/student/detail", "/student/delete", "/student/add", "/student/modify"}) public class StudentServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { StudentService studentService = new StudentServiceImpl(); String servletPath = request.getServletPath(); switch (servletPath) { case "/student/list" -> studentService.doList(request, response); case "/student/detail" -> studentService.doDetail(request, response); case "/student/delete" -> studentService.doDel(request, response); case "/student/add" -> studentService.doAdd(request, response); case "/student/modify" -> studentService.doModify(request, response); } } }
|