Java三层框架的解析

devtools/2024/9/20 7:16:22/ 标签: java, 三层框架, spring boot

引言:欢迎各位点击收看本篇博客,在历经很多的艰辛,我也是成功由小白浅浅进入了入门行列,也是收货到很多的知识,每次看黑马的JavaWeb课程视频,才使一个小菜鸡见识到了Java前后端是如何进行交互访问的,话不多说,进入正题。


目录

一.三层框架

二.前后端交互过程:

 三.如何进行接口测试:

 四.三层架构的设计模式:

五.正式入门三层框架

1.首先要写controller层:

2.service层的写法:

3.dao层的写法:


 

一.三层框架

我们在进行程序开发时,应该遵守单一职责原则,意思就是尽可能让每个接口、类、方法的职责更单一,如果我们将整个后端代码放在一个包一个类中,不仅仅是代码的可阅读性差,而且代码冗杂,耦合度很高。

1. controller:控制层,负责接受前端发送来的请求,对请求进行处理,并相应数据。

2. service:业务逻辑层,处理具体实现的业务逻辑。

3. dao:数据访问层(持久层),负责数据访问操作,包括数据的增删改查。

二.前后端交互过程:

首先通过浏览器发起请求,经过DispatcherServlet(称为核心控制器或者前端控制器)将请求信息封装到HttpServletRequest这个对象内,然后再将这个请求转给后面的每个Controller程序,由Controller程序对其进行处理(Controller程序通过调用Service程序,然后再Service程序中调用Mapper程序,最后Mapper程序处理完返回给Service然后再返回给Controller),随后Controller程序将处理完的响应信息返回给DispatcherServlet的HttpServletResponse对象中,然后DispatcherServlet再给浏览器响应数据。这也就是BS架构,浏览器/服务器架构模式。

 三.如何进行接口测试:

我们在写完后端程序肯定需要进行测试来判断代码的准确性,但是如果我们没有前端页面进行测试,我们如何进行接口测试呢?这个时候就需要使用Postman或者Apifox来进行接口测试。

 四.三层架构的设计模式:

根据第一与第二点,我们初步理解了三层框架的进行顺序,那么三层框架该是什么样的创建形式呢?

根据上图,我们可以看到这个是基于Springboot来开发的,在java.com.itheima包下创建了四个包以及运行类,而这四个包分别装有其分别对应的类与接口。 

我们都知道接口是Java程序对类定义其规则,所以一般我们在开发的时候会现在接口内写入想要实现的方法名,然后再实现类中写出实现方法。 

五.正式入门三层框架

在学习三层框架,我们都知道三层框架controller,service,dao三层,所以咱们在写接口的过程要按照其实现顺序依次写入。

我们先在pom.xml导入依赖以及在application.properties中写入MySQL的驱动以及配置文件的相关信息,,然后在tlias数据库下创建一个Dept部门类和一个Emp员工类。

pom.xml文件导入依赖:1.Springboot 2.MySQL 3.Lombok 4.pagehelper(分页插件)

application.properties配置文件写法:

java">spring.application.name=tliasspring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/tliasspring.datasource.username=rootspring.datasource.password=lxs15241690479mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImplmybatis.configuration.map-underscore-to-camel-case=true

1.首先要写controller层:

我们在写controller层之前要知道SpringBoot对注解的使用:

1. @ResponseBody:放在开头代表每个方法的返回值都会作为响应数据,如果是对象或者集合会先转为json格式然后再来响应。

2. @Controller:控制器组件

3. @RestController:主要由ResponseBody+Controller两个注解组成,也就会有这两个注解的作用。

4. @RequestMapping("url"):一个用来处理请求地址映射的注解,可用于映射一个请求或一个方法,可以用在类或方法上。

5. @***Mapping:这***是代表其有很多的样式,也就是要填入请求方式,如:Get,Post,Delete等。跟@RequestMapping差不多,但是使用这个注解就要跟随该注解前的请求方式才能够请求。

6. @RequestParam:

 用于将指定的请求参数赋值给方法中的形参。

有三个属性:
(1)value:请求参数名(必须配置)

(2)required:是否必需,默认为 true,即 请求中必须包含该参数,如果没有包含,将会抛出异常(可选配置)

(3)defaultValue:设置默认值,如果设置了该值,required 将自动设为 false,无论你是否配置了required,配置了什么值,都是 false(可选配置)

