什么是三层架构?

三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。区分层次的目的即为了“高内聚低耦合”的思想。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层(又称为持久层)、业务逻辑层(又或称为领域层)、表示层。

表示层(UI层):

表示层也称为界面层,位于最外层(最上层),离用户最近。用于显示数据和接收用户输入的数据,为用户提供一种交互式操作的界面。

业务逻辑层(BLL层):

负责关键业务的处理和数据的传递。复杂的逻辑判断和涉及到数据库的数据验证都需要在此做出处理。主要是针对具体的问题的操作,也可以理解成对数据层的操作,对数据业务逻辑处理,如果说数据层是积木,那逻辑层就是对这些积木的搭建。

数据访问层(DAL层):

主要负责对数据库的直接访问,为业务逻辑层提供数据,根据传入的值来操作数据库,增、删、改、查。

为什么要用三层架构呢?

1.团队开发,便于管理

三层架构使得合作开发成为可能,由于各层相互独立,一个小组只需负责一小块就可以。结构化的编程方法面对大型的项目会感到力不从心,因为结构化设计必定会使程序变的错综复杂。逻辑主要在BLL层,就使得UI层也就是客户端不承担太多的职责,即使更新业务逻辑,也无需修改客户端,不用重新部署。

2.解耦

上一层依赖于下一层,如果测试下一层没有问题,那么问题就只有可能发现在本层了,便于发现和改正BUG。体现了“高内聚,低耦合”的思想。比如楼房是分层的,我们要到哪一层楼非常方便,只需在电梯里按下那个楼层的层号即可。而三层架构就好比开发的软件“楼”,哪层出现Bug,哪层有问题,我们作为开发人员能够随时找到,并修正。 各个层次分工明确,将一个复杂问题简单拆分了。

3.代码的复用和劳动成本的减少

分层的根本在于代码的复用和劳动成本的减少。分层的最理想化的结果是实现层与层之间的互不依赖的内部实现,所谓的即插即用!

当然啦,三层架构也是有一定的缺点,但是总的来说,利大于弊。

那么下面写一个小项目来具体地深入了解一下三层架构

项目目录如下:

表示层Model:

package com.gpnu.book.entity;public class Books {@Overridepublic String toString() {return "Books [book_id=" + book_id + ", book_name=" + book_name + ", isbn=" + isbn + ", author=" + author + "]";}public Books() {}public Books(int book_id, String book_name, String isbn, String author) {super();this.book_id = book_id;this.book_name = book_name;this.isbn = isbn;this.author = author;}private int book_id;private String book_name;private String isbn;private String author;public int getBook_id() {return book_id;}public void setBook_id(int book_id) {this.book_id = book_id;}public String getBook_name() {return book_name;}public void setBook_name(String book_name) {this.book_name = book_name;}public String getIsbn() {return isbn;}public void setIsbn(String isbn) {this.isbn = isbn;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}
}

表示层Controller:

BooksServlet.java

