前面知识点大概都讲完了,今天来说一下星期天做的前后端交互的Demo,进行知识的汇总,查漏补缺。
这个Demo主要是把数据库中的信息展现到前端页面,用户通过点击按钮进行增删改查的操作。
流程图:
一、前端页面的搭建
工具:HBuilder X
语言:HTML、JS、CSS
框架:VUE
1.前端页面框架的搭建
1.1 项目结构vue基本框架搭建
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>前后端交互案例</title>
<script src="../js/axios.js" type="text/javascript"></script>
<script src="../js/vue.js" type="text/javascript"></script>
</head>
<body>
<div id="app">
<!-- 用户修改 -->
<div id="">
</div>
<!-- 用户新增 -->
<div id="">
</div>
<!-- 用户列表 -->
<div id="">
</div>
</div>
<script type="text/javascript">
const app=new Vue({
el:"#app",
data:{
}methods:{
},
created() {
}
})
</script>
</body>
</html>
知识点:
注意导入Ajax和vue的JS文件
注意生命周期函数created在VUE对象的根目录写,不在methods里写,由系统在完成创建对象后自动调用
1.2根据数据库数据进行内容填充
用户修改:
<div id="" align="center">
<h2>用户修改</h2>
编号:<input type="text" name="" id="" value="" disabled/>
姓名:<input type="text" name="" id="" value="" /><br>
年龄:<input type="text" name="" id="" value="" />
性别:<input type="text" name="" id="" value="" /><br>
<button type="button">确认修改</button>
</div>
用户新增:
<div id="" align="center">
<h2>用户新增</h2>
姓名:<input type="text" name="" id="" value="" />
年龄:<input type="text" name="" id="" value="" />
性别:<input type="text" name="" id="" value="" />
<button type="button">确认新增</button>
</div>
用户列表:
<div id="">
<table border="" cellspacing="" cellpadding="" align="center" width="80%">
<tr><th colspan="5"><h2>用户列表</h2></th></tr>
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>操作</th>
</tr>
<tr v-for="user in userList">
<td v-text="user.id"></td>
<td v-text="user.name"></td>
<td v-text="user.age"></td>
<td v-text="user.sex"></td>
<td align="center" width="15%">
<button type="button">修改</button>
<button type="button">删除</button>
</td>
</tr>
</table>
</div>
页面展现:

知识点:
用户修改编号的值不可以改,所以加disabled关键字不可输入
用户列表作为表名要合并列,加colspan="5"进行合并5列
v-for="user in userList" for循环 user为每一个属性 userList为要循环遍历的数组名
v-text 防止闪现问题的出现
1.3用户数据的填充
<script type="text/javascript">
axios.defaults.baseURL="http://127.0.0.1:8888/vue"
const app=new Vue({
el:"#app",
data:{
userdata:[]
}methods:{
userList(){
axios.get("findAll").then(promise => {
this.userdata=promise.data
})
}
},
created() {
this.userList()
}
})
</script>
知识点:
axios.defaults.baseURL语句定义默认URL地址头,一般在最开始写入,简化后面地址的编写
思路:在数据区定义一个空数组用来存放用户数据,添加userList方法用Ajax请求获取后端调用数据库的数据赋值给userdata空数组,created在页面展现之初就会默认执行,所以用它调用userList方法,使页面一加载就会展现出数据
二、后端项目的搭建
工具:IDEA
语言:JAVA
框架:Springboot、Spring、SpringMVC、Mybatis、MybatisPlus
1.后端项目框架的搭建
1.1核心配置文件
#端口配置
server:
port: 8888
#配置数据源
spring:
datasource:
#如果使用高版本驱动 则添加cj
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
#Spring整合MybatisPlus
mybatis-plus:
#定义别名包
type-aliases-package: com.jt.pojo
#导入映射文件
mapper-locations: classpath:/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
#为这个包下的sql打印日志
logging:
level:
com.jt.mapper: debug
知识点:
yml文件有严格的层级结构,注意前面的空格
不手动编写,直接复制粘贴进行具体业务内容的修改即可
1.2映射文件
<?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">
<mapper namespace="com.jt.mapper.UserMapper">
</mapper>
知识点:
注意持久层对应的接口
单表CRUE的操作改用MP,多表查询或者又复杂查询时再用Mybatis在此文件中编写sql语句
一般不在resources的根目录下,应重新建目录文件存放在里面
1.3启动类
package com.jt;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.jt.mapper")
public class RunApp {
public static void main(String[] args) {
SpringApplication.run(RunApp.class );
}
}
知识点:
手动添加包扫描,参数是持久层的全路径
写在大包下
1.4实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@TableName("demo_user")
public class User implements Serializable{
@TableId(type = IdType.AUTO)
private Integer id;
@TableField("name")
private String name;
@TableField("age")
private Integer age;
@TableField("sex")
private String sex;
}
知识点:
Lombok的使用简化代码编写
实现Serializable序列化接口:保证对象网络传输的有效性!!!
@TableName("demo_user")对应数据库的表名
@TableId(type = IdType.AUTO)主键添加自增
@TableField("name")如果属性名与数据库表字段名相同可以省略此注解
1.5持久层
public interface UserMapper extends BaseMapper<User> {
}
知识点:
继承BaseMapper<User>接口,就可以调用MP的基本CRUD的方法,必须传入泛型,传实体类名称
1.6业务层
接口
public interface UserService {
}
知识点:
在这里定义抽象方法,规范代码,解耦操作
接口实现类
@Service
public class UserServiceimpl implements UserService{
@Autowired
private UserMapper userMapper;
}
知识点:
进行IOC,交给spring管理
DI持久层,使用MP的方法
进行接口方法的重写,调用MP的具体方法完成业务功能
1.7控制层
@RestController
@RequestMapping("vue")
@CrossOrigin
public class UserController {
@Autowired
private UserService userService;
}
知识点:
@RestController包含@Controller和@ResponseBody两个注解,分别进行IOC交给spring管理和把java返回的对象变成JSON串传输
@RequestMapping("vue") URL定义类
@CrossOrigin解决跨域问题
DI入业务层进行业务的调用
1.8总体结构示例

