JavaWeb三层架构详解

什么是三层架构?

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

 

表示层(UI层):

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

 

业务逻辑层(BLL层):

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

 

数据访问层(DAL层):

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

 

为什么要用三层架构呢?

1.团队开发,便于管理

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

 

2.解耦

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

 

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

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

 

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

 

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

 

项目目录如下:

JavaWeb三层架构详解_第1张图片

表示层Model:

package com.gpnu.book.entity;
 
public class Books {
	@Override
	public 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 stub
		response.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成功");
		else
			System.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成功");
		else
			System.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 stub
		response.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);
		else
			doSelBooks(request, response);
	}
 
	private void doSelAllBooks(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		List 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"%>




Insert title here


添加
查询

addBooks.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




Insert title here


图书名称:
国际标准书号:
作者:

selBooks.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




Insert title here


selResult.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="com.gpnu.book.entity.Books,java.util.List" %>




Insert title here


新增

<% List book = (List)request.getAttribute("books"); if(book.size()!=0){ for(int i=0;i <% } }else{ %> <% } %>
图书编号图书名称国际标准号作者
${book.book_id } ${book.book_name } ${book.isbn } ${book.author } |删除
数据库中没有数据!

持久层接口:

package com.gpnu.book.dao;
 
import java.util.List;
 
import com.gpnu.book.entity.Books;
 
public interface BooksDao {
	List 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;
	}
	
	@Override
	public List 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;
	}
 
	@Override
	public int booksCount() {
		// TODO Auto-generated method stub
		return 0;
	}
 
	@Override
	public 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;
	}
 
	@Override
	public 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;
	}
 
	@Override
	public 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 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;
	}
	
	@Override
	public List 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;
	}
 
	@Override
	public 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;
	}
 
	@Override
	public 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;
	}
 
	@Override
	public 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;
	}
 
}

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

JavaWeb三层架构详解_第2张图片

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

JavaWeb三层架构详解_第3张图片

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

JavaWeb三层架构详解_第4张图片

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

JavaWeb三层架构详解_第5张图片

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

JavaWeb三层架构详解_第6张图片

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

JavaWeb三层架构详解_第7张图片

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

JavaWeb三层架构详解_第8张图片

 

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

 

你可能感兴趣的:(走进Java的世界,三层架构)