三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。区分层次的目的即为了“高内聚低耦合”的思想。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层(又称为持久层)、业务逻辑层(又或称为领域层)、表示层。
表示层也称为界面层,位于最外层(最上层),离用户最近。用于显示数据和接收用户输入的数据,为用户提供一种交互式操作的界面。
负责关键业务的处理和数据的传递。复杂的逻辑判断和涉及到数据库的数据验证都需要在此做出处理。主要是针对具体的问题的操作,也可以理解成对数据层的操作,对数据业务逻辑处理,如果说数据层是积木,那逻辑层就是对这些积木的搭建。
主要负责对数据库的直接访问,为业务逻辑层提供数据,根据传入的值来操作数据库,增、删、改、查。
1.团队开发,便于管理
三层架构使得合作开发成为可能,由于各层相互独立,一个小组只需负责一小块就可以。结构化的编程方法面对大型的项目会感到力不从心,因为结构化设计必定会使程序变的错综复杂。逻辑主要在BLL层,就使得UI层也就是客户端不承担太多的职责,即使更新业务逻辑,也无需修改客户端,不用重新部署。
2.解耦
上一层依赖于下一层,如果测试下一层没有问题,那么问题就只有可能发现在本层了,便于发现和改正BUG。体现了“高内聚,低耦合”的思想。比如楼房是分层的,我们要到哪一层楼非常方便,只需在电梯里按下那个楼层的层号即可。而三层架构就好比开发的软件“楼”,哪层出现Bug,哪层有问题,我们作为开发人员能够随时找到,并修正。 各个层次分工明确,将一个复杂问题简单拆分了。
3.代码的复用和劳动成本的减少
分层的根本在于代码的复用和劳动成本的减少。分层的最理想化的结果是实现层与层之间的互不依赖的内部实现,所谓的即插即用!
当然啦,三层架构也是有一定的缺点,但是总的来说,利大于弊。
那么下面写一个小项目来具体地深入了解一下三层架构
项目目录如下:
表示层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
${book.book_id }
${book.book_name }
${book.isbn }
${book.author }
|删除
<%
}
}else{
%>
数据库中没有数据!
<%
}
%>
持久层接口:
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;
}
}
我们启动一下项目,我们作为用户直接看到的就是表示层的视图了
而当我们点击查询,会跳转到查询的视图
点击查询,我们会跳转到表示层的控制器,也就是Servlet,此时Servle会调用业务逻辑层的方法
而业务逻辑层则会调用持久层(DAO层)的方法
最后持久层连接到数据库,读取数据库的数据,保存为一个Model类
将结果原路返回给表示层的视图View
整个运行过程可以浓缩为一张图:
转自:https://blog.csdn.net/a549654065/article/details/83064231