7.@PathVariable:

    @PathVariable是Rest风格衍生出的占位符,只支持一个属性value,类型是为String,代表绑定的属性名称。默认不传递时,绑定为同名的形参。 用来便捷地提取URL中的动态参数。应用时,在@RequestMapping请求路径中,将需要传递的参数用花括号{}括起来,然后,通过@PathVariable("参数名称")获取URL中对应的参数值。如果@PathVariable标明参数名称,则参数名称必须和URL中参数名称一致。

8. @Autowired:自动注入,上一篇Mybatis讲过,这里不细说。有需要了解请跳转:

Mybatis不明白?就这一篇带你轻松入门_mapper 新建一张表在哪里配置-CSDN博客

下面将@RequestBody放在前面的目的是为了简化写法,因为下面的@***Mapping()内都需要加上某url所以我们可以将/depts提前来简化写法,所以下面那个@GetMapping后面不是没有接口地址而是因为简化写法省略。

java">@Slf4j
@RequestMapping("/depts")
@RestController
public class DeptController {@Autowiredprivate DeptService deptService;@GetMappingpublic Result list(){log.info("查询全部部门数据");List<Dept> deptList = deptService.list();return Result.success(deptList);}@DeleteMapping("/{id}")  //动态接收数据public Result delete(@PathVariable Integer id){log.info("根据id删除部门:{}" + id);deptService.delete(id);return Result.success();}@PostMappingpublic Result add(@RequestBody Dept dept){//json格式使用实体类接受log.info("新增部门:{}" , dept);deptService.add(dept);return Result.success();}}

有时我们为了接受大量的数据也会定义一个实体类然后使用@RequestBody注解进行接收。

然后我们在这些Controller程序的方法看见其内部紧跟随调用其对应的Service方法来操作所接收的数据,随后return返回一个Result类success方法。下面的是Result类->

java">@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {private Integer code;//响应码,1 代表成功; 0 代表失败private String msg;  //响应信息 描述字符串private Object data; //返回的数据//增删改 成功响应public static Result success(){return new Result(1,"success",null);}//查询 成功响应public static Result success(Object data){return new Result(1,"success",data);}//失败响应public static Result error(String msg){return new Result(0,msg,null);}
}

上面的三个注解不懂的可以看我上篇文章,里面详细写出了Mybatis的相关内容。

 既然我们会调用service进行操作,所以接下来我们就进行service的操作。

2.service层的写法:

@Service:Spring Framework 中的一种注解,它标识了这个类是一个业务逻辑层的服务 Bean。这意味着当 Spring 应用启动时,该 Bean 会被自动创建并加入到 Spring 应用上下文中。简而言之,@Service 注解是一种用于标记服务层 Bean 的注解,是在 Spring Boot 应用中实现业务逻辑复用的重要方法之一。

业务逻辑层,处理具体实现的业务逻辑(处理数据),我们需要再其内部加上很多的操作方法所以先写接口后写类。

接口内写入规则:

java">public interface DeptService {List<Dept> list();void delete(Integer id);void add(Dept dept);
}

然后创建其实体类:

java">@Service
public class DeptServiceImpl implements DeptService {@Autowiredprivate DeptMapper deptMapper;@Overridepublic List<Dept> list() {return deptMapper.list();}@Overridepublic void delete(Integer id) {deptMapper.deleteById(id);}@Overridepublic void add(Dept dept) {dept.setCreateTime(LocalDateTime.now());dept.setUpdateTime(LocalDateTime.now());deptMapper.insert(dept);}
}

我们发现这层的方法体内代码非常的少,是不是可以直接与Mapper合并一层?

nonono,绝对不行的,这样会破坏原本三层架构的完整与独立性,而且三层架构低耦合,并且其注解的独立使用也无法让你变成两层架构,其实这个只是当前的代码不用写很多代码,如果咱们以后写大程序就可以看出service层的重要,每一层都是不可缺少的。

3.dao层的写法:

对于dao层,主要通过注解或者xml来操作数据,这里需要用到Mybatis的基础,详情请看下面链接,有我码一万四千多字的博客:Mybatis不明白?就这一篇带你轻松入门_mapper 新建一张表在哪里配置-CSDN博客

java">@Mapper
public interface DeptMapper {@Select("select * from dept")List<Dept> list();@Delete("delete from dept where id = #{id}")void deleteById(Integer id);@Insert("insert into dept(name, create_time, update_time) value (#{name} , #{createTime} , #{updateTime})")void insert(Dept dept);
}

