简单实现前后端数据交互
- 功能要求
- 主要涉及框架
- 后端
- 新建项目
- 新建数据库
- 编写实体类
- 编写映射类
- 编写控制器
- 前端
- head
- body
- 1.用户接口 UI
- 2. JS 交互
- 运行测试
- 总结
功能要求
简单实现 员工信息 从 后端 服务器 数据库 加载 并 动态渲染 在Web端,以及Web端新增 员工信息 发送给 后端服务器 写入 数据库 中,实现前后端的数据交互。
主要涉及框架
- Bootstrap
- Vue
- ajax
- Spring Boot
后端
新建项目
首先新建一个 Spring Starter Project 工程,勾选以下 4 个依赖
整个项目的包结构如下,可在 java 包下新建了3个包,分别用来存放控制器类、实体类和映射类,在 resources 包的 static 包下新建了一个 hr 页面,以及在这新建一个 js 文件夹用来存放写前端页面用到的 vue.js 和 axios.js 库,这样就可以从本地导入所需库,加快程序的部署与运行。
新建数据库
新建一个 hr 数据库,创建一个 员工表 employee,表结构如下
向表中插入几条数据
在配置文件 application.properties 中配置 数据源,MySQL的端口号默认是3306,但我电脑装了两个,这里避免冲突混淆,所以指定的端口号是5306,这里需要根据你自己的设定来配置。
编写实体类
在 entity 包下新建一个实体类Employee,对应上面创建的员工表
public class Employee {String name;char gender;String position;public Employee() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public char getGender() {return gender;}public void setGender(char gender) {this.gender = gender;}public String getPosition() {return position;}public void setPosition(String position) {this.position = position;}}
编写映射类
在mapper包下新建一个接口EmployeeMapper,作为员工表的映射,记得加上注解 @Mapper 标记为映射,在里面声明两个方法,分别是查找所有员工信息和插入一条员工信息,分别用 @Select 和 @Insert 注解标记
import java.util.List;import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;// 员工表映射@Mapper
public interface EmployeeMapper {/*** 查找全部员工信息* @return*/@Select("select name,gender,position from employee")List<Employee> findAll();/*** 插入一条员工信息* @param employee*/@Insert("insert into employee(name,gender,position) values(#{name},#{gender},#{position})")void save(Employee employee);
}
编写控制器
在controller包下新建一个HomeController类,加上 @Controller 注解标记为控制器,当请求根目录时返回视图的名字
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class HomeController {@RequestMapping("/")public String home() {return "hr.html";}
}
再新建一个EmployeeController 类,并标记为 @RestConroller ,这样请求 URL 时返回 JSON 数据而不是视图名,在里面维持一个EmployeeMapper的引用,并标记为自动加载 @Autowired,编写两个方法,分别是获取所有员工信息和新增员工信息,在方法里调用EmployeeMapper对象相应的方法,并加上HTTP 请求操作的注解 @GetMapping、@PostMapping,由于 ajax 返回的是JSON数据,参数必须加上 @RequestBody注解
import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;// 控制器@RestController
public class EmployeeController {@Autowiredpublic EmployeeMapper employeeMapper;// 查询@GetMapping("/employee")public List<Employee> find(){return employeeMapper.findAll();}// 插入@PostMapping("/employee")public void add(@RequestBody Employee employee) {employeeMapper.save(employee);}
}
前端
head
编写前端页面 hr.html,用到了 Bootstrap、Vue 和 axios 库,需要在头部导入相应的资源
<head><title>人力资源管理</title><!-- Required meta tags --><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><!-- Bootstrap CSS --><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"><!-- Vue.js 本地库--><script src="js/vue.js"></script><!-- axios.js 本地库 --><script src="js/axios.min.js"></script></head>
body
在 body 标签里编写内容,主要分为 两部分
1.用户接口 UI
<!-- 用户接口 --><div id="app" class="container"><!-- 巨幕、展板 --><div class="jumbotron"><h1 class="display-3">人力资源管理</h1><p class="lead">员工管理</p></div><!-- 面包屑导航 --><nav class="breadcrumb"><a class="breadcrumb-item" href="#">首页</a><a class="breadcrumb-item" href="#">部门管理</a><span class="breadcrumb-item active">员工管理</span><a class="breadcrumb-item" href="#">考勤管理</a></nav><!-- 容器 --><div class="container"><!-- 按钮 模态框 --><!-- Button trigger modal --><button type="button" class="btn btn-outline-success btn-lg my-3" data-toggle="modal" data-target="#modelId">录入新员工</button><!-- Modal --><div class="modal fade" id="modelId" tabindex="-1" role="dialog" aria-labelledby="modelTitleId" aria-hidden="true"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><h5 class="modal-title">录入新员工</h5><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button></div><div class="modal-body"><div class="form-group"><label for="">姓名</label><!-- v-modal 数据的双向绑定--><input v-model="name" type="text" class="form-control" name="" id="" placeholder="请输入姓名"></div><div class="form-group"><label for="">性别</label><input v-model="gender" type="text" class="form-control" name="" id="" placeholder="请输入性别 (男 or 女)"></div><div class="form-group"><label for="">职位</label><input v-model="position" type="text" class="form-control" name="" id="" placeholder="请输入职位"></div></div><div class="modal-footer"><button type="button" class="btn btn-danger" data-dismiss="modal">取消</button><!-- @click 点击事件绑定 --><button @click="add()" type="button" class="btn btn-success" data-dismiss="modal">新增</button></div></div></div></div><!-- 表格 --><table class="table"><thead class="table-dark text-center"><tr><th><input type="checkbox"></th><th>姓名</th><th>性别</th><th>职位</th><th>技能</th><th>操作</th></tr></thead><tbody><!-- v-for 声明式渲染 表格 数据 --><tr v-for="(emp, index) in empList"><td class="text-center"><input type="checkbox"></td><td>{{empList[index].name}}</td><td>{{empList[index].gender}}</td><td>{{empList[index].position}}</td><td>暂无</td><td>暂无</td></tr></tbody></table><!-- 分页 导航 --><nav aria-label="Page navigation"><ul class="pagination pagination justify-content-center"><li class="page-item disabled"><a class="page-link" href="#" aria-label="Previous"><span aria-hidden="true">上一页</span><span class="sr-only">Previous</span></a></li><li class="page-item active"><a class="page-link" href="#">1</a></li><li class="page-item"><a class="page-link" href="#">2</a></li><li class="page-item"><a class="page-link" href="#" aria-label="Next"><span aria-hidden="true">下一页</span><span class="sr-only">Next</span></a></li></ul></nav></div></div>
2. JS 交互
定义用户、网络的交互行为
<script>let v = new Vue({el: '#app',data: {name: '',gender: '',position: '',empList: []},methods: {// 新增员工add: function() {let p = {'name': this.name,'gender': this.gender,'position': this.position};// 发送数据给服务器axios.post('/employee', p).then(res => {console.log(res)}).catch(err => {console.error(err);})}},created() {console.log('---- created');// 从服务器获取数据axios.get('/employee').then(res => {console.log("获取结果:" + res)console.log(res.data);this.empList = res.data;}).catch(err => {console.error(err);})},})</script>
运行测试
启动 Spring Boot App,随后通过浏览器访问 http://127.0.0.1:8080/ ,数据都被加载出来,并声明式的渲染到表格中
新增员工信息,通过点击录入新员工按钮,在弹出的模态框中填入信息并点击新增按钮。
刷新页面,可以看到新增的员工信息也被加载出来
再查看一下数据库,新增的信息也被插入到数据库中了
总结
到此为止,功能要求基本都实现了。通过请求 URL 返回页面,页面被创建时向服务器发出GET请求,获取所有员工信息,使用Vue框架的声明式渲染把数据动态填充到页面表格中。当新增员工信息时,向服务器发出POST请求,把JSON数据传给后端服务器,服务器写入数据库中。