Java从入门到工作3 - 框架/工具

 3.1、SpringBoot框架结构

在 Spring Boot 或微服务架构中,每个服务的文件目录结构通常遵循一定的约定。以下是一个常见的 Spring Boot 服务目录结构示例,以及各个文件和目录的简要说明:

my-service
│
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── example
│   │   │           └── myservice
│   │   │               ├── MyServiceApplication.java  # 启动类
│   │   │               ├── controller                 # 控制器包
│   │   │               │   └── MyController.java      # 处理请求的控制器
│   │   │               ├── service                    # 服务包
│   │   │               │   └── MyService.java         # 业务逻辑
│   │   │               ├── repository                 # 数据访问包
│   │   │               │   └── MyRepository.java      # 数据访问层
│   │   │               └── model                      # 模型包
│   │   │                   └── MyModel.java           # 实体类
│   │   └── resources
│   │       ├── application.properties                 # 配置文件
│   │       └── static                                 # 静态资源(如 HTML, CSS, JS)
│   │           └── index.html                         # 主页
│   └── test
│       └── java
│           └── com
│               └── example
│                   └── myservice
│                       └── MyServiceApplicationTests.java  # 测试类
│
├── pom.xml                # Maven 项目管理文件
|---target                 marven 生成的文件
└── README.md              # 项目说明文件

主要目录和文件说明:

  • src/main/java: 存放 Java 代码的主目录。

    • MyServiceApplication.java: Spring Boot 启动类,包含 main 方法。
    • controller: 处理 HTTP 请求的控制器类。
    • service: 包含业务逻辑的服务类。
    • repository: 数据访问层,通常接口定义,与数据库交互。
    • model: 存放实体类,定义核心数据模型。
  • src/main/resources: 存放资源文件的目录。

    • application.properties: 应用配置文件,定义数据库连接、端口等配置。
    • static: 静态资源目录,存放前端资源。
  • src/test/java: 存放测试代码的目录。

    • MyServiceApplicationTests.java: 单元测试类,用于测试应用功能。
  • pom.xml: Maven 项目的配置和依赖管理文件。

  • README.md: 项目的说明文档。

  • target:项目构建的输出结果存放位置,构建、测试和其他过程产生的文件都集中在这里。每次执行 Maven 构建命令(如 mvn clean 或 mvn package)时,target 目录会被重新生成。

这个结构可以根据项目的具体需求做相应调整,但以上是一个基本的布局示例。

3.2、External Libraries

java中external libraries跟前端项目中 node_modules作用与概念一致,都是依赖包或者说外部库

具体使用上有区别,如下

  • Java项目:外部库由构建工具Maven等管理,不直接放在项目根目录中;依赖关系通过pom.xmlbuild.gradle文件定义。
  • 前端项目:依赖库直接下载到项目根目录中的node_modules文件夹中;依赖关系通过webpack等工具,package.json文件定义。

3.3、Maven

Java开发中的Maven就类似前端开发中的webpack

Apache Maven 是一个项目管理和构建工具,它基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建、报告和文档。官网 :http://maven.apache.org

3.4、MyBatis

3.4.1、什么是MyBatis?

mybatis是一个优秀的基于java的持久层框架,它内部封装了 jdbc,使开发者只需要关注sql语句本身,而不需要花费精力 去处理加载驱动、创建连接、创建statement等繁杂的过程。

它支持定制化 SQL、存储过程以及高级映射。MyBatis 可以简化数据库访问操作,提供了以下主要功能:

  1. SQL 映射:用户可以直接在 XML 文件或注解中定义 SQL 语句,从而控制 SQL 的执行。同时,MyBatis 还支持动态 SQL 功能。

  2. 对象关系映射:MyBatis 能够将数据库结果集自动映射到 Java 对象,支持复杂数据类型的映射。

  3. 灵活性:MyBatis 则没有强制要求使用特定的编程模型,开发者可以自由选择 SQL 语句的编写方式,更符合项目需求。

  4. 支持多种数据库:MyBatis 可以与多种关系型数据库搭配使用,适应性强。

  5. 缓存机制:MyBatis 提供了一级缓存和二级缓存,旨在提高数据访问性能。

