快速入门Web开发(中)后端开发(有重点)

news2024/11/27 14:46:43

你好,我是Qiuner. 为记录自己编程学习过程和帮助别人少走弯路而写博客 这是我的 github gitee

如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^)

想看更多 那就点个关注吧 我会尽力带来有趣的内容
CSDN 图片导入做的不是很好,因此如果有没有出现的图片请去这里 传送 https://juejin.cn/user/1942157160101860/posts
掘金的文档写作体验比CSDN好多了。。。。里面好像也有不少大佬

快速入门Web开发(中)后端开发(有重点)

image-20230814133911909

为什么你能通过一小段代码来访问网页?(重点)

image-20230817141426063

要明白这件事,首先要知道我们是如何访问网站的

访问网页的本质涉及多个技术层面,从用户输入网址到最终在浏览器上看到页面的过程包含了多个步骤:

  1. 域名解析:当你在浏览器中输入一个网址(URL),比如 http://www.example.com,浏览器首先需要将这个域名解析成对应的 IP 地址。这个过程通过域名系统(DNS)完成,将易于记忆的域名映射到实际的服务器 IP 地址。(本地)

  2. 发起连接:一旦浏览器获得了服务器的 IP 地址,它就会通过网络协议(通常是 HTTP 或 HTTPS)与服务器建立连接。这个过程涉及多个网络层的交互,包括 TCP/IP 协议等。(网络通信)

  3. 发送请求:浏览器发送一个 HTTP 请求给服务器,这个请求包含了请求的类型(GET、POST 等)、路径、头部信息(例如浏览器类型)、可能的请求体(对于 POST 请求)等。(网络通信)

  4. 服务器处理:服务器接收到请求后,根据请求的路径以及其他信息,决定要执行哪些操作。这通常涉及到服务器端的应用程序,比如一个 Web 应用程序。在以上的图片中,就是 Spring Boot 中的控制器方法。(服务器本地)

  5. 生成响应:服务器处理请求后,会生成一个 HTTP 响应。这个响应包括了响应的状态码(例如 200 OK、404 Not Found)、响应头部(例如内容类型),以及响应体(实际的数据内容)。(服务器本地)

  6. 传输响应:服务器将生成的 HTTP 响应通过网络传输回浏览器。(网络通信)

  7. 浏览器处理:浏览器接收到响应后,会根据响应的内容类型(例如 HTML、CSS、JavaScript 等)进行处理。浏览器会解析 HTML,构建 DOM(文档对象模型),加载和解析 CSS 样式,执行 JavaScript 等操作。(本地)

  8. 渲染页面:浏览器根据 DOM 结构和 CSS 样式对页面进行渲染,最终在浏览器窗口中呈现出用户可见的页面。(本地)

当你启动 Spring Boot 项目并且访问 http://localhost:8080 或其他定义的路径时,Spring Boot 内置的 Web 服务器( Tomcat 或其他容器)会拦截这些请求,并将请求映射到相应的控制器方法。控制器方法执行完成后,返回的内容会被直接写入 HTTP 响应,然后返回给浏览器进行显示。

后端工具

Maven

image-20230814134030079

image-20230814134131233

  • 依赖管理:因为要导入的jar包很多,所以使用Maven来快捷、方便的进行导包
  • 统一的结构:idea和eclipse等开发软件生成的项目结构不一样,使用maven可以直接导入
  • image-20230814134736034

image-20230814134825447

  • 快速的完成以上功能
https://maven.apache.org/
maven的架构

image-20230814135311572

  • 本地没有jar包的情况下,看有无链接私服,有则去私服找,没有就去中央找。私服本身没有,则私服去中央找

image-20230814135504050

image-20230814184141573

  • 其中bing目录存放可执行文件
  • conf存放maven配置文件
  • lib存放maven依赖的jar包资源
步骤二
  • conf中settings的第五十三行代码复制下,并填上maven仓库的地址(自定义)
步骤三
<mirror>
   	<id>alimaven</id>  
	<name>aliyun maven</name>  
	<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
	<mirrorOf>central</mirrorOf> 
</mirror>
  • 通过mvn -v校验是否成功。成功标志为出现版本号
配置maven

image-20230814185336520

  • 将maven使用jdk和编译器使用的设置成相同

