Spring-MVC
Spring MVC(Model-View-Controller)是Spring框架中的一个模块,用于构建基于MVC设计模式的Web应用程序。Spring MVC将应用程序分为三个主要部分:
Model:负责处理数据和业务逻辑。
View:负责展示数据。
Controller:负责处理用户请求并返回响应。
Spring MVC通过一系列的注解(如@Controller、@RequestMapping、@RequestParam等)简化了Web应用程序的开发。
Maven
Apache Maven 是一个项目管理和构建工具,它基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建。
Maven的作用
依赖管理:方便快捷的管理项目依赖的资源(jar包),避免版本冲突问题。
统一项目结构:提供标准、统一的项目结构。
项目构建:标准跨平台(Linux、Windows、MacOS)的自动化项目构建方式。
官网:http://maven.apache.org/
引入依赖,会先查找本地仓库有没有,没有在从远程仓库查找(私服 一般是公司内部有的),没有再从中央仓库查找,再从中央仓库下载到私服,再从私服中下载到本地仓库,再从本地仓库中下载。
Maven的安装
配置Maven环境(全局)
将你所配置的路径输入进去
选择jdk的版本
Maven坐标
2023版idea创建Maven项目
依赖管理
依赖:指当前项目运行所需要的jar包,一个项目中可以引入多个依赖。
引入依赖
<dependencies>
<dependency>...</dependency>
<dependency>...</dependency>
</dependencies>
依赖传递
依赖范围
生命周期
Maven的生命周期就是为了对所有的maven项目构建过程进行抽象和统一。
在同一套生命周期中,当运行后面的阶段时,前面的阶段都会运行。
Maven高级
分模块设计与开发
分模块设计:将项目按照功能拆分成若干个子模块,方便项目的管理维护、扩展,也方便模块间的相互调用,资源共享。
分模块设计需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分
继承与聚合
继承关系实现
版本锁定
在maven中,可以在父工程的pom文件中通过 <dependencyManagement> 来统一管理依赖版本。
子工程引入依赖时,无需指定 <version> 版本号,父工程统一管理。变更依赖版本,只需在父工程中统一变更。
把所有的版本聚到一起,方便查找修改
<dependencies> 是直接依赖,在父工程配置了依赖,子工程会直接继承下来。 <dependencyManagement> 是统一管理依赖版本,不会直接依赖,还需要在子工程中引入所需依赖(无需指定版本)
聚合
聚合:将多个模块组织成一个整体,同时进行项目的构建。
聚合工程 :一个不具有业务功能的“空”工程(有且仅有一个pom文件)
作用: 快速构建项目(无需根据依赖关系手动构建,直接在聚合工程上构建即可)
聚合工程中所包含的模块,在构建时,会自动根据模块间的依赖关系设置构建顺序,与聚合工程中模块的配置书写位置无关。
私服
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,用来代理位于外部的中央仓库,用于解决团队内部的资源共享与资源同步问题。
私服在企业项目开发中,一个项目/公司,只需要一台即可(无需我们自己搭建,会使用即可)。
资源上传与下载
HTTP协议
概念:Hyper Text Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则
特点:
1、基于TCP协议:面向连接,安全
2、基于请求-响应模型的:一次请求对应一次响应
3、HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的。
缺点:多次请求间不能共享数据。
优点:速度快。
HTTP-请求协议
请求行:请求数据第一行 (请求方式、资源路径、协议)
请求头:第二行开始,格式key:value
请求体:POST请求,存放请求参数
HTTP-响应协议
响应行:响应数据第一行(协议、状态码、描述
响应头:第二行开始,格式key:value
响应体:最后一部分,存放响应数据
HTTP响应格式
HTTP-协议解析
浏览器内置了解析HTTP-协议的程序
客户端借助web服务器 进行操作,响应数据
Web 服务器
Web服务器是一个软件程序,对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷。主要功能是 "提供网上信息浏览服务" 。
web服务器
对HTTP协议操作进行封装,简化web程序开发。
部署web项目,对外提供网上信息浏览服务。
Tomcat
一个轻量级的web服务器,支持servlet、jsp等少量javaEE规范。
也被称为web容器、servlet容器。
SpringBootWeb
Spring Boot 可以帮助我们非常快速的构建应用程序、简化开发、提高效率。
创建springboot工程:
创建springboot工程,并勾选web开发相关依赖。
Springboo内嵌Tomcat服务器
起步依赖:
spring-boot-starter-web:包含了web应用开发所需要的常见依赖。
spring-boot-starter-test:包含了单元测试所需要的常见依赖。
内嵌Tomcat服务器
基于Springboot开发的web应用程序,内置了tomcat服务器,当启动类运行时,会自动启动内嵌的tomcat服务器。
注解
@SpringBootApplication
作用:这是一个组合注解,包括了@Configuration、@EnableAutoConfiguration和@ComponentScan三个注解。用于标识SpringBoot应用程序的入口类。
@Configuration:指示这个类是一个配置类,它定义了一个或多个@Bean方法,用于创建和配置Spring应用程序上下文中的Bean。
@EnableAutoConfiguration:启用Spring Boot的自动配置机制,它会自动添加所需的依赖项和配置,以使应用程序能够运行。
@ComponentScan:指示Spring Boot扫描当前包及其子包中的所有@Component、@Service、@Repository和@Controller注解的类,并将它们注册为Spring Bean。
@SpringBootApplication注解通常被用于Spring Boot应用程序的入口类上,用于启动Spring Boot应用程序。它可以简化Spring应用程序的配置和启动过程。
用例:
@RestController
@RestController
@RestController的作用等同于@Controller + @ResponseBody @Controller注解,表明了这个类是一个控制器类
@RequestMapping
@RequestMapping
@RequestParam
@RequestParam
@DateTimeFormat:完成日期参数格式转换
@DateTimeFormat
@RequestBody
@RequestBody
@PathVariable
@PathVariable
@Component
@Autowired
@ComponentScan:@ComponentScan注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解 @SpringBootApplication 中,默认扫描的范围是启动类所在包及其子包。
@SpringBootApplication具有包扫描作用,默认扫描当前包及其子包
@Component,@Controller,@Service,@Repository
请求响应
请求(HttpServletRequest):获取请求数据
响应(HttpServletResponse):设置响应数据
请求
postman:常用于后端测试
Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。
作用:常用于进行接口测试
简单参数
原始方式
// 1. 简单参数
//原始方式
@RequestMapping("/simpleParam")
public String simpleParam(HttpServletRequest request){
//获取请求参数
String name = request.getParameter("name");
String ageStr = request.getParameter("age");
int age = Integer.parseInt(ageStr);
System.out.println(name+ ":" + age);
return "OK";
}
springboot方式
简单参数:参数名与形参变量名相同,定义形参即可接收参数。
// springboot方式
@RequestMapping("/simpleParam")
public String simpleParam(String name, Integer age){
System.out.println(name+ ":" + age);
return "OK";
}
简单参数:如果方法形参名称与请求参数名称不匹配,可以使用 @RequestParam 完成映射。
@RequestMapping("/simpleParam")
public String simpleParam(@RequestParam(name = "name", required = false) String username, Integer age){
System.out.println(username+ ":" + age);
return "OK";
}
@RequestParam中的required属性默认为true,代表该请求参数必须传递,如果不传递将报错。 如果该参数是可选的,可以将required属性设置为false。
实体参数
简单实体对象:请求参数名与形参对象属性名相同,定义POJO接收即可
public class User {
private String name;
private Integer age;
}
//2. 实体参数
@RequestMapping("/simplePojo")
public String simplePojo(User user){
System.out.println(user);
return "OK";
}
复杂实体对象:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数
public class Address {
private String province;
private String city;
}
public class User {
private String name;
private Integer age;
private Address address;
}
@RequestMapping("/complexPojo")
public String complexPojo(User user){
System.out.println(user);
return "OK";
}
数组集合参数
数组参数:请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数
//3. 数组集合参数
@RequestMapping("/arrayParam")
public String arrayParam(String[] hobby){
System.out.println(Arrays.toString(hobby));
return "OK";
}
//集合来接收
@RequestMapping("/listParam")
public String listParam(@RequestParam List<String> hobby){
System.out.println(hobby);
return "OK";
}
数组:请求参数名与形参中数组变量名相同,可以直接使用数组封装
集合:请求参数名与形参中集合变量名相同,通过@RequestParam绑定参数关系
日期参数
//4. 日期时间参数
@RequestMapping("/dateParam")
public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime){
System.out.println(updateTime);
return "OK";
}
Json参数
JSON参数:JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数,需要使用 @RequestBody 标识
public class Address {
private String province;
private String city;
}
public class User {
private String name;
private Integer age;
private Address address;
}
//5. json参数
@RequestMapping("/jsonParam")
public String jsonParam(@RequestBody User user){
System.out.println(user);
return "OK";
}
路径参数
路径参数:通过请求URL直接传递参数,使用{…}来标识该路径参数,需要使用 @PathVariable 获取路径参数
//6. 路径参数
@RequestMapping("/path/{id}")
public String pathParam(@PathVariable Integer id){
System.out.println(id);
return "OK";
}
@RequestMapping("/path/{id}/{name}")
public String pathParam2(@PathVariable Integer id , @PathVariable String name){
System.out.println(id);
System.out.println(name);
return "OK";
}
响应
Result类
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 ~");
}
@RequestMapping("/getAddr")
public Result getAddr(){
Address addr = new Address();
addr.setProvince("广东");
addr.setCity("深圳");
return Result.success(addr);
}
@RequestMapping("/listAddr")
public Result listAddr(){
List<Address> list = new ArrayList<>();
Address addr = new Address();
addr.setProvince("广东");
addr.setCity("深圳");
Address addr2 = new Address();
addr2.setProvince("陕西");
addr2.setCity("西安");
list.add(addr);
list.add(addr2);
return Result.success(list);
分层解耦
三层架构
controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据。
service:业务逻辑层,处理具体事务的逻辑。
dao:数据访问层(Data Access Object)(持久层),负责数据访问操作,包括数据的增删改查。
分层解耦
内聚:软件中各个功能模块内部的功能联系。
耦合:衡量软件中各个层/模块之间的依赖、关联的程度。
软件设计原则:高内聚低耦合
控制反转: Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。(@Component)
依赖注入: Dependency Injection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。(@Autowired)
Bean对象:IOC容器中创建、管理的对象,称之为bean。
IOC & DI
IOC
①. Service层 及 Dao层的实现类,交给IOC容器管理。
②. 为Controller及Service注入运行时,依赖的对象。
③. 运行测试。
DI
MYSQL
数据库:DataBase(DB),是存储和管理数据的仓库
数据库管理系统:DataBase Management System (DBMS),操纵和管理数据库的大型软件。
SQL:Structured Query Language,操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准。
mysql连接
DDL:Data Definition Language 数据定义语言,用来定义数据库对象(数据库,表,字段)
DML: Data Manipulation Language 数据操作语言,用来对数据库表中的数据进行增删改
DQL: Data Query Language 数据查询语言,用来查询数据库中表的记录
DCL: Data Control Language 数据控制语言,用来创建数据库用户、控制数据库的访问权限
DDL
DDL(数据库操
作)
DDL(表操作)
DML
添加数据(INSERT) 修改数据(UPDATE) 删除数据(DELETE)
insert into 表名 属性 values()
update 表名 set 属性=值1... [where 条件]
修改数据:update 表名 set 字段名1 = 值1 , 字段名2 = 值2 , .... [ where 条件 ]
delete from 表名 [where 条件]
删除数据:delete from 表名 [ where 条件 ]
DQL
DQL英文全称是Data Query Language(数据查询语言),用来查询数据库表中的记录。
关键字:SELECT
where与having区别:
执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组之后对结果进行过滤。
判断条件不同:where不能对聚合函数进行判断,而having可以
分组排序:ASC:升序(默认值) DESC:降序
Mybatis
@Mapper 在运行时,mybatis框架会自动生成该接口的实现类对象(代理对象),并且将该对象交给IOC容器管理
# 配置数据库的连接信息 - 四要素
#驱动类名称
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=1234
#配置mybatis的日志 指定输出到控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
增删改
@Mapper
public interface EmpMapper {
//删除操作
@Delete("delete from emp where id=#{id} ")
public void delete(Integer id);
//增加操作
@Options(keyProperty = "id",useGeneratedKeys = true)//会自动将生成的主键值,赋值给emp对象的id属性
@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);
//更新操作
@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的驼峰命名自动映射开关 a_column----->aColumn
mybatis.configuration.map-underscore-to-camel-case=true
// @Select("select * from emp where id=#{id}")
// public Emp getById(Integer id);
// 一、给字段起别名,让别名与实体类属性一致
@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,@Results注解手动映射封装
@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);
//三、开启mybatis的驼峰命名自动映射开关----dept_id---->deptId 在环境配置中添加
@Select("select * from emp where id=#{id}")
public Emp getById(Integer id);
contat连接
@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(String name, Short gender, LocalDate begin,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);
XML映射文件
MybatisX 是一款基于 IDEA 的快速开发Mybatis的插件,为效率而生
使用Mybatis的注解,主要是来完成一些简单的增删改查功能。如果需要实现复杂的SQL功能,建议使用XML来配置映射语句。
Mybatis动态SQL
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
XML映射文件定义规范
1 XML文件的名称与Mapper接口名称一致,并且放置在相同的包下(同包同名)
2 XML文件的namespace属性为Mapper接口全限定名一致
3 XML文件中sql语句中id与Mapper接口中的方法名一致
-->
<mapper namespace="com.itheima.mapper.EmpMapper">
<!--
<sql>:定义可重用的SQL片段
<include>:通过属性refid,指定包含的sql片段
-->
<sql id="commonSelect">
select id,username,password,name,gender,image,job,entrydate,dept_id,create_time,update_time
from emp
</sql>
<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>
<!--2-->
<!--resultType:单条记录所封装的类型-->
<!--
<if>:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL
<where>:where元素只会在子元素有内容的情况下才会插入where字句。而且会自动去除子句的开头and或or
-->
<select id="list" resultType="com.itheima.pojo.Emp"><!--3-->
<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>
<!--批量删除员工 delete from emp where id in (13,14,15)-->
<!--
collection:遍历的集合
item:遍历出来的元素
sepatator:分隔符
open:遍历开始前拼接的SQL片段
close:遍历结束后拼接的SQL片段
-->
<delete id="deleteById">
delete from emp where id in
<foreach collection="list" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
</mapper>