你好,我是Qiuner. 为记录自己编程学习过程和帮助别人少走弯路而写博客 这是我的 github gitee
如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^)
想看更多 那就点个关注吧 我会尽力带来有趣的内容
CSDN 图片导入做的不是很好,因此如果有没有出现的图片请去这里 传送 https://juejin.cn/user/1942157160101860/posts
掘金的文档写作体验比CSDN好多了。。。。里面好像也有不少大佬


要明白这件事,首先要知道我们是如何访问网站的
访问网页的本质涉及多个技术层面,从用户输入网址到最终在浏览器上看到页面的过程包含了多个步骤:
域名解析:当你在浏览器中输入一个网址(URL),比如 http://www.example.com,浏览器首先需要将这个域名解析成对应的 IP 地址。这个过程通过域名系统(DNS)完成,将易于记忆的域名映射到实际的服务器 IP 地址。(本地)
发起连接:一旦浏览器获得了服务器的 IP 地址,它就会通过网络协议(通常是 HTTP 或 HTTPS)与服务器建立连接。这个过程涉及多个网络层的交互,包括 TCP/IP 协议等。(网络通信)
发送请求:浏览器发送一个 HTTP 请求给服务器,这个请求包含了请求的类型(GET、POST 等)、路径、头部信息(例如浏览器类型)、可能的请求体(对于 POST 请求)等。(网络通信)
服务器处理:服务器接收到请求后,根据请求的路径以及其他信息,决定要执行哪些操作。这通常涉及到服务器端的应用程序,比如一个 Web 应用程序。在以上的图片中,就是 Spring Boot 中的控制器方法。(服务器本地)
生成响应:服务器处理请求后,会生成一个 HTTP 响应。这个响应包括了响应的状态码(例如 200 OK、404 Not Found)、响应头部(例如内容类型),以及响应体(实际的数据内容)。(服务器本地)
传输响应:服务器将生成的 HTTP 响应通过网络传输回浏览器。(网络通信)
浏览器处理:浏览器接收到响应后,会根据响应的内容类型(例如 HTML、CSS、JavaScript 等)进行处理。浏览器会解析 HTML,构建 DOM(文档对象模型),加载和解析 CSS 样式,执行 JavaScript 等操作。(本地)
渲染页面:浏览器根据 DOM 结构和 CSS 样式对页面进行渲染,最终在浏览器窗口中呈现出用户可见的页面。(本地)
当你启动 Spring Boot 项目并且访问 http://localhost:8080 或其他定义的路径时,Spring Boot 内置的 Web 服务器( Tomcat 或其他容器)会拦截这些请求,并将请求映射到相应的控制器方法。控制器方法执行完成后,返回的内容会被直接写入 HTTP 响应,然后返回给浏览器进行显示。







<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>






ch.qos.logback
logback-classic
1.2.3
:这个标签是pom.xml文件的根标签,用于包含所有的依赖项。:这个标签用于描述一个具体的依赖项。:这个标签指定了依赖项的组织或公司的唯一标识符。在这个例子中,依赖项的groupId是ch.qos.logback,表示这个依赖项是由logback项目组提供的。:这个标签指定了依赖项的名称或标识符。在这个例子中,依赖项的artifactId是logback-classic,表示这个依赖项是logback日志框架的经典版本。:这个标签指定了依赖项的版本号。在这个例子中,依赖项的版本号是1.2.3,表示使用logback-classic的1.2.3版本。依赖就好比是一个软件模块需要借助其他模块或组件才能正常工作。类比一下,你可以把依赖想象成一个人需要使用其他人的工具才能完成任务。比如,你要修理自行车,但是你需要用到一个扳手,而你自己没有。这时,你就需要依赖别人借给你一个扳手才能完成修理任务。
在软件开发中,也是类似的情况。一个软件模块可能需要使用其他模块提供的功能,比如某个库或框架。这样,它就需要在项目中引入这个库或框架的代码,以便能够调用它提供的功能。为了方便管理这些依赖关系,开发人员通常会使用依赖管理工具。这个工具会帮助自动下载和引入所需的库、框架或其他依赖项,确保项目能够正常构建和运行。

在maven页面可以看到依赖是否生效
依赖与jar包作用是一样的,但是依赖更容易维护与直接修改











想要发出post请求得自己编写程序,可以用postman来代替


package com.example.springboot_one.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
// 请求处理类
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
System.out.printf("hello");
return "hello";
}
}