image-20230814191035396

  • 在idea2022中直接创建普通的项目,选择java中的maven即可

image-20230814200120942

image-20230814200007935

Maven项目导入

image-20230814200814378

  • 调出maven

image-20230814200833548

  • 点击加号即可
添加Maven依赖
<!--添加依赖-->
    <dependencies>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
    </dependencies>
  • <dependencies>:这个标签是pom.xml文件的根标签,用于包含所有的依赖项。
  • <dependency>:这个标签用于描述一个具体的依赖项。
  • <groupId>:这个标签指定了依赖项的组织或公司的唯一标识符。在这个例子中,依赖项的groupId是ch.qos.logback,表示这个依赖项是由logback项目组提供的。
  • <artifactId>:这个标签指定了依赖项的名称或标识符。在这个例子中,依赖项的artifactId是logback-classic,表示这个依赖项是logback日志框架的经典版本。
  • <version>:这个标签指定了依赖项的版本号。在这个例子中,依赖项的版本号是1.2.3,表示使用logback-classic的1.2.3版本。
什么是依赖

依赖就好比是一个软件模块需要借助其他模块或组件才能正常工作。类比一下,你可以把依赖想象成一个人需要使用其他人的工具才能完成任务。比如,你要修理自行车,但是你需要用到一个扳手,而你自己没有。这时,你就需要依赖别人借给你一个扳手才能完成修理任务。
在软件开发中,也是类似的情况。一个软件模块可能需要使用其他模块提供的功能,比如某个库或框架。这样,它就需要在项目中引入这个库或框架的代码,以便能够调用它提供的功能。为了方便管理这些依赖关系,开发人员通常会使用依赖管理工具。这个工具会帮助自动下载和引入所需的库、框架或其他依赖项,确保项目能够正常构建和运行。

  • 点击重写加载后
  • image-20230814201550985

在maven页面可以看到依赖是否生效

依赖与jar包

依赖与jar包作用是一样的,但是依赖更容易维护与直接修改

依赖特性

image-20230814202123906

image-20230814203627849

image-20230814203822822

image-20230814204058265

image-20230814204130144

  • 运行后面的依赖,前面的依赖也会执行

image-20230814204202348

  • 在同一套生命周期中,运行后面阶段,前面阶段都会运行

image-20230814204244505

  • maven所有操作由插件执行

Tomcat

  • 一个web服务器

image-20230815210700859

  • 默认端口号为8080

image-20230815211422723

image-20230815211606528

image-20230815211621832

postman

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

SpringBoot初体验

image-20230814204917978

image-20230815100644949

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";
    }
}
  • 运行SpringbootOneApplication这个文件

image-20230815214140858

image-20230815214518840

image-20230815214547303

image-20230816081024440

  • Tomcat又称servlet容器

image-20230816081403878

  • BS架构体验一般指对宽带需求大,现在已经不是问题
  • CS架构虽然可以在本地处理一些数据,但不同平台要开发不同的版本

http协议

image-20230815201341081

image-20230815202042539

  • 请求头和请求体之间的空行是必须的

请求

  • image-20230815201718780

image-20230815202235820

路径由

image-20230815202326423

变成

image-20230815202402362

  • get请求的参数就在这里面了(通过?来实现),而post请求的参数不在

响应

image-20230815204032139

image-20230815204046530

image-20230815204145246

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

状态码大全:https://cloud.tencent.com/developer/chapter/13553

image-20230815210511295

SpringBoot

HttpServletRequest对象

HttpServletRequest是Java Servlet API中的一个接口,用于表示客户端的HTTP请求。它提供了许多方法来获取关于请求的信息,如请求的URL、参数、头部信息等。通过HttpServletRequest,可以从客户端接收数据并对请求进行处理。

HttpServletRequest对象提供了以下方法来获取请求的各种信息:

  1. 请求行信息:如请求的URL、请求的方法(GET、POST等)、HTTP协议版本等。
  2. 请求头信息:如User-Agent、Referer、Accept-Language等。
  3. 请求参数:可以通过getParameter()方法来获取请求的参数,如表单提交的参数、URL中的查询参数等。
  4. 请求体信息:对于POST请求,请求体中可能包含请求的实体内容,可以通过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";
  }