package com.gpnu.book.servlet;import java.io.IOException;
import java.util.List;import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.gpnu.book.entity.Books;
import com.gpnu.book.service.BooksService;
import com.gpnu.book.service.impl.BooksServiceImpl;/*** Servlet implementation class Books*/
@WebServlet("/BooksServlet")
public class BooksServlet extends HttpServlet {private static final long serialVersionUID = 1L;BooksService booksService = BooksServiceImpl.getInstance();/*** @see HttpServlet#HttpServlet()*/public BooksServlet() {super();// TODO Auto-generated constructor stub}/*** @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)*/protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubresponse.getWriter().append("Served at: ").append(request.getContextPath());doPost(request, response);}/*** @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)*/protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("UTF-8");String action = request.getParameter("action");System.out.println("action:" + action);if (action.equals("add")) {doAddBooks(request, response);response.sendRedirect("index.jsp");}else if (action.equals("select")) {response.sendRedirect(request.getContextPath() + "/Books/selBooks.jsp");}else if (action.equals("remove")) {doDelBooks(request, response);response.sendRedirect("SelBooksServlet");}}private void doAddBooks(HttpServletRequest request, HttpServletResponse response) throws IOException {Books book = new Books();//book.setBook_id(Integer.parseInt(request.getParameter("book_id")));book.setBook_name(request.getParameter("book_name"));book.setIsbn(request.getParameter("isbn"));book.setAuthor(request.getParameter("author"));int result = booksService.addBooks(book);if (result > 0)System.out.println("添加book成功");elseSystem.out.println("添加book失败");}private void doDelBooks(HttpServletRequest request, HttpServletResponse response) throws IOException {int id = Integer.parseInt(request.getParameter("id"));int result = booksService.delBooks(id);if (result > 0)System.out.println("删除book成功");elseSystem.out.println("删除book失败");}
}

SelBooksServlet.java

package com.gpnu.book.servlet;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.gpnu.book.entity.Books;
import com.gpnu.book.service.BooksService;
import com.gpnu.book.service.impl.BooksServiceImpl;/*** Servlet implementation class SelBooksServlet*/
@WebServlet("/SelBooksServlet")
public class SelBooksServlet extends HttpServlet {private static final long serialVersionUID = 1L;BooksService booksService = BooksServiceImpl.getInstance();/*** @see HttpServlet#HttpServlet()*/public SelBooksServlet() {super();// TODO Auto-generated constructor stub}/*** @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)*/protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubresponse.getWriter().append("Served at: ").append(request.getContextPath());doPost(request, response);}/*** @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)*/private static String keyword = "";protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("UTF-8");keyword = request.getParameter("keyword");System.out.println("keyword:" + keyword);if (keyword == "")doSelAllBooks(request, response);elsedoSelBooks(request, response);}private void doSelAllBooks(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {List<Books> list = booksService.selAllBooks();request.setAttribute("books", list);System.out.println("查询所有");RequestDispatcher view = request.getRequestDispatcher("/Books/selResult.jsp");view.forward(request, response);}  private void doSelBooks(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {Books book = booksService.selBooks(keyword);List list = new ArrayList();list.add(book);request.setAttribute("books", list);System.out.println("条件查询");RequestDispatcher view = request.getRequestDispatcher("/Books/selResult.jsp");view.forward(request, response);}}

表示层View:

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="Books/addBooks.jsp">添加</a>
<a href="BooksServlet?action=select">查询</a>
</body>
</html>

addBooks.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/book/BooksServlet?action=add" method="post">
<table border="1" cellspacing="0" cellpadding="0" style="align:center;"><tr><td>图书名称:</td><td><input type="text" name="book_name"></td></tr><tr><td>国际标准书号:</td><td><input type="text" name="isbn"></td></tr><tr><td>作者:</td><td><input type="text" name="author"></td></tr><tr><td><input type="submit" value="提交"></td><td><input type="button" value="返回"></td></tr></table></form>
</body>
</html>

selBooks.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/book/SelBooksServlet" method="post">
<input type="text" name="keyword"><input type="submit" value="查询">
</form>
</body>
</html>

selResult.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@ page import="com.gpnu.book.entity.Books,java.util.List" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="Books/addBooks.jsp">新增</a>
<br>
<table border="1" cellspacing="0" cellpadding="0" style="align:center;"><tr bgcolor="ff9900" style="font-weight:bold;"><th>图书编号</th><th>图书名称</th><th>国际标准号</th><th>作者</th></tr>
<%List<Books> book = (List)request.getAttribute("books");if(book.size()!=0){for(int i=0;i<book.size();i++) {pageContext.setAttribute("book",book.get(i));
%>  <tr><td>${book.book_id }</td>    <td>${book.book_name }</td><td>${book.isbn }</td><td>${book.author }</td><td>|<a href="BooksServlet?action=remove&id=${book.book_id }" onclick='return confirm("确定要删除吗?")'>删除</a></td></tr> <%}}else{%>
<tr><td colspan="6">数据库中没有数据!</td></tr><%}%>
</table>
</body>
</html>

持久层接口:

package com.gpnu.book.dao;import java.util.List;import com.gpnu.book.entity.Books;public interface BooksDao {List<Books> selAllBooks();Books selBooks(String keyword);int addBooks(Books book);int delBooks(int book_id);int booksCount();
}

持久层实现类:

package com.gpnu.book.dao.impl;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;import com.gpnu.book.dao.BooksDao;
import com.gpnu.book.entity.Books;
import com.gpnu.book.common.DBUtils;public class BooksDaoImpl implements BooksDao {private Connection conn;public BooksDaoImpl(Connection conn) {this.conn = conn;}@Overridepublic List<Books> selAllBooks() {List list = new ArrayList();PreparedStatement pstam = null;ResultSet rs = null;Books book = null;     try {pstam = conn.prepareStatement("select * from tbl_book");rs = pstam.executeQuery();while (rs.next()) {book = new Books();book.setBook_id(rs.getInt("book_id"));book.setBook_name(rs.getString("book_name"));book.setIsbn(rs.getString("isbn"));book.setAuthor(rs.getString("author"));list.add(book);}} catch (SQLException e) {System.out.println("在查询全部book的时候出错了.错误信息是 :" + e.getMessage());} finally {DBUtils.closeStatement(rs, pstam);}return list;}@Overridepublic int booksCount() {// TODO Auto-generated method stubreturn 0;}@Overridepublic Books selBooks(String keyword) {Books book = new Books();PreparedStatement pStatement = null;ResultSet rSet = null;try {pStatement = conn.prepareStatement("select * from tbl_book where book_name like ?");pStatement.setString(1, "%" + keyword + "%");rSet = pStatement.executeQuery();if (rSet.next()) {book.setBook_id(rSet.getInt("book_id"));book.setBook_name(rSet.getString("book_name"));   book.setIsbn(rSet.getString("isbn"));book.setAuthor(rSet.getString("author"));}} catch (SQLException e) {e.printStackTrace();} finally {DBUtils.closeStatement(rSet, pStatement);}return book;}@Overridepublic int addBooks(Books book) {int result = 0;PreparedStatement pstam = null;try {pstam = conn.prepareStatement("insert into tbl_book(book_name,isbn,author) values(?,?,?)");//pstam.setInt(1, book.getBook_id());pstam.setString(1, book.getBook_name());pstam.setString(2, book.getIsbn());pstam.setString(3, book.getAuthor());result = pstam.executeUpdate();} catch (SQLException e) {System.out.println("添加book出错.错误信息是 :" + e.getMessage());} finally {DBUtils.closeStatement(null, pstam);}return result;}@Overridepublic int delBooks(int book_id) {int result = 0;PreparedStatement pstam = null;try {pstam = conn.prepareStatement("DELETE FROM tbl_book WHERE book_id =?");pstam.setInt(1, book_id);result = pstam.executeUpdate();} catch (SQLException e) {System.out.println("删除book出错.错误信息是 :" + e.getMessage());} finally {DBUtils.closeStatement(null, pstam);}return result;}}

业务逻辑层接口:

package com.gpnu.book.service;import java.util.List;import com.gpnu.book.entity.Books;public interface BooksService {List<Books> selAllBooks();Books selBooks(String keyword);int addBooks(Books book);int delBooks(int book_id);
}

业务逻辑层实现类

package com.gpnu.book.service.impl;import java.sql.Connection;
import java.util.List;import com.gpnu.book.entity.Books;
import com.gpnu.book.service.BooksService;
import com.gpnu.book.common.DBUtils;
import com.gpnu.book.dao.BooksDao;
import com.gpnu.book.dao.impl.BooksDaoImpl;public class BooksServiceImpl implements BooksService {private static final BooksService instance = new BooksServiceImpl();public static BooksService getInstance() {return instance;}@Overridepublic List<Books> selAllBooks() {Connection conn = null;List list = null;try {conn = DBUtils.getConnection();DBUtils.beginTransaction(conn);BooksDao booksDao = new BooksDaoImpl(conn);list = booksDao.selAllBooks();DBUtils.commit(conn);} catch (Exception e) {System.out.println("查询所有books错误" + e.getMessage());} finally {DBUtils.closeConnection(conn);}return list;}@Overridepublic Books selBooks(String keyword) {Connection conn = null;Books book = null;try {conn = DBUtils.getConnection();DBUtils.beginTransaction(conn);BooksDao booksDao = new BooksDaoImpl(conn);book = booksDao.selBooks(keyword);DBUtils.commit(conn);} catch (Exception e) {System.out.println("条件查询books错误" + e.getMessage());} finally {DBUtils.closeConnection(conn);}return book;}@Overridepublic int addBooks(Books book) {Connection conn = null;int result = 0;try {conn = DBUtils.getConnection();DBUtils.beginTransaction(conn);BooksDao booksDao = new BooksDaoImpl(conn);result = booksDao.addBooks(book);DBUtils.commit(conn);} catch (Exception e) {System.out.println("增加books错误" + e.getMessage());} finally {DBUtils.closeConnection(conn);}return result;}@Overridepublic int delBooks(int book_id) {Connection conn = null;int result = 0;try {conn = DBUtils.getConnection();DBUtils.beginTransaction(conn);BooksDao booksDao = new BooksDaoImpl(conn);result = booksDao.delBooks(book_id);DBUtils.commit(conn);} catch (Exception e) {System.out.println("删除books错误" + e.getMessage());} finally {            DBUtils.closeConnection(conn);}return result;}}

我们启动一下项目,我们作为用户直接看到的就是表示层的视图了

而当我们点击查询,会跳转到查询的视图

点击查询,我们会跳转到表示层的控制器,也就是Servlet,此时Servle会调用业务逻辑层的方法

而业务逻辑层则会调用持久层(DAO层)的方法

最后持久层连接到数据库,读取数据库的数据,保存为一个Model类

将结果原路返回给表示层的视图View

整个运行过程可以浓缩为一张图:

转自:https://blog.csdn.net/a549654065/article/details/83064231

JavaWeb三层架构详解相关推荐

  1. JAVA三层架构详解

    JAVA三层架构详解 三层架构分别是什么 为什么要有三层架构 三层架构思想下的项目目录结构 三层架构分别是什么 通俗说三层架构指的就是: 前端所能看见的界面为第一层,专业术语表示层(UI层) 后端对相 ...

  2. java 三层架构_java三层架构详解

    三层架构模式介绍 三层架构模式: 三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer).业务逻辑层(Bu ...

  3. 程序基础之三层架构详解

    我们在编写程序时,最基本最常用的就是三层架构,那么关于三层架构,有些人肯定会有很多问题和不理解的地方,所以我们就根据问题来认识一下三层架构. 什么是三层架构 为什么要用三层架构 三层架构有什么优点缺点 ...

  4. asp.net三层架构详解

    一.数据库 /*==============================================================*/ /* DBMS name:      Microsof ...

  5. C#_三层(BLL DAL Model)架构详解

    C#_三层架构详解 三层架构: 表现层(UI).业务逻辑层(BLL).数据访问层(DAL)再加上实体类库(Model) 表现层(UI):一般都是窗体的设计或者网页的设计,是可以一眼就可以看到的界面. ...

  6. java调用webservice_笃学私教:Java开发网站架构演变过程-从单体应用到微服务架构详解...

    原标题:笃学私教:Java开发网站架构演变过程-从单体应用到微服务架构详解 Java开发网站架构演变过程,到目前为止,大致分为5个阶段,分别为单体架构.集群架构.分布式架构.SOA架构和微服务架构.下 ...

  7. 大型分布式架构详解:架构模式+敏捷性+可扩展+案例等

    大型分布式架构详解:架构模式+敏捷性+可扩展+案例等 本篇是大型分布式网站架构的技术总结篇. 主要对大型分布式架构中涉及的架构模式.高性能.高可用.可伸缩.敏捷性.可扩展等技术点进行简要总结,对大型分 ...

  8. 高并发高流量网站架构详解

    (推荐)高并发高流量网站架构详解 Web2.0的兴起,掀起了互联网新一轮的网络创业大潮.以用户为导 向的新网站建设概念,细分了网站功能和用户群,不仅成功的造就了一大批新生的网站,也极大的方便了上网的人 ...

  9. 千万级PV规模高性能高并发网站架构详解

    1.缓存(expires) 2.deflate压缩 3.Apache/nginx静态服务器提供html页面内容 4.CDN/cache缓存静态内容如:html.jpg.gif.js等 5.MYSQL数 ...

最新文章

  1. java 正则 cpu 100_这六个原因真的可以使Java应用程序的CPU使用率飙升到100%吗?...
  2. Thinkphp 源码分析
  3. 我的android面试经历
  4. python对csv文件中的数据进行分类_利用Python对csv文件中的数据进行排序
  5. 每天九点十分开始每半小时一次执行一个cron_每天通勤4小时!西咸双城生活的上班族,不简单...
  6. 【转】AI-900认证考试攻略
  7. winfrom导出DataGridView为Excel方法
  8. wrapper怎么用_用责任链模式设计拦截器
  9. ASP.NET Form Authentication安全漏洞及对策
  10. 小学生手写Python程序解魔方!这是高手,这绝对是高手!
  11. 彭荣新:喜马拉雅自研网关架构演进过程
  12. python读取matlab矩阵_matlab、python中矩阵的互相导入导出方式
  13. ios tweak之binary not signed (use ldid -S)问题解决
  14. 开发环境 测试环境 定义_如何快速搭建ES开发测试环境?
  15. ROS机器人程序设计(原书第2版)2.4.1 ROS文件系统导览
  16. java 开关按钮_SwitchButton开关按钮的多种实现方式
  17. 向量的范数(有例子,简单好理解)
  18. 基于FPGA的AD/DA实验
  19. MGS摄像头:USF56S335_3238_V2 IMX335 5MP UVC应用手册
  20. .rgb格式文件的Python读取、格式转换

热门文章

  1. MSP430学习笔记11-八路ADC采集诺基亚5110液晶显示
  2. 特种机械车辆控制器SPC-CFMC-D24N20资料
  3. Gbase8a数据库安装与使用
  4. selenium鼠标双击操作
  5. 医药行业数字化转型加速,上云势在必行!
  6. Linux中安装数据库
  7. 【ML】基于机器学习的心脏病预测研究(附代码和数据集,多层感知机模型)
  8. CF - E95(div2) -- B. Negative Prefixes【贪心】
  9. 自制文字工具籍,包含了免费离线高精度图片转文字(OCR)
  10. 基于XMPP的IOS聊天客户端程序(IOS端二)