技术标签: spring 架构 java javaweb mvc
Mvc概念:M:model(模型),V:view(视图),C:Controller(控制器)
视图层:用于做数据的展示以及与用户进行交互的一个界面
控制层:能够接收客户端的请求,具体的业务功能还是需要模型组件来完成。
模型层:负责处理业务逻辑以及数据库的交互,承载数据。模型分为多种,有简单的pojo/vo(value object),有业务模型组件,以及数据访问层组件。
模型层类别:
1)pojo/vo:值对象:一个fruit类就是值对象,可以获取相应的属性数据。
2)DAO:数据访问对象:连接数据库并操作相应数据库表单的DAO类
3)BO: 业务对象:业务对象调用相应的数据对象进行一系列操作。
区分业务对象以及数据访问对象:
1)DAO中的方法都是单精度方法或细粒度的方法,一个方法只考虑一个操作,比如添加到数据库就是insert,无需考虑其他操作的影响。
2)BO中的方法属于业务方法,实际的业务是比较复杂的,因此业务方法粒度是比较粗的。service层的业务实现,具体要调用已经定义的dao层接口,封装service层业务逻辑有利于通用的业务逻辑的独立性和重复利用性。程序显得非常简洁。
例如账户注册这个功能属于业务功能,因此注册这个方法属于业务方法。
那么这个业务方法就包含了许多DAO方法,也就是说注册这个业务功能需要通过多个DAO方法的组合进行调用,从而完成注册功能的实现。
注册:
1、检查用户名是否被注册-DAO中的select操作
2、向用户表新增一条新用户记录-DAO中的insert操作
3、向用户表新增一条新用户记录-DAO中的insert操作
4、向系统消息表新增一条新用户记录-DAO中的insert操作
5、向系统日志表新增一条新用户记录-DAO中的insert操作
6、。。。
简单的说DAO层是跟数据库打交道的,service层是处理一些业务流程(不仅仅包括DAO调用操作)。
能够将各个层次强制性分开,这样分开之后就会减少层与层之间的依赖,这样就能最大化的重用代码了。例如MVC层的话多个视图就能共享一个模型,控制器也可以连接不同的模型和视图来完成用户的需求,三个部件相互独立这种设计思想能构造好的松耦合构建。
在原来优化后的水果系统中用户发送请求的处理流程如下图所示:
用户中央控制器接收请求后直接向控制层发出命令,由控制层访问model进行一系列的DAO方法调用获取数据,最后view渲染页面。
当日积月累的使用MVC模式开发之后,会逐渐感受到层与层之间的粘连以及模棱两可的地方存在,这就是service层出现的重要原因。业务逻辑粘连了C层以及M层,因此需要将业务逻辑解耦出来,成为独立的Service层。
假设现在你做这个功能会用到user表和权限表,那么你前台的页面访问action,action再去调用用户模块service,用户模块service判断你是操作user表还是权限表,如果你操作的是user表则service的实现类就去调用userDAO。如果是操作的是权限表则调用权限的DAO。也就是说DAO一定是和数据库的每张表一一对应,而service则不是。
没有service层会产生的问题:
只能在控制层直接实现业务逻辑导致多个控制器无法共享通用的业务逻辑,如果业务逻辑需要升级,则需要直接在源代码上修改兼容,会导致控制器代码不断膨胀复杂。
service层的作用:
service是业务层,是使用一个或者多个模型执行操作的方法。
1:封装一些通用的业务逻辑。
2:与数据层交互。
3:其他请求:如获取远程服务数据。
因此需构建一个业务模型来进行模型的调用,这样控制器能够更专注于模型构建的调用以及视图的处理。
package com.ck.fruit.biz.impl;
import com.ck.dao.FruitDAO;
import com.ck.fruit.biz.FruitService;
import com.ck.fruit.pojo.Fruit;
import java.util.List;
public class FruitServiceImpl implements FruitService {
FruitDAO fruitDAO=null;
@Override
public List<Fruit> getFruitList(String keyword, Integer pageNo) {
return fruitDAO.getFruitList(keyword,pageNo);
}
@Override
public void addFruit(Fruit fruit) {
fruitDAO.addFruit(fruit);
}
@Override
public Fruit getFruitById(Integer fid) {
return fruitDAO.getFruitByFid(fid);
}
@Override
public void delFruit(Integer fid) {
fruitDAO.deleteFruit(fid);
}
@Override
public Integer getPageCount(String keyword) {
Integer fruitCount=fruitDAO.countNum(keyword);
Integer pageCount=(fruitCount+5-1)/5;
return pageCount;
}
@Override
public void updateFruit(Fruit fruit) {
fruitDAO.updateFruit(fruit);
}
}
构建上述模型之后在控制器上进行业务调用即可,无需再直接再调用fruitDAO中的方法。
Service层是建立在DAO层之上的,建立了DAO层后才可以建立Service层,而Service层又是在Controller层之下的,因而Service层应该既调用DAO层的接口,又要提供接口给Controller层的类来进行调用,它刚好处于一个中间层的位置。每个模型都有一个Service接口,每个接口分别封装各自的业务处理方法。
采用MVC综合设计模式,MVC本身不属于设计模式的一种,它描述的是一种结构,最终目的达到解耦,解耦说的意思是你更改某一层代码,不会影响我其他层代码,如果你会像spring这样的框架,你会了解面向接口编程,表示层调用控制层,控制层调用业务层,业务层调用数据访问层。初期也许都是new对象去调用下一层,比如你在业务层new一个DAO类的对象,调用DAO类方法访问数据库,这样写是不对的,因为在业务层中是不应该含有具体对象,最多只能有引用,如果有具体对象存在,就耦合了。因此在层与层之间实现解耦很有必要,IOC就能实现此需求。
<bean id="fruit" class="com.ck.fruit.controllers.FruitController">
<property name="fruitService" ref="fruitService"/>
</bean>
这样就可以通过配置中的属性找到类所需要的依赖并进行实例化,这就是注入依赖。
1.在原先的项目中在控制器以及service层中均存在实例化其它层的类再进行调用,这样层与层之间就存在耦合依赖的情况,因此需要对当前结构进行改进。
2.将需要的类先赋值为null
3.建立一个Beanfactory接口并创建其实现类用来构建一个MAP集合存放xml配置文件中存放的类
xml配置文件,各个bean节点对应各个类,bean中的property节点表示该bean代表的类需要依赖的类,用于后续注入依赖使用。
ClassPathXmlApplicationContext类实现beanFactory接口,将xml配置文件中的类全部通过反射映射入相应集合中:
将xml中所有的类注入集合后就要开始组装bean之间的依赖关系,通过获取bean下的property子节点,来从集合中获取相应的类实例,然后通过反射技术将相应的类中的属性赋值,注入依赖。
最终实现水果系统:
文章浏览阅读1.5k次。简介:最新大猿人中控充值系统 免授权破解版 支持公众号H5、分销等功能功能简介:大猿人中控系统目前是市面上用的最多的电话费充值中控系统,支持代理分销、公众号H5、API接口对接等功能,也是目前最完善的一款中控系统,前端全开源,已破解免授权!配置环境:php7.3 + Redis搭建教程:1、首先吧大猿人中控系统压缩包上传到服务器内进行解压,然后吧数据库文件导入数据库内2、修改/application/database.php 文件进行配置链接数据库。_猿人充值系统 3.2 漏洞
文章浏览阅读81次。为什么80%的码农都做不了架构师?>>> ..._gtk3 异形窗口
文章浏览阅读2.6k次。#include <stdio.h>#include <string.h>#include <string.h>int main(void){ int a[5][5] = {17,24,1,8,15, 23,5,7,14,16, 4,6,13,20,22, 10,12,19,21,3, 11,18,25._验证下列矩阵是否为魔方阵。魔方阵是每一行、每一列、主副对角线上的元素之和都是
文章浏览阅读51次。免费领取项目源码,请关注赞收藏并私信博主,谢谢-本课题研究的疫情返乡人员管理系统,主要功能模块包括:防疫须知、疫情用品、返乡报备、用户反馈管理等,主要是主要采取Mysql作为后台数据的主要存储单元,运用软件工程原理和开发方法,采用Python的Django技术构建的,实现了系统的全部功能。本次报告,首先分析了研究的背景、作用、意义,为研究工作的合理性打下了基础。
文章浏览阅读1.1k次。首先我这篇博客的内容是我不知道oracle里的 cache 是什么,结果越查越多。。。“序列的cache通常为 20,但在需要依据序列值判断创建的先后顺序时必须是 NOCACHE”,关于这句话,是公司的数据库规范里提到的一句话,但是我感觉nocache会导致的问题好像还不少,所以我很纠结,但是除了根据序列值判断创建的先后顺序外,还有其他的靠谱的方式来判断先后顺序吗?难道入库时间不可以吗..._数据库中的nocache是什么意思
文章浏览阅读193次。一、字符串多行书写有时为了书写阅读方便,需要将一大串的字符串写成多行举例源码 MyUart_Printf("moduleConfigParams=>\r\n"\ "\tuartBaudrate:%s\r\n"\ "\tuartStopbit:%s\r\n"\ "\tparityType:%s\r\n"\ "\trfC..._c语言编辑多行源代码中的字符串
文章浏览阅读71次。HTTP Archieve有个统计,图片内容已经占到了互联网内容总量的62%,也就是说超过一半的流量和时间都用来下载图片。从性能优化的角度看,图片也绝对是优化的热点和重点之一,Google PageSpeed或者Yahoo的14条性能优化规则无不把图片优化作为重要的优化手段,本文覆盖了Web图片优化的方方面面,从基本的图片格式选择、到尚未被广泛支持的响应式图片均有所提及。Google Web ..._jpegoptim optipng pngquant gifsicle
文章浏览阅读249次,点赞4次,收藏4次。openGauss提供向量化引擎,通常用在OLAP数据仓库类系统。主要是因为分析型系统通常是数据处理密集型,基本上都是采用顺序方式来访问表中大部分的数据,然后再进行计算,最后将计算结果输出给用户。
文章浏览阅读639次。相信很多站长在使用宝塔面板的同时也会安装云锁用于加固服务器安全性,不过有时因为Nginx版本过高等问题导致安装云锁时无法自动安装Web防护模块,所以还需要我们在Linux系统下额外将云锁Web防护模块编译进Nginx才可以。之前也转载过一篇一、上传云锁Web防护模块压缩包并解压Ps:其实宝塔添加模块功能里可以通过配置shell脚本实现这些前置准备,但我还是喜欢用手动的方式上传,这样使步骤看起来更直..._宝塔 云锁自编译 测试
文章浏览阅读8.4k次。原文作者:雪飘碧鸳 在github上导入项目,或其他地方导入Android Studio,出现Error:A problem occurred configuring project ‘:app’.的错误。其实这种错误有很多种原因,需要对每种情况进行不同的处理才行,这里说的一种情况是JNI的情况,即该项目使用到C/C++库,此时需要引入NDK才行,先看下错误提示Gradle ‘trunk’ ..._error:a problem occurred configuring project ':app'.
文章浏览阅读603次。groupby一个索引的比较简单,这里主要讲两个索引的:这里先设dataframe为下图然后根据第0列和第1列来进行分组,再对第二列进行数量统计,这里用了nunique函数来进行数量统计上图中最上面的2表示是根据原表的第3列即序号2的那一列使用的agg函数得到的结果。unstack是把一维表转换成二维表,即把(0,1)这对分组条件分别写成表的行列索引,一一对应agg函数得到的结果,如下图:stack是把二维表转换成一维表,类似花括号形式(就像是思维导图一层一层括出去),第一列写上原本的行索引_group by unstack
文章浏览阅读2.2k次。宝塔新建网站:假设文件夹根目录为/home/nextcloud创建FTP,数据集。并且选择php版本。删除文件夹根目录/home/nextcloud下的两个html文件。下载nextcloud文件:官网链接可以使用wget:wget https://download.nextcloud.com/server/releases/nextcloud-20.0.0.zip,或者本地端下载后拖过去。多线程下载:sudo apt install axel axel -n 20 ht.._宝塔做nas