假期的我,好懒。
第五章:综合案例
【目标】
使用vue完成查询所有、更新、保存的操作
【路径】
1:案例需求
2:数据库设计与表结构
3:服务器端
4:浏览器端(vue)
【讲解】
5.1 案例需求
完成用户的查询与修改操作
前端(浏览器端):vue
后端(服务器端):spring boot+spring mvc+spring data jpa(spring的全家桶)
1
2
3Springboot:不需要在写spring的配置文件(xml),简化sprng开发。
Spring data jpa:用来操作数据库,很多方法都定义好了,不需要在sql语句,只需要做对象和数据库表的映射。
5.2 数据库设计与表结构
1
2
3
4
5
6
7
8
9
10CREATE DATABASE vue;
USE vue;
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT,
age INT,
username VARCHAR(20),password VARCHAR(50),
email VARCHAR(50),
sex VARCHAR(20)
)
导入数据:
INSERT INTO USER (username,PASSWORD,age,sex,email) VALUES ('张三','123',22,'男','zhangsan@163.com'),('李四','123',20,'女','lisi@163.com')
User类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class User {
private Integer id;
private String username;
private String password;
private String sex;
private Integer age;
private String email;
省略getter/setter
}
5.3 服务器端
【目标】
服务器端开发,使用springboot+springmvc+springdatajpa
【路径】
1:创建项目
2:导入jar包
3:配置文件(application.properties)
4:创建springboot引导类(启动tomcat)
5:创建实体
6:创建Dao
7:创建Service
8:创建Controller
5.3.1 创建项目
创建web工程 vue_day01_user
5.3.2 导入jar包
pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.atguigugroupId>
<artifactId>vue_day01_userartifactId>
<version>1.0-SNAPSHOTversion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.4.0.RELEASEversion>
parent>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
dependencies>
project>
5.3.3 配置文件(application.properties)
在resource
文件夹下面新建 application.properties
文件
1
2
3
4
5
6
7
8
9
10spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/vue
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.show-sql=true
spring.jpa.database=MySQL
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true:控制台显示jpa底层执行的sql语句
spring.jpa.database=MySQL:数据库是mysql
spring.jpa.generate-ddl=true:没有表,会根据实体中的映射配置,生成数据库表
spring.jpa.hibernate.ddl-auto=update:没有表,会根据实体中的映射配置,生成数据库表
5.3.4 创建springboot引导类
1
2
3
4
5
6
7
8
9
10
11
12
13package com.atguigu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
运行起步类(main方法),会自动启动内置的tomcat服务器,方便开发。
5.3.5 创建实体
创建包com.atguigu.domain,创建类User.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package com.atguigu.domain;
import javax.persistence.*;
/**
* User
*
* @Author: 马伟奇
* @CreateTime: 2020-01-05
* @Description:
*/
@Entity
@Table(name="user")
public class User implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private Integer id;
private String username;
private String password;
private String sex;
private int age;
private String email;
// 提供set、get、toString方法
}
@Entity:表示当前类是实体类
@Table:表示实体类名和表名的映射(如果实体类名和表名相同,可以省略)
@Id:表示该字段是主键id
@GeneratedValue:表示该主键是自增长
@Column:表示实体属性名和表中列名的映射(如果实体类属性名和表中列名相同,可以省略)
5.3.6 创建Dao
创建包com.atguigu.dao,创建接口UserDao.java
spring data jpa要求继承extends JpaRepository
1
2
3
4
5
6
7
8package com.atguigu.dao;
import com.atguigu.pojo.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserDao extends JpaRepository<User, Integer> {
}
5.3.7 创建Service
创建包com.atguigu.service,创建接口UserService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14package com.atguigu.service;
import com.atguigu.pojo.User;
import java.util.List;
public interface UserService {
public ListfindAll();
public User findOne(int id);
public void update(User user);
}
创建接口的实现类,UserServiceImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31package com.atguigu.service.impl;
import com.atguigu.dao.UserDao;
import com.atguigu.pojo.User;
import com.atguigu.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public ListfindAll() {
return userDao.findAll();
}
public User findOne(int id) {
return userDao.findOne(id);
}
public void update(User user) {
// 如果User存在ID,就是更新;如果User不存在ID,添加;
userDao.save(user);
}
}
注意:如果是高版本的spring data jpa,findOne方法的调用略有变化。
1
2
3
4
5
6
7
8@Override
public User findOne(Integer id) {
// User user = new User();
// user.setId(id);
// Example example = Example.of(user);
// User u = userDao.findOne(example).get();
return userDao.findById(id).get();
}
使用Example用来封装查询条件
5.3.8 创建Controller
创建包com.atguigu.controller,创建类UserController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36package com.atguigu.controller;
import com.atguigu.pojo.User;
import com.atguigu.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/findAll")
public ListfindAll(){
return userService.findAll();
}
// 使用restful接收id属性值;restful风格:url="user/findOne/10"
@RequestMapping("/findOne/{id}")
public User findOne(@PathVariable("id") Integer id){
return userService.findOne(id);
}
@RequestMapping("/update")
public void update(@RequestBody User user){
userService.update(user);
}
}
不使用restful风格接收id属性值
1
2
3
4
5// 使用传统方式接收id属性值;传统方式:url="user/findOne?id=10"
@RequestMapping("/findOne")
public User findOne(Integer id){
return userService.findOne(id);
}
5.4 浏览器端(重点)
【目标】
使用vue完成,查询所有,主键查询,更新保存功能
【路径】
1:介绍user.html
2:查询所有功能
3:主键查询功能
4:更新保存功能
拷贝页面到resources下的static中
5.4.1 user.html
我们把所有的vue的内容放置到user.js中
1
2
3<script src="./js/vuejs-2.5.16.js">script>
<script src="./js/axios-0.18.0.js">script>
<script src="./js/user.js">script>
5.4.2 查询所有
user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19var vue = new Vue({
el:'#app',
data:{
userList:[]
},
methods:{
findAll:function(){
axios.get("/user/findAll").then((response)=>{
this.userList = response.data;
})
}
},
created:function(){
this.findAll();
}
})
user.html
1
2
3
4
5
6
7
8
9
10
11
12
13<tr v-for="u in userList">
<td><input name="ids" type="checkbox">td>
<td>{{u.id}}td>
<td>{{u.username}}td>
<td>{{u.password}}td>
<td>{{u.sex}}td>
<td>{{u.age}}td>
<td class="text-center">{{u.email}}td>
<td class="text-center">
<button type="button" class="btn bg-olive btn-xs">详情button>
<button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#myModal" >编辑button>
td>
tr>
5.4.3 主键查询
user.html
添加:@click=“findOne(u.id)”
1
2
3
4<td class="text-center">
<button type="button" class="btn bg-olive btn-xs">详情button>
<button type="button" class="btn bg-olive btn-xs" @click="findOne(u.id)" data-toggle="modal" data-target="#myModal" >编辑button>
td>
user.js
写findOne方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26var vue = new Vue({
el:'#app',
data:{
userList:[],
user:{}
},
methods:{
findAll:function(){
var _this=this; //this代表是vue对象
axios.get("./user/findAll").then(function(response){
// this变成了window(可以使用_this或者vue)
vue.userList = response.data;
})
},
findOne:function(id){
var _this=this; //this代表是vue对象
axios.get("./user/findOne/"+id).then(function(response){
// this变成了window,使用_this
_this.user = response.data;
})
}
},
created:function(){
this.findAll();
}
})
对应的Controller
1
2
3
4
5// 使用restful接收id属性值
@RequestMapping("/findOne/{id}")
public User findOne(@PathVariable("id") Integer id){
return userService.findOne(id);
}
方案二:或者findOne方法可以使用正常传递参数:
1
2
3
4
5
6
7// get请求传递参数,方案一:
axios.get("./user/findOne",{params:{id:id}}).then(function (resposne) {
alert(JSON.stringify(resposne.data));
_this.user = resposne.data;
}).catch(function (error) {
})
对应的Controller
1
2
3
4
5
6// id查询
@RequestMapping(value = "/findOne")
public User findOne(Integer id){
User user = userService.findById(id);
return user;
}
user.html
数据绑定回显。使用 v-model=“user.username”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59<div id="myModal" class="modal modal-primary" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×span>button>
<h4 class="modal-title">用户信息h4>
div>
<div class="modal-body">
<div class="box-body">
<div class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">用户名:label>
<div class="col-sm-5">
<input type="text" class="form-control" v-model="user.username">
div>
div>
<div class="form-group">
<label class="col-sm-2 control-label">密码:label>
<div class="col-sm-5">
<input type="text" class="form-control" v-model="user.password">
div>
div>
<div class="form-group">
<label class="col-sm-2 control-label">性别:label>
<div class="col-sm-5">
<input type="text" class="form-control" v-model="user.sex">
div>
div>
<div class="form-group">
<label class="col-sm-2 control-label">年龄:label>
<div class="col-sm-5">
<input type="text" class="form-control" v-model="user.age">
div>
div>
<div class="form-group">
<label class="col-sm-2 control-label">邮箱:label>
<div class="col-sm-5">
<input type="text" class="form-control" v-model="user.email">
div>
div>
div>
div>
div>
<div class="modal-footer">
<button type="button" class="btn btn-outline" data-dismiss="modal">关闭button>
<button type="button" class="btn btn-outline" data-dismiss="modal">修改button>
div>
div>
div>
div>
5.4.4 更新
user.html
添加:@click=“update()”
1
2
3
4<div class="modal-footer">
<button type="button" class="btn btn-outline" data-dismiss="modal">关闭button>
<button type="button" class="btn btn-outline" @click="update()" data-dismiss="modal">修改button>
div>
user.js
编写update方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38var vue = new Vue({
el:'#app',
data:{
userList:[],
user:{}
},
methods:{
findAll:function(){
var _this=this; //this代表是vue对象
axios.get("./user/findAll").then(function(response){
// this变成了window(可以使用_this或者vue)
vue.userList = response.data;
})
},
findOne:function(id){
var _this=this; //this代表是vue对象
axios.get("./user/findOne/"+id).then(function(response){
// this变成了window
_this.user = response.data;
})
},
update:function(){
var _this=this; //this代表是vue对象
axios.post("./user/update",this.user).then(function(response){
_this.findAll();
}).catch(function(err){
alert("修改失败:"+err);
})
}
},
created:function(){
this.findAll();
}
})
访问:http://localhost:8080/user.html
【小结】
1:案例需求
2:数据库设计与表结构
3:服务器端
4:浏览器端(重点)
ajax(传递json,响应json)(封装vue中模型)