运行结果

image-20230818155713620

image-20230818155726140

SptingBoot版本
 @RequestMapping("/simpleParam")
  public String simpleParam(String name,int age) {//此处也可以改为Integer
    System.out.printf(name+":"+age);
    return "OK";
  }
  • 结果一样
以上都是get请求,如何使用post请求呢?

image-20230818161816944

  • 参数名不一致时候会放回null
参数名映射

image-20230818162319948

image-20230818162401135

实体参数映射(设置网站内容页)

image-20230818162528467

image-20230818162709330

复杂实体

image-20230818162747001

  • 通过创建两个类来满足需要。一个类包含另一个

image-20230818163051065

image-20230818163107487

数组集合参数

image-20230818163214699

  • 只要数组名相同

  • image-20230818163350728

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

image-20230819090312561

image-20230819090432879

日期参数

image-20230819090533039

json参数

image-20230819090822511

  • json格式数据使用不了get

image-20230819090930068

  • 需要做到key与实体对象的属性名相同
路径参数

image-20230819091349972

  • @PathVariable是Spring框架中的一个注解,用于将URL中的参数绑定到方法的参数上。

    可以使用@PathVariable注解来获取URL中的动态参数。这些参数可以是在URL路径中的一部分,用花括号{}括起来,并通过@PathVariable注解来绑定到方法的参数上。

  • 使用这个注解后,可以使得访问路径是变化的。如 localhost:8080/path/2和localhost:8080/10

image-20230819091938301

什么是控制器?

控制器(Controller)是MVC(Model-View-Controller)设计模式中的一个组件,用于接收用户的请求并处理请求的逻辑。控制器负责从用户请求中提取数据,调用合适的业务逻辑进行处理,并返回响应给用户。

控制器在Web应用程序中起到了桥梁的作用,它接收来自用户的请求,并根据请求的内容决定如何处理。控制器通常包含多个处理方法,每个方法对应不同的请求路径和请求方法,用于处理不同的请求。

控制器的主要作用包括:

  1. 接收请求:控制器监听来自客户端的请求,根据请求的路径和方法来确定调用哪个处理方法。
  2. 处理请求:控制器中的处理方法会根据业务逻辑对请求进行处理,可能会操作数据库、调用其他服务等。
  3. 提取数据:控制器从请求中提取所需的数据,例如请求参数、请求头、请求体等。
  4. 调用服务:控制器可能需要调用其他服务或组件来完成请求的处理,例如调用业务逻辑组件、数据访问组件等。
  5. 返回响应:控制器根据请求的处理结果生成响应数据,可以是HTML页面、JSON数据、XML数据等。

在Web开发中,控制器通常与视图(View)和模型(Model)一起工作,通过模型从数据库或其他数据源中获取数据,并将数据传递给视图进行渲染,最终返回给用户显示。

  • 控制器的表现形式就是注解

@RestController

  • 是一个注解,用于将类标记为RESTful风格的控制器。

@RequestMapping

  • 这个注解使得被拦截的请求能与被注解的方法进行配对,配对成功了,就按照方法内的代码工作。其中,返回是返回给客户端的

**基本用法:**在控制器类或方法上使用 @RequestMapping 注解,指定请求的 URL 路径。例如:

