同步请求和异步请求
- 同步:指单线程依次做几件事
- 异步:指多线程同时做几件事
- 同步请求: 指客户端浏览器只有一个主线程,负责渲染页面和发出请求等操作, 如果主线程发请求的话则会停止渲染页面,直到服务器响应了数据之后再次显示, 由于主线程发出请求时会清空原有内容,这样同步请求只能实现页面的整体刷新,无法实现局部刷新.
- 异步请求:指客户端由主线程负责渲染页面,发出请求用到子线程,这样子线程发出请求时原页面内容不受影响,可以将查询回来的内容展示在原页面基础之上, 这个过程称为局部刷新.
客户端如何发出异步请求?
- 通过Axios前端框架发出异步请求
- 在html页面中引入 axios框架文件
canglaoshi.org中的配置文件下载中的JavaScript 组件库
Axios参数中get和post请求的区别
- 从字面意思理解, get是跟服务器要数据, post是给服务器上传数据
- get:请求参数在请求地址的后面(可见), 请求参数的大小有限制只能上传几k的数据(所以文件上传不会使用get)
- 应用场景: 查询请求基本都使用get, 删除请求一般也使用get
get异步请求获取参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>首页</h1>
<div>
<h2>{{info}}</h2>
<input type="button" value="异步请求get" @click="f1()">
<input type="button" value="异步请求post" @click="f2()">
</div>
<script src="js/vue.min.js"></script>
<script src="js/axios.min.js"></script>
<script>
let v = new Vue({
el:"div",
data:{
info:"测试Vue"
},
methods:{
f1(){
// alert("方法执行了!");
//发出异步请求 向/helloAxios发出异步的get请求
//response代表响应对象, 里面的data属性是服务器响应的内容
axios.get("/helloAxios?info=tom").then(function (response) {
alert("服务响应内容:"+response.data);
})
},
}
})
</script>
</body>
</html>
package cn.tedu.boot33.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AxiosController {
@RequestMapping("/helloAxios")
public String helloAxios(String info){
return "测试成功!"+info;
}
}
- post:请求参数在请求体里面(不可见),参数没有大小限制
- 应用场景:文件上传,带有敏感信息的参数比如密码(注册和登录), 需要从form表单中获取数据时使用post请求代码更简洁(document.querySelector("form"))
Axios优化
回调地狱
业务中经常遇到A的数据来源B,B的数据来源C.以此类推, 则形成了Ajax嵌套的结构. 如代码所示:
<script>
axios.defaults.baseURL = "http://localhost:8080"
/**
* 需求:
* 1.发送第一个ajax请求之后得到的结果
* 当做第二个ajax的参数
*/
let user = {id:100, name:"tomcat猫", age: 20}
axios.post("/axios/saveUser",user)
.then(function(promise){
console.log(promise.data)
let arg1 = promise.data
/* 第二个ajax*/
axios.post("/axios/xxxx",arg1)
.then(function(promise2){
console.log(promise2.data)
let arg2 = promise2.data
axios.post("/axios/xxx2",arg2)
.then(function(promise3){
console.log(promise3.data)
})
})
})
</script>
回调地狱问题说明
由于Ajax不断的嵌套,导致代码的耦合性高,不便于维护.
如何解决问题: 将Ajax的请求由2行,变为一行.
回调地狱优化-async-await
1. async 控制同步异步 标识函数
2. await 标识Ajax请求
<script>
axios.defaults.baseURL = "http://localhost:8080"
/**
* 1.定义一个函数
* 规则:
* 1. async 标识函数
* 2. await 标识请求
* 3. 2者必须同时出现
* 4. 可以直接获取then中的回调对象promise
*/
async function saveUser(){
let user = {id: 100,name:"春节已过!!!"}
let promise = await axios.post("/axios/saveUser",user)
console.log(promise.data)
}
/* 2.调用函数 */
saveUser()
</script>
箭头函数写法
/* 3.箭头函数写法
1.去除function关键字
2.参数与函数体之间使用 => 连接
3.如果只有一个参数,则参数括号可以省略
4.箭头函数使用一般用于回调函数
5.如果使用function关键字 则使用this时会产生歧义
*/
let user2 = {id: 200,name:"箭头函数!!!"}
axios.post("/axios/saveUser",user2)
.then(function(promise){
console.log(promise.data)
})
axios.post("/axios/saveUser",user2)
.then( promise => {
console.log(promise.data)
})
Mybatis
导入数据库
1.使用SqlYog连接数据库
2.检查Mysql数据库的服务是否启动
3.导入数据库
4.JDBC连接数据库
```java
//利用jdbc,完成新增的功能
private static void method2() throws Exception{
//1,注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2,获取数据库的连接
//数据传输协议 数据库的ip 端口号 数据库名
String url = "jdbc:mysql://localhost:3306/cgb2107";
Connection c = DriverManager.getConnection(url,"root","root");
//3,获取传输器
Statement s = c.createStatement();
//4,利用传输器执行 增删改的SQL
//executeUpdate()用来执行增删改的SQL,只返回影响行数
int rows = s.executeUpdate(
"INSERT INTO emp(ename,job) VALUES('rose','副总')");
//5,释放资源
//r.close();//结果集
s.close();//传输器
c.close();//连接
}
结论: 采用JDBC的方式去操作数据库,开发效率低, JDBC的运行效率是最高的.
Mybatis
概念
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
*持久化: 将内存中的数据保存到磁盘中的过程.
*持久层: 利用Mybatis操作代码Mapper/Dao,实现数据的持久化.
*高级映射: 对象与数据表一一映射,对象中的属性与数据表中的字段一一映射.
*简化操作: 将JDBC代码进行简化,从对象的角度考虑问题,实现数据操作. (面向对象的方式操作数据库)
Mybatis项目创建
1.创建新的项目mybatis_demo1
2.导入pom.xml文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--mybatis依赖包-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!--jdbc依赖包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--添加lombok的包-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
lombok插件安装
作用: 为POJO对象自动生成get/set/构造/toString/equals等方法.以后无需程序员手动的操作.
1.插件安装:
2.手动导入
网址: https://plugins.jetbrains.com/plugin/6317-lombok
从本地中选择lombok文件,安装完成之后,重启即可
导入src文件
lombok说明
使用步骤
- 在pom.xml文件中添加jar包
- 在IDEA中安装lombok的插件
- 在POJO中使用注解
lombok常用注解
检查是否有效:
链式加载
说明: 重写Set方法,要求用户的数据返回,返回User对象.
注解: @Accessors(chain = true) //开启链式加载
package com.jt.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data //Getter, Setter, RequiredArgsConstructor,
// ToString, EqualsAndHashCode, Value
@NoArgsConstructor //无参构造
@AllArgsConstructor //全参构造
@Accessors(chain = true) //开启链式加载
public class User implements Serializable {
private Integer id;
private String name;
private Integer age;
private String sex;
/*public User setId(Integer id){
this.id = id;
return this;
}*/
/*public void addUser(){
User user = new User();
user.setId(1000)
.setName("tomcat")
.setAge(18)
.setSex("男");
}*/
}
Mybatis入门案例
pom中导入jar包
<!--mybatis依赖包-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!--jdbc依赖包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--添加lombok的包-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
程序连接数据库
application.yml文件是SpringBoot的配置文件.
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
#yml文件 0不解析 如果字母以0开头则引号包裹
#password: "0123456"
password: root
编辑UserMapper.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">
<!--1.namespace是mybaits映射文件的唯一标识,与接口对应-->
<mapper namespace="com.jt.mapper.UserMapper">
<!--2.执行业务操作
id: 与接口方法一一对应.
resultType: 返回的POJO对象类型全路径
将结果集自动的封装为对象
-->
<select id="findAll" resultType="com.jt.pojo.User">
select * from demo_user
</select>
<!-- <insert></insert>
<update></update>
<delete></delete>-->
</mapper>
Spring整合Mybatis
#3.配置Mybatis
mybatis:
#定义别名包
type-aliases-package: com.jt.pojo
#将所有的映射文件全部加载
mapper-locations: classpath:/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
#4.打印Sql com.jt.mapper下的Sql日志
logging:
level:
com.jt.mapper: debug
Mybatis的测试
package com.jt;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
/**
* 要求:
* 1.测试注解的包路径 必须在主启动类的同包及子包中
* 2.该注解只能在测试方法中使用
* 3.该注解的作用:启动时会启动spring容器(创建对象),
* 可以从容器中注入任意对象!!!
*/
@SpringBootTest
public class TestMybatis {
@Autowired //按照类型进行的set注入
private UserMapper userMapper;
@Test
public void testFindAll(){
System.out.println(userMapper.getClass());
List<User> userList = userMapper.findAll();
System.out.println(userList);
}
}
注解:
@SpringBootTest
要求:
1.测试注解的包路径 必须在主启动类的同包及子包中
2.该注解只能在测试方法中使用
3.该注解的作用:启动时会启动spring容器(创建对象),可以从容器中注入任意对象!!!
补充:
Axios参数中post向login提交v.user,然后Contoller层对v.user处理后得到一个值,将值返回给Axios中的response.data进行处理