javaweb后端部分学习

后端部分

Maven

Maven(apache旗下)是一款用于管理和构建java项目的工具,它基于项目对象模型POM(Project Object Model)的概念,通过一小段描述信息来管理项目的构建。

apache: 开源软件基金会

Maven的作用

  • 依赖管理

​ 方便快捷的管理项目依赖的资源(jar包),避免版本冲突问题

  • 项目构建

​ 标准跨平台(Linux, Windows、MacOS)的自动化项目构建方式 (清理、编译、测试、打包、发布)

  • 统一项目结构

​ 提供标准、统一的项目结构

仓库

仓库: 用于存储资源,管理各种jar包

  • 本地仓库: 自己计算机上的一个目录
  • 中央仓库: 由Maven团队维护的全球唯一的。仓库地址: https://repo1.maven.org/maven2/
  • 远程仓库(私服): 一般由公司团队搭建的私有仓库

Maven坐标

  • 什么是坐标

​ Maven中的坐标是资源的唯一标识,通过该坐标可以唯一定位资源位置。

​ 使用坐标来定义项目或引入项目中需要的依赖。

  • Maven坐标主要组成

​ groupId:定义当前Mave项目隶属组织名称(通常是域名反写, 例如: com.xtzy)

​ artifactId: 定义当前Maven项目名称(通过是模块名称,例如order-service)

​ version: 定义当前版本号

HTTP协议

概念

Hyper Text Transfer Protocol 超文本传输协议,规定了浏览器和服务器之间数据传输的规则。

特点

  1. 基于TCP协议: 面向连接,安全
  2. 基于请求-响应模型的: 一次请求对应一次响应
  3. HTTP协议是无状态的协议: 对于事务处理没有记忆能力.每次请求-响应都是独立的。
    • 缺点: 多次亲贵之间不能共享数据。
    • 优点: 速度快

多次请求没有状态,对于事务处理没有记忆能力,每次请求-响应都是单独的

HTTP-请求数据格式

image-20240113151316904

image-20240113151316904

HTTP-响应数据格式

image-20240113151316904

image-20240113151911850

常见的响应状态码

HTTP 响应状态码 - HTTP | MDN (mozilla.org)

image-20240113152336428

HTTP-协议解析

Tomcat

Web服务器:

  • 对HTTP协议操作进行封装,简化web程序开发
  • 部署web项目,对外提供网上信息浏览服务。

image-20240113154033826

请求响应

postman

Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。

作用:常用于进行接口测试

简单参数

  • 原始方式(繁琐 不推荐)

在原始的web程序中,获取请求参数,需要通过HttpServletRequest对象手动获取

  • SpringBoot方式

简单参数: 参数名与形参变量名相同,定义形参即可接收参数。

@RequestMapping("/simpleParam")
public String simpleParam(String name, Integer age){
    System.out.println(name+":" + age);
    return "0K";
}

简单参数: 如果方法形参名称与请求参数名称不匹配,可以使用@RequestParam完成映射。

@RequestMapping("/simpleParam")
public String simpleParam(@RequestParam(name ="name") String username, Integer age){
    System.out.println(username+":" + age);
    return "0K";
}

注意事项:

  • @RequestParam中的required属性默认为true,代表该请求参数必须传递,如果不传递将报错。如果该参数是可选的,可以将required属性设置为false。

报错400是浏览器的错误。

实体参数

  • 简单实体对象: 请求参数名与形参对象属性名相同.定义POJO接收即可
  • 复杂实体对象: 请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数.

数组集合参数

  • 数组参数: 请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数
@RequestMapping("/arrayParam")
public String arrayParam(String[] hobby) {
    System.out.println(Array.toString(hobby));
    return "OK";
}
  • 集合参数: 请求参数名与形参集合名称相同且请求参数为多个,@RequestParam绑定参数关系

    @RequestMapping("/listParam")
    public String listParam(@RequestParam List hobby) {
    System.out.println(hobby);
      return "OK";
    }

日期参数

  • 日期参数: 使用@DateTimeFormat注解完成日期参数格式转换
@RequestMapping("/dateParam")
public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:MM:mm:ss") LocalDateTime updateTime){
    System.out.println(updateTime);
    return "OK";
}