javaCopy code@RequestMapping("/hello")
public String hello() {
  return "Hello, World!";

  • 该注解有很多用法,自行百度

为什么你能通过一小段代码来访问网页?(重点)

image-20230817141426063

要明白这件事,首先要知道我们是如何访问网站的

访问网页的本质涉及多个技术层面,从用户输入网址到最终在浏览器上看到页面的过程包含了多个步骤:

  1. 域名解析:当你在浏览器中输入一个网址(URL),比如 http://www.example.com,浏览器首先需要将这个域名解析成对应的 IP 地址。这个过程通过域名系统(DNS)完成,将易于记忆的域名映射到实际的服务器 IP 地址。(本地)

  2. 发起连接:一旦浏览器获得了服务器的 IP 地址,它就会通过网络协议(通常是 HTTP 或 HTTPS)与服务器建立连接。这个过程涉及多个网络层的交互,包括 TCP/IP 协议等。(网络通信)

  3. 发送请求:浏览器发送一个 HTTP 请求给服务器,这个请求包含了请求的类型(GET、POST 等)、路径、头部信息(例如浏览器类型)、可能的请求体(对于 POST 请求)等。(网络通信)

  4. 服务器处理:服务器接收到请求后,根据请求的路径以及其他信息,决定要执行哪些操作。这通常涉及到服务器端的应用程序,比如一个 Web 应用程序。在以上的图片中,就是 Spring Boot 中的控制器方法。(服务器本地)

  5. 生成响应:服务器处理请求后,会生成一个 HTTP 响应。这个响应包括了响应的状态码(例如 200 OK、404 Not Found)、响应头部(例如内容类型),以及响应体(实际的数据内容)。(服务器本地)

  6. 传输响应:服务器将生成的 HTTP 响应通过网络传输回浏览器。(网络通信)

  7. 浏览器处理:浏览器接收到响应后,会根据响应的内容类型(例如 HTML、CSS、JavaScript 等)进行处理。浏览器会解析 HTML,构建 DOM(文档对象模型),加载和解析 CSS 样式,执行 JavaScript 等操作。(本地)

  8. 渲染页面:浏览器根据 DOM 结构和 CSS 样式对页面进行渲染,最终在浏览器窗口中呈现出用户可见的页面。(本地)

当你启动 Spring Boot 项目并且访问 http://localhost:8080 或其他定义的路径时,Spring Boot 内置的 Web 服务器( Tomcat 或其他容器)会拦截这些请求,并将请求映射到相应的控制器方法。控制器方法执行完成后,返回的内容会被直接写入 HTTP 响应,然后返回给浏览器进行显示。

响应数据

image-20230819092035893

image-20230819092515108

  • 以上几个方法被称为功能接口
  • 这样开发不便管理

image-20230819092613743

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 ~");
    }
  • 仔细观看以上代码就懂了

image-20230819154058552

案列

image-20230819155202293

//文件寻址
 String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();

  1. this.getClass():获取当前对象所属的类。
  2. getClassLoader():获取类加载器对象。
  3. getResource("emp.xml"):通过类加载器对象的getResource()方法,传入资源文件的相对路径(相对于类路径),返回一个URL对象,指向该资源文件。
  4. 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

分层解耦

三层结构

image-20230819175558776

  • 使得一个类或者一个接口只做一件事

  • 其中,数据的来源可能有很多。因此凭借接口实现dao层

image-20230819192654901

image-20230819192720170

  • 这样将代码单一功能化,也称为高内聚

分层解耦(高内聚低耦合(最好没有耦合))

image-20230819193054985

  • 因为引用,现在会有耦合

  • 要切换成b类,不止一处地方需要变动
  • 使用容器来解耦

image-20230819193430342

controller层与前端交互

控制反转

  • 一种设计的思路

image-20230819193633886

  • @Component是一个注解(Annotation),在Spring框架中用于标识一个类为组件(Component)。

    在Spring中,组件是指可被自动扫描和实例化的类。通过使用@Component注解,告诉Spring框架将被标注的类作为组件进行管理。被标注的EmpserviceA称为loc中的bean

  • @Autowired是一个注解(Annotation),在Spring框架中用于实现依赖注入(Dependency Injection)。

    依赖注入是指将一个对象的依赖关系由容器动态地注入到对象中,而不是由对象自己创建或查找依赖对象。通过使用@Autowired注解,可以告诉Spring框架自动装配相应的依赖对象。

  • 容器需要把要用的都加到容器里去

当要切换不同的dao层时,就通过操作@Component来改变容器存储不同

image-20230819204604449

  • 寻找RestController的实现

image-20230819204231554

image-20230819204326038

组件扫描

image-20230819204914394

image-20230819205034529

  • 指定后,默认扫描包会更改,因此还要加上原来的包

image-20230819205445354

  • Primary更改优先级别
  • Qualifier/Resource设置访问

image-20230819205612530

数据库(有重点)

image-20230819205832656

image-20230819205928970

image-20230819210451187

image-20230819210604445

通用规则

image-20230819210633288

image-20230819210754866

流程

image-20230819210933250

image-20230819212026490

image-20230820092133254

image-20230820165427306

  • 创建数据库一般有这两个字段

