文章目录

    • @[toc]
  • 一、回顾三层架构
    • 1.1基本概念
    • 1.2作用与组成
    • 1.3三层架构命名规范
      • 1.3.1UI层(表示层)
      • 1.3.2业务逻辑层
      • 1.3.3数据访问层
  • 二、MVC
    • 2.1MVC简介
    • 2.2MVC与三层架构的关系
      • 2.3在Web应用中使用MVC架构原因
      • 2.4MVC的优点
      • 2.5MVC的缺点
  • 三、三层架构和MVC的区别
  • 四、总结
  • 五、补充

一、回顾三层架构

1.1基本概念

三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:

1、界面层(User Interface layer)JSP、HTML5

2、业务逻辑层(Business Logic Layer)

3、数据访问层(Data access layer)持久层(DAO)


1.2作用与组成

区分层次的目的即为了 “高内聚低耦合” 的思想。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层、业务逻辑层(又或称为领域层)、表示层。


1.3三层架构命名规范

这里以第三波书店为案例

1.3.1UI层(表示层)

在创建JavaWeb项目的时候我们的项目中会包含一个名称为webappweb的目录,在该目录下的xxx.jspxxx.html页面就是所谓的表示层,通俗点来说就是我们客户端浏览器运行应用程序时所看到的操作界面。


1.3.2业务逻辑层

该层主要提供业务服务接口和接口对应的实现类

例如service包下的BookService接口