三、前后交互设计
1.获取用户数据
前端发起Ajax请求数据,后端进行方法调用返回List集合
//所有用户数据
@GetMapping("findAll")
public List<User> findAll(){
return userService.findAll();
}
@Override
public List<User> findAll() {
return userMapper.selectList(null);
}
知识点:
在查询所有时,构造器直接传NULL即可
页面展现:

2.进行用户删除操作
前端发起Ajax请求删除数据,后端进行方法调用返回删除提示信息
前端代码
<button type="button" @click="deleteuser(user)">删除</button>
deleteuser(user){
axios.delete("deleteuser",{params:user}).then(promise => {
alert(promise.data)
this.userList()
})
}
思路:删除按钮添加点击事件并传入user参数,方法区添加方法发起删除Ajax请求,删除后弹出后端返回的删除成功提示信息,并再次调用userList方法进行列表的刷新操作
知识点:
delete和get传的参数为对象时要加{params:对象名}
后端代码:
@DeleteMapping("deleteuser")
public String deleteuser(Integer id){
userService.deleteuser(id);
return "删除成功";
}
@Override
public void deleteuser(Integer id) {
userMapper.deleteById(id);
}
知识点:
传入的时User对象,接收时可以接收User对象,也可以接收Integer id,因为mvc底层会从传入user对象自动进行拼接setid、setname等,只接受id后面用deleteById方法简单一点
页面展现:

王昭君成功删除了
3.进行用户新增操作
前端发起Ajax请求新增数据,后端进行方法调用返回新增提示信息
前端代码
<div id="" align="center">
<h2>用户新增</h2>
姓名:<input type="text" name="" id="" value="" v-model="useradd.name"/>
年龄:<input type="text" name="" id="" value="" v-model="useradd.age"/>
性别:<input type="text" name="" id="" value="" v-model="useradd.sex"/>
<button type="button" @click="postuser">确认新增</button>
</div>
useradd:{
name:'',
age:'',
sex:''
}
postuser(){
axios.post("postuser",this.useradd).then(promise => {
alert(promise.data)
this.userList()
this.useradd={}
})
}
思路:新建一个useradd对象用来与新增输入双向绑定,添加点击事件调用postuser方法进行Ajax请求发送,然后进行后端返回提示信息弹框,刷新列表,清空新增输入框内容
知识点:
post和put向后端传对象时可以直接传对象名称
后端代码:
@PostMapping("postuser")
public String postuser(@RequestBody User user){
userService.postuser(user);
return "新增成功";
}
@Override
public void postuser(User user) {
userMapper.insert(user);
}
知识点:
前端用post和put传入的是对象,后端接收的时候需要加@RequestBody注解:表示把json串转化为User对象
页面展现:

4.用户信息修改
前端发起Ajax请求修改数据,后端进行方法调用返回修改提示信息
前端代码:
<button type="button" @click="getuser(user)">修改</button>
getuser(user){
this.upuser=user
}
upuser:{
id:'',
name:'',
age:'',
sex:''
}
<div id="" align="center">
<h2>用户修改</h2>
编号:<input type="text" name="" id="" value="" disabled v-model="upuser.id"/>
姓名:<input type="text" name="" id="" value="" v-model="upuser.name"/><br>
年龄:<input type="text" name="" id="" value="" v-model="upuser.age"/>
性别:<input type="text" name="" id="" value="" v-model="upuser.sex"/><br>
<button type="button" @click="putuser">确认修改</button>
</div>
async putuser(){
let{data:result} =
await axios.put("upuser",this.upuser)
alert(result)
this.userList()
this.upuser={}
}
思路:通过修改按钮添加触发事件把当前user值赋值给定义的upuser对象,同时与修改输入框进行双向绑定,值出现在修改框里,进行修改后点击按钮触发点击事件进行Ajax向后台发起修改,弹出后端修改成功返回的值,刷新列表,把修改框清空。
知识点:
put传对象可以直接传
Ajax新写法,同一行调用一个方法执行,防止BUG
后端代码:
@PutMapping("upuser")
public String upuser(@RequestBody User user){
userService.upuser(user);
return "修改成功";
}
@Override
public void upuser(User user) {
userMapper.updateById(user);
}
知识点:
post和put接收json对象需要加@RequestBody注解
updateById方法解析对象的值,id为where条件,其他为要修改的值
如果有重复的条件和修改的值可以用restFul+对象的方式传输,后端接收时需要分别加@RequestBody和@PathVariable注解,接收的url需要更换名称,否则会覆盖,引发BUG,具体如下
@PutMapping("updateUserByName/{wherename}")
//restFul可以尾对象的属性赋值
//注意restFul的名称不要与属性重名,否则会覆盖,引发BUG
public String ccc(@RequestBody User user,@PathVariable String wherename){
userService.upp3(user,wherename);
return "修改成功";
}
页面展现:

到这里这个小Demo就结束了!
满怀希望就会所向披靡!!!
7万+



被折叠的 条评论
为什么被折叠?