路径由

变成




| 状态码分类 | 说明 |
|---|---|
| 1xx | 响应中——临时状态码,表示请求已经接受,告诉客户端应该继续请求或者如果它已经完成则忽略它 |
| 2xx | 成功——表示请求已经被成功接收,处理已完成 |
| 3xx | 重定向——重定向到其它地方:它让客户端再发起一个请求以完成整个处理。 |
| 4xx | 客户端错误——处理发生错误,责任在客户端,如:客户端的请求一个不存在的资源,客户端未被授权,禁止访问等 |
| 5xx | 服务器端错误——处理发生错误,责任在服务端,如:服务端抛出异常,路由出错,HTTP版本不支持等 |
| 状态码 | 英文描述 | 解释 |
|---|---|---|
| 200 | OK | 客户端请求成功,即处理成功,这是我们最想看到的状态码 |
| 302 | Found | 指示所请求的资源已移动到由Location响应头给定的 URL,浏览器会自动重新访问到这个页面 |
| 304 | Not Modified | 告诉客户端,你请求的资源至上次取得后,服务端并未更改,你直接用你本地缓存吧。隐式重定向 |
| 400 | Bad Request | 客户端请求有语法错误,不能被服务器所理解 |
| 403 | Forbidden | 服务器收到请求,但是拒绝提供服务,比如:没有权限访问相关资源 |
| 404 | Not Found | 请求资源不存在,一般是URL输入有误,或者网站资源被删除了 |
| 405 | Method Not Allowed | 请求方式有误,比如应该用GET请求方式的资源,用了POST |
| 428 | Precondition Required | 服务器要求有条件的请求,告诉客户端要想访问该资源,必须携带特定的请求头 |
| 429 | Too Many Requests | 指示用户在给定时间内发送了太多请求(“限速”),配合 Retry-After(多长时间后可以请求)响应头一起使用 |
| 431 | Request Header Fields Too Large | 请求头太大,服务器不愿意处理请求,因为它的头部字段太大。请求可以在减少请求头域的大小后重新提交。 |
| 500 | Internal Server Error | 服务器发生不可预期的错误。服务器出异常了,赶紧看日志去吧 |
| 503 | Service Unavailable | 服务器尚未准备好处理请求,服务器刚刚启动,还未初始化好 |
状态码大全:https://cloud.tencent.com/developer/chapter/13553

HttpServletRequest是Java Servlet API中的一个接口,用于表示客户端的HTTP请求。它提供了许多方法来获取关于请求的信息,如请求的URL、参数、头部信息等。通过HttpServletRequest,可以从客户端接收数据并对请求进行处理。
HttpServletRequest对象提供了以下方法来获取请求的各种信息:
getParameter()方法来获取请求的参数,如表单提交的参数、URL中的查询参数等。getInputStream()或getReader()方法来获取请求体的内容。通过HttpServletRequest对象,开发者可以获取到客户端发送过来的各种信息,并根据这些信息进行相应的处理和响应。
@RequestMapping("/simpleParam")
public String simpleParam(HttpServletRequest request) {
String name = request.getParameter("name");
String ageStr = request.getParameter("age");
/*
getParameter()是HttpServletRequest接口中的一个方法,用于获取HTTP请求中的参数值。
它接收一个String类型的参数名称,并返回对应参数名称的值。
getParameter()方法会根据参数名称在请求中查找对应的值,并将其作为String类型返回。
如果请求中不存在该参数或参数值为空,则getParameter()方法返回null。
需要注意的是,getParameter()方法只能获取到请求中的查询参数或表单提交的参数。
对于其他类型的请求体,如JSON或XML数据,需要使用其他方法来获取请求体中的数据。*/
int age= Integer.parseInt(ageStr);
System.out.printf(name+":"+age);
return "OK";
}
运行结果


@RequestMapping("/simpleParam")
public String simpleParam(String name,int age) {//此处也可以改为Integer
System.out.printf(name+":"+age);
return "OK";
}









只要数组名相同

默认封装成数组,需要加一下符号






@PathVariable是Spring框架中的一个注解,用于将URL中的参数绑定到方法的参数上。
可以使用@PathVariable注解来获取URL中的动态参数。这些参数可以是在URL路径中的一部分,用花括号{}括起来,并通过@PathVariable注解来绑定到方法的参数上。
使用这个注解后,可以使得访问路径是变化的。如 localhost:8080/path/2和localhost:8080/10