image-20230820165656633

image-20230820170459003

DQL

image-20230820170725484

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

image-20230820184354108

image-20230820184855913

image-20230820190911999

image-20230820191322391

image-20230820191449731

-- 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;

image-20230820195038839

image-20230820195103819

表关系及对应

一对多

image-20230820203323898

image-20230820203701278

image-20230820205704964

  • 多的一方添加外键
一对一

image-20230820205829382

多对多

image-20230820210033094

多表设计的流程

  • 步骤一画er图

image-20230820210642354

image-20230820211057866

image-20230820211107070

image-20230820211116048

image-20230820211128707

多表查询

内连接

image-20230820211853123

image-20230820212140491

外连接

-

  • 左外连接会包含左表中的所有数据
  • 右外连接会包含右表中的所有数据
  • 可以解决一方值为空,对应不到对方的情况
  • 基本用左外,右外可以替换成左外

image-20230820212548134

子查询

image-20230820212625557

image-20230820212725729

image-20230820213006371

  • 以上出现了两种方式

image-20230820213055727

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

事物

image-20230831085934329

image-20230831090155081

索引

image-20230904125849617

  • 索引将原本的挨个查询变成使用数据结构来查询

image-20230904130057073

image-20230904130548526

image-20230904130508383

image-20230904140253253

image-20230904140311703

写MySQl代码的方式(重点)

1、分析需要用到那几张表(提前做好er图),然后再开始写代码

2、先写查询条件再写查询显示项

mysql语句的难点(重点)

优先级,你需要知道每个语句的优先级

image-20230821110151079

-- 查询每个分类下最贵的菜品,展示出分类的名称、最贵的菜品的价格
select c.name,max(d.price)
from category c,
     dish d
where d.category_id = c.id
group by c.id;
  • 比如以上的案列,我以为是先执行语句是从左边执行到右边,于是认为先查询最贵的价格了,而最贵的价格只有一个,因此只会出现一个拥有最贵的分类。但代码不是这么运作的。

一个用的到的函数—concat()

  • 函数格式是CONCAT(‘参数1’,’参数2’,’参数3’)
  • 使用该函数可以将括号中的参数拼接在一起,用于sql的预编译

JDBC

  • sun公司提供的api

image-20230821183545242

image-20230821183652525

image-20230821183758600

数据库链接池

image-20230821184035024

  • 用户使用数据库连接池用完了还回去

image-20230821184618520

切换数据库链接池

在配置文件中增加德鲁伊数据库链接池即可

//德鲁伊数据库链接词
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid-spring-boot-starter</artifactId>
   <version>1.2.8</version>
</dependency>

image-20230821185356328

lombik(注解简化代码)

image-20230821185538703

image-20230821185605351

  • 写在类的前面

  • 原理就是根据注解生成相应的方法

image-20230821190746504

Mybatis基于注解来配置sql

image-20230821152916276

  • 只需要定义接口就好不需要定义实现类
#配置数据库中的链接信息
# 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

@Mapper是一个MyBatis注解,用于标注DAO层的Mapper接口。

MyBatis是一个支持定制化SQL、存储过程以及高级映射的优秀持久层框架。在MyBatis中,DAO层的Mapper接口负责与数据库交互,封装各种CRUD操作。

@Mapper注解用于告诉MyBatis框架,该接口需要被自动实现为Mapper代理。MyBatis会在应用启动时自动扫描带有@Mapper注解的接口,并为这些接口生成实现类。

  • 标注在类上面,即可使用

  • 也是交给loc容器管理

@Select与其他的语句映射

查询就是@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);
 //可以有返回值。返回值意思是影响的记录数

image-20230821202134399

Test

  • 使用@test注解可以进行测试

日志与预编译

image-20230904101721085

image-20230904101857307

  • 通过?(预编译)使得能够高性能的工作

image-20230904102225560

  • 登录的本质就是将输入的用户名和密码拿去查询,看是否能查到

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

image-20230904123426467

  • 使用$()是直接拼接字符串
  • 使用#()是使用预编译

image-20230904123618089

SQL注入

image-20230904101917252

image-20230904123014411

  • 没有使用预编译的SQL可以通过输入密码或者账号时,改为mysql语句的形式,来修改。

  • 使用预编译,将把输入的字符都变为一个参数,代替问号