JSON参数

  • JSON参数: JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数,需要使用@RequestBody标识。
@RequestMapping("/jsonParam")
public String jsonParam(@RequestBody User user){
    System.out.println(user);
    return "OK";
}

路径参数

  • 路径参数; 通过请求URL直接传递参数,使用{...}来标识该路径参数,需要使用@PathVariable获取路径参数
@RequestMapping("/path/{id}")
public String pathParam(@PathVariable Integer id){
    System.out.println(id);
    return "OK";
}

@RequestMapping("/path/{id}/{name}")
public String pathParam(@PathVariable Integer id,@PathVariable String name){
    System.out.println(id + ": " + name);
    return "OK";
}

响应数据

@ResponseBody

  • 类型; 方法注解、类注解
  • 位置: Controller方法上/类上
  • 作用: 将方法返回值直接响应,如果返回值类型是实体对象/集合,将会转换为JSON格式响应
  • 说明: @RestController = @Controller + @ResponseBody;

统一管理

image-20240115084113127

Result类

package com.xtzy.pojo;
// 统一响应结果封装类
public class Result {
    private Integer code; // 1 成功 ,0 失败
    private String msg; // 提示信息
    private Object data; // 返回数据

    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) {
    }
    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 +
                '}';
    }
}

小案例

案例: 获取员工数据,返回统一响应结果,在页面渲染展示

  • 加载并解析emp.xml文件中的数据,完成数据处理,并在页面进行展示。
// emp.xml
<emps>
    <emp>
        <name>金毛狮王</name>
        <age>55</age
                        <image>https://cdn.jsdelivr.net/gh/xtzyyyyy/blogImage@main/img/qiu.jpg</image>
        <gender>1</gender>
        <!-- 1 讲师 2 班主任 3 就业指导 -->
        <job>1</job>
    </emp>

    <emp>
        <name>白眉鹰王</name>
        <age>65</age                        <image>https://cdn.jsdelivr.net/gh/xtzyyyyy/blogImage@main/img/gd1.jpg</image>
        <gender>1</gender>
        <!-- 1 讲师 2 班主任 3 就业指导 -->
        <job>1</job>
    </emp>
</emps>

分层解耦

三层架构

image-20240118144638169

拆分前后对比

image-20240118145415879

分层解耦(IOC-DI引入)

  • 内聚: 软件中各个功能模块内部的功能联系
  • 耦合: 衡量软件中各个层/模块之间的依赖、关联的程度。

image-20240118150111030

@Compont

将当前类交给IOC容器管理,成为IOC容器中的bean

@Autowired

运行时,IOC容器会提供该类型的bean对象,并赋值给该变量- 依赖注入,即默认按照类型自动装配

IOC&DI-IOC详解

Bean的声明(衍生注解)

image-20240118151659454

@RestController

@RestController = @Controller + @ResponseBody

Bean组件扫描

  • 前面声明bean的四大注解,要想生效,还需要被组件扫描注解@ComponentScan扫描。
  • @ComponentScan注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解@SpringBootApplication中,默认扫描的范围是启动类所在包及其子包。

默认扫描当前包及其子包

IOC&DI-DI详解

Bean注入

image-20240118153320756

@Resource与Autowired区别

  • @Autowired是spring框架提供的注解,而@Resource是JDK提供的注解
  • @Autowired默认是按照类型注入的.而@Resource默认是按照名称注入的

Mysql

什么是数据库?

  • 数据库: DataBase(DB),是存储和管理数据的仓库。
  • 数据库管理系统: DataBase Management System(DBMS),操纵和管理数据库的大型软件。
  • SQL: Structured Query Language,操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准。

where之后不能使用聚合函数,having可以

起始索引=(页码-1) * 展示记录数

image-20240120091242512

Mybatis

  • MyBatis是一款优秀的持久层框架,用于简化JDBC的开发
  • MyBatis本是Apache的一个开源项目IBatis,2010年这个项目由apache迁移到了google code,并且改名为Mybatis。2013年11月迁移到Github.
  • 官网:https://mybatis.org/mybatis-3/

使用Mybatis查询所有用户数据

步骤:

  1. 准备工作(插件springboot工程、数据库表user、实体类User)
  2. 引入Mybatis的相关依赖,配置Mybatis(数据库的连接信息)
  3. 编写SQL语句(注解/XML)