随后我们点击执行类运行程序,然后使用Postman或者Apifox进行测试接口,同时也要注意请求方式的使用以及路径的正确书写,我们一般写成localhost:8080/depts/......,剩下的就由你来完成了。


最后,我们可以看出三层框架很简单,但是内部用到了很多知识点,这就需要咱们多学多练多观察,别忘了点个关注,多多支持,记得三连哈,有问题欢迎在评论区里留言。


http://www.ppmy.cn/devtools/55619.html

相关文章

突发!OpenAI停止不支持国家API,7月9日开始执行

6月25日凌晨&#xff0c;有部分开发者收到了OpenAI的信&#xff0c;“根据数据显示&#xff0c;你的组织有来自OpenAl目前不支持的地区的API流量。从7月9日起&#xff0c;将采取额外措施&#xff0c;停止来自不在OpenAI支持的国家、地区名单上的API使用。” 但这位网友表示&am…

C#面: 能够将非静态的方法覆写成静态方法吗?

在C#中&#xff0c;不能将非静态方法覆写成静态方法。这是因为静态方法是属于类的&#xff0c;而非静态方法是属于类的实例的。覆写&#xff08;重写&#xff09;是指在派生类中重新实现基类中的虚方法或抽象方法&#xff0c;以改变其行为。而静态方法是无法被派生类所继承的&a…

【前端面试】理解 JavaScript 中的 Set 和 Map 对象

目录 一、Set 对象1. 基本操作2. 遍历操作3. Set 的特性4. 与数组的互操作 二、Map 对象1. 基本操作2. 遍历操作3. Map 的特性4. 与对象的比较 三、算法题及题解题目&#xff1a;找出数组中的重复元素题目&#xff1a;数组去重题目&#xff1a;统计字符串中每个字符出现的次数题…

“鱼与熊掌兼得专业与学校的权衡” 或 “高考后专业与学校的选择之道”。这两个标题都符合内容,且简洁明了。

引言&#xff1a; 24年的高考帷幕落下&#xff0c;对于每一位考生来说&#xff0c;选择学校和专业无疑是一场重大的决策。分数受限的条件下&#xff0c;“鱼与熊掌不可兼得”&#xff0c;是选择一个心仪的专业还是知名度更高的学校&#xff0c;这是一个困扰了众多考生和家长的长…

upload-labs第14关

upload-labs第14关 第十四关一、源代码分析代码审计 二、绕过分析a. 制作图片码首先需要一个照片&#xff0c;然后其次需要一个eval.php。 b.上传图片码上传成功 c.结合文件包含漏洞进行访问访问&#xff1a;http://192.168.1.110/upload-labs-master/include.php?filehttp://…

python写excel

确保已安装 xlsxwriter&#xff1a; pip install xlsxwriter使用 xlsxwriter 设置特定单元格的背景色&#xff1a; import pandas as pd创建示例 DataFrame df1 pd.DataFrame({A: [1, 2, 3],B: [4, 5, 6] })将 DataFrame 导出到 Excel 使用 xlsxwriter file_path output_…

MongoDB 索引

MongoDB中的索引类型主要包括以下几种&#xff1a; 单字段索引&#xff08;Single Field Indexes&#xff09;&#xff1a;这是最基本的索引类型&#xff0c;它可以基于集合中的单个字段创建。复合索引&#xff08;Compound Indexes&#xff09;&#xff1a;复合索引是单字段索…

如何隐藏真实的MAC地址和IP地址,保证多账户的安全?

在计算机网络中&#xff0c;MAC地址&#xff08;Media Access Control Address&#xff09;和IP地址&#xff08;Internet Protocol Address&#xff09;是两个重要的概念&#xff0c;用于网络设备之间的通信。虽然它们都用于标识设备&#xff0c;但在运作原理和作用上有着明显…

【机器学习】——【线性回归模型】——详细【学习路线】

目录 1. 引言 2. 线性回归理论基础 2.1 线性模型概述 2.2 最小二乘法 3. 数学基础 3.1 矩阵运算 3.2 微积分 3.3 统计学 4. 实现与应用 4.1 使用Scikit-learn实现线性回归 4.2 模型评估 5. 深入理解 5.1 多元线性回归 5.2 特征选择 5.3 理解模型内部 6. 实战与项…