Mybatis使用

image-20230821162355520

image-20230821162545972

  • 注意,上面的链接那边要填写自己的数据库名称

image-20230821162607648

image-20230821162614418

配置sql

image-20230821162843721

image-20230821163115531

增加员工(涉及主键返回问题)

image-20230904124656807

  • 出现以上数据过多时,可以通过列多个参数,也可以通过使用一个对象

image-20230904124854578

  • 以上字母是emp中的属性名称

image-20230904125003350

多对多关系(两张表)

image-20230904140724424

  • 需要使用共通的id,使用@Options

image-20230904140920165

更新数据

image-20230904141353378

image-20230904142717134

image-20230904145216524

  • 以上想要实现模糊查询,但是#{}会被替换成?,所以不能使用。而是要用 ${}

image-20230904150002081

  • ​ 使用concat函数解决
    //方式二
   @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);

image-20230904150247629

变量映射

image-20230904142731893

    方案一: 给字段起别名, 让别名与实体类属性一致
    @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);
  • 方案三配置application.properties文件
#驱动类名称
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

image-20230904144504441

XML文件定义的三种规范

一、同包同名

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

image-20230908101118859

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

如图

image-20230908101625184

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

  • mapper接口中的方法名为list,返回值是List

image-20230908102346432

  • xml中的id也为list,返回值为List

image-20230908112248704

XML映射文件来配置sql

image-20230904164814418

  • 一个接口与一个映射文件相对应

  • 红色是要求一,紫色是要求二

<?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">
  • 每次配置xml文件时候,根据配置东西的不同要选择不同的约束。比如以上就是mysql的约束

访问mybatis中文网获得

https://mybatis.net.cn/getting-started.html

image-20230904201751172

image-20230904202113105

image-20230904202128958

动态SQL

image-20230904202522574

  • 指查询条件随着用户所填变化而变化
  • 以上if有一个缺陷,当name为空而gender有值的时候,会出现语法错误
动态查询

image-20230904212414679

  • 使用where解决
动态更新

image-20230904212838552

  • 通过Alt+回车可以自动生成动态sql代码

image-20230904213230494

  • 不同的关键字能生成不同

  • 也会if限制,多个 ,

image-20230904213328757

image-20230904213347708

批量删除

image-20230904213814634

代码复用

image-20230904214111467

  • 用于代码的复用性

配置文件

使用application.properties配置文件

image-20230911104738662

image-20230911110057162

不同的配置文件

image-20230911110821711

image-20230911110921959

image-20230911111110916

image-20230911113337864

011)]

XML映射文件来配置sql