package com.bookshop.service;import com.bookshop.entity.Book;import java.util.List;/*** 业务逻辑层,图书业务接口** @author Aiden*/
public interface BookService {//按照指定的条数查询图书列表List<Book> findListByCount(Integer count);//分页查询图书信息List<Book> findListByPage(Integer pageIndex, Integer pageSize, Integer categoryId);//根据图书分类查询图书总条数Long getTotalCount(Integer categoryId);//根据图书主键编号查询图书信息Book findByBookId(String bookId);}

例如service.impl包下的BookServiceImpl

package com.bookshop.service.impl;import com.bookshop.dao.BookDao;
import com.bookshop.dao.impl.BookDaoImp;
import com.bookshop.entity.Book;
import com.bookshop.service.BookService;
import com.bookshop.utils.JDBCUtils;import java.util.List;/*** 图书业务实现类** @author Aiden*/
public class BookServiceImpl implements BookService {//创建dao实例private BookDao dao = new BookDaoImp();@Overridepublic List<Book> findListByCount(Integer count) {List<Book> list = null;try {list = dao.findListByCount(count);} catch (Exception exception) {exception.printStackTrace();}return list;}@Overridepublic List<Book> findListByPage(Integer pageIndex, Integer pageSize, Integer categoryId) {List<Book> list = null;try {Integer currentPage = (pageIndex - 1) * pageSize;list = dao.findListByPage(currentPage, pageSize, categoryId);} catch (Exception exception) {exception.printStackTrace();} finally {JDBCUtils.close();}return list;}@Overridepublic Long getTotalCount(Integer categoryId) {Long count = 0L;try {count = dao.getTotalCount(categoryId);} catch (Exception exception) {exception.printStackTrace();}return count;}@Overridepublic Book findByBookId(String bookId) {Book book = null;try {book = dao.findByBookId(bookId);} catch (Exception exception) {exception.printStackTrace();}return book;}
}

1.3.3数据访问层

该层主要提供数据服务接口和接口对应的实现类

例如dao包下的BookDao接口

package com.bookshop.dao;import com.bookshop.entity.Book;import java.util.List;/*** 数据访问层,图书DAO接口** @author Aiden*/
public interface BookDao {//按照指定的条数查询图书列表List<Book> findListByCount(Integer count) throws Exception;//分页查询图书信息List<Book> findListByPage(Integer pageIndex, Integer pageSize, Integer categoryId) throws Exception;//根据图书类型查询总条数Long getTotalCount(Integer categoryId) throws Exception;//新增图书信息int insert(Book book) throws Exception;//修改图书信息int update(Book book) throws Exception;//删除图书信息int delete(Integer bookId) throws Exception;//修改上下架状态(sale:0:下 1:上架)int updateSaleByBookId(Integer bookId, Integer sale) throws Exception;//根据图书主键编号查询图书信息Book findByBookId(String bookId) throws Exception;
}

例如dao.impl包下的BookDaoImpl接口

package com.bookshop.dao.impl;import com.bookshop.dao.BookDao;
import com.bookshop.entity.Book;
import com.bookshop.utils.JDBCUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;/*** 图书DAO接口实现类,提供对MySql数据库服务器的CURD操作* @author Aiden*/
public class BookDaoImp implements BookDao {QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());@Overridepublic List<Book> findListByCount(Integer count) throws Exception {Connection connection = JDBCUtils.getConnection();String sql = "SELECT * from Books LIMIT ?";List<Book> list = queryRunner.query(connection, sql, new BeanListHandler<>(Book.class), count);//关闭连接对象JDBCUtils.closeConnection(connection);return list;}@Overridepublic List<Book> findListByPage(Integer pageIndex, Integer pageSize, Integer categoryId) throws Exception {Connection connection = JDBCUtils.getConnection();StringBuffer sql = new StringBuffer();List<Object> params = new ArrayList<>();sql.append("select * from books ");if (categoryId != null && categoryId > 0) {sql.append("where categoryId=? ");params.add(categoryId);}sql.append(" limit ?,? ");params.add(pageIndex);params.add(pageSize);List<Book> list = queryRunner.query(connection, sql.toString(), new BeanListHandler<>(Book.class), params.toArray());//关闭连接对象JDBCUtils.closeConnection(connection);return list;}@Overridepublic Long getTotalCount(Integer categoryId) throws Exception {Connection connection = JDBCUtils.getConnection();StringBuffer sql = new StringBuffer();List<Object> params = new ArrayList<>();sql.append("select count(0) from books");if (categoryId != null && categoryId > 0) {sql.append(" where categoryId=? ");params.add(categoryId);}Long totalCount = (Long) queryRunner.query(connection, sql.toString(), new ScalarHandler<>(1), params.toArray());//关闭连接对象JDBCUtils.closeConnection(connection);return totalCount;}@Overridepublic Book findByBookId(String bookId) throws Exception {String sql = "select b.*,c.categoryName,p.publisherName from books b \n" +"inner join category c on b.categoryId=c.categoryId \n" +"inner join publisher p on b.publisherId=p.publisherId\n" +"where b.bookId=?";//获取连接Connection connection = JDBCUtils.getConnection();Book book = queryRunner.query(sql, new BeanHandler<>(Book.class), bookId);//关闭连接JDBCUtils.closeConnection(connection);return book;}@Overridepublic int insert(Book book) throws Exception {return 0;}@Overridepublic int update(Book book) throws Exception {return 0;}@Overridepublic int delete(Integer bookId) throws Exception {return 0;}@Overridepublic int updateSaleByBookId(Integer bookId, Integer sale) throws Exception {return 0;}}

二、MVC

2.1MVC简介

MVC 全名是Model View Controller,是 模型(model)视图(view)控制器(controller) 的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

模型:

模型是应用程序的主体部分,表示业务数据和业务逻辑。一个模型能为多个视图提供数据。由于应用于模型的代码只需要写一次就可以被多个视图重用,所以提高了代码的可重用性。

视图

视图是用户看到并与之交互的界面,可以向用户显示相关的数据,也可以接收用户的输入,但是不进行任何实际的业务处理。

控制器

控制器主要用于接收客户端请求,获取请求参数,调用业务层服务方法,决定用哪个模型组件去处理请求,然后决定调用哪个视图来显示模型处理返回的数据。


2.2MVC与三层架构的关系

M :(Model) 对应三层架构中的 JavaBean (数据访问层+业务逻辑层)

V :(View) 对应三层架构中的表示层(JSP页面/html页面

C :(Controller)控制器(ServletJSP


2.3在Web应用中使用MVC架构原因

用户界面逻辑的更改往往比业务逻辑频繁,尤其是在基于Web的应用程序中。

例如,可能添加新的用户界面页,或者可能完全打乱现有的页面布局。对显示的更改,尽可能地不要影响到数据和业务逻辑。

目前大部分Web应用都是将数据代码和表示混在一起。经验比较丰富的开发者会将数据从表示层分离开来,但这通常不是很容易做到的,它需要精心的计划和不断的尝试。MVC从根本上强制性的将它们分开。尽管构造MVC应用需要一些额外的工作,但它带来的好处是无庸质疑的。


2.4MVC的优点

(1) 有利于团队开发分工协作和质量控制,降低开发成本。

(2) 可以为一个模型在运行时同时建立和使用多个视图。变化-传播机制可以确保所有相关的视图及时得到模型数据变化,从而使所有关联的视图和控制器做到行为同步。

(3) 视图与控制器的可接插性,允许更换视图和控制器对象,而且可以根据需求动态的打开或关闭、甚至在运行期间进行对象替换。

(4) 模型的可移植性。因为模型是独立于视图的,所以可以把一个模型独立地移植到新的平台工作。需要做的只是在新平台上对视图和控制器进行新的修改。

(5) 潜在的框架结构。可以基于此模型建立应用程序框架,不仅仅是用在设计界面的设计中。


2.5MVC的缺点

(1)增加了系统结构和实现的复杂性。对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。

(2)视图对模型数据的访问效率低。视图可能需要多次调用Model才能获得足够的显示数据。

(3)完全理解MVC并不是很容易。使用MVC需要精心的计划,由于它的内部原理比较复杂,所以需要花费一些时间去思考。同时由于模型和视图要严格的分离,这样也给调试应用程序到来了一定的困难。


三、三层架构和MVC的区别

MVC(模型Model-视图View-控制器Controller)是一种架构模式,可以用它来创建在域对象和UI表示层对象之间的区分。

同样是架构级别的,相同的地方在于他们都有一个表现层,但是他们不同的地方在于其他的两个层。

在三层架构中没有定义Controller的概念。这是最不同的地方。而MVC也没有把业务的逻辑访问看成两个层,这是采用三层架构或MVC搭建程序最主要的区别。当然了。在三层中也提到了Model,但是三层架构中Model的概念与MVC中Model的概念是不一样的,“三层”中典型的Model层是由业务逻辑与访问数据组成的。而MVC里,则是以实体类构成的。


四、总结


五、补充

关于上文业务实现类与dao实现类中出现的JDBCUtils为数据库操作工具辅助类,该类的实现代码如下:

maven依赖

<!--mysql数据库驱动-->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.26</version>
</dependency>
<!--druid数据源-->
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.10</version>
</dependency>
<!--数据库操作工具类-->
<dependency><groupId>commons-dbutils</groupId><artifactId>commons-dbutils</artifactId><version>1.7</version>
</dependency>
<!--servlet-api-->
<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version>
</dependency>

JDBCUtils工具类

package com.bookshop.utils;import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;/*** JDBCUtils工具类*/
public class JDBCUtils {private static DruidDataSource dataSource;//数据源private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();//本地线程private static Connection conn;//连接对象//静态代码块static {InputStream is = null;try {Properties properties = new Properties();is = JDBCUtilPlus.class.getClassLoader().getResourceAsStream("druid.properties");properties.load(is);is.close();dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {e.printStackTrace();} finally {if (is != null) {try {is.close();//关闭流} catch (IOException e) {e.printStackTrace();}}}}/*** 获取连接* @return*/public static Connection getConnection() {try {conn = threadLocal.get();if (conn == null) {conn = dataSource.getConnection();threadLocal.set(conn);}return conn;} catch (SQLException e) {e.printStackTrace();}return null;}/*** 获取数据源* @return*/public static DataSource getDataSource() {return dataSource;}/*** 开启事务*/public static void startTransaction() {try {Connection connection = getConnection();if (connection != null) {connection.setAutoCommit(false);}} catch (SQLException e) {e.printStackTrace();}}/*** 提交事务*/public static void commitTransaction() {try {Connection connection = threadLocal.get();if (connection != null) {connection.commit();}} catch (SQLException e) {e.printStackTrace();}}/*** 回滚事务*/public static void rollbackTransaction() {try {Connection connection = threadLocal.get();if (connection != null) {connection.rollback();}} catch (SQLException e) {e.printStackTrace();}}/*** 关闭事务*/public static void close() {try {Connection connection = threadLocal.get();if (connection != null) {if (!connection.getAutoCommit()) {threadLocal.remove();connection.close();}}} catch (SQLException e) {e.printStackTrace();}}/*** 普通关闭** @param connection*/public static void closeConnection(Connection connection) {try {if (connection != null) {if (connection.getAutoCommit()) {threadLocal.remove();connection.close();}}} catch (SQLException e) {e.printStackTrace();}}
}

druid.properties配置类

#数据库连接基础信息
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/bookshopplus?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username=root
password=root
#初始化连接数个数
initialSize=20
#最大连接数个数
maxActive=100
#空闲的连接数个数
minIdle=6
#获取连接最大等待时间
maxWait=60000
#从连接池获取连接时,是否检测连接可用性,开启性能会有些许影响
testOnBorrow=true
#启用空闲连接检测,以便回收
testWhileIdle=true
#释放连接到连接池时,是否检测连接可用性,开启性能会有些许影响
testOnReturn=false
#系统启动时通过该sql语句验证数据库是否可用,例如oracle用SELECT 'x' from dual,mysql用SELECT 'x'
validationQuery=select 'x'
#监控数据库
filters=start
#关闭超过30分钟的空闲连接,1800秒,也就是30分钟
removeAbandonedTimeout=1800
#对于长时间不使用的连接强制关闭
removeAbandoned=true
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis=60000

Servlet控制器

package com.bookshop.servlet;import com.bookshop.entity.Book;
import com.bookshop.service.BookService;
import com.bookshop.service.impl.BookServiceImpl;
import com.bookshop.utils.Page;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 java.io.IOException;
import java.util.List;/*** Servlet 图书管理控制器* @author Aiden*/
@WebServlet("/BookServlet")
public class BookServlet extends HttpServlet {//用于处理客户端请求服务方法@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//查询、新增、修改、删除String action = request.getParameter("action");action = (action == null) ? "select" : action;BookService bookService = new BookServiceImpl();switch (action) {case "select": //查询图书selectBookInfo(request, response, bookService);break;case "details"://查询图书详情信息queryBookDetails(request, response, bookService);break;case "insert": //新增操作break;case "update": //修改操作break;case "delete": //删除操作break;default:selectBookInfo(request, response, bookService);break;}}/*** 查询图书详情信息*/private void queryBookDetails(HttpServletRequest request, HttpServletResponse response, BookService bookService) throws ServletException, IOException {//根据图书主键编号,查询图书对象,传递到details.jsp页面String bookId = request.getParameter("bookId");Book book = bookService.findByBookId(bookId);request.setAttribute("book", book);request.getRequestDispatcher("details.jsp").forward(request, response);}/*** 查询图书信息*/private void selectBookInfo(HttpServletRequest request, HttpServletResponse response, BookService bookService) throws ServletException, IOException {//获取前端请求的页码索引Integer pageIndex = request.getParameter("pageIndex") == null ? 1 : Integer.parseInt(request.getParameter("pageIndex"));Integer pageSize = 12;//获取图书分类的编号Integer categoryId = request.getParameter("cId") == null ? 0 : Integer.parseInt(request.getParameter("cId"));//查询总条数Long totalCount = bookService.getTotalCount(categoryId);//分页数据列表List<Book> bookList = bookService.findListByPage(pageIndex, pageSize, categoryId);Page<Book> page = new Page<Book>(pageIndex, pageSize, totalCount.intValue(), bookList);//将数据保存在request作用域中request.setAttribute("page", page);request.setAttribute("cId", categoryId);//跳转到图书首页request.getRequestDispatcher("booklist.jsp").forward(request, response);}
}

JSP-05三层架构+MVC相关推荐

  1. php的mvc三层架构,MVC三层架构

    1.三层架构 表现层(web层) web层:接受客户端请求,向客户端响应结果,通常客户端使用http协议请求: 控制层:负责接受请求 展示层:结果的展示 业务层(service层) 事务处理+业务处理 ...

  2. Android app按三层架构+MVC整理(重构)代码可行吗

    项目是别人写的,领导让我们重构. 虽然有MVP和MVVM,但领导用了三层架构(表现层,业务层,数据访问层)+MVC这么多年,敲定还是按这种体系.领导负责定基调,具体的实施当然由我们这些人做. 于是大体 ...

  3. .NET 三层架构+MVC+EF实现对数据库表的增删改查

    数据库: 表 项目层级: Model类库下: Student.cs类源码: namespace Model {public

  4. JavaWeb之JSP和MVC三层架构

    JSP JSP概述 JSP的作用 JSP(全称:Java Server Pages):Java 服务端页面.是一种动态的网页技术,其中既可以定义 HTML.JS.CSS等静态内容,还可以定义 Java ...

  5. 三层架构与MVC的区别

    我们平时总是将混为一谈,殊不知它俩并不是一个概念.下面我来为大家揭晓我所知道的一些真相. 首先,它俩根本不是一个概念. 三层架构是一个分层式的软件体系架构设计,它可适用于任何一个项目. MVC是一个设 ...

  6. Javaweb MVC设计模式、Modle发展史、项目分层和三层架构

    文章目录 MVC设计模式 MVC的目的 MVC举例 jsp+servlet+javabean模式 MVC的优点 MVC的缺点 Modle 发展史 项目分层 三层架构 MVC设计模式 MVC模式(Mod ...

  7. MVC三层架构简单理解

    文章目录 MVC三层架构: 1.理解MVC: 2.以前的架构(只有两层): 3 MVC 三层架构: MVC三层架构: 1.理解MVC: Model view Controller 模型.视图.控制器 ...

  8. 三层架构与MVC区别

    我们平时总是将混为一谈,殊不知它俩并不是一个概念.下面我来为大家揭晓我所知道的一些真相. 首先,它俩根本不是一个概念. 三层架构是一个分层式的软件体系架构设计,它可适用于任何一个项目. MVC是一个设 ...

  9. MVC模式与三层架构的区别

    MVC模式与三层架构的区别 原文地址:http://www.cnblogs.com/yourshj/p/5197310.html 之前总是混淆MVC表现模式和三层架构模式,为此记录下. 三层架构和MV ...

最新文章

  1. 使COUNT(*)查询总数变快
  2. CentOS系统提示用户名不在sudoers文件中
  3. 响应性web设计实战总结(二)
  4. 搭建你的嵌入式Vxworks开发环境
  5. 服务器监控工具_8款服务器和应用性能监控工具
  6. 站在BERT肩膀上的NLP新秀们(PART I)
  7. XML中的DOCTYPE属性
  8. python函数和代码复用思维导图_Python语言程序---代码复用与函数递归(二)
  9. baidu__git_android
  10. 小米air2se耳机只有一边有声音怎么办_别光盯着AirPods,这些无线蓝牙耳机,其实也很好用...
  11. [面经]星环科技大数据后台开发实习面试
  12. 计算机用word做海报,如何使用word文档制作精美海报
  13. Windows“控制面板”在哪?win10怎么打开控制面板(快捷方法)打开控制面板的多种方法都在这里
  14. 科大讯飞语音识别SDK的ROS包修改
  15. 计算机视觉物体识别的过程,(物体识别过程.doc
  16. 点星PBX(DotAsterisk)和讯时MX100G数字中继网关外呼去掉本地被叫号码区号的方法
  17. 数据结构 —— 队列、栈、链表的区别
  18. 关于12球问题的讨论
  19. springboot使用Cassandra组合查询数据
  20. html复选框代码隐藏勾勾,[译] 为什么 HTML 中复选框样式难写 — 本文给你答案

热门文章

  1. opencv 特征提取综述
  2. js判断某个变量是否等于undefined
  3. 中亦科技将二度上会:八成收入来自金融,研发、销售投入有待平衡
  4. 【论文研读】GAN 逆映射 综述 GAN Inversion: A Survey 关键部分翻译 研读思考
  5. python3在线编译器-python3编译器
  6. Gephi简易学习[六]———— 拓展分析红楼梦数据
  7. 如何免费的,在线将PDF转换成其Word?
  8. 263企业邮箱在foxmail上的成功设置(smtpwcom/popwcom.xxoo.com)
  9. java研发面经分享:滴滴、美团、网易、58赶集等
  10. linux centos 查看操作系统版本