@Mapper

在运行时,会自动生成该接口的实现类对象(代理对象),并且将该对象交给IOC容器管理

配置SQL提示

image-20240120123202316

JDBC

Java DataBase Connectivity: 使用Java语言操作关系型数据库的一套API。

数据库连接池

  • 是一个容器,负责分配、管理数据库连接(Connection)
  • 优势: 优势复用、提升系统响应速度
  • 接口: DataSource
  • 产品: C3P0、DBCP、Druid、Hikari

lombok

  • Lombok是一个实用的java类库,能通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,并可以自动化生成日志变量,简化java开发,提高效率。

image-20240120130146784

注意事项:

  • Lombok会在编译时,自动生成对应的java代码。我们使用lombok时,还需要安装一个lombok的插件(idea自带)

Test

package com.xtzy;

import com.xtzy.mapper.EmpMapper;
import com.xtzy.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDate;
import java.time.LocalDateTime;

@SpringBootTest
class SpringbootMybatisCrudApplicationTests {

    @Autowired
    private EmpMapper empMapper;

    @Test
    public void testDelete() {
        int delete = empMapper.delete(17);
        System.out.println(delete);
    }

    @Test
    public void testInsert() {
        Emp emp = new Emp();
        emp.setUsername("Tom");
        emp.setName("汤姆");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        empMapper.insert(emp);
    }
    @Test
    public void testUpdate() {
        Emp emp = new Emp();
        emp.setId(18);
        emp.setUsername("Tom1");
        emp.setName("汤姆1");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        empMapper.update(emp);
    }

    @Test
    public void testGetById() {
        Emp emp = empMapper.getById(1);
        System.out.println(emp);
    }
}

Mybatis基础操作-删除

接口方法写在mapper文件夹下的类中。

  • SQL语句:
delete from emo where id = 17;
  • 接口方法:
@Delete("delete from emp where id = #{id}")
public int delete(Integer id);

Mybatis基础操作-删除

日志输出

  • 可以在application.properties中,打开mybatis的日志,并指定输入到控制台。
# 指定mybatis输出日志的位置,输出到控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

预编译SQL

优势:

  • 性能更高
  • 更安全(防止SQL注入)

image-20240120212722823

SQL注入

  • SQL注入是通过操作输入的数据来修改事先定义好的sql语句,以达到执行代码对服务器进行攻击的方法。
' or '1' = '1

参数占位符(面试题)

image-20240120220529147

Mybatis基础操作-新增

  • SQL语句:
insert into emp(username,  name, gender, image, job, entrydate, dept_id, create_time, update_time)
values ('Tom','汤姆','1','1.jpg',1, '2005-01-01', 1, now(), now());
  • 接口方法
@Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
" values (#{username}, #{name}, #{gender}, #{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})")
public void insert(Emp emp);

属性名要写成驼峰命名

Mybatis基础操作-新增(主键返回)

  • 描述: 在数据添加成功后,需要获取插入数据库数据的主键。如: 添加套餐数据时,还需要维护套餐菜品关系表数据。
  • 实现
@Options(keyProperty="id",useGeneatedKeys=true)
@Insert(”...“)

Mybatis基础操作-更新

  • SQL语句:
update emp set username = '', name = '', gender = '', image = '',
job = '', entrydate = '', dept_id = '', update_time = '' where  id = 1;insert into emp(username,  name, gender, image, job, entrydate, dept_id, create_time, update_time)
values ('Tom','汤姆','1','1.jpg',1, '2005-01-01', 1, now(), now());
  • 接口方法
@Update("update emp set username = #{username}, name = #{name}, gender = #{gender}, image = #{image}," +
"job = #{job}, entrydate = #{entrydate}, dept_id = #{deptId}, update_time = #{updateTime} where id = #{id};")
 public void update(Emp emp);

属性名要写成驼峰命名

Mybatis基础操作-查询(根据id查询)

  • SQL语句:
select * from emp where id = 1;
  • 接口方法
@Select("select * from emp where id = #{id}")
public Emp getById(Integer id);

数据封装