[外链图片转存中…(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">
  • 每次配置xml文件时候,根据配置东西的不同要选择不同的约束。比如以上就是mysql的约束

访问mybatis中文网获得

https://mybatis.net.cn/getting-started.html

[外链图片转存中…(img-x1DGCwa8-1714007817011)]

[外链图片转存中…(img-pyMgdDtU-1714007817012)]

[外链图片转存中…(img-ns5YgnHb-1714007817012)]

动态SQL

[外链图片转存中…(img-TMZ5N4Z2-1714007817012)]

  • 指查询条件随着用户所填变化而变化
  • 以上if有一个缺陷,当name为空而gender有值的时候,会出现语法错误
动态查询

[外链图片转存中…(img-7qvdoCno-1714007817013)]

  • 使用where解决
动态更新

[外链图片转存中…(img-POn4JMiQ-1714007817014)]

  • 通过Alt+回车可以自动生成动态sql代码

[外链图片转存中…(img-1361I06g-1714007817014)]

  • 不同的关键字能生成不同

  • 也会if限制,多个 ,

[外链图片转存中…(img-LuWRjqH0-1714007817014)]

[外链图片转存中…(img-DHfKCUpS-1714007817015)]

批量删除

[外链图片转存中…(img-IYeQxTWd-1714007817015)]

代码复用

[外链图片转存中…(img-lSHub1Zt-1714007817016)]

  • 用于代码的复用性

配置文件

使用application.properties配置文件

[外链图片转存中…(img-c56FDcEe-1714007817016)]

[外链图片转存中…(img-Tr1oaWUZ-1714007817016)]

不同的配置文件

[外链图片转存中…(img-3gaN4fAv-1714007817017)]

[外链图片转存中…(img-uM9nInYb-1714007817017)]

[外链图片转存中…(img-cXZyXj6a-1714007817018)]

[外链图片转存中…(img-uhWTISOU-1714007817018)]

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle 数据迁移同步优化(三)

简述 CloudCanal 最近再次对其 Oracle 源端数据同步进行了一系列优化&#xff0c;这些优化基于用户在真实场景中的反馈&#xff0c;具备很强的生产级别参考意义。 本文将简要介绍这些优化项&#xff0c;希望带给读者一些收获。 增量事件 SCN 乱序问题MISSING_SCN 事件干扰新…

信息系统项目管理师0069:数据运维(5信息系统工程—5.2数据工程—5.2.3数据运维)

点击查看专栏目录 文章目录 5.2.3数据运维1.数据存储2.数据备份3.数据容灾4.数据质量评价与控制记忆要点总结5.2.3数据运维 数据开发利用的前提是通过合适的方式将数据保存到存储介质上,并能保证有效的访问,还要通过数据备份和容灾手段,保证数据的高可用性。数据质量管理是在…

让直播和视频通话更精彩的实时换脸神器: 亲妈都未必认识

DeepFacelive&#xff1a;让直播和视频通话更精彩的实时换脸神器&#xff01; 你是否想在直播或视频通话时&#xff0c;给观众带来惊喜和欢乐&#xff1f;你是否想尝试一下换脸的乐趣&#xff0c;展现出不同的自己&#xff1f;如果你的答案是肯定的&#xff0c;那么你一定不能错…

什么是云手机?云手机有什么用?

过去&#xff0c;我们手中的手机是我们生活、工作、娱乐的得力助手&#xff0c;但随着时代的变迁和技术的发展&#xff0c;我们需要的不仅仅是一部手机&#xff0c;而是一个更强大、更灵活的工具。在这个时候&#xff0c;云手机横空出世&#xff0c;成为了我们手机使用的新选择…

性能工具之 JMeter 自定义 Java Sampler 支持国密 SM2 算法

文章目录 一、前言二、加密接口1、什么是SM22、被测接口加密逻辑 三、准备工作四、JMeter 扩展实现步骤1&#xff1a;准备开发环境步骤2&#xff1a;了解实现方法步骤3&#xff1a;runTest 方法步骤4&#xff1a;getDefaultParameters 方法步骤5&#xff1a;setupTest 方法 五、…

MATLAB 向量

MATLAB 向量 向量是一维数字数组。MATLAB允许创建两种类型的向量 行向量 列向量 行向量 行向量通过将元素集括在方括号中并使用空格或逗号定界元素来创建。 示例 r [7 8 9 10 11] MATLAB将执行上述语句并返回以下结果- r 7 8 9 10 11 列向量 列向量 通过将元素集括在方…

GPU深度学习环境搭建:Win10+CUDA 11.7+Pytorch1.13.1+Anaconda3+python3.10.9

1. 查看显卡驱动及对应cuda版本关系 1.1 显卡驱动和cuda版本信息查看方法 在命令行中输入【nvidia-smi】可以当前显卡驱动版本和cuda版本。 根据显示,显卡驱动版本为:Driver Version: 516.59,CUDA 的版本为:CUDA Version 11.7。 此处我们可以根据下面的表1 显卡驱动和c…

Android Studio实现内容丰富的安卓校园超市

获取源码请点击文章末尾QQ名片联系&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动 项目代号168 1.开发环境 后端用springboot框架&#xff0c;安卓的用android studio开发 android stuido3.6 jdk1.8 idea mysql tomcat 2.功能介绍 安卓端&#xff1a; 1.注册…

# 从浅入深 学习 SpringCloud 微服务架构(六)Feign(2)

从浅入深 学习 SpringCloud 微服务架构&#xff08;六&#xff09;Feign&#xff08;2&#xff09; 一、feign 的配置&#xff1a; 1、从 Spring Cloud Edgware 开始&#xff0c;Feign 支持使用属性自定义 Feign。 对于一个指定名称的 FeignClient&#xff08;例如该 Feign …

迅雷不限速破解方法

背景&#xff1a;现在迅雷和百度云的下载速度真的太恶心了&#xff0c;所以总有大佬可以采用厉害的方法进行破解&#xff0c;在网上看了一圈&#xff0c;很多都是骗人或者是无效的&#xff0c;找了一个靠谱的方法&#xff0c;亲测速度能达到10M以上&#xff0c;非常给力。 以下…

linux部署nacos

1.预备环境准备 Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行Nacos&#xff0c;还需要为此配置 Maven环境&#xff0c;请确保是在以下版本环境中安装使用: 64 bit OS&#xff0c;支持 Linux/Unix/Mac/Windows&#xff0c;推荐选用 Linux/Unix/Mac。64 bit JDK …

私有化部署 Llama3 大模型, 支持 API 访问

私有化部署 Llama3 大模型, 支持 API 访问 视频 https://www.bilibili.com/video/BV1wD421n75p/ 前言 原文 https://ducafecat.com/blog/llama3-model-api-local 通过 ollama 本地运行 Llama3 大模型其实对我们开发来说很有意义&#xff0c;你可以私有化放服务上了。 然后通…

五、yolov8 tensorRT c++部署及接口封装(保姆级教程附源码)

采用 CTensorRT来部署深度学习模型有以下几个优点&#xff1a; 高性能推理&#xff1a;TensorRT是一个高性能的深度学习推理&#xff08;Inference&#xff09;优化器&#xff0c;专门为NVIDIA GPU硬件平台设计&#xff0c;能够提供低延迟、高吞吐量的模型推理性能。这意味着在…

12 c++版本的坦克大战

前言 呵呵 这大概是 大学里面的 c 贪吃蛇了吧 有一些 面向对象的理解, 但是不多 这里 具体的实现 就不赘述, 仅仅是 发一下代码 以及 具体的使用 坦克大战 #include<iostream> #include<windows.h> #include<conio.h> #include<ctime> #include…

深度学习基础之《TensorFlow框架(13)—二进制数据》

一、CIFAR-10二进制数据集介绍 1、CIFAR-10数据集 CIFAR-10数据集由10个类别的60000个32x32彩色图像组成&#xff0c;每个类别有6000个图像。有50000个训练图像和10000个测试图像 2、数据集分为五个训练批次和一个测试批次&#xff0c;每个批次有10000个图像 3、data_batch_…

强化SSH服务安全的最佳实践

SSH&#xff08;Secure Shell&#xff09;作为一种广泛应用于Linux和其他类Unix系统中的强大工具&#xff0c;为管理员提供了安全的远程登录和命令执行功能。在现今高度互联的网络环境中&#xff0c;确保SSH服务的安全性显得尤为重要。本文将详细阐述一系列SSH服务的最佳实践&a…

探索文本向量化的新高峰:合合信息acge_text_embedding 模型

前言 文本向量化是将文本数据转换为数值向量的过程。由于计算机只能处理数值数据&#xff0c;文本数据需要被转换成数值形式才能被算法和模型处理。这种向量化的过程使得文本数据能够被机器学习、深度学习等算法有效地处理。文本向量化的方法有多种&#xff0c;其中常见的有以…

输入influx但是无法进入influxdb

问题描述&#xff1a; 博主想通过DockerJmeterInfluxDBGrafana搭建性能测试可视化平台&#xff0c;但是按照别的教程输入influx却无法进入inluxdb&#xff0c;输入输出如下&#xff1a; NAME:influx - Influx ClientUSAGE:influx [command]HINT: If you are looking for the I…

多种方法论的融合,可以把FMEA做得更好——FMEA软件

免费试用FMEA软件-免费版-SunFMEA FMEA&#xff0c;即故障模式与影响分析&#xff0c;是一种预防性质量工具&#xff0c;用于识别产品或过程中潜在的故障模式&#xff0c;评估其对系统的影响&#xff0c;并优先处理那些可能导致严重后果的故障。在实际应用中&#xff0c;单一的…

HashMap常用的API

HashMap好用的API isEmpty()和clear() 例子 package com.example.springbootdemo;import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest;import java.util.HashMap;/*** Author yimeng* Date 2024/4/26 9:27* PackageName:com.…