MyBatis 适合于需要复杂 SQL 操作的项目,开发者可以对 SQL 语句进行精细控制。与其他 ORM 框架相比,MyBatis 更加轻量级和灵活,但需要开发者自己管理 SQL 逻辑。

3.4.1、如何使用?

3.4.1.1、实体类

 在项目下创建一个User.java的实体。

public class User {private int id;public int getId() {return id;}public void setId(int id) {this.id = id;}
}
3.4.1.2、实体类映射文件
<mapper namespace="userMapper"><select id="findAll" resultType="路径/User">select * from db1.user</select>
</mapper>

namespace:命名空间。起名可以随意。例如使用时我们可以用userMapper.findAll来使用对应的select语句。

resultType:结果类型。从数据库查询到的数据封装到哪个位置。例如我们这里的select子句查询到的结果要封装到User实体集中,但是这里用user而不适用domain.User是因为在接下来的核心配置文件SqlMapConfig.xml中我们通过typeAliases标签将domain.User更名为user。

3.5、框架专有名词

SpringBoot代码结构中启动类controller控制器、service服务、repository数据访问、model模型,这些专有名称怎么理解?前端有没有类似的概念可以类比着理解?

以下是每个部分的简要说明,以及与前端的类比:

控制器 (controller)

  • 作用:控制器负责前端HTTP请求处理和路由,并调用相应的服务。
  • 类比:可以类比于前端的路由组件(如 React Router 中的路由),负责处理用户的请求和展示对应的视图。

服务 (service)

  • 作用:包含业务逻辑,处理来自控制器的请求,进行数据处理,然后调用数据访问层(Repository)。
  • 类比:类似于前端的服务模块(如 API 调用逻辑),负责处理请求的具体实现,比如数据获取和处理。

数据访问 (repository)

  • 作用:与数据库交互,负责执行 CRUD(创建、读取、更新、删除)操作。
  • 类比:可以与前端的 API 请求管理工具(如 Axios 或 Fetch API)相对应,这些工具用于与后端接口交互并获取数据。

模型 (model)

  • 作用:定义数据模型,通常对应数据库表的结构,包含数据的属性和验证规则,包装数据的对象。
  • 类比:类似于前端的状态管理(如 Redux 的 store),用来定义和管理应用的数据结构。

启动类 (MyServiceApplication.java)

  • 作用:这是应用的入口,包含 main 方法,负责启动 Spring Boot 应用。
  • 类比:类似于前端应用的入口文件(如 index.js 或 main.js),是应用加载的起点。