控制器(Controller)是MVC(Model-View-Controller)设计模式中的一个组件,用于接收用户的请求并处理请求的逻辑。控制器负责从用户请求中提取数据,调用合适的业务逻辑进行处理,并返回响应给用户。
控制器在Web应用程序中起到了桥梁的作用,它接收来自用户的请求,并根据请求的内容决定如何处理。控制器通常包含多个处理方法,每个方法对应不同的请求路径和请求方法,用于处理不同的请求。
控制器的主要作用包括:
在Web开发中,控制器通常与视图(View)和模型(Model)一起工作,通过模型从数据库或其他数据源中获取数据,并将数据传递给视图进行渲染,最终返回给用户显示。
**基本用法:**在控制器类或方法上使用 @RequestMapping 注解,指定请求的 URL 路径。例如:
javaCopy code@RequestMapping("/hello")
public String hello() {
return "Hello, World!";

要明白这件事,首先要知道我们是如何访问网站的
访问网页的本质涉及多个技术层面,从用户输入网址到最终在浏览器上看到页面的过程包含了多个步骤:
域名解析:当你在浏览器中输入一个网址(URL),比如 http://www.example.com,浏览器首先需要将这个域名解析成对应的 IP 地址。这个过程通过域名系统(DNS)完成,将易于记忆的域名映射到实际的服务器 IP 地址。(本地)
发起连接:一旦浏览器获得了服务器的 IP 地址,它就会通过网络协议(通常是 HTTP 或 HTTPS)与服务器建立连接。这个过程涉及多个网络层的交互,包括 TCP/IP 协议等。(网络通信)
发送请求:浏览器发送一个 HTTP 请求给服务器,这个请求包含了请求的类型(GET、POST 等)、路径、头部信息(例如浏览器类型)、可能的请求体(对于 POST 请求)等。(网络通信)
服务器处理:服务器接收到请求后,根据请求的路径以及其他信息,决定要执行哪些操作。这通常涉及到服务器端的应用程序,比如一个 Web 应用程序。在以上的图片中,就是 Spring Boot 中的控制器方法。(服务器本地)
生成响应:服务器处理请求后,会生成一个 HTTP 响应。这个响应包括了响应的状态码(例如 200 OK、404 Not Found)、响应头部(例如内容类型),以及响应体(实际的数据内容)。(服务器本地)
传输响应:服务器将生成的 HTTP 响应通过网络传输回浏览器。(网络通信)
浏览器处理:浏览器接收到响应后,会根据响应的内容类型(例如 HTML、CSS、JavaScript 等)进行处理。浏览器会解析 HTML,构建 DOM(文档对象模型),加载和解析 CSS 样式,执行 JavaScript 等操作。(本地)
渲染页面:浏览器根据 DOM 结构和 CSS 样式对页面进行渲染,最终在浏览器窗口中呈现出用户可见的页面。(本地)
当你启动 Spring Boot 项目并且访问 http://localhost:8080 或其他定义的路径时,Spring Boot 内置的 Web 服务器( Tomcat 或其他容器)会拦截这些请求,并将请求映射到相应的控制器方法。控制器方法执行完成后,返回的内容会被直接写入 HTTP 响应,然后返回给浏览器进行显示。



package com.itheima.pojo;
/**
* 统一响应结果封装类
*/
public class Result {
private Integer code ;//1 成功 , 0 失败
private String msg; //提示信息
private Object data; //数据 date
public Result() {
}
public Result(Integer code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public static Result success(Object data){
return new Result(1, "success", data);
}
public static Result success(){
return new Result(1, "success", null);
}
public static Result error(String msg){
return new Result(0, msg, null);
}
@Override
public String toString() {
return "Result{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
@RequestMapping("/hello")
public Result hello(){
System.out.println("Hello World ~");
//return new Result(1,"success","Hello World ~");
return Result.success("Hello World ~");
}


//文件寻址
String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
this.getClass():获取当前对象所属的类。getClassLoader():获取类加载器对象。getResource("emp.xml"):通过类加载器对象的getResource()方法,传入资源文件的相对路径(相对于类路径),返回一个URL对象,指向该资源文件。getFile():通过URL对象的getFile()方法,获取资源文件在文件系统中的绝对路径。最终,将获取到的绝对路径赋值给file变量
关于类加载器
类加载器对象(ClassLoader Object)是Java中用于加载类文件的工具。它负责将类的字节码文件加载到Java虚拟机中,并转换为可执行的类对象。
在Java中,每个类加载器都是一个ClassLoader对象。ClassLoader对象负责查找类文件、加载类文件、定义类和管理类的生命周期。每个类加载器都有一个父类加载器(除了引导类加载器),它们按照一定的层次结构进行组织。
package com.itheima.controller;
import com.itheima.pojo.Emp;
import com.itheima.pojo.Result;
import com.itheima.utils.XmlParserUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class EmpController {
@RequestMapping("/listEmp")
public Result list(){
//1. 加载并解析emp.xml(获取数据)
String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
System.out.println(file);
List<Emp> empList = XmlParserUtils.parse(file, Emp.class);//XmlParserUtils对象用来处理xml文件
//2. 对数据进行转换处理 - gender, job(处理数据)
empList.stream().forEach(emp -> {//使用lambda表达式,相当于js中的箭头函数。
//处理 gender 1: 男, 2:
String gender = emp.getGender();//类里面
//为什么emp没有声明为Emp类型的数据却能使用Emp类中的方法?
//因为lambda表达式中的emp(这个位置的变量)是通过上下文来判断类型。
//而empList是Emp类数据
if("1".equals(gender)){
emp.setGender("男");
}else if("2".equals(gender)){
emp.setGender("女");
}
//处理job - 1: 讲师, 2: 班主任 , 3: 就业指导
String job = emp.getJob();
if("1".equals(job)){
emp.setJob("讲师");
}else if("2".equals(job)){
emp.setJob("班主任");
}else if("3".equals(job)){
emp.setJob("就业指导");
}
});
//3. 响应数据
return Result.success(empList);
}
}
package com.itheima.pojo;
public class Emp {
private String name;
private Integer age;
private String image;
private String gender;
private String job;
public Emp() {
}
public Emp(String name, Integer age, String image, String gender, String job) {
this.name = name;
this.age = age;
this.image = image;
this.gender = gender;
this.job = job;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
@Override
public String toString() {
return "Emp{" +
"name='" + name + '\'' +
", age=" + age +
", image='" + image + '\'' +
", gender='" + gender + '\'' +
", job='" + job + '\'' +
'}';
}
}
见
https://www.bilibili.com/video/BV1m84y1w7Tb?p=74&spm_id_from=pageDriver&vd_source=077127c579b82c23164b07dbc24cd570

使得一个类或者一个接口只做一件事
其中,数据的来源可能有很多。因此凭借接口实现dao层






@Component是一个注解(Annotation),在Spring框架中用于标识一个类为组件(Component)。
在Spring中,组件是指可被自动扫描和实例化的类。通过使用@Component注解,告诉Spring框架将被标注的类作为组件进行管理。被标注的EmpserviceA称为loc中的bean
@Autowired是一个注解(Annotation),在Spring框架中用于实现依赖注入(Dependency Injection)。
依赖注入是指将一个对象的依赖关系由容器动态地注入到对象中,而不是由对象自己创建或查找依赖对象。通过使用@Autowired注解,可以告诉Spring框架自动装配相应的依赖对象。
容器需要把要用的都加到容器里去
当要切换不同的dao层时,就通过操作@Component来改变容器存储不同




















查询所有字段不要用星号,效率低下





-- if语句
select if(gender=1,'男性','女性'),count(*)
from tb_emp group by gender ;
-- case语句
select (case job when 1 then '班主任' when 2 then '讲师' when 3 then '学工主管' when 4 then '教研主管' else '无职位' end)
,count(*)
from tb_emp
group by job;




















-- 查询每个分类下最贵的菜品,展示出分类的名称、最贵的菜品的价格
select c.name,max(d.price)-- 不一定要用子查询,可以直接筛选出最贵的
from category c,
dish d
where d.category_id = c.id
group by c.id;








1、分析需要用到那几张表(提前做好er图),然后再开始写代码
2、先写查询条件再写查询显示项
优先级,你需要知道每个语句的优先级

-- 查询每个分类下最贵的菜品,展示出分类的名称、最贵的菜品的价格
select c.name,max(d.price)
from category c,
dish d
where d.category_id = c.id
group by c.id;






在配置文件中增加德鲁伊数据库链接池即可
//德鲁伊数据库链接词
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>



写在类的前面
原理就是根据注解生成相应的方法


#配置数据库中的链接信息
# mysql项目的application.properties配置
#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=123456
@Mapper是一个MyBatis注解,用于标注DAO层的Mapper接口。
MyBatis是一个支持定制化SQL、存储过程以及高级映射的优秀持久层框架。在MyBatis中,DAO层的Mapper接口负责与数据库交互,封装各种CRUD操作。
@Mapper注解用于告诉MyBatis框架,该接口需要被自动实现为Mapper代理。MyBatis会在应用启动时自动扫描带有@Mapper注解的接口,并为这些接口生成实现类。
标注在类上面,即可使用
也是交给loc容器管理
查询就是@select,删除就是@delete
MyBatis通过注解的方式,可以直接将SQL语句映射到DAO方法上,无需编写XML映射文件。
//根据ID删除数据
@Delete("delete from emp where id=#{id}")
//mybatis实现了根据 #{} 来实现注释绑定的注释方法传参
public void delete(Integer id);
//public int delete(Integer id);
//可以有返回值。返回值意思是影响的记录数




其中count(*)能够统计查询到的总行数




没有使用预编译的SQL可以通过输入密码或者账号时,改为mysql语句的形式,来修改。
使用预编译,将把输入的字符都变为一个参数,代替问号















//方式二
@Select("select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and " +
"entrydate between #{begin} and #{end} order by update_time desc ")
public List<Emp> list(String name, Short gender, LocalDate begin , LocalDate end);


方案一: 给字段起别名, 让别名与实体类属性一致
@Select("select id, username, password, name, gender, image, job, entrydate, " +
"dept_id deptId, create_time createTime, update_time updateTime from emp where id = #{id}")
public Emp getById(Integer id);
方案二: 通过@Results, @Result注解手动映射封装
@Results({
@Result(column = "dept_id", property = "deptId"),
@Result(column = "create_time", property = "createTime"),
@Result(column = "update_time", property = "updateTime")
})
@Select("select * from emp where id = #{id}")
public Emp getById(Integer id);
#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库链接的url
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
#3306后面内容是要链接数据库的名称
#链接数据库的用户名
spring.datasource.username=root
#链接数据库的密码
spring.datasource.password=123456
#开启mybatis的驼峰命名自动映射开关 a_bbb ----> aBbb
mybatis.configuration.map-underscore-to-camel-case=true
#配置mybatis的日志 指定输出到控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

一、同包同名
比如我要配置com.example.webcase下mapper的xml,那么便要如以下一样

二、一个xml文件对应一个接口,且名称完全一致
如图

三、xml中SQL语句的id要与mapper接口中的方法名保持一致,并且放回类型也是一致的



一个接口与一个映射文件相对应
红色是要求一,紫色是要求二
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
访问mybatis中文网获得
https://mybatis.net.cn/getting-started.html







不同的关键字能生成不同
也会if限制,多个 ,










011)]
[外链图片转存中…(img-x4YKjqVs-1714007817011)]
一个接口与一个映射文件相对应
红色是要求一,紫色是要求二
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
访问mybatis中文网获得
https://mybatis.net.cn/getting-started.html
[外链图片转存中…(img-x1DGCwa8-1714007817011)]
[外链图片转存中…(img-pyMgdDtU-1714007817012)]
[外链图片转存中…(img-ns5YgnHb-1714007817012)]
[外链图片转存中…(img-TMZ5N4Z2-1714007817012)]
[外链图片转存中…(img-7qvdoCno-1714007817013)]
[外链图片转存中…(img-POn4JMiQ-1714007817014)]
[外链图片转存中…(img-1361I06g-1714007817014)]
不同的关键字能生成不同
也会if限制,多个 ,
[外链图片转存中…(img-LuWRjqH0-1714007817014)]
[外链图片转存中…(img-DHfKCUpS-1714007817015)]
[外链图片转存中…(img-IYeQxTWd-1714007817015)]
[外链图片转存中…(img-lSHub1Zt-1714007817016)]
[外链图片转存中…(img-c56FDcEe-1714007817016)]
[外链图片转存中…(img-Tr1oaWUZ-1714007817016)]
[外链图片转存中…(img-3gaN4fAv-1714007817017)]
[外链图片转存中…(img-uM9nInYb-1714007817017)]
[外链图片转存中…(img-cXZyXj6a-1714007817018)]
[外链图片转存中…(img-uhWTISOU-1714007817018)]