用python工具实现自动检测报表缺失哪些天日期的数据(亲测可用)

目录 代码思路如下: 1、看某张表的所有有数据的日期 2、计算缺失的日期 遇到难点: 1、清空mysql的表 2、报表日期的字段格式五花八门,需要进行统一格式化 完整可用代码如下: 1、表结构 2、python代码 在前面的文章,详细介绍了如果监测mysql或hive当天或当月的表…

微信小程序使用ThreeX开发3d

注意&#xff1a;本代码是用uniapp开发微信小程序&#xff0c;模型使用.glb格式&#xff0c;以下出现&#xff08;glb模型压缩&#xff09;代表改代码是使用压缩时需要使用的&#xff0c;不压缩可以不写 Demo:gitee地址 焦明玉/vue2_threex_demo 1.微信小程序后台添加Threex…

深度学习入门2—— 神经网络的组成和3层神经网络的实现

由上一章结尾&#xff0c;我们知道神经网络的一个重要性质是它可以自动地从数据中学习到合适的权重参数。接下来会介绍神经网络的概要&#xff0c;然后再结合手写数字识别案例进行介绍。 1.神经网络概要 1.1从感知机到神经网 我们可以用图来表示神经网络&#xff0c;我们把最…

[C#] opencvsharp对Mat数据进行序列化或者反序列化以及格式化输出

【简要介绍】 在OpenCVSharp中&#xff0c;FileStorage类用于将数据&#xff08;包括OpenCV的Mat类型数据&#xff09;序列化为XML或YAML格式的文件&#xff0c;以及从这些文件中反序列化数据。以下是关于FileStorage类用法的详细说明&#xff1a; 写入数据&#xff08;序列化…

【Docker】容器

目录 1. 容器启动 2. 容器启动/重启/停止 3. 进入容器 4. 容器查询 5. docker 镜像的构建 方式一&#xff1a;docker 容器 commit 方式二&#xff1a;Dockerfile 定制镜像 1. 容器启动 docker run –it/-d –p/P –name imageID/name 2. 容器启动/重启/停止 docker sta…

fc-list命令使用指南

fc-list命令使用指南 一、什么是fc-list? fc-list是FontConfig库的一部分&#xff0c;最初为Linux和其他Unix-like系统开发。我们可以用这个命令行快速查询和列出系统中安装的字体。 现在&#xff0c;Windows用户也集成了这个工具&#xff0c;所以我们来讲解一下用法。 二、…

算力服务先锋!和鲸科技入选《2024中国智算产业生态图谱》

2024 年 6 月 18 日&#xff0c;由科智咨询发起的《2024中国智算产业生态图谱》正式发布&#xff0c;依托 ModelWhale 构建的智算算力资源服务&#xff0c;以及深耕多年的 ModelWhale 数据科学协同平台优势&#xff0c;和鲸科技成功入选。 “智算时代”技术不断进步&#xff0c…

SpringCloudAlibaba组件之间的版本兼容问题

我之前的SpringCloud项目以及使用的组件的版本是这些 但是我不知道具体的版本兼容问题&#xff0c;以及各种组件之间对应的版本 想要使用我们的springcloud和springcloudAlibaba组件&#xff0c;我们就要版本对应&#xff0c;不然就是一堆依赖报错&#xff0c;要不就是缺了这个…

UE5近战对抗系统Tutorial

文章目录 BP_Character 组合攻击Notify State 检测攻击BP_Character 攻击反馈BP_Character 生命系统BP_Character 死亡效果BP_Character 武器系统BP_Enemy 初始化和行为树 BP_Character 组合攻击 首先我们获取攻击动画&#xff0c;在这里使用的是 Easy Combo Buffering 的攻击…

leetcode34:在排序数组中查找元素的第一个和最后一个位置

题目链接&#xff1a;34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:vector<int> searchRange(vector<int>& nums, int target) {if(nums.empty()) {return {-1, -1};}vector<int> R…

哈夫曼编码

一.哈夫曼树 哈夫曼树&#xff08;Huffman Tree&#xff09;是一种用于数据压缩的二叉树。它基于字符出现的频率构建&#xff0c;使得高频字符使用较短的编码&#xff0c;低频字符使用较长的编码&#xff0c;从而实现数据压缩。哈夫曼树也被称为最优二叉树或哈夫曼编码树。 哈夫…