假设你有一个获取用户信息的请求:

  1. 前端向 /users/{id} 发送 GET 请求。
  2. 控制器的 getUserById 方法被调用。
  3. 控制器调用服务的 findById 方法,传入用户 ID。
  4. 服务通过调用仓储(Repository的 findById 方法查询数据库。
  5. 仓储(Repository返回用户信息给服务,服务处理后返回给控制器
  6. 控制器将用户信息返回给前端。

这种设计遵循了分层架构的原则,各层关注不同的职责,使代码更加模块化和易于维护。

3.6、微服务 

微服务相关知识有优秀系列博文分享给大家,我也看的这些:地址

3.7、Eureka

负责服务的注册与发现,使得服务能够找到彼此。

Eureka一般跟springBoot、springClud配合使用,一般需要起多个服务。有时springboot报某个服务未启动

Load balancer does not have available server for client: serviceA

 但IDEA可能也显示这个服务是启动状态,这时就要去看Eureka的页面了,以Eureka为准。因为该端口可能被占用了

3.8、Fegin

Fegin提供了一种声明式的 HTTP 客户端调用方式,简化了 RESTful 服务的调用。使用 Feign 可以让你的代码更加简洁易读,并自动处理负载均衡和服务调用的细节。

3.8.1、有Eureka还需Fegin吗?

在 Spring Boot 中使用 Eureka 进行服务注册和发现,再使用 RestTemplate 或其他手动的 HTTP 客户端进行服务调用,可以解决服务启动和互相调用的问题。但 Feign 代替手动,实现服务的自动调用。

3.8.1.1、实例Demo

实例地址:微服务组件之OpenFeign服务调用组件的介绍及其使用方法

如上示例虽然写的很清楚,但是我对了七八遍还是没看懂。如下为AI帮我梳理的注解

当你通过浏览器或工具请求 http://localhost:7070/api/service/consumer/getUserInfo?username=root 时,执行过程如下:

3.8.2.1. 接收请求

  • 请求首先被发送到 service-consumer 微服务。
  • 因为请求的 URL 匹配到 DemoController 的 @GetMapping 注解,Spring 会调用 getUserInfo 方法。

3.8.2.2. 调用 Feign 客户端

  • 在 DemoController 的 getUserInfo 方法中,使用 apiProviderFeign.getUserInfo(username) 调用 Feign 客户端。
  • username 被传递为 root

3.8.2.3. 发送 Feign 请求

  • Feign 客户端 ApiProviderFeign 收到请求,并将其转换为对 service-provider 微服务的 HTTP POST 请求。
  • 请求的 URL 为 http://localhost:8081/api/service/provider/getUserInfo(假设 service-provider 在 8081 端口)。
  • 请求 Body 中包含参数 username=root

3.8.2.4. 处理服务提供者请求

  • service-provider 微服务接收到请求并匹配到 ApiController 的 getUserInfo 方法。
  • 方法内部创建一个 Map,并将 username 和一些静态值放入其中。

3.8.2.5. 返回结果

  • getUserInfo 方法返回一个包含用户信息的 Map(例如:{"id": "1001", "username": "root", "pass": "123456"})。
  • Feign 客户端将接收到的结果转换为一个 Map<String, String> 对象,并返回给 DemoController

3.8.2.6. 返回响应给客户端

  • DemoController 中的 getUserInfo 方法将结果返回给最初发起请求的客户端(浏览器或 HTTP 客户端)。
3.8.1.2、Demo的接口

理解 ApiProviderFeign 需要明确几个概念:

3.8.3.1. 接口的作用

ApiProviderFeign 是一个声明式的 Feign 客户端接口,主要用于定义如何调用外部服务(即 service-provider)。它并不需要实现具体的方法,因为 Feign 会在运行时为这个接口创建代理对象。

3.8.3.2. 实现和动态代理

尽管 ApiProviderFeign 是一个接口,但在 Spring Cloud 的上下文中,Feign 会根据这个接口自动生成一个实现类。所以,你不需要手动实现 ApiProviderFeign,也不需要看到其实现代码。

  • 当你在代码中使用 @FeignClient 注解时,Feign 会扫描并创建一个实现了 ApiProviderFeign 接口的动态代理对象。

3.8.3.3. 如何调用接口

  • 在 DemoController 中,apiProviderFeign 是通过 Spring 的依赖注入 (@Autowired) 获取到的。其实是获取到了 Feign 代理对象,它实现了 ApiProviderFeign 接口。
  • 调用 apiProviderFeign.getUserInfo(username) 实际上是调用这个动态代理对象的方法,而这个方法的逻辑是内部通过 HTTP 调用 service-provider 的相应接口。

3.8.3.4. 调用方式

接口本身并不能被调用,必须通过实现它的类或代理对象来进行调用。在这段代码中,Feign 创建的代理对象实现了 ApiProviderFeign,使得调用 apiProviderFeign.getUserInfo(username) 成为可能。

总结

  • ApiProviderFeign 作为 Feign 客户端接口定义了如何与 service-provider 对接。
  • Spring Cloud Feign 会在应用启动时为这个接口生成实现,并注入到使用它的类中。
  • apiProviderFeign 是通过依赖注入获得的代理对象,可以直接调用接口定义的方法。
3.8.1.3、接口注解理解?

在 service-consumer 子工程中,@PostMapping("/api/service/provider/getUserInfo") 注解的理解如下:

1. 请求类型

@PostMapping 是一个组合注解,用于处理 HTTP POST 请求。它指示该方法会处理发往指定 URL 的 POST 请求。

2. 路径定义

"/api/service/provider/getUserInfo" 是该方法处理请求的具体路径。这意味着当调用 ApiProviderFeign.getUserInfo 方法时,将发起一个 POST 请求,路径为 /api/service/provider/getUserInfo

3. Feign 执行

当你在 DemoController 中通过 apiProviderFeign.getUserInfo(username) 调用时,Feign 会:

  • 生成一个对应的 HTTP POST 请求。
  • 将请求的 URL 设置为 "/api/service/provider/getUserInfo"
  • 传递必要的参数(在这个例子中是 username)。

4. 服务交互

该注解确保了 service-consumer 能够正确地调用 service-provider 提供的 GET 用户信息的功能。这个路径与 service-provider 中 ApiController 的处理路径相对应。

总结

  • @PostMapping 注解表明这个方法处理 POST 请求。
  • 路径指定了请求的目标。
  • 此注解与 Feign 客户端配合使用,使得 service-consumer 可以正确地发起请求并与 service-provider 进行交互。

这里接口的@PostMapping注解指示服务提供者具体地址。

因此Demo中service-provider工程并未直接实现service-consumer工程的interface,所以需要service-provider和interface都需要明确写明@PostMapping路径。

但如果service-provider直接实现该interface,则service-provider无需再写@PostMapping,spiringboot可直接找到。此种情况下,service-consumer中@PostMapping中地址无实际意义可以随意填写(不能包含数字),只要不重复即可,但不写不行。

3.8.2、哪些调用需要Fegin?

包含启动类的文件夹可以视为独立服务,服务之间的调用需要通过 Feign 来实现。

没有启动类的文件夹仅用于存放文件,不需要通过 Feign 进行调用,其他服务可以直接访问这些文件。

3.9、实体类

实体类(entity)通常是用来表示数据库表对应的对象。

它们通常包含与数据库字段相对应的属性,并提供相应的 getter 和 setter 方法。实体类的主要目的是用于存储和传递数据。

3.10、Mapper

Mapper是数据访问层(DAO层)的一种表现形式。

Mapper层通常用于定义与数据库交互的接口,这些接口中的方法对应着数据库中的CRUD(创建、读取、更新、删除)操作。在MyBatis等ORM框架中,Mapper接口并没有直接的实现类,取而代之的是一个XML文件,该文件中定义了SQL语句和Java接口的绑定关系。当调用Mapper接口的方法时,实际上是通过动态代理机制,根据接口方法与XML文件中的SQL语句进行匹配,从而执行相应的数据库操作。

Mapper和实体类在Java应用程序中扮演着不同的角色,Mapper负责数据访问和操作,而实体类则负责数据的表示和封装。

3.10.1、因mapper,不需要实体类了?

不完全正确。尽管 MyBatis 和 Mapper 提供了便捷的数据访问能力,但实体类仍然是必要的。原因如下:

  1. 对象映射:实体类用来表示数据库表的结构,每个实体类的属性对应数据库表中的字段。MyBatis 通过这些实体类将数据库记录映射为 Java 对象。

  2. 代码清晰性:实体类增进了代码的可读性和维护性,使得数据结构更清晰。

  3. 业务逻辑:在某些情况下,实体类不仅仅用于数据映射,它们可能还包含与业务相关的方法和逻辑,这样可以更好地组织代码。

因此,虽然 MyBatis 和 Mapper 简化了数据库操作,但实体类仍然是不可或缺的部分。在使用 MyBatis 时,你仍然需要定义实体类以便进行数据映射和操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/488970.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot的青少年心理健康教育网站

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

基于事件驱动的websocket简单实现

websocket的实现 什么是websocket&#xff1f; WebSocket 是一种网络通信协议&#xff0c;旨在为客户端和服务器之间提供全双工、实时的通信通道。它是在 HTML5 规范中引入的&#xff0c;可以让浏览器与服务器进行持久化连接&#xff0c;以便实现低延迟的数据交换。 WebSock…

JavaEE 【知识改变命运】04 多线程(3)

文章目录 多线程带来的风险-线程安全线程不安全的举例分析产出线程安全的原因&#xff1a;1.线程是抢占式的2. 多线程修改同一个变量&#xff08;程序的要求&#xff09;3. 原子性4. 内存可见性5. 指令重排序 总结线程安全问题产生的原因解决线程安全问题1. synchronized关键字…

ElasticSearch如何做性能优化?

大家好&#xff0c;我是锋哥。今天分享关于【ElasticSearch如何做性能优化&#xff1f;】面试题。希望对大家有帮助&#xff1b; ElasticSearch如何做性能优化&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Elasticsearch 中&#xff0c;性能优化是…

Chrome浏览器调用ActiveX控件--allWebOffice控件

背景 allWebOffice控件能够实现在浏览器窗口中在线操作文档的应用&#xff08;阅读、编辑、保存等&#xff09;&#xff0c;支持编辑文档时保留修改痕迹&#xff0c;支持书签位置内容动态填充&#xff0c;支持公文套红&#xff0c;支持文档保护控制等诸多办公功能&#xff0c;…

贪心算法(一)

目录 一、贪心算法 二、柠檬水找零 三、将数组和减半的最少操作次数 四、最大数 五、摆动序列 一、贪心算法 贪心算法的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 贪心策略&#xff1a;1、把解决问题的过程分为若干步。2、解决每一步的时候&#xff…

Scratch节日作品 | 圣诞节礼物——体验节日的温馨与编程的乐趣! ❄️

今天为大家推荐一款充满节日氛围的Scratch作品——《圣诞礼物》&#xff01;这款程序不仅带来了雪花飘落、圣诞老人和麋鹿的经典场景&#xff0c;还通过编程的形式让小朋友们体验到收到礼物的喜悦。通过这款游戏&#xff0c;小朋友们能学习编程知识、了解圣诞文化&#xff0c;同…

基于Qwen2-VL模型针对 ImageToText 任务进行微调训练 - 数据处理

基于Qwen2-VL模型针对 ImageToText 任务进行微调训练 - 数据处理 flyfish 给定的图像生成一段自然语言描述。它的目标是生成一个或多个句子&#xff0c;能够准确地描述图像中的主要内容、物体、动作、场景等信息。例如&#xff0c;对于一张包含一只狗在草地上奔跑的图像&…

Spring Boot整合 RabbitMQ

文章目录 一. 引入依赖二. 添加配置三. Work Queue(工作队列模式)声明队列生产者消费者 四. Publish/Subscribe(发布订阅模式)声明队列和交换机生产者消费者 五. Routing(路由模式)声明队列和交换机生产者消费者 六. Topics(通配符模式)声明队列和交换机生产者消费者 一. 引入依…

谷粒商城—分布式基础

1. 整体介绍 1)安装vagrant 2)安装Centos7 $ vagrant init centos/7 A `Vagrantfile` has been placed in this directory. You are now ready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on…

