第三阶段(CGB个人笔记)
关于POM.xml文件说明
1.1.1 mave坐标说明
maven的基本信息:
坐标: 1.组ID 公司域名倒写
2.项目的名称 不能重复 不能数字开头
3.项目版本
坐标作用: 1.用来管理/区分项目
2.项目的打包路径就是坐标的位置
<groupId>com.jt</groupId><artifactId>springboot_demo2_mybatis</artifactId><version>1.0-SNAPSHOT</version>
1.1.2 mave命令
常规用法:
1.配置mave环境变量
2.通过dos窗口 执行命令.几乎不用
IDEA插件方式:
- clean 清空项目编译之后的文件class(位于target目录中)
- install 将项目中的target中的class进行打包 xxx.jar包
install时会将测试类一同打包.所以需要注意代码正确性. - 跳过测试类打包
<properties><java.version>1.8</java.version><!--跳过测试类打包--><skipTests>true</skipTests></properties>
2.2.4 parent标签作用
定位:SpringBoot:作用是整合SSM,使框架使用更加简化 原则:"开箱即用" parent主要作用:1.SpringBoot在内部兼容了几乎所有的第三方框架2.SpringBoot官网已经将所有兼容的版本进行了定义 (几乎解决了版本冲突问题)以后几乎不写版本号概括:parent标签中管理其他的项目版本信息. <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.2</version><relativePath/> </parent>
2.2.5 dependency说明
<!--原则: 按需导入 --> <dependencies><dependency><groupId>org.springframework.boot</groupId><!--springboot启动项(器)在包的内部SpringBoot已经完成了项目的"整合"(配置) 用户拿来就用web导入SpringMVC--><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
2.2.6 插件说明
<!--SpringBoot项目与Maven整合的一个插件可以通过插件 执行项目打包/测试/文档生成等操作注意事项: 该插件不能省略项目发布时: java -jar xxxx.jar 报错:没有主清单信息!!!! --> <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.5.2</version></plugin></plugins> </build>
3 SpringBoot 高级用法
3.1 关于配置文件语法说明
3.1.1 properties 语法说明
数据结构: KEY-VALUE 数据类型: String类型/Number数值 语法: 1.key-value使用=号连接2.不需要添加多余的""号3.pro文件在IDEA中的编码格式UTF-8(手动可改)pro文件在被程序读取时默认采用ISO-8859-1格式,中文必定乱码4.key=value不要出现多余的空格 server.port=8090
3.1.2 YML 语法说明
数据结构 key-value 数据类型 String/Number 语法:1.key:(空格)value2.key与key之间有层级关系,注意缩进3.字符编码都采用UTF-84.可读性较pro文件 更加友好 server:port: 8090
3.2 属性赋值
说明: 如果将数据直接写死到.java文件中,如果需要修改,则重新编译打包.不方便.如何优化??
优化: 通过配置文件动态为属性赋值!!!
3.2.2 YML为属性赋值
3.2.2.1 编辑YML配置文件
说明: Spring负责管理YML文件中的数据.
3.2.2.2 Controller为属性赋值
1.@ResponseBody 可以将对象转化为JSON串 2.如果返回值为String类型,则返回本身 纠正: A.JSON串 规则:从Spring容器根据key获取数据,之后为属性赋值 语法: spel表达式 ${key} @Value("${user.day}") private String day;
3.2.3 Pro为属性赋值
YML是SpringBoot的核心配置文件, 一般用来整合其他第三方框架,如果将大量的业务数据放到YML中不符合编码规范. 所以将业务数据写到Pro配置文件中
3.2.3.2 准备pro配置文件
编辑pro配置文件
spring容器启动时,动态添加配置文件 一般需要修改字符集
关于注解赋值: 1.必须满足key-value结构2.如果属性只有一个并且是value属性,则可以省略不写3.如果还是乱码则检查IDEA pro字符集编码格式
@PropertySource(value="classpath:/person.properties",encoding="UTF-8")
3.2.4 为属性赋值意义
1.实现了.java文件与属性赋值的解耦
2.为了属性特定的业务赋值
3.SpringBoot整合第三方框架时,如果需要额外的配置文件时,常常采用上述的操作实现. 方便扩展
Redis为属性赋值操作
3.4 框架关系
3.5 Spring自动装配过程
3.5.1 Spring"容器"
说明:Spring容器是在内存中一大块的区域,存储Spring管理对象
数据结构:key-value结构
数据类型:Map集合
Map详细说明:key:类型首字母小写 Value: 对象
3.5.2 依赖注入的原理
1.按照类型注入
按照属性的类型 去Map集中中查找是否有改类型的对象. 如果有则注入.
2.按照名称注入 根据属性的name 去Map集中中查找对应的KEY
@Autowired@Qualifier(value="李四")private SpringService springService;
自动装配的规则说明:
自动装配的规则说明:
1.如果对象在进行实例化.如果对象中的属性被 @Autowired注解修饰,则说明应该先注入属性.
2.先根据属性的类型,查找Map集合中是否有该类型的对象.
3.如果根据类型查找没有找到,则根据属性的名称按照name查找对象.
4.如果上述的方式都没有找到,则报错实例化对象失败.原则:Spring容器中要求 接口必须单实现. 如果有多实现则通过@Qualifier(“xxxx”)区分即可
1. SpringBoot高级用法
1.1 Lombok插件
<!--添加lombok依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
1.1.3 Lombok使用
作用:通过程序自动生成的实体对象的get/set/toString/equals/hashCode等方法.
链式加载原理: 重启了POJO的set方法. 返回当前对象
public User setId(Integer id) {this.id = id;return this;}
常用注解:
1.1.4 关于Lombok面试问题(初级)
问题: lombok的使用需要在IDE中提前安装插件!!!,如果项目在Linux系统中部署发布.是否需要提前安装插件!!!
答案: 不要!!!
原因: lombok插件编译期有效.(编译期:由xxx.java文件编译为xxxx.class文件).在打包之前class文件中已经包含了set/get等方法,所以项目打包之后可以直接运行.无需安装插件!!!.
2. SpringBoot整合Mybatis
2.1.1 检查数据库是否可用(这个重要)
说明: 正常的情况下mysql服务项 开机自启. 有时由于某种原因 导致数据库服务启动失败.
问题描述: 数据库链接报错.显示链接不可用.
检查服务项:
2.1.3 数据库导入和导出
导出数据库: 将mysql中的数据库以 xxx.sql文件进行转储.
导入数据库: 读取xxx.sql文件 之后工具执行其中的sql,最终实现数据的导入功能.
说明: 上述的操作称之为数据库冷备份. 一般在生产环境下 为了保证数据的安全.一般都会定期冷备份.(周期3-7天左右) 一般一式3份. 数据库的冷备份是恢复数据最后有效的手段.
特点: 冷备份容易丢失数据. 热备份可以实现实时备份.
2 SpringBoot整合Mybatis
2.2.3 编辑POJO实体对象
说明: 一般实体对象只需要添加get/set/toString等方法,无需添加构造方法.
2.2.4 序列化作用
一般如果需要对象进行传递时,要求POJO对象必须实现序列化接口.否则数据传输必然报错.
2.2 整合Mybatis
2.2.0 SpringBoot整合Mybatis步骤
- 添加jar包文件依赖
- SpringBoot整合Mybatis 添加配置文件 1.连接数据库 2.SpringBoot整合Mybatis
- 创建Mapper接口
- 创建XML映射文件.
2.2.1 导入jar包文件
- mybatis包
- 数据库驱动包
- JDBC包
<!--定位: SpringBoot主要的作用整合SSM,使得框架的使用更加简化原则: "开箱即用"parent主要的作用:1.SpringBoot在内部兼容了当下几乎所有的第三方框架2.SpringBoot官网已经将所有兼容的版本进行了定义(几乎解决了版本冲突问题)以后几乎不写版本号概括: parent标签中管理其他的项目版本信息.--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.2</version><relativePath/></parent><properties><java.version>1.8</java.version><!--跳过测试类打包--><skipTests>true</skipTests></properties><!--原则: 按需导入 --><dependencies><dependency><groupId>org.springframework.boot</groupId><!--springboot启动项(器)在包的内部SpringBoot已经完成了项目的"整合"(配置) 用户拿来就用web导入SpringMVC--><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--支持热部署 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><!--添加lombok依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--引入数据库驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--springBoot数据库连接 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!--spring整合mybatis 暂时 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version></dependency></dependencies><!--SpringBoot项目与Maven整合的一个插件可以通过插件 执行项目打包/测试/文档生成等操作注意事项: 该插件不能省略项目发布时: java -jar xxxx.jar 报错:没有主清单信息!!!!--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.5.2</version></plugin></plugins></build>
2.2.2 关于数据源配置
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=trueusername: rootpassword: root
serverTimezone=GMT%2B8& %2B= + GMT+8&
useUnicode=true&characterEncoding=utf8& 是否使用unicode编码及设定字符集
autoReconnect=true 是否自动重连
allowMultiQueries=true 是否允许批量操作
2.2.3 Mybatis配置文件
server:port: 8090spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=trueusername: rootpassword: root#如果数据库密码以数字0开头 则必须使用""号包裹#password: "01234"#SpringBoot整合Mybatis配置
mybatis:type-aliases-package: com.jt.pojomapper-locations: classpath:/mybatis/*.xml#开启驼峰映射configuration:map-underscore-to-camel-case: true
2.2.4 编辑UserMapper接口/映射文件
1.编辑UserMapper接口
2.编辑UserMapper.xml映射文件
1.<!--规则: namespace必须与接口一一对应 -->
<mapper namespace="com.jt.mapper.UserMapper"> 包名字加类名
驼峰命名规则:
表字段: user_id,user_name
对象的属性: userId,userName
resultType: 保证属性与字段名称必须一致.
Mybatis提供了驼峰命名规则:
规则: 字
段user_id~~~去除_线~~~之后映射对象的属性
userId
2.3.1 项目结构配置
说明: 编辑maven项目时,会有源文件/资源文件/测试文件. 可以通过IDEA提供选项手动的配置
2.3.2 Spring容器管理Mapper接口
说明: 利用@mapperScan注解为接口创建代理对象
@SpringBootApplication
@MapperScan("com.jt.mapper") Spring容器内部为接口创建代理对象JDK的动态代理对象
public class SpringBootRun {//标准写法public static void main(String[] args) {SpringApplication.run(SpringBootRun.class, args);}
}
2.3.3 编辑测试案例
要求: 1.测试包路径必须在主启动类的同包及子包中. 2.从Spring容器中可以获取对象进行调用.
@SpringBootTest
类名上
调用mapper service controller!!单元测试~~
@Autowired 依赖注入(代理对象)
private UserMapper userMapper;
@Test 自定义注解
public void testGetAll(){
System.out.println(userMapper.getClass());
List<User> userList = userMapper.getAll();
System.out.println(userList);
}
1. SpringBoot整合Mybatis说明
1.1 Mybatis介绍
概括: MyBatis 是一款优秀的持久层框架,并且在内部整合的了JDBC,简化了用户操作数据库的过程.
Mybatis是一个半自动化的ORM映射框架
1.2 ORM思想
对象关系映射(英语:Object Relational Mapping,简称ORM)
用来实现面向对象编程语言不同类型系统的数据之间的转换
核心知识:
宗旨: 以对象的方式操作数据库
1. 要求查询的结果集可以自动的封装为对象 (读)
2. 利用对象封装数据,之后(自动)动态的生成Sql语句执行相关操作. (更新)
1.3 SpringBoot整合Mybatis流程
- 导入依赖jar包 数据库驱动/JDBC包/Spring整合Mybatis包
- 编辑application.yml文件 配置数据源/配置Spring整合Mybatis
- 编辑Mybatis 接口文件/编辑xxx.xml映射文件
- 通过@MapperScan为接口创建代理对象.
1.4 @SpringBootTest
说明: 该注解是SpringBoot程序 为了简化后端代码测试 提供了专门的测试API.
关键点: 测试时需要Spring容器管理对象,同时将测试的对象获取 之后进行测试.
注意事项: 测试注解只能在测试包中运行.
1.5 Mybatis调用流程
Spring容器为接口创建代理对象. Spring容器启动对象立即创建
根据 @Autowired 注解动态注入Mapper接口的代理对象
用户通过Mapper接口调用方法.(执行业务操作)
Mybatis根据接口方法动态匹配xml的映射文件
1.根据Mapper的接口路径匹配xml映射文件中的 com.jt.mapper.UserMapper
2.根据接口的方法 匹配xml映射文件中的Sql ID 之后执行Sql语句
5.Mybatis将结果集封装为对象 之后返回.
1.6 关于Mybatis-statement异常说明
1.更换xml映射文件
2. 更换YML文件
3. 由于IDEA缓存导致Mybatis链接异常.
2. MybatisPlus
2.1 MP介绍
2.1.1 什么是MP
2.1.1 什么是MP(了解即可)
MP核心思想:
利用对象操作数据库,单表查询几乎不写SQL
2.2.1 导入jar包
说明:MybatisPlus对Mybatis的增强(包含),所有jar包只需要导入MP的即可.原有的Mybatis需要删除.
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.2</version><relativePath/></parent><properties><java.version>1.8</java.version><!--跳过测试类打包--><skipTests>true</skipTests></properties><!--原则: 按需导入 --><dependencies><dependency><groupId>org.springframework.boot</groupId><!--springboot启动项(器)在包的内部SpringBoot已经完成了项目的"整合"(配置) 用户拿来就用web导入SpringMVC--><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--支持热部署 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><!--添加lombok依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--引入数据库驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--springBoot数据库连接 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!--导入MP包之后,删除原有的Mybatis的包 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.5.2</version></plugin></plugins></build>
2.2.2 配置对象关系映射
2.2.3 继承公共API接口
2.2.4 编辑YML配置文件
工具API测试
新增用户
Mybatis: 1.mapper接口 2.xml映射 Sql
MP: 调用接口方法
@Test
public void testInsert(){
User user = new User();
user.setName("吴亦凡").setAge(30).setSex("男");
//单表操作几乎不写Sql
userMapper.insert(user);
2.2.6 打印日志
server:port: 8090spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=trueusername: rootpassword: root#SpringBoot整合MP
mybatis-plus:type-aliases-package: com.jt.pojomapper-locations: classpath:/mybatis/*.xmlconfiguration:map-underscore-to-camel-case: true# Mapper接口执行 打印Sql日志
logging:level:com.jt.mapper: debug
2.3 MP实现原理
用户执行User对象入库操作 userMapper.insert(user);
由于接口方法中需要传递泛型对象,则根据用户配置查找对应的泛型对象
根据用户的接口获取Mapper接口的父级接口BaseMapper,根据BaseMapper中的泛型对象 获取信息User.class类型
根据User.class 动态获取@TableName(“demo_user”) 获取对象对应的表名.之后通过@TableField(“name”)绑定与之对应的字段. 至此对象与表完成了映射.
根据上述的映射关系,动态的拼接Sql语句.
例子: userMapper.insert(user对象) 如何转化Sql?
**insert into 表名(字段名…) values (属性值…)
insert into demo_user(id,name,age,sex) values (“吴xx”,xx,xx,xx)
**
MP将动态生成的Sql交给Mybatis执行最终实现数据入库操作!!!
2.4 MP用法
2.4.1 根据ID查询数据
MP:用对象操作数据库.
学习:代码结构
根据Id=1查询数据. ID=主键
User user = userMapper.selectById(1)
2.4.2 条件构造器-对象封装
2.4.3 条件构造器-特殊字符查询
2.4.4 条件构造器-like关键字
2.4.5 条件构造器-orderBy
2.4.6 条件构造器-in关键字
案例6: 查询Id=1,3,5,6,7的数据 关键字: 单表查询 in or 效率相差不大 多表查询时 建议使用 or 性能更快
可变参数类型:
1.可变参数类型 数据结构实质是一个数组.
2.定义可变参数类型时,必须位于方法参数的最后一位!
void addUser(Integer age,Integer... ids);
void addUser(Integer age,Integer[] ids);
1.方法1 条件构造器
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.in("age","1,3,5,6,7");
List<User> userList1 = userMapper.selectList(queryWrapper);
// 2.MP 特殊方法调用 以后尽可能使用对象类型(对象有方法)
Integer[] ids = new Integer[]{1,2,3,4,5,6};
List idList = Arrays.asList(ids);
List<User> userList2 = userMapper.selectBatchIds(idList)
2.4.7 条件构造器-动态Sql
案例7: 根据 name/sex 动态查询数据库
解析: 如果name/sex有值则动态拼接where条件.
否则不写where条件.
动态Sql实现: condition 参数
布尔类型值 true: 拼接where条件
false: 不拼接where条件
字符串判断API:
StringUtils.hasLength(name);
@Testpublic void testSelectNS(){String name = null;String sex = "";QueryWrapper<User> queryWrapper = new QueryWrapper();//判断是否有值boolean nameFlag = StringUtils.hasLength(name);boolean sexFlag = StringUtils.hasLength(sex);queryWrapper.eq(nameFlag,"name",name).eq(sexFlag,"sex",sex);List userList = userMapper.selectList(queryWrapper);System.out.println(userList);
1.搭建后端完成结构
1.1 后端结构说明
1.1.1 后端作用
- 接送前端发送的数据.(接收) SpringMVC Controller
- 按照用户的业务需求处理数据(处理) Spring Service
- 将处理之后的结果,按照特定的要求 返回给用户(返回) SpringMVC Controller
1.1.2 代码结构
1.1.3 后端测试要求
要求:接收URL请求地址,之后JSON数据返回.
URL: http://localhost:8090/getAll
要求利用MP的方式查询数据库.
1.SpringMVC C层接收请求给出响应
标识Controller类 交给Spring容器管理/返回JSON数据
@RestController(接收请求)
需求: 查询全部用户信息
URL: /getAll
返回值: List<User>
@RequestMapping("/getAll")绝对路径,唯一标签
public List<User> getAll(){
return userService.getAll();
1.1.5 编辑UserService
Spring层处理业务数据 (接口类,实现类)
@Service (Spring层用Service) 实现类
@Autowired //JDK动态代理对象 (DI依赖注入)
private UserMapper userMapper;
2.前后端业务调用
2.1 前后端调用流程
2.2.2 编辑前端页面
需求: 前端准备一个表格,之后在表格中展现后端查询的所有数据.
知识点:
1.html css
2.jQuery 知识
3.Ajax $.ajax({…})
4.了解JS的处理基本用法. VUE
html页面:
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>用户列表demo</title></head><body><table border="1px" align="center" width="80%"><tr><td colspan="4" align="center"><h1>用户列表</h1></td></tr><tr><td align="center">编号</td><td align="center">姓名</td><td align="center">年龄</td><td align="center">性别</td></tr><tr><td align="center">100</td><td align="center">黑熊精</td><td align="center">3000</td><td align="center">男</td></tr><h1>作用:获取后端数据 之后也页面展现</h1></table></body>
</html>
2.3 关于JSON结构
2.3.1 什么是JSON
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
2.3.2 Object格式
{ "id": 100, "name":"tomcat", "age":18}
2.3.2 Array格式
[100, "张三", "李四"]
2.3.3 嵌套结构
案例:
[{"id":15,"name":"小猫猫"},
{"id":24,"name":"张修雨",
"color":["白丝袜","黑丝袜","小姐姐","小猫咪"],
"丝袜":[{ "name":"卡其色丝袜","level":"完美"},
{ "name":"玫瑰色丝袜","level":"高级" }
]
}
]
2.4 关于Ajax
2.4.1 Ajax介绍
Ajax即Asynchronous Javascript And XML(异步JavaScript和XML 使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作。
特点:
1. 局部刷新
2. 异步访问
2.4.2 Ajax为什么可以异步
同步:
当用户发起请求时,后端没有返回数据,此时用户页面就无法展现.一直是加载中的状态(整个页面同时刷新)
异步的原因:有Ajax引擎
步骤:
1. 用户将请求发送给Ajax引擎. 之后JS继续向下执行.
2. Ajax引擎接收用户请求之后,通过代理的方式访问后端服务器.
3. 后端服务器接收请求之后,执行业务操作,最终将响应的结果返回值代理服务器(Ajax引擎)
4. 引擎通过回调函数的方式返回给用户数据.
2.4.3 jQuery下载
网址: https://jquery.com/
2.5 jQuery前后端调用
2.5.1 JS中循环写法
基础循环写法//JS可以将接收的JSON串动态转化为JS对象$.get(url,function(data){//循环遍历返回值for(var i=0; i<data.length;i++){console.log(data[i])}})in关键字
//JS可以将接收的JSON串动态转化为JS对象
$.get(url,function(data){//循环遍历返回值//in 遍历数组下标for(index in data){//从0开始console.log(data[index])}
})of 关键字
//JS可以将接收的JSON串动态转化为JS对象$.get(url,function(data){//循环遍历返回值//of 关键字 直接获取遍历对象for(user of data){console.log(user)}})
2.5.2 模版字符串
说明: 模版字符串语法从ES5以后提供的
语法: 反引号
特点:
1. 被反引号包裹的都是字符串 可以随意换行 可以保留代码结构.
2. 可以动态的从对象中获取数据 语法: ${对象.属性}
用法:
for(user of data){//获取数据信息var tr = `<tr align="center"><td>${user.id}</td><td>${user.name}</td><td>${user.age}</td><td>${user.sex}</td></tr>`//将tr标签追加到表格中$("#tab1").append(tr)}
2.5.3 Ajax获取远程数据
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>用户列表demo</title><!-- html是一种解释执行的语言 --><!-- 导入JS函数类库 --><script src="jquery-3.6.0.min.js"></script><script>//让页面加载完成之后,再次调用//编程方式: 函数式编程$(function(){/*** 常见Ajax写法:* 1.$.ajax({})* 2.$.get() get类型* 3.$.post()* 4.$.getJSON()*//*** 语法说明:* $.get(url,data,function(data){},dataType)* 参数说明:* 1.url: 请求服务器的网址* 2.data: 前端向服务器传递的参数 字符串* 3.回调函数: 请求成功之后开始回调* 4.dataType: 返回值结果的数据类型. 可以省略自动判断* */var url = "http://localhost:8090/getAll"/*** 关于data语法: id=100 name="tom"* 写法: 25上课!!!!* 1.JS对象写法* {id:100,name:"tom"}* 2.字符串拼接* id=100&name=tom*///var data = "id=100&name=tom"var data = {id:100,name:"tom"}//JS可以将接收的JSON串动态转化为JS对象$.get(url,function(data){//循环遍历返回值//of 关键字 直接获取遍历对象for(user of data){//获取数据信息var tr = `<tr align="center"><td>${user.id}</td><td>${user.name}</td><td>${user.age}</td><td>${user.sex}</td></tr>`//将tr标签追加到表格中$("#tab1").append(tr)}})})/*** 传统Ajax 功能强大*/$.ajax({url: "http://localhost:8090/getAll",type: "get",data: {id:100,name:"tomcat"},success: function(data){console.log(data)},error: function(data){//浏览器的返回值console.log(data)},async: true //默认为true 异步 false 同步调用})/* 1. 基本循环for(var i=0; i<data.length;i++){console.log(data[i])}2.in 关键字for(index in data){console.log(data[index])}*/</script></head><body><table id="tab1" border="1px" align="center" width="80%"><tr><td colspan="4" align="center"><h1>用户列表</h1></td></tr><tr><td align="center">编号</td><td align="center">姓名</td><td align="center">年龄</td><td align="center">性别</td></tr><!-- <tr><td align="center">100</td><td align="center">黑熊精</td><td align="center">3000</td><td align="center">男</td></tr> --></table></body>
</html>
1. Vue JS
1.1 VUE介绍
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
1.2 Vue优点
1).体积小 压缩后的文件只有33k
2).运行效率更高 采用虚拟机DOM,一种可以预先通过javaScript对数据进行计算.把最终的DOM操作计算出来并且优化的技术. 由于这个DOM操作属于预处理操作,并没有真实的操作DOM ,所以叫做虚拟DOM
3).双向数据绑定 让开发者不再去操作DOM,将更多的经历投入到业务中
4).生态丰富 市面上有大量的开源项目基于vue 进行开发 成熟稳定.
1.2 VUE组件说明
1.3 VUE基本语法
步骤:
1.导入vue.js文件 html下部编辑
2.指定区域进行渲染 需要准备div vue.js代码
3.创建VUE.js对象 指定渲染区域 动态调用
在div中展现msg属性 插值表达式: {{key}}
语法:
1.const 定义常量的
2.let: 作用和var类似, 有作用域的概念
3.var 特点:没有作用域
1.指定区域 el: "#app",
2.定义属性 data: { //key:value
1.4 数据显示
命令: v-text/v-html/v-once/v-pre 指令
特点: 如果页面没有渲染完成,则直接展现给用户 插值表达式需要直接显示
注意事项: 只有显示时采用,输入操作不可使用
1.v-text指令: 如果页面没有渲染完成,则不显示信息
2.v-html 直接渲染html标签
3.v-pre 跳过预编译 显示标签体本身
4.v-once 只渲染一次
1.5 双向数据绑定
1.5.1 双向数据绑定代码
双向数据绑定: 实现了页面与数据的绑定. 页面变数据变 / 数据变页面变.
双向数据绑定 v-model
1.数据端---页面
2.页面-----数据
<input name="msg" v-model="msg"/><br>
{{msg}}
1.5.2 MVVM设计思想
知识回顾: MVC模式 核心思想 减少代码的耦合性
M Model:封装的数据
V View 视图层: 数据的展现
C Contro 控制层 程序的流转的过程
衍生: 3层代码的结构 Controller—Service–Mapper/Dao
针对于: 后端服务器.
MVVM思想说明:
M: Model 封装的数据. 数据层
V: View 数据的展现 视图层
VM: viewModel视图数据的控制层 控制数据流转
MVVM设计思想是前端模拟后端为了解耦的一种设计思想.
1.5.3 双向数据绑定原理
原理步骤:
1.用户修改页面时,通过DOM的监听器感知用户的修改行为,之后通过虚拟DOM对象,第一时间更新Model中的属性.
2.当数据发生变化,由虚拟DOM根据数据绑定的规则,第一事件通知真实的DOM对象.至此页面数据发生变化.
1.6 事件绑定
语法:
v-on:click="函数/直接进行计算"
1.7 按键触发机制
语法: 1.v-on:keydown="" 按下触发2.v-on:keyup="" 弹起来触发3.v-on:keypress="" 小键盘触发按键支持:.enter .tab.delete (捕获“删除”和“退格”键).esc .space.up .down .left .rightaddNum(){//this.num = this.num + this.num2//将字符串转化为数值类型this.num += parseInt(this.num2)
1.9 按键修饰符
1.9.1 阻止冒泡 .stop
难点: 元素可能需要嵌套,事件可能嵌套
说明: 如果事件嵌套则必然带来事件的冒泡.
解决方案: 阻止事件冒泡 .stop属性
1.9.2 阻止默认行为 .prevent
a标签作用中的href的跳转是默认规则
要求: 用户点击a标签 不跳转页面,同时触发事件
解决: 阻止标签的默认行为 @click.prevent
用途: prevent阻止页面跳转 a标签/form表单 action同步请求
2 SpringMVC 参数取值详情说明
2.0 Servlet:
Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器
总结: Servlet是java与前端页面进行数据交互的一种机制
核心对象:
1. request对象 封装用户请求的参数/请求头/请求全部内容
2. response对象 封装用户响应信息
2.1 Servlet获取参数规则(很重要)
/*** 注意事项: 如果后端服务器没有匹配的方法,也会报跨域错误.* URL:http://localhost:8090/getUserById?id=1&age=18* 参数: id=1* 返回值: User对象* servlet特点:* 1.获取的数据都是String类型*/@GetMapping("/getUserById")public User getUserById(Integer id){//1.SpringMVC框架通过Servlet中request对象,根据参数名称获取值// String id = request.getParameter("age");//2.SpringMVC根据已知的数据类型 自动的实现数据转化return null;}/*@GetMapping("/getUserById")public User getUserById(HttpServletRequest request,HttpServletResponse response){//1.参数获取 每个参数都需要手动获取String id = request.getParameter("id");String age = request.getParameter("age");//2.数据类型转化int intId = Integer.parseInt(id);System.out.println("根据ID查询数据库~~~~~");return null;}*/
2.1 对象方式
2.1.1 页面对象封装
2.1.2 后端参数接收问题(很重要)
/*** URL: http://localhost:8090/getUserByUser* 参数: user对象的数据* 返回值: User*/@GetMapping("/getUserByUser")public User getUserByUser(User user){//1.SpringMVC如果解析到参数是对象 先获取其中的Get方法// getId()/getName()......//2.将方法get去除首字母小写~~~id1111/name/age/sex//3.实例化一个User对象之后调用setxxx()方法实现赋值//4.最终方法中获取一个实例化的User对象//String id = request.getParameter("id");return user;}
8.1 属性绑定
8.2 分支结构
用法: 如果数据为真则展现html标签
语法: v-if/v-else-if/v-else
要求: v-if可以单独使用
另外2个必须与v-if连用
8.3 循环结构
8.4 表单操作
8.5 计算属性
总结: 计算属性相对于方法 效率高(从虚拟DOM中直接获取结果)
8.6 数组操作
push() 在结尾追加元素
pop() 删除最后一个元素
shift() 删除第一个元素
unshift() 在开头追加元素
splice() 替换数组中的数据 !!!!
sort() 数据排序
reverse() 数组反转
8.7 VUE生命周期(难点!!)
生命周期函数的作用:
如果需要对VUE对象中的数据进行额外的操作.则使用生命周期函数.
目的: 框架的扩展性更好.(实现定制化)
1.2 SpringMVC 参数传递方式
1.2.1 简单的参数传递
1.2.2 对象的方式传递
1.2.3 RestFul风格
特点:
1. 参数需要使用/ 进行分割
2. 参数的位置是固定的.
3. restFul请求方法路径不能出现动词
1.2.3 RestFul风格-简单参数接收
1.2.4 RestFul风格-对象参数接收
restFul的优化:如果{参数名称}与对象中的属性名称一致,则SpringMVC动态的为对象赋值,@PathVariable 可以省略注意事项:前后端的参数的传递必须保持一致!!!!
2. Axios学习
2.1 Axios介绍
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
特点:
1.从浏览器中创建 XMLHttpRequests
2.从 node.js 创建 http 请求
3.支持 Promise API
4.拦截请求和响应
5.转换请求数据和响应数据
6.取消请求
7.自动转换 JSON 数据
8.客户端支持防御 XSRF
结构说明:
1. JS中原生提供了Ajax操作. 弊端: 操作特别的复杂 易用性较差.
2. jQuery中的Ajax 封装了原生的JS Ajax 提高了开发的效率
3. Axios是VUE中默认支持的Ajax的请求的方式.
** 特点: 调用简洁 解决了 “回调地狱问题”!!!**
2.2 回调地狱问题(了解)
说明: 前端中如果需要发起大量的Ajax请求,并且Ajax 请求有嵌套的关系.则可能引发回调地狱问题.
例子: 请求 参数A --1–结果B/参数B—2–结果C/参数C—3--- 结果D
课下了解: 什么是回调地狱!!!
2.3.2 Axios调用步骤
- 导入Axios的JS文件
- 发起Ajax请求
- 解析返回值
注意事项:
1.Axios将原来的嵌套的结构,改为链式加载方式
2.回调函数中的data,不是服务器的返回值,是promise对象
promise对象说明: 其中data表示服务器的返回值.
2.4 Axios-Get-简单参数
2.4.1 前端Ajax请求
GET请求-简单参数的写法
then(): 回调函数通过then返回 结构
axios.get("http://localhost:8090/axios/getUserById?id=100").then(function(result){console.log(result.data)})
2.4.2 后端Controller
2.5 Axios-Get-resultFul结构
2.5.1 前端Ajax请求
/*** restFul风格实现业务传参 * 需求: 根据name/age查询数据* URL: http://localhost:8090/axios/user/tomcat/18* 注意: 模版字符串优化参数 ``*/let name = "mysql"let age = 20axios.get(`http://localhost:8090/axios/user/${name}/${age}`).then(function(result){console.log(result.data)})
2.5.2 编辑后端Controller
2.6 Axios-Get-对象传参(重要!!!)
2.6.0 F12的说明
一般用来检查网络的请求 使用network 其中不要添加缓存, 检查所有的请求的路径
2.6.1 需求说明
如果用户查询数据 其中包含了多个参数,可以使用restFul风格(少量参数)/可以使用对象封装(多个参数)
如果参数较多则建议使用对象的方式封装.
案例: 查询name=“mysql” age=18 sex="女"的用户 要求使用对象的方式封装参数
2.6.2 编辑前端Ajax
语法: axios.get("url","参数").then(回调函数)
如果多个属性,可以封装属性.
let user = {name: "mysql",age: 18,sex: "女"}
结构: key: value key固定写法 params 参数对象
axios.get("http://localhost:8090/axios/user/getUserObj",{params: user}).then(function(result){console.log(result.data)})
2.6.3 编辑后端Controller
2.7 Axios-Delete请求
2.7.1 Delete请求说明
一般用户通过Delete请求做删除操作. 删除的语法与Get请求的语法一致的.
2.7.2 Delete请求方式说明 了解delete代码结构
1.不带参数的删除
axios.delete(“url地址”).then(function(result){ … })2.携带个别参数 ?id=100
axios.delete(“url地址?id=100”).then(function(result){ … })3.restFul结构
可以使用模版字符串的方式简化代码结构
axios.delete( "url地址/xxx/xxx/xxx").then(function(result){ … })4.采用对象的方式进行参数传递
let 对象 = {xxxx:xxxx,xxxx:xxxx}
axios.delete( "url地址/xxx/xxx/xxx", {params: 封装后的对象}).then(function(result){ … })
2.8 Axios-post请求
2.8.1 编辑页面Ajax
1.什么时候使用post请求???? 答:一般采用form表单提交时,采用post请求类型主要用于数据的新增操作2.get请求/post请求主要的区别get: 参数动态的拼接到URL地址中 ?id=xx&name=xxx 数据是可见的post: 一般采用post请求数据是涉密的
总结:
如果需要对象传参
1.get请求采用 axios.get(url,{params: 对象})
2.post请求 axios.post(url,对象)
2.8.2 参数的数据结构
说明: 如果采用post的方式传递对象,则数据结构是一个JSON
2.8.3 编辑后端Controller
2.9关于前后端调用细节说明
2.9.1 请求类型
请求的类型是由程序员手动控制
- 分类A
1.get 请求类型 查询
2.delete 请求类型 删除- 分类B
1.post 请求类型 form表单提交 新增操作
2.put 请求类型 更新操作
2.9.2 关于POST请求说明
浏览器解析数据结构:
说明: 数据在进行参数传递时 数据需要转化
2.9.3 jQuery中的post请求/Axios中的post请求对比/restFul格式
Axios中的Post请求格式
如果传递的数据是JSON串 ,则在后端采用@RequestBody注解 实现JSON串转化为对象
- jQuery中的post请求格式
如果采用form表单的方式提交,则可以直接采用对象的方式接收
name=xxx&age=xx&sex=xx
3. restFul的格式是将参数拼接到URL中 采用特殊的方式获取数据
2.10 Axios-post-restFul结构
2.11 async-await用法-箭头函数(变态!!!)
2.11.1 概念解释
1.async/await 是ES7引入的新语法 可以更加方便的进行异步操作
2.async 关键字用在函数上. 返回值是一个promise对象
3.await 关键字用在async 函数中
2.11.2 箭头函数
axios的get请求语法 知识点:
1.箭头函数 主要简化回调函数的写法 思路: 重复的 固定的可以简化
规则: 如果参数只有一个则括号可以省略
let url = "http://localhost:8090/axios/getUserById?id=100"axios.get(url).then( result => {alert(result.data)})
2.11.3 async-await 操作
axios的get请求语法知识点:1.箭头函数 主要简化回调函数的写法思路: 重复的 固定的可以简化规则: 如果参数只有一个则括号可以省略2.async-await简化 解构赋值2.1 async 需要标识函数2.2 await 需要标识ajax请求上述的操作可以将多行js 封装为一行执行 简化代码操作
2.11.4 Axios配置信息
说明: 可以通过下列的配置简化 Ajax请求的路径
//配置基本请求路径axios.defaults.baseURL = "http://localhost:8080/"
1.1 Axios案例
1.1.1 Ajax发展史
1. Axios 主要封装了promise对象. 将调用变得更加的简化. 整合VUE.js中大部分条件下都整合axios 发起ajax请求.
1.1.2 请求的类型
http常用的请求类型 8种 但是一般四种需要单独的记忆.
查询操作时 GET请求类型 特点: 参数结构key=value URL?key=value&key2=value2
新增(form表单) POST请求类型 特点: 会将参数封装到请求头中 相对更加的安全 key=value key2=value2 可以直接采用对象的方式接收.
Axios中的post 参数是一个JSON串 {key1:vallue1, key2:value2} 将JSON串转化为对象 @RequestBody
删除操作 DELETE请求类型 特点:与GET请求类型 一致的.
更新操作 PUT请求类型 特点: 与POST请求类型一致的.
RestFul风格: 在上述的四大请求类型中都可以使用(单独的体系) 参数使用/分割 注意参数结构 灵活选用.
1.2 Axios-删除数据
请求方式说明:
1.2.2 编辑Controller方法
1.2.3 编辑Service方法
1.3 Axios作业-修改数据
1.3.1 业务说明
- 准备修改的DIV 其中包含4部分数据. name/age/sex where id!!!
- 当用户点击修改按钮时,应该实现数据的回显.
- 当用户已经修改完成之后,需要点击提交按钮时 应该发起ajax请求实现数据修改操作.
注意事项:
在vue.js中看到了INPUT框, 则表示双向数据绑定. 必须在data中定义属性.
请求参数详情信息:
2 组件化思想
说明: 传统的页面开发,会将大量的HTML/CSS/JS进行引入,但是引入之后结构混乱 不便于管理. 开发维护时 成本较高.
组件化思想:
在VUE中 可以将一个组件,看作是一个页面. 在其中可以引入独立的样式/JS/HTML 进行单独的管理.
组件可以进行复用.
关键字: 组件–页面 (html/css/js)
2.组件化步骤:
1.定义组件
全局组件: 任意的DIV都可以引入该组件
局部组件: 只有特定的DIV可以引入组件
2. 编辑组件的key(注意驼峰规则的写法)
编辑组件体 特殊语法: 定义属性时 data(){return{ key:value}}
html标签: 使用template进行标记
3.通过key对组件进行引用.
注意:
1.组件标签的使用 放到app标签之内 才能解析2.如果采用驼峰规则命令则中间使用-线连接
定义组件的模版html 注意事项:
1.切记标识在app之外!!!!
2.要求模版字符串必须有根标签 div
Vue.component("helloCom",{//定义属性 必须添加return 返回值data() {return {msg: "我是一个组件"}},template: "#helloTem"})
2.2.3 key-value 简化写法
3. VUE中的路由
说明: 用户发起一个请求,在互联网中经过多个站点的跳转.最终获取服务器端的数据. 把互联网中网络的链路称之为路由. (网络用语)
VUE中的路由: 根据用户的请求URL地址,展现特定的组件(页面)信息. (控制用户程序跳转过程)
3.2 路由步骤
- 导入路由.JS
- 指定路由的跳转链接
- 定义路由的填充位.
** 4. 封装组件信息, 指定路由对象 (难!!!)** - 在VUE对象中声明路由
1.导入路由JS 先导入vue.js 再导入路由.js 顺序问题
二:定义链接 1.router-link 被编译之后转化为a标签
2.关键字 to 被编译之后转化为href属性
三: 指定路由的填充位置 未来展现组件信息 填充的位置被解析之后 就是一个DIV
<router-view></router-view>
定义组件的标签体
<template id="userTem"><div><h3>用户信息</h3></div></template>
定义路由对象 routes: 路由的多个映射通过该属性进行定义.
let vueRouter = new VueRouter({routes: [{path: "/user", component: userCom},{path: "/dog", component: dogCom}]})
//实现路由的挂载
router: vueRouter
3.4 重定向和转发
注意事项: 请求和转发都是服务器行为 不会做额外的操作
说明: 用户访问服务器,但是目标服务器无法处理该请求,由服务器内部将请求交给其他服务器处理. 这个过程称之为转发.
3.4.2 重定向问题
说明: 用户访问服务器,但是目标服务器无法处理该请求,目标服务器返回一个能够处理请求的网址.由用户再次发起请求,访问服务器获取数据.
3.4 路由关键字
redirect 路由的重定向
需求: 要求用户访问 "/"根目录 要求重定向到 "/user"请求路径中.
1.1 路由嵌套规则
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>路由入门案例</title></head><body><div id="app"><!-- 1.定义路由 --><router-link to="/user">用户</router-link><router-link to="/dog">狗狗</router-link><!-- 路由占位符A --><router-view></router-view></div><!-- 定义模版标签 --><template id="userTem"><div><h1>定义用户组件</h1></div></template><template id="dogTem"><div><h1>定义宠物组件</h1><!-- 准备2个组件 --><router-link to="/samo">萨摩耶</router-link><router-link to="/bite">比特犬</router-link><!-- 定义路由占位符B --><router-view></router-view></div></template><template id="samoTem"><div><h3>白色的狗狗</h3></div></template><template id="biteTem"><div><h3>一只凶猛的狗</h3></div></template><script src="../js/vue.js"></script><script src="../js/vue-router.js"></script><script>let userCom = {template: "#userTem"}let dogCom = {template: "#dogTem"}let samoCom = {template: "#samoTem"}let biteCom = {template: "#biteTem"}/* 路由展现问题说明:如果需要进行路由的嵌套 需要采用children 子级的路由会在当前的路由占位符中进行展现*///定义路由对象let router = new VueRouter({routes: [{path: "/user", component: userCom},{path: "/dog", component: dogCom, children:[{path: "/samo", component: samoCom},{path: "/bite", component: biteCom}]}]})//需要vue对象 进行挂载const app = new Vue({el: "#app",//vue对象挂载路由router: router})</script></body>
</html>
安装脚手架
注意事项
如果通过鼠标点击DOS命令窗口, 则DOS命令窗口可能出于锁定的状态. 通过ctrl+c的形式 解除锁定
2.4.2 什么是脚手架
原来写前端代码时 需要自己手动维护html/css/js. 并且如果文件如果很多 缺乏一种统一的方式进行管理.
可以向后端代码一样Controller/Service/Mapper 将代码进行分层管理. 前端仿照后端 开发了一个脚手架项目结构.
2.4.4 正确理解.vue文件
知识复习:
1. 组件 HTML/CSS/JS 这些都可以封装到组件中.
2. ** 重点:在脚手架中 xxx.vue 代表一个组件 **
2.4.7 脚手架加载流程
3.总结
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时。 前端脚手架运行的一个平台
类比: java程序 -----tomcat服务器.
脚手架 前端框架 类似于: java中的 spring框架
VUE.JS 类似于: java代码
vue-cli 构建脚手架的一个客户端工具 以视图的方式直观的给用户展现.
类比: SqlYog!!!
1.1.1 CDN说明
标签结构体说明:
1.JS引入过程
//1.从JS文件中引入组件
import {Container
} from 'element-ui'//2.实现父子组件参数传递.
Vue.use(Container)
2.1 user表设计
1.ID 是主键自增
2.密码: 加密之后的密文 加密API
3.status 0-1 布尔类型值 0-false 1-true 启用还是禁用
4.创建时间/修改时间 每张表里需要单独定义 可以进行封装优化
2.2 User对象说明
说明: 一张表对应一个User对象
2.3 用户登陆业务实现流程
步骤1: 用户输入完 用户名和密码之后,点击登录按钮
步骤2: 准备username/password数据 向后台服务器发送请求, 请求类型: post类型
步骤3: 后台服务器接收用户的请求参数 username/password
步骤4: 根据用户名和密码查询数据库 结果: 有数据 用户名和密码正确
| 没有结果 用户名和密码错误
步骤5: 后端服务器应该返回一个业务回执 标识业务逻辑是否正确执行
假设: status 200 正确, 201 表示失败
步骤6: 前端服务器根据用户的200/201 提示用户操作成功/操作失败.
2.4 业务接口文档
说明:一般做前后端交互时,必须有业务接口文档. 文档中详细阐述了业务需求/url地址/参数/返回值信息等要素.
前后端严格按照业务接口文档进行编码.
2.5 系统返回值SysResult对象
关于SysResult对象的说明: 该对象用来实现 后端与前端业务的交互.
业务执行正确 status=200 业务执行错误 status=201
概念: 前后端交互的层级 定义为 VO层
2.7 前端页面解析(调用流程!!!)
2.7.1 页面URL请求地址
2.7.3 token的作用
说明: 前端服务器: 用户进行登陆操作时 输入用户名和密码进行校验!!!
将数据信息发送到后端服务器进行校验 查询数据库
假设: 用户用户名和密码正确!!! 页面应该跳转到系统的首页 “/home” 对
问题: 是否可以在浏览器中直接输入 “/home” 理论上不允许访问该页面!
解决方案:
后端服务器返回一个独一无二的 token数据, 前端只要携带token 认为该用户已经登陆.可以跳转页面.
权限操作雏形!!!
总结: token是用来标识用户已经登陆!!!
2.7.4 MD5介绍
MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。这套算法的程序在 RFC 1321 标准中被加以规范。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。
总结:
1.MD5信息摘要算法
2.通常可以将数据进行MD5加密 生成 “数字指纹”
3.现阶段md5的加密的算法应用于各大网站中
4.md5加密之后 理论上来说 无法由密文转化为明文 不可以反向编译
5. 限定输入密码的次数!!! 3-5次 锁定账户!!!
核心算法:
知识回顾: 高中的函数!!!
什么是函数: 给定未知数x 经过函数计算 得到一个唯一的结果y
实质: MD5的本质就是hash算法!!!
流传的MD5可以被破解的原理: 就是将md5进行反向查询
md5 改进版: hash(明文+ 盐值) 了解
1.1 用户数据存储
规则: 服务器返回的响应的数据应该采用一种特殊的方式进行保存.否则用户的数据将会丢失.
{status: 200, msg: "服务器处理成功", data: "4edf7d1fbe2f4b14bc7227c85b4998b3"}
1.1.2 Session
总结:
1. Session 是会话控制
2. Session可以用户存储数据
3. Session生命周期整个会话 在会话期间数据有效, 如果会话窗口关闭 则数据清除.
4. Session数据存储在浏览器的内存中(前端的)
1.1.3 Cookie(了解)
总结:
1. Cookie 是一个文本文件
2. Cookie 存储的是用户信息 (加密数据 更加安全)
3. Cookie 保存到用户的计算机终端中 可以临时/永久的存储信息.
1.1.4 关于Session和Cookie的总结
- 手机银行的用户登录信息?? session 安全性要求较高
- 购物网站 要求用户七天免密登录?? 使用Cookie进行存储!!
- 公司的财务系统的登录信息? 建议使用Session
- 总结: 如果对于数据安全性要求较高 则使用Session. 如果存储一些大量查询的数据(不重要的)一般采用Cookie进行保存.
用户登录之后 将用户信息保存到Session中.
JS代码如下:
浏览器中的Session 控制:(面试题)
当会话关闭时,Session数据将会被清空
2 系统首页跳转
JS实现页面跳转
2.编辑路由规则
2.2 路由导航守卫
1. 前端实现: VUE中提供了路由导航守卫!!!
2. 单点登录策略 第四阶段进行讲解
配置路由导航守卫 控制权限
1.to 要跳转的网址
2.from 请求从哪里来
3.next 回调函数 放行/跳转
3.1.1 表设计说明
说明: 如果查询所有的一级菜单 则parent_id = 0
如果查询二级菜单信息 则parent_id = 1级菜单的ID
如果查询三级菜单信息 则parent_id= 2级菜单的ID
3.1.2 Rights的POJO
3.1.3 构建层级代码结构
编辑Mapper----Service-----Controller 层级代码 方便后续业务调用
3.1.4 关于端口号说明
8000端口: VUE UI vue客户端管理器所有占用的端口.
8080端口: jtadmin 脚手架项目启动时占用的端口号
8091端口: 后台SpringBoot业务系统的端口号
编辑页面JS
说明:当页面访问时,根据生命周期函数,调用getMenuList()方法.从后台的服务器获取菜单列表信息. JS如下.
3.2.4 关于层级表设计的说明
案例: 有一个业务逻辑 父子关系有3级 问:表如何设计?
业务关系: 爷爷—父亲—儿子-----孙子------重孙子
想法1: 定义三张表 爷爷表(id)—父亲表(parent_id–爷爷)—儿子表(parent_id—父亲)
数据结构复杂!!! 不便于扩展!!!
想法2: 定义一张表(id-----parent_id)
要求: 每个ID都应该有自己的parent_id
总结: 如果有父子关系,则一遍采用parent_id的方式进行封装. 自关联的方式
用户点击2级菜单时,跳转的路径 是由数据表中的path字段进行控制.
3.3.2 左侧菜单路由机制
1.定义路由占位符 在Home组件中 在中间定义了路由占位符.
2.编辑路由机制
根据路由嵌套的规则,通过children属性 实现组件嵌套.最终实现课堂页面效果.
3.3.3 左侧菜单路由全部实现
当用户默认跳转到home时,应该默认展现 Welcome的组件 关键语法:重定向机制
效果:
4 ElementUI 基本用法
1.面包屑导航 elementUI 提供的组件 Breadcrumb BreadcrumbItem 2.引入组件 element.js import Vue.use
1.1.1 表设计
1.1.3 页面调用JS流程
1.生命周期函数
2.getUserList()函数定义
知识铺垫: 每页20条Sql: select * from user limit 起始位置,每页条数第一页:select * from user limit 0,20 下标[0-19]第二页:select * from user limit 20,20 下标[20-39]第三页:select * from user limit 40,20 下标[40-59]第N页:select * from user limit (n-1)*rows,rows
1.2 MP方式实现分页查询(API调用!!!)
/*** 以MP的方式分页查询* 需求:* 1.分页查询 List<user>* 2.获取记录总数 封装pageResult对象** @param pageResult* @return*/@Overridepublic PageResult getUserList(PageResult pageResult) {//第一部分 实现数据的封装!!!int pageNum = pageResult.getPageNum(); //获取页面int pageSize = pageResult.getPageSize();//获取条件//参数1: page分页对象Page<User> page = new Page(pageNum,pageSize);//参数2: 分页的查询条件 username模糊查询//问题: 如果用户没有传递query like关键字 拼接参数//动态拼接: 传参拼接like condition:true 拼接like条件// false 不拼接 like关键字QueryWrapper<User> queryWrapper = new QueryWrapper<>();//判断用户是否传参 如果传参 返回true 反之 返回falseboolean flag = StringUtils.hasLength(pageResult.getQuery());queryWrapper.like(flag,"username",pageResult.getQuery());//规则: page2个参数 根据分页查询返回 total/分页后的记录 4个参数page = userMapper.selectPage(page,queryWrapper);//根据分页对象,获取想要的结果List<User> userList = page.getRecords();long total = page.getTotal();pageResult.setTotal(total).setRows(userList);return pageResult;}
1.2.2 编辑配置类
SpringBoot整合第三方框架时,提供了配置类的机制, 通过这种机制,第三方框架可以实现定制化的对象的创建.
//1.表示这个类 是一个配置类 目的: 封装对象-交给Spring容器管理
@Configuration
public class MybatisPlusConfig {// @Bean 将方法的返回值对象,交给Spring容器管理//MP分页机制 Mysql分页语句/Oracle分页语句 为了实现功能复用 需要手动配置//根据数据库类型不同 之后动态的生成Sql MP才能调用分页对象@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {//定义分页拦截器对象MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MARIADB));return interceptor;}}
1.3 用户状态修改
用户通过开关 控制 状态 true/false 在数据库中 存储true 用1, 存储false 用0
页面JS分析(了解)
说明: 如果修改状态信息,则必须获取当前行的数据. id/status
作用域插槽: 一般在表格循环遍历时,如果需要获取当前行数据,则采用作用域插槽的方式.
作用域插槽用法:
1.4 用户新增
用户JS分析(了解)
1. 数据的自动填充
数据库中每张表里 都包含创建时间/修改时间的字段. 如果每次操作表,都手动的去维护时间信息.则响应开发效率. 能否优化策略.
解决策略: MybatisPlus 实现自动填充功能.
MPAPI说明
1.2.1 语法规则
实现元对象处理器接口:com.baomidou.mybatisplus.core.handlers.MetaObjectHandler
注解填充字段 @TableField(… fill = FieldFill.INSERT) 生成器策略部分也可以配置!
1.2.2 添加注解
新增操作 需要自动填充 created/updated.
修改操作 需要自动填充 updated
1.2.3 编辑配置类
@Component //将对象交给Spring容器管理
public class MyMetaObjectHandler implements MetaObjectHandler {//当数据库做新增操作时,自动调用 API调用 不需要问为什么//metaObject对象 是MP自动填充的配置 有默认行为@Overridepublic void insertFill(MetaObject metaObject) {//获取当前时间Date date = new Date();this.setFieldValByName("created", date, metaObject);this.setFieldValByName("updated", date, metaObject);}//当数据库做修改操作时,自动调用@Overridepublic void updateFill(MetaObject metaObject) {//获取当前时间Date date = new Date();this.setFieldValByName("updated", date, metaObject);}
}
3. 关于事务说明
3.1 什么是事务
说明: 如果后台服务器执行正常,则业务正确,事务提交. 如果业务执行失败.事务应该回滚.
3.2 现有代码的业务测试
说明: 如图如果程序执行过程中有报错信息.应该实现事务的回滚. 但是发现现有代码有2个问题
1: 没有添加事物.
2. 后台服务器报错之后,用户没有提示.
3.3 添加事物-@Transactional注解
3.4 全局异常的处理机制
一般控制异常信息. 通常情况下需要添加try-catch 用法.
弊端: 所有的方法都需要try-catch的控制. 必然导致代码的结构复杂.
解决方案: Spring内部提供了一种规则 全局异常的处理机制.
Spring为了整合全局异常的处理 开发了如下的注解
1.@RestControllerAdvice //定义全局异常的处理类 返回值JSON串
2.@ExceptionHandler 标识拦截的异常的类型,如果类型匹配,则执行方法
@RestControllerAdvice 类上
@ExceptionHandler(RuntimeException.class) 方法上
4.2.3 商品分类业务说明
如何利用对象封装3级菜单结构?
一级菜单
children-----> 二级菜单信息
children-------> 三级菜单信息
1. 全局异常处理/事务控制关系
2 商品分类业务实现
2.1.2 优化策略
数据结构: Map<K,V> map
Key=“父级ID” Value=List<当前父级的子级>
用法: 如果想要获取任意父级的子级 map.get(父级的ID)
用法说明: Value 只有父级的子级信息,没有嵌套结构
Map<父级ID,List<ItemCat{id=xx,name=xx,children=null}>>
1.封装Map集合 Map<Key=父级ID,value=List<ItemCat对象>>
2.说明: 将所有的数据库的父子关系,进行封装.(没有嵌套!!!!)
3.优势: 只查询一次数据库,就可以完成父子关系的封装.
策略:
1. key不存在, 准备一个新List集合,将自己当作第一个元素追加
2. key存在, 获取原有list集合,将自己追加.
2.4 商品分类删除操作
1.如果被删除的标签是3级标签,则可以直接删除.
2.如果被删除的标签是2级标签,则需要先删除3级,再删除2级.
3.如果被删除的标签是1级标签,则需要先删除3级,在删除2级.最后删除1级.
1.1 VUE 过滤器用法
定义过滤器 Vue.filter("定义过滤器名称",function(参数){ 过滤器需要添加return
1.3.2 Item和ItemDesc关系
Item表: 主要封装了商品的基本信息.
ItemDesc表: 主要封装商品详情信息(大字段—html代码片段)
原因: 如果用户频繁的查询大字段 则影响效率. 所以将商品信息分为item和itemDesc
关联关系: item.id = itemDesc.id ID的值一致的.
问题分析:* 1.item入库之后,才会有主键信息. 对象理论上的ID=null* 2.itemDesc入库时,必须获取与Item.id一样的数据.* 如何解决:* 设定主键自动回显功能!!!!!* 如何设计:* 开启主键自增 主键回显的配置 Mybatis原生操作* <insert id="xxxx" useGeneratedKeys="true" keyColumn="主键字段" keyProperty="主键属性">** </insert>* MybatisPlus:* MP在完成入库操作时,自动的实现了数据的回显功能. 所以ID是有值的.* 知识: 哪种情况会有自动的回显功能!!!!!* BUG: 由于测试数据可能会出现重复的现象. 需要提前删除多余的记录
1.3.5 正则表达式
匹配确定的次数:
例子: a{5} a出现5次
a{5,} a出现至少5次 >=5
a{5,8} a出现只能 5-8次
匹配任意字符
匹配字符区间范围
[xyz] 该字符只能取值 x/y/z中的一个 匹配单个字符
^ xyz 该字符除了xyz之外的其他字符.
[a-z] 该字符必须 a-z的区间中的一个
[0-9] 该字符必须 0-9的区间中的一个
分组结构:
(png|jpg|gif) 字符只能匹配png|jpg|gif中的一个 匹配的是字符串
校验文件上传的类型 jpg|png|gif
2.应该校验文件是否为恶意程序. 木马.exe.jpg
3.为了提高检索效率 应该分目录存储. 1.hash方式 xx/xx/xx/xx 分布不均
2.日期格式 yyyy/MM/dd 目录不断增长
4.防止文件重名 UUID.jpg校验文件是否为恶意程序 判断依据 属性宽度和高度 aa.exe.jpg
3 .项目部署流程图
理解:文件上传路径的作用
3.1.1 路由地址修改
3.1.2 文件上传路径说明
3.1.3 文件上传路径
1. 安装JDK
工作目录
1.3 上传安装包
说明: 拖拽文件,实现文件上传.
1.4 解压文件
命令: 解压指令 ’ tar -xvf jdk-8u51-linux-x64.tar.gz ’
命令2: 删除安装文件 rm -f jdk-8u51-linux-x64.tar.gz
命令3: 修改文件名称 mv jdk1.8xxxxxx jdk1.8
测试JDK是否正常
如果检查JDK命令不能正常执行, 说明文件目录位置不正确 ,需要移动到正确的位置.
1.6 JDK环境调试
命令: vim /etc/profile#设定jdk环境
export JAVA_HOME=/usr/local/src/jdk1.8
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib
命令2: 让JDK环境变量立即生效 source /etc/profile
或者重启Linux系统即可.
数据库安装文档
3 虚拟机快照
说明: 如果做重大操作时,可能带来不可挽回的影响,则提前打快照,保留当前的状态.
4 部署后台服务器
修改目录地址
说明: 将来所有的图片都会上传到Linux的目录中,所以需要进行修改
项目打包
说明: 如果打包问题,则检查maven的配置!!!
4.4 上传jar包
项目发布命令
命令: java -jar 8091.jar
启动效果:
1.检查端口号是否正确
2.测试数据库链接是否正常 如果出现如图效果 ,则表示一切OK
5. tomcat集群部署
将后台服务器修改端口号之后,install 生成8091/8092. 传入Linux系统
前台发布命令
命令: java -jar 8091.jar & java -jar 8092.jar &
启动成功之后,回车跳入Linux系统.
弊端: 与当前的Session绑定. 如果Session关闭,则服务器全部停止.
5.3 端口号占用问题(经常性!!!)
说明: 由于操作不当,可能导致前一个tomcat服务器没有正常关闭.一直保留在内存中.之后启动必然报端口号占用.
1.查询: java进程命令 jps
5.4 关闭进程项
说明: 如果需要关闭Linux系统中的进程,则需要如下命令
语法: kill PID号
命令:
1. kill PID号 常规关闭进程
2. kil -15 PID号 较为严格的关闭. (当前的进程被其他进程引用 无法关闭)
3. kill -9 PID号 强制关闭进程
后台项目启动
java -jar 8091.jar & 该方式是前台启动方式.服务会与当前的session进行绑定. 如果session关闭.则服务停止.
这种前台的启动只适用于测试阶段.可以直观的反应报错的信息.
1.2 后台启动
命令: nohup java -jar 8091.jar => 8091.log &
说明: 通过上述命令可以实现后台启动,不会与session绑定.
1.3 浏览文件
cat 输出文件所有的内容 文件内容较少的场景
more 输出文档所有的内容,分页输出,空格浏览下一屏,q退出
less 用法和more相同,只是通过PgUp、PgOn键来控制
tail 用于显示文件后几号,使用频繁
tail -10 nginx.conf 查看nginx.conf的最后10行
tail –f nginx.conf 动态查看日志,方便查看日志新增的信息
ctrl+c 结束查看
1.4 脚本启动
说明: Linux系统中提供了shell脚本. 可以提供批处理的机制.
注意事项: 标识符 xxx.sh 注意表头
编辑脚本: vim start.sh
运行脚本: sh start.sh
关于HOSTS文件说明
通常用户访问服务器, 可以通过IP或者域名的方式访问. 域名与IP应该是一一对应的.
域名:由三大运营商负责提供的. 同时兼容DNS服务.
DNS说明: 全球的域名解析服务. 域名名称------IP地址 (一般有演示 1-2天, 2小时有效)
规则: 如果在本机进行业务测试. 则windows/Linux系统,提供了一个测试的文件.在该文件中可以编辑域名与IP的映射关系. 但是只对本机有效. 该文件就是hosts文件.
2.2 编辑hosts文件
路径: C:\Windows\System32\drivers\etc
修改文件内容:
127.0.0.1 localhost
::1 localhost
#图片服务器域名
#127.0.0.1 image.jt.com
#前端域名地址
#127.0.0.1 web.jt.com
#后端域名地址
#127.0.0.1 manage.jt.com#Linux系统配置 只对本机测试有效
192.168.126.129 image.jt.com
192.168.126.129 web.jt.com
192.168.126.129 manage.jt.com
3. Nginx
特点:
1.nginx 是反向代理服务器/web服务器
2.占用内存少 不到2M tomcat 300-400M
3.并发能力强 3-5万次/秒
tomcat并发能力 150-220次/秒 JVM调优(增大运行内存) 1000次/秒
4.解析:
1.功能简单 只做请求的"转发"处理
2.开发语言 C语言
3.2 官网
URL:http://nginx.org/en/download.html
去找收藏
3.3 代理机制
3.3.0 图片反向代理案例
3.3.1 反向代理(必须掌握)
小结:
1. 反向代理保护了服务器信息. 称之为服务器端代理(业务数据获取)
2. 正向代理保护了用户的信息. 称之为客户端代理. (网络出口)
3. 用户每次请求几乎都有正向和反向代理的影子.
3.4 前端项目发布
nginx目录结构说明
http {#每个服务都是一个serverserver {#默认监听80端口listen 80;#监听域名信息server_name localhost;#具体反向代理服务 / 默认写法location / {#root 代理的是一个目录root html;#默认访问页面index index.html index.htm;}}
}
前端发布准备工作
3.4.3 前端打包操作
3.4.4 上传前端项目
将前端打包好的目录dist 上传到指定的位置 /usr/local/nginx 目录下
配置前端反向代理
通过http://web.jt.com:80 访问前端的静态资源文件.
修改nginx配置文件:
#配置前端服务器server {listen 80;server_name web.jt.com;location / {root dist;index index.html;}}
后端服务器发布
3.5.2 配置tomcat集群
#一次请求,访问一个服务器 集群的配置 负载均衡机制# upstream 集群的关键字.# tomcats 是集群的名称 可以任意 xxxx# server 每个服务的地址# 默认采用轮询的策略,依次访问服务器.upstream tomcats {server 192.168.126.129:8091;server 192.168.126.129:8092;}#配置后端服务器 8091/8092#后端域名 manage.jt.comserver {listen 80;server_name manage.jt.com;location / {#proxy_pass 反向代理服务器发起是一个http请求proxy_pass http://tomcats;}}
3.6 实现图片回显
配置图片反向代理
说明: 修改成功之后,上传nginx.conf文件 之后重启服务器.
4. git学习
4.1 运行过程
组成部分: 1. 工作区 2.缓存区 3.本地仓库 4.远程仓库
4.2 git 安装和下载
网址: https://git-scm.com/downloads
说明: 下载成功,之后一路下一步即可.
1.检查当前分支 git branch
2.创建分支 git checkout -b 新分支名称
3.推送新分支 git push -u origin 新分支名称 第一次推送需要写-u
4.将文件添加到暂存区 git add .
5.提交代码 git commit -m “提交消息”
6.推动代码到云端 git push
7.合并代码到主分支 git merge 分支名称
8.克隆代码 git clone “仓库地址”
4.5 IDEA 关联GIT
第三阶段(CGB个人笔记)相关推荐
- 自学it18大数据笔记-第三阶段Spark-day04——会持续更新……
笔记为自学时随手记录,如有错误,欢迎指正,不胜感激!现已广州转移至上海,欢迎小伙伴们加qq或微博沟通交流(QQ,微博和博客同名) 笔记分享:自学it18大数据笔记-第三阶段Spark-day04--会 ...
- 自学it18大数据笔记-第三阶段Scala-day06——会持续更新……
笔记为自学时随手记录,如有错误,欢迎指正,不胜感激!现已广州转移至上海,欢迎小伙伴们加qq或微博沟通交流(QQ,微博和博客同名) 笔记分享:自学it18大数据笔记-第三阶段Scala-day06--会 ...
- 【方向盘】达到Linux第三阶段的常用命令笔记记录---Part Ⅱ
实现自己既定的目标,必须能耐得住寂寞单干 本文已被https://yourbatman.cn收录:女娲Knife-Initializr工程可公开访问啦:程序员专用网盘https://wangpan.y ...
- Linux运维 第三阶段 (二) DHCP
Linux运维 第三阶段 (二) DHCP服务 dhcp(dynamic host configuration protocol) 前期bootp(无盘工作站)-->dhcp(引入租约lease ...
- Linux运维 第三阶段 (十八) varnish
Linux运维 第三阶段 (十八) varnish 数据: 结构化数据,RDBMS: 非结构化数据,FS,存海量小文件,NAS.SAN.DFS可提供较好的性能: web cache: 程序具有局部性( ...
- Linux运维 第三阶段 (一) 网络配置及openssl加密
Linux运维 第三阶段 (一) 网络配置及openssl加密 主机接入网络:IP,netmask,gateway,hostname,DNS1,DNS2,DNS3,route,dhcp(dynamic ...
- Linux教学辅助训练(第三阶段)
Linux教学辅助训练(第三阶段) 标签(空格分隔): Linux辅助训练-陈思齐 ---更多资料点我查看 提示:本阶段性练习题是对<实战教学笔记>相应章节知识的归纳与扩展部分,必须要 会 ...
- Kaldi三音素GMM学习笔记
建议在csdn资源页中免费下载该学习笔记的PDF版进行阅读:)点击进入下载页面 Kaldi三音素GMM学习笔记 三音素GMM与单音素GMM的主要差别在于决策树状态绑定,与GMM参数更新相关的原理.程序 ...
- java 高并发第三阶段实战_JAVA多线程编程实战视频-第三阶段(共80节)
高并发编程第三阶段01讲 AtomicInteger多线程下测试讲解 高并发编程第三阶段02讲 AtomicInteger API详解,以及CAS算法详细介绍 高并发编程第三阶段03讲 利用CAS构造 ...
最新文章
- mysql 使用位运算
- 文本 To 音频
- 《研磨设计模式》chap17 策略模式(2) 总结
- 自动化办公之excel教程(4):使用艺术字,图片,图形美化工作表
- php网站的编辑器,5款适合PHP使用的HTML编辑器推荐
- Java EE中的重新验证(java.util.regex.Pattern)
- 一些移动端的ui框架
- 微信小程序-配置请求合法域名的问题以及豆瓣api问题
- BootStrap中Model模态框点击除了×号和关闭按钮外的其他区域不消失
- 再次理解HTTP请求过程[概念原理篇]
- oracle 物化视图 on commit,oracle物化视图的一般用法
- PMP学习系列2:PMP报名考试相关细则
- html5播放 h.264裸流,[转载]成功在MP4封装的H264视频中提取能播放的裸流
- 【M365运维】Outlook会议室查找工具找不到会议室
- Docker 极简入门指南
- 高数笔记(二):极限的运算法则,极限存在准则,两个重要极限,无穷小的比较
- 2018贵州省大学生程序设计竞赛参赛感言
- Android Jetpack 架构组件之 Room
- 分享如何在 PingCode 这类专业的看板软件中管理敏捷Kanban 项目
- janus videoroom之媒体录制