Emp(id=1, username=jinyong, password=123456, name=金庸, gender=1, image=1.jpg, job=4, entrydate=2000-01-01, deptId=null, createTime=null, updateTime=null)
  • 实体类属性名和数据库表查询返回的字段名一致,mybatis会自动封装。
  • 如果实体类属性名和 数据库表查询返回的字段名不一致,不能自动封装。

image-20240121104907195

不一致的字段导致结果为null的解决方法

// 方案一: 给字段取别名, 让别名与实体类属性一致

// 方案二: 通过@ResultMap注解, 为查询结果指定映射关系

// 方案三: 开启mybatis的驼峰命名自动映射开关 --- a_column ----> aColumn
mybatis.configuration.map-underscore-to-camel-case=true (写在application.properties中)

Mybatis基础操作-查询(条件查询)

  • SQL语句:
select * from emp where name like '%张%' and gender = 1 and entrydate between  '2010-01-01' and '2020-01-01' order by update_time desc

-- 改进(推荐)
select * from emp where name like concat('%', '张', '%') and gender = 1 and entrydate between  '2010-01-01' and '2020-01-01' order by update_time desc
  • 接口方法
@Select("select * from emp where name like '%${name}%' and gender = #{gender} and " +
"entrydate between #{begin} and #{end} order by update_time desc")
public List<Emp> list(@Param("name") String name,@Param("gender") Short gender,@Param("begin") LocalDate begin, @Param("end") LocalDate end);

-- 改进
@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(@Param("name") String name,@Param("gender") Short gender,@Param("begin") LocalDate begin, @Param("end") LocalDate end);

参数名说明

image-20240121114543019

XML映射文件

规范

  • XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)
  • XML映射文件的namespace属性为Mapper接口全限定名一致。
  • XML映射文件中SQL语句的id与Mapper接口中的方法名一致,并保持返回类型一致。

image-20240121154021739

tips: 在resources文件夹下创建多级目录要使用/

resultType: 单条记录所封装的类型

MybatisX

  • Mybatisx是一款基于IDEA的快速开发Mybatis的插件,为效率而生。

Mybatis动态SQL

随着用户的输入或外部条件的变化而变化的SQL语句,我们称为动态SQL。

< if >

用户判断条件是否成立,使用test属性进行条件判断,如果条件为true,则拼接sql。

< where >

where元素只会在子元素有内容的情况下才插入where子句。而且会自动去除子句的开头的AND或OR

< set>

用来替换set关键字,去除字段之后多余的逗号。

< foreach>

用于批量操作当中。

sql%include

  • < sql >: 定义可重用的SQL片段。
  • < include>: 通过属性refid,指定包含的sql片段

xml文件

<!-- xml 文件模板-->
<?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">
<mapper  namespace="com.xtzy.mapper.EmpMapper">
<sql id="commonSelect"> select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp </sql>
<select id="list" resultType="com.xtzy.pojo.Emp">
      <!--  select *
        from emp -->
        <include refid="commonSelect"/>
        <where>
            <if test="name != null">
            name like concat('%', #{name}, '%')
            </if>
            <if test="gender != null">
            and gender = #{gender}
            </if>
            <if test="begin != null and end != null">
            and entrydate between #{begin} and #{end}
            </if>
        </where>
        order by update_time desc
    </select>
 <!--  动态更新员工 -->
<update id="update2">
update emp
<set>
<if test="username != null">username = #{username},</if>
<if test="name != null">name = #{name},</if>
<if test="gender != null">gender = #{gender},</if>
<if test="image != null">image = #{image},</if>
<if test="job != null">job = #{job},</if>
<if test="entrydate != null">entrydate = #{entrydate},</if>
<if test="deptId != null">dept_id = #{deptId},</if>
<if test="updateTime != null">update_time = #{updateTime}</if>
</set>
where id = #{id}
</update>

<!-- 批量删除员工 (18,19,20) -->
<!-- 
        collection: 遍历的集合
        item: 遍历出来的元素
        separator: 分隔符
        open: 遍历开始前拼接的SQL片段
        close: 遍历结束后拼接的SQL片段
     -->
<delete id="deleteByIds">
delete from emp where id in
<foreach collection="ids" item="id" separator="," open="(" close=")"> #{id} </foreach>
</delete>
</mapper>
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