maven的基本信息:
坐标: 1.组ID 公司域名倒写
2.项目的名称 不能重复 不能数字开头
3.项目版本
坐标作用: 1.用来管理/区分项目
2.项目的打包路径就是坐标的位置
com.jt
springboot_demo2_mybatis
1.0-SNAPSHOT
常规用法:
1.配置mave环境变量
2.通过dos窗口 执行命令.几乎不用
IDEA插件方式:
1.8 true
定位:SpringBoot:作用是整合SSM,使框架使用更加简化 原则:"开箱即用" parent主要作用: 1.SpringBoot在内部兼容了几乎所有的第三方框架 2.SpringBoot官网已经将所有兼容的版本进行了定义 (几乎解决了版本冲突问题)以后几乎不写版本号 概括:parent标签中管理其他的项目版本信息.
org.springframework.boot spring-boot-starter-parent 2.5.2
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test
org.springframework.boot spring-boot-maven-plugin 2.5.2
数据结构: KEY-VALUE 数据类型: String类型/Number数值 语法: 1.key-value使用=号连接 2.不需要添加多余的""号 3.pro文件在IDEA中的编码格式UTF-8(手动可改) pro文件在被程序读取时默认采用ISO-8859-1格式,中文必定乱码 4.key=value不要出现多余的空格 server.port=8090
数据结构 key-value 数据类型 String/Number 语法: 1.key:(空格)value 2.key与key之间有层级关系,注意缩进 3.字符编码都采用UTF-8 4.可读性较pro文件 更加友好 server: port: 8090
说明: 如果将数据直接写死到.java文件中,如果需要修改,则重新编译打包.不方便.如何优化??
优化: 通过配置文件动态为属性赋值!!!
3.2.2.1 编辑YML配置文件
说明: Spring负责管理YML文件中的数据.
1.@ResponseBody 可以将对象转化为JSON串 2.如果返回值为String类型,则返回本身 纠正: A.JSON串 规则:从Spring容器根据key获取数据,之后为属性赋值 语法: spel表达式 ${key} @Value("${user.day}") private String day;
YML是SpringBoot的核心配置文件, 一般用来整合其他第三方框架,如果将大量的业务数据放到YML中不符合编码规范. 所以将业务数据写到Pro配置文件中
spring容器启动时,动态添加配置文件 一般需要修改字符集
关于注解赋值: 1.必须满足key-value结构
2.如果属性只有一个并且是value属性,则可以省略不写
3.如果还是乱码则检查IDEA pro字符集编码格式
@PropertySource(value="classpath:/person.properties",encoding="UTF-8")
1.实现了.java文件与属性赋值的解耦
2.为了属性特定的业务赋值
3.SpringBoot整合第三方框架时,如果需要额外的配置文件时,常常采用上述的操作实现. 方便扩展
Redis为属性赋值操作
说明:Spring容器是在内存中一大块的区域,存储Spring管理对象
数据结构:key-value结构
数据类型:Map集合
Map详细说明:key:类型首字母小写 Value: 对象
1.按照类型注入
按照属性的类型 去Map集中中查找是否有改类型的对象. 如果有则注入.
2.按照名称注入 根据属性的name 去Map集中中查找对应的KEY
@Autowired
@Qualifier(value="李四")
private SpringService springService;
自动装配的规则说明:
1.如果对象在进行实例化.如果对象中的属性被 @Autowired注解修饰,则说明应该先注入属性.
2.先根据属性的类型,查找Map集合中是否有该类型的对象.
3.如果根据类型查找没有找到,则根据属性的名称按照name查找对象.
4.如果上述的方式都没有找到,则报错实例化对象失败.原则:Spring容器中要求 接口必须单实现. 如果有多实现则通过@Qualifier(“xxxx”)区分即可
org.projectlombok
lombok
作用:通过程序自动生成的实体对象的get/set/toString/equals/hashCode等方法.
链式加载原理: 重启了POJO的set方法. 返回当前对象
public User setId(Integer id) {
this.id = id;
return this;
}
问题: lombok的使用需要在IDE中提前安装插件!!!,如果项目在Linux系统中部署发布.是否需要提前安装插件!!!
答案: 不要!!!
原因: lombok插件编译期有效.(编译期:由xxx.java文件编译为xxxx.class文件).在打包之前class文件中已经包含了set/get等方法,所以项目打包之后可以直接运行.无需安装插件!!!.
说明: 正常的情况下mysql服务项 开机自启. 有时由于某种原因 导致数据库服务启动失败.
问题描述: 数据库链接报错.显示链接不可用.
检查服务项:
导出数据库: 将mysql中的数据库以 xxx.sql文件进行转储.
导入数据库: 读取xxx.sql文件 之后工具执行其中的sql,最终实现数据的导入功能.
说明: 上述的操作称之为数据库冷备份. 一般在生产环境下 为了保证数据的安全.一般都会定期冷备份.(周期3-7天左右) 一般一式3份. 数据库的冷备份是恢复数据最后有效的手段.
特点: 冷备份容易丢失数据. 热备份可以实现实时备份.
说明: 一般实体对象只需要添加get/set/toString等方法,无需添加构造方法.
一般如果需要对象进行传递时,要求POJO对象必须实现序列化接口.否则数据传输必然报错.
org.springframework.boot
spring-boot-starter-parent
2.5.2
1.8
true
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-devtools
org.projectlombok
lombok
mysql
mysql-connector-java
runtime
org.springframework.boot
spring-boot-starter-jdbc
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.2.0
org.springframework.boot
spring-boot-maven-plugin
2.5.2
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
serverTimezone=GMT%2B8& %2B= + GMT+8&
useUnicode=true&characterEncoding=utf8& 是否使用unicode编码及设定字符集
autoReconnect=true 是否自动重连
allowMultiQueries=true 是否允许批量操作
server:
port: 8090
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
#如果数据库密码以数字0开头 则必须使用""号包裹
#password: "01234"
#SpringBoot整合Mybatis配置
mybatis:
type-aliases-package: com.jt.pojo
mapper-locations: classpath:/mybatis/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
2.编辑UserMapper.xml映射文件
1.
驼峰命名规则:
表字段: user_id,user_name
对象的属性: userId,userName
resultType: 保证属性与字段名称必须一致.
Mybatis提供了驼峰命名规则:
规则: 字
段user_id~~~去除_线~~~之后映射对象的属性
userId
说明: 编辑maven项目时,会有源文件/资源文件/测试文件. 可以通过IDEA提供选项手动的配置
说明: 利用@mapperScan注解为接口创建代理对象
@SpringBootApplication
@MapperScan("com.jt.mapper") Spring容器内部为接口创建代理对象
JDK的动态代理对象
public class SpringBootRun {
//标准写法
public static void main(String[] args) {
SpringApplication.run(SpringBootRun.class, args);
}
}
要求: 1.测试包路径必须在主启动类的同包及子包中.
2.从Spring容器中可以获取对象进行调用.
@SpringBootTest
类名上
调用mapper service controller!!单元测试~~
@Autowired 依赖注入(代理对象)
private UserMapper userMapper;
@Test 自定义注解
public void testGetAll(){
System.out.println(userMapper.getClass());
List
System.out.println(userList);
}
概括: MyBatis 是一款优秀的持久层框架,并且在内部整合的了JDBC,简化了用户操作数据库的过程.
Mybatis是一个半自动化的ORM映射框架
对象关系映射(英语:Object Relational Mapping,简称ORM)
用来实现面向对象编程语言不同类型系统的数据之间的转换
核心知识:
宗旨: 以对象的方式操作数据库
1. 要求查询的结果集可以自动的封装为对象 (读)
2. 利用对象封装数据,之后(自动)动态的生成Sql语句执行相关操作. (更新)
说明: 该注解是SpringBoot程序 为了简化后端代码测试 提供了专门的测试API.
关键点: 测试时需要Spring容器管理对象,同时将测试的对象获取 之后进行测试.
注意事项: 测试注解只能在测试包中运行.
Spring容器为接口创建代理对象. Spring容器启动对象立即创建
根据 @Autowired 注解动态注入Mapper接口的代理对象
用户通过Mapper接口调用方法.(执行业务操作)
Mybatis根据接口方法动态匹配xml的映射文件
1.根据Mapper的接口路径匹配xml映射文件中的 com.jt.mapper.UserMapper
2.根据接口的方法 匹配xml映射文件中的Sql ID 之后执行Sql语句
5.Mybatis将结果集封装为对象 之后返回.
1.更换xml映射文件
2. 更换YML文件
3. 由于IDEA缓存导致Mybatis链接异常.
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
利用对象操作数据库,单表查询几乎不写SQL
说明:MybatisPlus对Mybatis的增强(包含),所有jar包只需要导入MP的即可.原有的Mybatis需要删除.
org.springframework.boot
spring-boot-starter-parent
2.5.2
1.8
true
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-devtools
org.projectlombok
lombok
mysql
mysql-connector-java
runtime
org.springframework.boot
spring-boot-starter-jdbc
com.baomidou
mybatis-plus-boot-starter
3.4.3
org.springframework.boot
spring-boot-maven-plugin
2.5.2
新增用户
Mybatis: 1.mapper接口 2.xml映射 Sql
MP: 调用接口方法
@Test
public void testInsert(){
User user = new User();
user.setName("吴亦凡").setAge(30).setSex("男");
//单表操作几乎不写Sql
userMapper.insert(user);
server:
port: 8090
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
#SpringBoot整合MP
mybatis-plus:
type-aliases-package: com.jt.pojo
mapper-locations: classpath:/mybatis/*.xml
configuration:
map-underscore-to-camel-case: true
# Mapper接口执行 打印Sql日志
logging:
level:
com.jt.mapper: debug
用户执行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执行最终实现数据入库操作!!!
MP:用对象操作数据库.
学习:代码结构
根据Id=1查询数据. ID=主键
User user = userMapper.selectById(1)
案例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
queryWrapper.in("age","1,3,5,6,7");
List
// 2.MP 特殊方法调用 以后尽可能使用对象类型(对象有方法)
Integer[] ids = new Integer[]{1,2,3,4,5,6};
List idList = Arrays.asList(ids);
List
案例7: 根据 name/sex 动态查询数据库
解析: 如果name/sex有值则动态拼接where条件.
否则不写where条件.
动态Sql实现: condition 参数
布尔类型值 true: 拼接where条件
false: 不拼接where条件
字符串判断API:
StringUtils.hasLength(name);
@Test
public void testSelectNS(){
String name = null;
String sex = "";
QueryWrapper 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);
要求:接收URL请求地址,之后JSON数据返回.
URL: http://localhost:8090/getAll
要求利用MP的方式查询数据库.
1.SpringMVC C层接收请求给出响应
标识Controller类 交给Spring容器管理/返回JSON数据
@RestController(接收请求)
需求: 查询全部用户信息
URL: /getAll
返回值: List
@RequestMapping("/getAll")绝对路径,唯一标签
public List
return userService.getAll();
@Service (Spring层用Service) 实现类
@Autowired //JDK动态代理对象 (DI依赖注入)
private UserMapper userMapper;
需求: 前端准备一个表格,之后在表格中展现后端查询的所有数据.
知识点:
1.html css
2.jQuery 知识
3.Ajax $.ajax({…})
4.了解JS的处理基本用法. VUE
html页面:
用户列表demo
用户列表
编号
姓名
年龄
性别
100
黑熊精
3000
男
作用:获取后端数据 之后也页面展现
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
{ "id": 100, "name":"tomcat", "age":18}
[100, "张三", "李四"]
案例:
[{"id":15,"name":"小猫猫"},
{"id":24,"name":"张修雨",
"color":["白丝袜","黑丝袜","小姐姐","小猫咪"],
"丝袜":[{ "name":"卡其色丝袜","level":"完美"},
{ "name":"玫瑰色丝袜","level":"高级" }
]
}
]
Ajax即Asynchronous Javascript And XML(异步JavaScript和XML 使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作。
特点:
1. 局部刷新
2. 异步访问
同步:
当用户发起请求时,后端没有返回数据,此时用户页面就无法展现.一直是加载中的状态(整个页面同时刷新)
异步的原因:有Ajax引擎
步骤:
1. 用户将请求发送给Ajax引擎. 之后JS继续向下执行.
2. Ajax引擎接收用户请求之后,通过代理的方式访问后端服务器.
3. 后端服务器接收请求之后,执行业务操作,最终将响应的结果返回值代理服务器(Ajax引擎)
4. 引擎通过回调函数的方式返回给用户数据.
网址: https://jquery.com/
基础循环写法
//JS可以将接收的JSON串动态转化为JS对象
$.get(url,function(data){
//循环遍历返回值
for(var i=0; i
说明: 模版字符串语法从ES5以后提供的
语法: 反引号
特点:
1. 被反引号包裹的都是字符串 可以随意换行 可以保留代码结构.
2. 可以动态的从对象中获取数据 语法: ${对象.属性}
for(user of data){
//获取数据信息
var tr =
`
${user.id}
${user.name}
${user.age}
${user.sex}
`
//将tr标签追加到表格中
$("#tab1").append(tr)
}
用户列表demo
用户列表
编号
姓名
年龄
性别
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
1).体积小 压缩后的文件只有33k
2).运行效率更高 采用虚拟机DOM,一种可以预先通过javaScript对数据进行计算.把最终的DOM操作计算出来并且优化的技术. 由于这个DOM操作属于预处理操作,并没有真实的操作DOM ,所以叫做虚拟DOM
3).双向数据绑定 让开发者不再去操作DOM,将更多的经历投入到业务中
4).生态丰富 市面上有大量的开源项目基于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
命令: v-text/v-html/v-once/v-pre 指令
特点: 如果页面没有渲染完成,则直接展现给用户 插值表达式需要直接显示
注意事项: 只有显示时采用,输入操作不可使用
1.v-text指令: 如果页面没有渲染完成,则不显示信息
2.v-html 直接渲染html标签
3.v-pre 跳过预编译 显示标签体本身
4.v-once 只渲染一次
双向数据绑定: 实现了页面与数据的绑定. 页面变数据变 / 数据变页面变.
双向数据绑定 v-model
1.数据端---页面
2.页面-----数据
{ {msg}}
知识回顾: MVC模式 核心思想 减少代码的耦合性
M Model:封装的数据
V View 视图层: 数据的展现
C Contro 控制层 程序的流转的过程
衍生: 3层代码的结构 Controller—Service–Mapper/Dao
针对于: 后端服务器.
MVVM思想说明:
M: Model 封装的数据. 数据层
V: View 数据的展现 视图层
VM: viewModel视图数据的控制层 控制数据流转
MVVM设计思想是前端模拟后端为了解耦的一种设计思想.
原理步骤:
1.用户修改页面时,通过DOM的监听器感知用户的修改行为,之后通过虚拟DOM对象,第一时间更新Model中的属性.
2.当数据发生变化,由虚拟DOM根据数据绑定的规则,第一事件通知真实的DOM对象.至此页面数据发生变化.
语法:
v-on:click="函数/直接进行计算"
语法:
1.v-on:keydown="" 按下触发
2.v-on:keyup="" 弹起来触发
3.v-on:keypress="" 小键盘触发
按键支持:
.enter .tab
.delete (捕获“删除”和“退格”键)
.esc .space
.up .down .left .right
addNum(){
//this.num = this.num + this.num2
//将字符串转化为数值类型
this.num += parseInt(this.num2)
难点: 元素可能需要嵌套,事件可能嵌套
说明: 如果事件嵌套则必然带来事件的冒泡.
解决方案: 阻止事件冒泡 .stop属性
a标签作用中的href的跳转是默认规则
要求: 用户点击a标签 不跳转页面,同时触发事件
解决: 阻止标签的默认行为 @click.prevent
用途: prevent阻止页面跳转 a标签/form表单 action同步请求
Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器
总结: Servlet是java与前端页面进行数据交互的一种机制
核心对象:
1. request对象 封装用户请求的参数/请求头/请求全部内容
2. response对象 封装用户响应信息
/**
* 注意事项: 如果后端服务器没有匹配的方法,也会报跨域错误.
* 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;
}*/
/**
* 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;
}
语法: v-bind:href="VUE中的属性"
简化写法
用法: 如果数据为真则展现html标签
语法: v-if/v-else-if/v-else
要求: v-if可以单独使用
另外2个必须与v-if连用
用法: 通过循环 展现标签+数据
语法:
v-for((value,index) in array)
v-for((value,key,index) in obj)
v-for(user in userList) 后续通过user.属性取值
1. 一般数据进行提交时都会使用表单.
2. 每个表单几乎都写action. action现在几乎不用(同步操作)
一般通过 阻止默认行为的方式 禁用action,之后手写点击事件触发后续操作(Ajax)
3. 用户录入标签体 1.文本框 2.单选 3.多选 4.下拉框 5.文本域
4. 掌握各个标签的双向数据绑定的写法. 值有多个 使用数组.
5. 表单修饰符 1.number 只能输入数值类型 2.trim 去除左右空格 3.lazy 离焦事件才触发
API:
1.字符串转化为数组 拆串 split('')
2.将数组倒序 .reverse()
3.将数组转化为字符串 .join('')
计算属性功能用法:
1.插值表达式中应该写简单的算数计算,如果复杂应该封装
2.如果数据操作相同则应该简化过程.
总结: 计算属性相对于方法 效率高(从虚拟DOM中直接获取结果)
push() 在结尾追加元素
pop() 删除最后一个元素
shift() 删除第一个元素
unshift() 在开头追加元素
splice() 替换数组中的数据 !!!!
sort() 数据排序
reverse() 数组反转
周期:
1.初始化周期
1.beforeCreate vue对象实例化之前(刚开始)
2. created
3. beforeMount
4. Mounted 说明VUE对象实例化成功(DIV渲染完成)
2.修改周期
1. beforeUpdate 用户修改数据之前
2. updated 用户修改数据之后
3.销毁周期
1. beforeDestroy VUE对象销毁前
2. destroyed VUE对象销毁后(最后一步)
生命周期函数的作用:
如果需要对VUE对象中的数据进行额外的操作.则使用生命周期函数.
目的: 框架的扩展性更好.(实现定制化)
特点:
1. 参数需要使用/ 进行分割
2. 参数的位置是固定的.
3. restFul请求方法路径不能出现动词
作用:
用户可以通过一个URL请求的地址,可以实现不同的业务操作
知识回顾:
查询: http://localhost:8090/getUserById?id=100 类型:get
新增: http://localhost:8090/insertUser 类型:post
更新: http://localhost:8090/updateUser 类型:post
删除: http://localhost:8090/deleteUserById?id=200 类型:get
意图明显: 常规的请求的方式其中包含了动词,导致操作的意图非常明显.
RestFul风格实现CURD操作:
1.查询: http://localhost:8090/user/100 type:GET
2.新增: http://localhost:8090/user/tomcat/18/男 type:POST
3.删除: http://localhost:8090/user/100 type:DELETE
4.更新: http://localhost:8090/user/mysql/100 type:PUT
type: GET
RequestMapping 默认的可以接收所有的请求类型
RestFul语法:
1.参数的位置固定.
2.参数必须使用{}包裹
3.必须使用@PathVariable 动态的接收参数
注意事项: {参数名称}必须与方法中的名称一致.
restFul的优化:
如果{参数名称}与对象中的属性名称一致,
则SpringMVC动态的为对象赋值,
@PathVariable 可以省略
注意事项:
前后端的参数的传递必须保持一致!!!!
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的请求的方式.
** 特点: 调用简洁 解决了 “回调地狱问题”!!!**
说明: 前端中如果需要发起大量的Ajax请求,并且Ajax 请求有嵌套的关系.则可能引发回调地狱问题.
例子: 请求 参数A --1–结果B/参数B—2–结果C/参数C—3--- 结果D
课下了解: 什么是回调地狱!!!
注意事项:
1.Axios将原来的嵌套的结构,改为链式加载方式
2.回调函数中的data,不是服务器的返回值,是promise对象
GET请求-简单参数的写法
then(): 回调函数通过then返回 结构
axios.get("http://localhost:8090/axios/getUserById?id=100")
.then(function(result){
console.log(result.data)
})
/**
* restFul风格实现业务传参
* 需求: 根据name/age查询数据
* URL: http://localhost:8090/axios/user/tomcat/18
* 注意: 模版字符串优化参数 ``
*/
let name = "mysql"
let age = 20
axios.get(`http://localhost:8090/axios/user/${name}/${age}`)
.then(function(result){
console.log(result.data)
})
一般用来检查网络的请求 使用network 其中不要添加缓存, 检查所有的请求的路径
如果用户查询数据 其中包含了多个参数,可以使用restFul风格(少量参数)/可以使用对象封装(多个参数)
如果参数较多则建议使用对象的方式封装.
案例: 查询name=“mysql” age=18 sex="女"的用户 要求使用对象的方式封装参数
语法: 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)
})
一般用户通过Delete请求做删除操作. 删除的语法与Get请求的语法一致的.
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){ … })
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,对象)
说明: 如果采用post的方式传递对象,则数据结构是一个JSON
请求的类型是由程序员手动控制
- 分类A
1.get 请求类型 查询
2.delete 请求类型 删除- 分类B
1.post 请求类型 form表单提交 新增操作
2.put 请求类型 更新操作
说明: 数据在进行参数传递时 数据需要转化
如果传递的数据是JSON串 ,则在后端采用@RequestBody注解 实现JSON串转化为对象
如果采用form表单的方式提交,则可以直接采用对象的方式接收
name=xxx&age=xx&sex=xx
3. restFul的格式是将参数拼接到URL中 采用特殊的方式获取数据
1.async/await 是ES7引入的新语法 可以更加方便的进行异步操作
2.async 关键字用在函数上. 返回值是一个promise对象
3.await 关键字用在async 函数中
axios的get请求语法
知识点:
1.箭头函数 主要简化回调函数的写法
思路: 重复的 固定的可以简化
规则: 如果参数只有一个则括号可以省略
let url = "http://localhost:8090/axios/getUserById?id=100"
axios.get(url)
.then( result => {
alert(result.data)
})
axios的get请求语法
知识点:
1.箭头函数 主要简化回调函数的写法
思路: 重复的 固定的可以简化
规则: 如果参数只有一个则括号可以省略
2.async-await简化 解构赋值
2.1 async 需要标识函数
2.2 await 需要标识ajax请求
上述的操作可以将多行js 封装为一行执行 简化代码操作
说明: 可以通过下列的配置简化 Ajax请求的路径
//配置基本请求路径 axios.defaults.baseURL = "http://localhost:8080/"
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风格: 在上述的四大请求类型中都可以使用(单独的体系) 参数使用/分割 注意参数结构 灵活选用.
请求方式说明:
注意事项:
在vue.js中看到了INPUT框, 则表示双向数据绑定. 必须在data中定义属性.
说明: 传统的页面开发,会将大量的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"
})
说明: 用户发起一个请求,在互联网中经过多个站点的跳转.最终获取服务器端的数据. 把互联网中网络的链路称之为路由. (网络用语)
VUE中的路由: 根据用户的请求URL地址,展现特定的组件(页面)信息. (控制用户程序跳转过程)
1.导入路由JS 先导入vue.js 再导入路由.js 顺序问题
二:定义链接 1.router-link 被编译之后转化为a标签
2.关键字 to 被编译之后转化为href属性
三: 指定路由的填充位置 未来展现组件信息 填充的位置被解析之后 就是一个DIV
定义组件的标签体
用户信息
定义路由对象 routes: 路由的多个映射通过该属性进行定义.
let vueRouter = new VueRouter({
routes: [
{path: "/user", component: userCom},
{path: "/dog", component: dogCom}
]
})
//实现路由的挂载
router: vueRouter
注意事项: 请求和转发都是服务器行为 不会做额外的操作
说明: 用户访问服务器,但是目标服务器无法处理该请求,由服务器内部将请求交给其他服务器处理. 这个过程称之为转发.
说明: 用户访问服务器,但是目标服务器无法处理该请求,目标服务器返回一个能够处理请求的网址.由用户再次发起请求,访问服务器获取数据.
redirect 路由的重定向
需求: 要求用户访问 "/"根目录 要求重定向到 "/user"请求路径中.
路由入门案例
用户
狗狗
定义用户组件
定义宠物组件
萨摩耶
比特犬
白色的狗狗
一只凶猛的狗
如果通过鼠标点击DOS命令窗口, 则DOS命令窗口可能出于锁定的状态. 通过ctrl+c的形式 解除锁定
原来写前端代码时 需要自己手动维护html/css/js. 并且如果文件如果很多 缺乏一种统一的方式进行管理.
可以向后端代码一样Controller/Service/Mapper 将代码进行分层管理. 前端仿照后端 开发了一个脚手架项目结构.
知识复习:
1. 组件 HTML/CSS/JS 这些都可以封装到组件中.
2. ** 重点:在脚手架中 xxx.vue 代表一个组件 **
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时。 前端脚手架运行的一个平台
类比: java程序 -----tomcat服务器.
脚手架 前端框架 类似于: java中的 spring框架
VUE.JS 类似于: java代码
vue-cli 构建脚手架的一个客户端工具 以视图的方式直观的给用户展现.
类比: SqlYog!!!
标签结构体说明:
1.JS引入过程
//1.从JS文件中引入组件
import {
Container
} from 'element-ui'
//2.实现父子组件参数传递.
Vue.use(Container)
1.ID 是主键自增
2.密码: 加密之后的密文 加密API
3.status 0-1 布尔类型值 0-false 1-true 启用还是禁用
4.创建时间/修改时间 每张表里需要单独定义 可以进行封装优化
说明: 一张表对应一个User对象
步骤1: 用户输入完 用户名和密码之后,点击登录按钮
步骤2: 准备username/password数据 向后台服务器发送请求, 请求类型: post类型
步骤3: 后台服务器接收用户的请求参数 username/password
步骤4: 根据用户名和密码查询数据库 结果: 有数据 用户名和密码正确
| 没有结果 用户名和密码错误
步骤5: 后端服务器应该返回一个业务回执 标识业务逻辑是否正确执行
假设: status 200 正确, 201 表示失败
步骤6: 前端服务器根据用户的200/201 提示用户操作成功/操作失败.
说明:一般做前后端交互时,必须有业务接口文档. 文档中详细阐述了业务需求/url地址/参数/返回值信息等要素.
前后端严格按照业务接口文档进行编码.
关于SysResult对象的说明: 该对象用来实现 后端与前端业务的交互.
业务执行正确 status=200 业务执行错误 status=201
概念: 前后端交互的层级 定义为 VO层
说明: 前端服务器: 用户进行登陆操作时 输入用户名和密码进行校验!!!
将数据信息发送到后端服务器进行校验 查询数据库
假设: 用户用户名和密码正确!!! 页面应该跳转到系统的首页 “/home” 对
问题: 是否可以在浏览器中直接输入 “/home” 理论上不允许访问该页面!
解决方案:
后端服务器返回一个独一无二的 token数据, 前端只要携带token 认为该用户已经登陆.可以跳转页面.
权限操作雏形!!!
总结: token是用来标识用户已经登陆!!!
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 改进版: hash(明文+ 盐值) 了解
规则: 服务器返回的响应的数据应该采用一种特殊的方式进行保存.否则用户的数据将会丢失.
{status: 200, msg: "服务器处理成功", data: "4edf7d1fbe2f4b14bc7227c85b4998b3"}
总结:
1. Session 是会话控制
2. Session可以用户存储数据
3. Session生命周期整个会话 在会话期间数据有效, 如果会话窗口关闭 则数据清除.
4. Session数据存储在浏览器的内存中(前端的)
总结:
1. Cookie 是一个文本文件
2. Cookie 存储的是用户信息 (加密数据 更加安全)
3. Cookie 保存到用户的计算机终端中 可以临时/永久的存储信息.
用户登录之后 将用户信息保存到Session中.
JS代码如下:
浏览器中的Session 控制:(面试题)
当会话关闭时,Session数据将会被清空
JS实现页面跳转
2.编辑路由规则
1. 前端实现: VUE中提供了路由导航守卫!!!
2. 单点登录策略 第四阶段进行讲解
配置路由导航守卫 控制权限
1.to 要跳转的网址
2.from 请求从哪里来
3.next 回调函数 放行/跳转
说明: 如果查询所有的一级菜单 则parent_id = 0
如果查询二级菜单信息 则parent_id = 1级菜单的ID
如果查询三级菜单信息 则parent_id= 2级菜单的ID
编辑Mapper----Service-----Controller 层级代码 方便后续业务调用
8000端口: VUE UI vue客户端管理器所有占用的端口.
8080端口: jtadmin 脚手架项目启动时占用的端口号
8091端口: 后台SpringBoot业务系统的端口号
说明:当页面访问时,根据生命周期函数,调用getMenuList()方法.从后台的服务器获取菜单列表信息. JS如下.
案例: 有一个业务逻辑 父子关系有3级 问:表如何设计?
业务关系: 爷爷—父亲—儿子-----孙子------重孙子
想法1: 定义三张表 爷爷表(id)—父亲表(parent_id–爷爷)—儿子表(parent_id—父亲)
数据结构复杂!!! 不便于扩展!!!
想法2: 定义一张表(id-----parent_id)
要求: 每个ID都应该有自己的parent_id
总结: 如果有父子关系,则一遍采用parent_id的方式进行封装. 自关联的方式
用户点击2级菜单时,跳转的路径 是由数据表中的path字段进行控制.
1.定义路由占位符 在Home组件中 在中间定义了路由占位符.
2.编辑路由机制
根据路由嵌套的规则,通过children属性 实现组件嵌套.最终实现课堂页面效果.
当用户默认跳转到home时,应该默认展现 Welcome的组件 关键语法:重定向机制
效果:
1.面包屑导航 elementUI 提供的组件 Breadcrumb BreadcrumbItem 2.引入组件 element.js import Vue.use
1.生命周期函数
知识铺垫: 每页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
/**
* 以MP的方式分页查询
* 需求:
* 1.分页查询 List
* 2.获取记录总数 封装pageResult对象
*
* @param pageResult
* @return
*/
@Override
public PageResult getUserList(PageResult pageResult) {
//第一部分 实现数据的封装!!!
int pageNum = pageResult.getPageNum(); //获取页面
int pageSize = pageResult.getPageSize();//获取条件
//参数1: page分页对象
Page page = new Page(pageNum,pageSize);
//参数2: 分页的查询条件 username模糊查询
//问题: 如果用户没有传递query like关键字 拼接参数
//动态拼接: 传参拼接like condition:true 拼接like条件
// false 不拼接 like关键字
QueryWrapper queryWrapper = new QueryWrapper<>();
//判断用户是否传参 如果传参 返回true 反之 返回false
boolean flag = StringUtils.hasLength(pageResult.getQuery());
queryWrapper.like(flag,"username",pageResult.getQuery());
//规则: page2个参数 根据分页查询返回 total/分页后的记录 4个参数
page = userMapper.selectPage(page,queryWrapper);
//根据分页对象,获取想要的结果
List userList = page.getRecords();
long total = page.getTotal();
pageResult.setTotal(total).setRows(userList);
return pageResult;
}
SpringBoot整合第三方框架时,提供了配置类的机制, 通过这种机制,第三方框架可以实现定制化的对象的创建.
//1.表示这个类 是一个配置类 目的: 封装对象-交给Spring容器管理
@Configuration
public class MybatisPlusConfig {
// @Bean 将方法的返回值对象,交给Spring容器管理
//MP分页机制 Mysql分页语句/Oracle分页语句 为了实现功能复用 需要手动配置
//根据数据库类型不同 之后动态的生成Sql MP才能调用分页对象
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
//定义分页拦截器对象
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MARIADB));
return interceptor;
}
}
用户通过开关 控制 状态 true/false 在数据库中 存储true 用1, 存储false 用0
说明: 如果修改状态信息,则必须获取当前行的数据. id/status
作用域插槽: 一般在表格循环遍历时,如果需要获取当前行数据,则采用作用域插槽的方式.
作用域插槽用法:
数据库中每张表里 都包含创建时间/修改时间的字段. 如果每次操作表,都手动的去维护时间信息.则响应开发效率. 能否优化策略.
解决策略: MybatisPlus 实现自动填充功能.
实现元对象处理器接口:com.baomidou.mybatisplus.core.handlers.MetaObjectHandler
注解填充字段 @TableField(… fill = FieldFill.INSERT) 生成器策略部分也可以配置!
新增操作 需要自动填充 created/updated.
修改操作 需要自动填充 updated
@Component //将对象交给Spring容器管理
public class MyMetaObjectHandler implements MetaObjectHandler {
//当数据库做新增操作时,自动调用 API调用 不需要问为什么
//metaObject对象 是MP自动填充的配置 有默认行为
@Override
public void insertFill(MetaObject metaObject) {
//获取当前时间
Date date = new Date();
this.setFieldValByName("created", date, metaObject);
this.setFieldValByName("updated", date, metaObject);
}
//当数据库做修改操作时,自动调用
@Override
public void updateFill(MetaObject metaObject) {
//获取当前时间
Date date = new Date();
this.setFieldValByName("updated", date, metaObject);
}
}
3. 关于事务说明
3.1 什么是事务
说明: 如果后台服务器执行正常,则业务正确,事务提交. 如果业务执行失败.事务应该回滚.
3.2 现有代码的业务测试
说明: 如图如果程序执行过程中有报错信息.应该实现事务的回滚. 但是发现现有代码有2个问题
1: 没有添加事物.
2. 后台服务器报错之后,用户没有提示.
一般控制异常信息. 通常情况下需要添加try-catch 用法.
弊端: 所有的方法都需要try-catch的控制. 必然导致代码的结构复杂.
解决方案: Spring内部提供了一种规则 全局异常的处理机制.
Spring为了整合全局异常的处理 开发了如下的注解
1.@RestControllerAdvice //定义全局异常的处理类 返回值JSON串
2.@ExceptionHandler 标识拦截的异常的类型,如果类型匹配,则执行方法
@RestControllerAdvice 类上
@ExceptionHandler(RuntimeException.class) 方法上
如何利用对象封装3级菜单结构?
一级菜单
children-----> 二级菜单信息
children-------> 三级菜单信息
数据结构: Map
Key=“父级ID” Value=List<当前父级的子级>
用法: 如果想要获取任意父级的子级 map.get(父级的ID)
用法说明: Value 只有父级的子级信息,没有嵌套结构
Map<父级ID,List
1.封装Map集合 Map
2.说明: 将所有的数据库的父子关系,进行封装.(没有嵌套!!!!)
3.优势: 只查询一次数据库,就可以完成父子关系的封装.
策略:
1. key不存在, 准备一个新List集合,将自己当作第一个元素追加
2. key存在, 获取原有list集合,将自己追加.
1.如果被删除的标签是3级标签,则可以直接删除.
2.如果被删除的标签是2级标签,则需要先删除3级,再删除2级.
3.如果被删除的标签是1级标签,则需要先删除3级,在删除2级.最后删除1级.
定义过滤器
Vue.filter("定义过滤器名称",function(参数){ 过滤器需要添加return
Item表: 主要封装了商品的基本信息.
ItemDesc表: 主要封装商品详情信息(大字段—html代码片段)
原因: 如果用户频繁的查询大字段 则影响效率. 所以将商品信息分为item和itemDesc
关联关系: item.id = itemDesc.id ID的值一致的.
问题分析:
* 1.item入库之后,才会有主键信息. 对象理论上的ID=null
* 2.itemDesc入库时,必须获取与Item.id一样的数据.
* 如何解决:
* 设定主键自动回显功能!!!!!
* 如何设计:
* 开启主键自增 主键回显的配置 Mybatis原生操作
*
*
*
* MybatisPlus:
* MP在完成入库操作时,自动的实现了数据的回显功能. 所以ID是有值的.
* 知识: 哪种情况会有自动的回显功能!!!!!
* BUG: 由于测试数据可能会出现重复的现象. 需要提前删除多余的记录
匹配确定的次数:
例子: 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
理解:文件上传路径的作用
工作目录
命令: 解压指令 ’ tar -xvf jdk-8u51-linux-x64.tar.gz ’
命令2: 删除安装文件 rm -f jdk-8u51-linux-x64.tar.gz
命令3: 修改文件名称 mv jdk1.8xxxxxx jdk1.8
如果检查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系统即可.
数据库安装文档
说明: 如果做重大操作时,可能带来不可挽回的影响,则提前打快照,保留当前的状态.
说明: 将来所有的图片都会上传到Linux的目录中,所以需要进行修改
说明: 如果打包问题,则检查maven的配置!!!
命令: java -jar 8091.jar
启动效果:
1.检查端口号是否正确
2.测试数据库链接是否正常 如果出现如图效果 ,则表示一切OK
将后台服务器修改端口号之后,install 生成8091/8092. 传入Linux系统
命令: java -jar 8091.jar & java -jar 8092.jar &
启动成功之后,回车跳入Linux系统.
弊端: 与当前的Session绑定. 如果Session关闭,则服务器全部停止.
说明: 由于操作不当,可能导致前一个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关闭.则服务停止.
这种前台的启动只适用于测试阶段.可以直观的反应报错的信息.
命令: nohup java -jar 8091.jar => 8091.log &
说明: 通过上述命令可以实现后台启动,不会与session绑定.
cat 输出文件所有的内容 文件内容较少的场景
more 输出文档所有的内容,分页输出,空格浏览下一屏,q退出
less 用法和more相同,只是通过PgUp、PgOn键来控制
tail 用于显示文件后几号,使用频繁
tail -10 nginx.conf 查看nginx.conf的最后10行
tail –f nginx.conf 动态查看日志,方便查看日志新增的信息
ctrl+c 结束查看
说明: Linux系统中提供了shell脚本. 可以提供批处理的机制.
注意事项: 标识符 xxx.sh 注意表头
编辑脚本: vim start.sh
运行脚本: sh start.sh
通常用户访问服务器, 可以通过IP或者域名的方式访问. 域名与IP应该是一一对应的.
域名:由三大运营商负责提供的. 同时兼容DNS服务.
DNS说明: 全球的域名解析服务. 域名名称------IP地址 (一般有演示 1-2天, 2小时有效)
规则: 如果在本机进行业务测试. 则windows/Linux系统,提供了一个测试的文件.在该文件中可以编辑域名与IP的映射关系. 但是只对本机有效. 该文件就是hosts文件.
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
特点:
1.nginx 是反向代理服务器/web服务器
2.占用内存少 不到2M tomcat 300-400M
3.并发能力强 3-5万次/秒
tomcat并发能力 150-220次/秒 JVM调优(增大运行内存) 1000次/秒
4.解析:
1.功能简单 只做请求的"转发"处理
2.开发语言 C语言
URL:http://nginx.org/en/download.html
去找收藏
反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。反向代理服务器通常可用来作为Web加速,即使用反向代理作为Web服务器的前置机来降低网络和服务器的负载,提高访问效率。
总结:
1. 代理服务器位于 用户和服务器之间
2. 用户以为代理服务器就是目标服务器.
3. 用户无需了解真实服务器地址.
4. 反向代理服务器保护了 服务器端的信息 (服务器端代理)
3.3.2 正向代理(了解)
正向代理,意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从目标服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。
特点:
1. 代理服务器位于用户与服务器之间
2. 用户了解访问的服务器到底是谁.
3. 只有用户可以使用正向代理 (客户端代理)
4. 正向代理保护了用户的信息.
小结:
1. 反向代理保护了服务器信息. 称之为服务器端代理(业务数据获取)
2. 正向代理保护了用户的信息. 称之为客户端代理. (网络出口)
3. 用户每次请求几乎都有正向和反向代理的影子.
http {
#每个服务都是一个server
server {
#默认监听80端口
listen 80;
#监听域名信息
server_name localhost;
#具体反向代理服务 / 默认写法
location / {
#root 代理的是一个目录
root html;
#默认访问页面
index index.html index.htm;
}
}
}
2.修改AddItem.vue 文件 指向远程服务器
项目打包
2.打包之后的路径 打包生成dist文件目录.
将前端打包好的目录dist 上传到指定的位置 /usr/local/nginx 目录下
通过http://web.jt.com:80 访问前端的静态资源文件.
修改nginx配置文件:
#配置前端服务器
server {
listen 80;
server_name web.jt.com;
location / {
root dist;
index index.html;
}
}
启nginx服务
说明: 前端项目 web.jt.com 向后端服务器 manage.jt.com 发送请求.
问题: 后端服务器有8091/8092都可以为用户提供服务.
难点: 通过域名负载均衡一个服务器 为用户提供数据支持.
#一次请求,访问一个服务器 集群的配置 负载均衡机制
# upstream 集群的关键字.
# tomcats 是集群的名称 可以任意 xxxx
# server 每个服务的地址
# 默认采用轮询的策略,依次访问服务器.
upstream tomcats {
server 192.168.126.129:8091;
server 192.168.126.129:8092;
}
#配置后端服务器 8091/8092
#后端域名 manage.jt.com
server {
listen 80;
server_name manage.jt.com;
location / {
#proxy_pass 反向代理服务器发起是一个http请求
proxy_pass http://tomcats;
}
}
说明: 修改成功之后,上传nginx.conf文件 之后重启服务器.
组成部分: 1. 工作区 2.缓存区 3.本地仓库 4.远程仓库
网址: https://git-scm.com/downloads
说明: 下载成功,之后一路下一步即可.