【考前预习】1.计算机网络概述

往期推荐 子网掩码、网络地址、广播地址、子网划分及计算-CSDN博客 一文搞懂大数据流式计算引擎Flink【万字详解&#xff0c;史上最全】-CSDN博客 浅学React和JSX-CSDN博客 浅谈云原生--微服务、CICD、Serverless、服务网格_云原生 serverless-CSDN博客 浅谈维度建模、数据分析…

计算机视觉与医学的结合:推动医学领域研究的新机遇

目录 引言医学领域面临的发文难题计算机视觉与医学的结合&#xff1a;发展趋势计算机视觉结合医学的研究方向高区位参考文章结语 引言 计算机视觉&#xff08;Computer Vision, CV&#xff09;技术作为人工智能的重要分支&#xff0c;已经在多个领域取得了显著的应用成果&…

AI智算-k8s部署大语言模型管理工具Ollama

文章目录 简介k8s部署OllamaOpen WebUI访问Open-WebUI 简介 Github&#xff1a;https://github.com/ollama/ollama 官网&#xff1a;https://ollama.com/ API&#xff1a;https://github.com/ollama/ollama/blob/main/docs/api.md Ollama 是一个基于 Go 语言开发的可以本地运…

PyQt事件机制练习

一、思维导图 二、代码 import sysfrom PyQt6.QtTextToSpeech import QTextToSpeech from PyQt6.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QLineEdit from PyQt6 import uic from PyQt6.QtCore import Qt, QTimerEvent, QTimeclass MyWidget(QWidget):d…

