CGB2107-Day07-实现前后端调用
1. 框架整理
1.1 展现Sql日志
#语法: 1.key:(空格)value结构
# 2.注意层级缩进
server:
port: 8090
#整合1.数据源
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: "0123456"
#SpringBoot整合mybatis
mybatis:
#指定别名包
type-aliases-package: com.jt.pojo
#加载指定的xml映射文件
mapper-locations: classpath:/mybatis/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
#Sql日志文件打印
logging:
level:
com.jt.mapper: debug
1.2 SpringMVC参数传递说明
1.2.1 简单参数传值
说明: 利用MVC可以直接将参数写到方法中,可以直接获取.
/**
* URL:http://localhost:8090/mvc?name="李四"
* @return
*/
@GetMapping("/mvc")
public Object testDemo(String name){
return "参数名称:"+name;
}
123456789
1.2.2 对象接收数据
说明: 如果用户传递的数据有多个, 则可以使用对象接收.
/**
* URL:http://localhost:8090/mvc?name="李四"&age=18&sex="女"
* 说明: 如果使用对象的方式进行接收,则必须有Setxx方法.
* @return
*/
@GetMapping("/mvc")
public Object testDemo(User user){
return "参数名称:"+user;
}
12345678910
1.2.3 对象的引用赋值
问题: 如果前端出现了同名提交的参数问题.则直接影响后台数据接收.所以前端参数要求不能出现重名属性.
解决方案: 利用对象的引用赋值.
<input type="text" name="name" value="二郎神"/>
<input type="text" name="age" value="3000"/>
<input type="text" name="dog.name" value="啸天犬"/>
<input type="text" name="dog.age" value="1800"/>
1.封装User对象
public class User {
private Integer id;
private String name;
private Integer age;
private Dog dog; //对象的引用
}
public class Dog {
private Integer id;
private String name;
private Integer age;
}
1.3 RESTFul业务说明
1.3.1 编辑UserController方法
/**
* 作业:
* 5. 更新操作 利用restFul的结构, 根据Id修改数据,修改name/age
* URL:http://localhost:8090/user/貂蝉/18/227 PUT
* 查询: http://localhost:8090/user/18 GET
* 解析: URL:http://localhost:8090/user/{name}/{age}/{id}
*
* RestFul语法:
* 1.用户url编辑
* 1.1 参数与参数之间使用/分割.
* 1.2 restFul结构顺序一旦确定,不能随意更改
* 1.3 如果使用restFul结构,请求路径中不能出现动词.隐藏目的.
*
* 2.用户规范:
* 由于restFul结构请求路径都是名词,所以不能区分业务逻辑.
* 所以采用请求类型,严格区分业务需求.
* 2.1 GET 查询操作
* 2.2 POST 新增操作/form表单提交
* 2.3 PUT 修改操作
* 2.4 DELETE 删除操作
*
* 3.参数接收
* 1.参数与参数之间使用/分割.
* 2.参数必须使用{xxx}包裹
* 3.使用特定的注解@PathVariable("name") String name 接收参数
* 4.如果接收参数的名称与对象中的属性名称一致,则可以使用对象接收
*
*/
@GetMapping("/user/{name}/{age}/{id}")
public Object restFul(User user){
userService.update(user);
return "数据更新成功!!!";
}
1.3.2 编辑UserService
- 接口写法
public interface UserService {
void update(User user);
}
1234
- 编辑业务实现类
@Override
public void update(User user) {
userMapper.update(user);
}
12345
1.3.3 编辑Mapper接口
//@Delete("xxxxx")
//@Insert("sql语句")
//@Select("查询操作的sql")
@Update("update demo_user set name=#{name}, age=#{age} where id=#{id}")
void update(User user);
12345
2. 前后端调用
2.1 VUE入门案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>VUE入门案例</title>
</head>
<body>
<h1>vue入门案例</h1>
<div id="app">
<h3>获取数据: {{msg}}</h3>
</div>
<!-- 使用步骤:
1.导入js.文件
2.准备根标签
3.创建vue对象,并且实现挂载.
4.定义属性.实现数据动态取值
知识补充: new Vue({}) 函数式编程
关于变量说明:
1. js中变量定义 早期 var 全局变量 没有作用域.
2. let有作用域的概念
3. const 常量定义 不允许修改
-->
<script src="../js/vue.js"></script>
<script>
//1.创建VUE对象
const app = new Vue({
//
el: "#app",
data: {
msg: "您好VUE JS"
}
})
</script>
</body>
</html>
2.2 VUE 生命周期函数(重点!!!)
2.2.1 生命周期函数图例
概念: 生命周期函数,是VUE针对与用户提供的扩展的功能.如果编辑了生命周期函数,则vue对象自动执行,无需手动调用.
生命周期函数种类:
- 初始化阶段 beforeCreate created beforeMount mounted VUE对象正在的实例化
- Vue对象的修改 beforeUpdate, updated
- 对象销毁 beforeDestroy destroyed
2.2.2 VUE生命周期函数案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试vue生命周期函数</title>
</head>
<body>
<div id="app">
<h3 v-text="msg"></h3>
<button @click="destroy">销毁</button>
</div>
<!--引入js函数类库 -->
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el : "#app",
data : {
msg: "vue生命周期"
},
//在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
beforeCreate(){
console.log("beforeCreate")
},
//在实例创建完成后被立即调用
created(){
console.log("created")
},
//在挂载开始之前被调用:相关的 render 函数首次被调用。
beforeMount(){
console.log("beforeMount")
},
//实例被挂载后调用,这时 el 被新创建的 vm.$el 替换了。
mounted(){
console.log("mounted")
},
//数据更新时调用,发生在虚拟 DOM 打补丁之前
beforeUpdate(){
console.log("beforeUpdate")
},
//由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
updated(){
console.log("updated")
},
//实例销毁之前调用。在这一步,实例仍然完全可用
beforeDestroy(){
console.log("beforeDestroy")
},
//实例销毁后调用。
destroyed(){
console.log("destroyed")
},
methods:{
destroy(){
//强制VUE对象执行销毁操作
this.$destroy()
}
}
})
</script>
</body>
</html>
2.2.3 生命周期函数难点讲解(了解)
- beforeCreate
官网说明: 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
解析: VUE对象被JS刚解析之后,实例化成功. 内部的属性暂时都为null. - created
官方说明: 在实例创建完成后被立即调用
解析: VUE对象开始加载其中的属性和属性的值,当加载完成,对象实例化成功!!! 仅限于创建不执行业务操作. - beforeMount
官方说明: 在挂载开始之前被调用:相关的 render 函数首次被调用。
解析: vue对象中 el: “#app”, 通过app指定的ID,将指定的区域交给Vue对象进行管理. - mounted
官方说明: 实例被挂载后调用,这时 el 被新创建的 vm.$el 替换了。
解析: 当对象创建完成之后,并且指定区域开始 “渲染”,将区域中的标签/表达式进行解析加载. 当数据加载成功之后,这时mounted执行完成.这时用户可以看到解析后的页面.
3 前后端调用Axios
3.1 Ajax
3.1.1 同步说明
同步特点: 一个线程成依次加载执行,如果数据没有加载完成则其他数据处于等待的状态.
3.1.2 异步说明
Ajax特点: 局部刷新,异步访问.
Ajax为什么可以异步: Ajax的设计原理-Ajax引擎
3.1.3 Ajax引擎
- 用户发起请求,交给Ajax引擎进行处理, 用户可以执行其它的操作.
- Ajax引擎接收到用户请求之后, 发起Http请求访问目标服务器.
- 后台服务器将数据返回给Ajax引擎.
- Ajax引擎 将最终获取的数据 通过回调函数的方式 交给用户处理.
3.2 Axios 案例练习
3.2.1 编辑页面JS
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>Ajax请求的测试</h1>
<!-- 1.引入JS -->
<script src="../js/axios.js"></script>
<!-- 2.axios入门 -->
<script>
/**
* 需求:获取后台服务器的业务数据
* URL: http://localhost:8090/getUser
* 参数说明:
* url: ajax的请求的地址.
* 参数: ajax请求的参数.
*/
let url = "http://localhost:8090/getUser"
axios.get(url)
.then(function(promise){
console.log(promise.data)
})
</script>
</body>
</html>
3.2.2 编辑后台UserController
4 Axios 作业练习
4.1 根据id查询数据
4.1.1 编辑页面html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Get请求练习</title>
</head>
<body>
<h1>Ajax项目前测试</h1>
<!-- 导入js jar包 -->
<script src="../js/axios.js"></script>
<script>
/**
* 总结: 前端Get请求参数传递的方式3种
* 方式1: 通过?属性=属性值的方法拼接.
* 方式2: 通过对象的方式实现数据传递.
* 方式3: 利用restFul的结构实现参数传递.
*
* 作业1: 根据ID查询用户信息
* 作业2: 根据age/sex查询用户信息
*/
/**
* 作业1
* url地址: http://localhost:8090/axios/findUserById
* 参数: id=1
* 返回值: console.log输出
*/
let url1 = "http://localhost:8090/axios/findUserById?id=1"
axios.get(url1)
.then(function(promise){
console.log(promise.data)
})
</script>
</body>
</html>
4.1.2 编辑AxiosController
package com.jt.controller;
import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin
@RequestMapping("/axios")
public class AxiosController {
@Autowired
private UserService userService;
/**
* 根据ID查询用户信息
* URL: http://localhost:8090/axios/findUserById?id=1
*/
@GetMapping("/findUserById")
public User findUserById(Integer id){
return userService.findUserById(id);
}
}
4.2 根据name和age查询数据
4.2.1 编辑HTML页面
/**
* 作业2: 根据age/sex查询用户信息
* url地址: http://localhost:8090/axios/findUserByAS
* 参数: id=1
* 返回值: console.log输出
* 知识点: 根据对象传递参数时,使用params关键字
*/
let url2 = "http://localhost:8090/axios/findUserByAS"
//封装对象
let user = {
age: 18,
sex: "女"
}
axios.get(url2,{params : user})
.then(function(promise){
console.log(promise.data)
})
1234567891011121314151617
4.2.2 F12 数据说明
4.2.3 编辑AxiosController
/**
* 根据age和sex查询数据
* URL地址:http://localhost:8090/axios/findUserByAS?age=18&sex=%E5%A5%B3
* 请求类型: get
* 参数: age/sex
* 返回值: list<User>
*/
@GetMapping("/findUserByAS")
public List<User> findUserByAS(User user){
return userService.findUserByAS(user);
}
123456789101112
4.2.4 编辑AxiosService
1.业务接口
- 编辑UserServiceImpl实现类
@Override
public List<User> findUserByAS(User user) {
return userMapper.findUserByAS(user);
}
12345