硬件设计 | Altium Designer软件PCB规则设置

基于Altium Designer&#xff08;24.9.1&#xff09;版本 嘉立创PCB工艺加工能力范围说明-嘉立创PCB打样专业工厂-线路板打样 规则参考-嘉立创 注意事项 1.每次设置完规则参数都要点击应用保存 2.每次创建PCB&#xff0c;都要设置好参数 3.可以设置默认规则&#xff0c;将…

【计算机学习笔记】GB2312、GBK、Unicode等字符编码的理解

之前编写win32程序时没怎么关注过宽字符到底是个啥东西&#xff0c;最近在编写网络框架又遇到字符相关的问题&#xff0c;所以写一篇文章记录一下&#xff08;有些部分属于个人理解&#xff0c;如果有错误欢迎指出&#xff09; 目录 几个常见的编码方式Unicode和UTF-8、UTF-16、…

深入理解 CSS 文本换行: overflow-wrap 和 word-break

前言 正常情况下&#xff0c;在固定宽度的盒子中的中文会自动换行。但是&#xff0c;当遇到非常长的英文单词或者很长的 URL 时&#xff0c;文本可能就不会自动换行&#xff0c;而会溢出所在容器。幸运的是&#xff0c;CSS 为我们提供了一些和文本换行相关的属性&#xff1b;今…

centos9升级OpenSSH

需求 Centos9系统升级OpenSSH和OpenSSL OpenSSH升级为openssh-9.8p1 OpenSSL默认为OpenSSL-3.2.2&#xff08;根据需求进行升级&#xff09; 将源码包编译为rpm包 查看OpenSSH和OpenSSL版本 ssh -V下载源码包并上传到服务器 openssh最新版本下载地址 wget https://cdn.openb…

Pull requests 和Merge Request其实是一个意思

Pull requests的定义 在Git中&#xff0c;PR&#xff08;Pull Request&#xff09;是一种协作开发的常用方式。它允许开发者将自己的代码变更&#xff08;通常是一个分支&#xff09;提交到项目的仓库中&#xff0c;然后请求负责代码审查的人员将这些变更合并到主分支中。通过…

【ubuntu】将Chroma配置为LINUX服务

Chroma是一个轻量级向量数据库。既然是数据库&#xff0c;那么我希望它是能够长时间运行。最直接的方式是配置为service服务。 可惜官方没有去提供配置为服务的办法&#xff0c;而鄙人对docker又不是特别感冒。所以自己研究了下chroma配置为服务的方式。 系统&#xff1a;ubu…