SpringBoot 是提供一种快速整合的方式
文章目录
- 前期准备
-
- 新建数据库
- 新建项目
- [config 配置包](#config 配置包)
- application.yml
- 后端业务开发
-
- [po 类](#po 类)
- [mapper 接口](#mapper 接口)
- [service 接口](#service 接口)
- [service 实现类](#service 实现类)
- [controller 类](#controller 类)
- 测试
- 前端页面开发
前期准备
新建数据库
sql
drop table if exists emp;
create table emp
(
empno int primary key auto_increment,
ename varchar(20),
job varchar(9),
hiredate date,
sal double
);
新建项目
新建SpringBoot项目,这里是第三种,项目建好后查看 main/java文件夹下的Application
@SpringBootApplication
:主启动类
相当于@Configuration
配置类、@EnableAutoConfiguration
开启自动配置、@CommponentScan
组件扫描(默认扫描的是主启动类所在包及子包)
在主启动类中还需要在类的上面加两个注解
java
@MapperScan("com.ssm.mapper") //mapper包的限定名
@EnableTransactionManagement //开启事务管理
提示:以下是本篇文章正文内容,下面案例可供参考
config 配置包
MvcConfig 类
java
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
public class MvcConfig implements WebMvcConfigurer {
/**
* 跨域访问设置
*/
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
.allowedHeaders("*")
.exposedHeaders("*");
}
}
application.yml
把application.properties
重命名为:application.yml
sql
server:
port: 1234 # 配置内嵌Tomcat端口号
servlet:
context-path: /ssm # 配置应用名
# 配置数据库
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver # mysql驱动程序类名 8-com.mysql.cj.jdbc.Driver 5-com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/ssm?characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: 123456
# 配置日志输出级别
logging:
level:
# 项目包名
com.ssm: debug
# 配置mybatis实体类的别名包
mybatis:
type-aliases-package: com.ssm.po
后端业务开发
po 类
@Data
:默认自动生成Getter、Setter、toString
@AllArgsConstructor
:默认生成有参构造方法(需要有参的时候两个都加上)
项目中默认就有无参的
@NoArgsConstructor
:默认生成无参构造方法
java
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data // 默认自动生成Getter、Setter、toString
// 需要有参的就加下面两个注解,因为默认就有无参的
@AllArgsConstructor // 默认生成有参构造方法
@NoArgsConstructor // 默认生成无参构造方法
public class Emp {
private Integer empno;
private String ename;
private String job;
@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
private Date hiredate;
private Double sal;
}
mapper 接口
增加和修改用的参数是实体类,删除和 id 查询用的是 int 主键
查询所有数据用List
简单语句写注解里:
java
@Mapper
public interface EmpMapper {
// 主键自增,这里不用写
@Insert("insert into emp (ename,job,hiredate,sal) values(#{ename},#{job},#{hiredate},#{sal})")
int insert(Emp emp);
@Delete("delete from emp where empno=#{no}")
int delete(int empno);
@Update("update emp set ename=#{ename},job=#{job},hiredate=#{hiredate},sal=#{sal} where empno=#{empno}")
int update(Emp emp);
// 查询所有数据的时候,把所有属性都写出来
@Select("select empno,ename,job,hiredate,sal from emp")
List<Emp> queryAllEmps();
}
service 接口
java
public interface EmpService {
String insert(Emp emp);
String delete(int empno);
String update(Emp emp);
List<Emp> queryAllEmps();
}
service 实现类
java
@Service
public class EmpServiceImpl implements EmpService{
// 添加依赖注入的注解
@Autowired
// 依赖关系,service依赖mapper
private EmpMapper mapper;
@Override
public String insert(Emp emp) {
// 添加未实现的方法
return mapper.insert(emp)>0?"增加员工数据成功":"增加员工数据失败";
}
@Override // int类型可以随意起名,这里是主键方便区分
public String delete(int empno) {
return mapper.delete(empno)>0?"删除员工数据成功":"删除员工数据失败";
}
@Override
public String update(Emp emp) {
return mapper.update(emp)>0?"修改员工数据成功":"修改员工数据失败";
}
@Override
public List<Emp> queryAllEmps() {
return mapper.queryAllEmps();
}
}
controller 类
基于rest
风格
@RequestBody
注解作用:提示SpringMVC框架客户端发送的请求数据格式是JSON
@PathVariable("主键")
表示获取请求路径中的主键参数,并将其绑定到方法的主键参数上。
java
@RestController
@RequestMapping("/emp")
public class EmpController {
@Autowired
// controller依赖service接口
private EmpService service;
@PostMapping
// @RequestBody注解作用:提示SpringMVC框架客户端发送的请求数据格式是JSON
public String add(@RequestBody Emp emp) {
// 返回service处理的结果
return service.insert(emp);
}
@DeleteMapping("/{empno}")
public String delete(@PathVariable("empno")int empno) {
return service.delete(empno);
}
@PutMapping
public String update(@RequestBody Emp emp) {
return service.update(emp);
}
@GetMapping
public List<Emp> query(){
return service.queryAllEmps();
}
}
测试
在后端程序中右键主启动类启动 Spring Boot App
增加数据测试
POST请求
回到数据库可以看到增加了一条数据
删除数据测试
DELETE 方法,链接后面跟主键
回到数据库可以看到 2号数据被删除
修改数据测试
PUT 请求
Headers 里面的值不删,在Body里面加上要修改的主键,及对应要修改的数据
回到数据库可以看到 1号数据被修改
查新数据测试
GET请求
前端页面开发
vue新建项目后删掉无用代码
新建增加、修改、查询视图
接下来在 index.js 文件内配置路由
java
import Query from '@/views/Query'
import Add from '@/views/Add'
import Update from '@/views/Update'
const routes = [
{
path:'/',
name:'query',
component:Query
},
{
path:'/add',
name:'add',
component:Add
},
{
path:'/update',
name:'update',
component:Update
}
]
查询页面
在查询视图中
看到按钮就加上@click=" "
数据的表格要加vfor
指令和插值语法
html
<template>
<div>
<button @click="query">查询</button>
<button @click="goAdd">增加</button>
<table>
<tr>
<th>员工编号</th>
<th>员工姓名</th>
<th>员工岗位</th>
<th>入职日期</th>
<th>员工工资</th>
<th>修改</th>
<th>删除</th>
</tr>
<tr v-for="(item, index) in items" :key="index">
<th>{{ item.empno }}</th>
<th>{{ item.ename }}</th>
<th>{{ item.job }}</th>
<th>{{ item.hiredate }}</th>
<th>{{ item.sal }}</th>
<th><button @click="goUpdate(index)">修改</button></th>
<th><button @click="del(index)">删除</button></th>
</tr>
</table>
</div>
</template>
接下来现配数据:vfor
指令中的items
javascript
data () {
return {
items:[]
}
},
接下来重点是方法,差所有数据,前后端要联系起来,导入 Ajax 的库axios
javascript
import axios from 'axios'
在methods
内配置查询方法:
javascript
query(){
axios.get('http://localhost:1234/ssm/emp')
},
因为删除、增加、修改都要发请求,地址都是http://localhost:1234/ssm/emp,有点麻烦
接下来配置一个代理服务器,简化路径
在项目最后一个文件vue.config.js
里面配置:
javascript
// 最后一行})前回车,前面代码后加逗号
devServer: {
proxy:{
'/api':{
//target: 'http://localhost',
//target: 'http://localhost:端口号/后端文件名/'
target: 'http://localhost:1234/ssm/',
ws: true,
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
以后再发请求这个路径就可以被/api
替代
路径后面跟上.then()
,里面加上箭头函数,里面写响应(resp),最后写赋值
所以最后查询视图的路径及代码:
javascript
query(){
axios.get('/api/emp')
.then((resp)=> {
this.items = resp.data
})
},
启动项目:点击查询
删除功能
在查询视图内
复制上面删除按钮中的方法,加在methods
方法内:
直接发请求
javascript
// i代表数组下标
del(i){
axios.delete(`/api/emp/${this.items[i].empno}`)
.then( (resp)=>{
alert(resp.data)
// 删完后查询一下
this.query()
})
},
添加页面
首先在首页视图中加上添加的方法,以便跳转
不需要传参,只需要跳转的路径
javascript
goAdd(){
this.$router.push('/add')
},
这时候可以跳转,但是大白屏
在添加视图内
html
<template>
<div>
员工姓名:<input type="text" v-model="emp.ename"> <br>
员工岗位:<input type="text" v-model="emp.job"> <br>
入职日期:<input type="date" v-model="emp.hiredate"> <br>
员工工资:<input type="number" v-model="emp.sal"> <br>
<button @click="add">提交</button>
</div>
</template>
先导入axios
javascript
import axios from 'axios'
data
数据中:
javascript
data () {
return {
emp:{
ename: '',
job: '',
hiredate: '',
sal: ''
}
}
},
最后添加methods
方法
javascript
methods: {
add(){
// 增加post请求,方法里面两个参,一个地址一个数据
axios.post('/api/emp',this.emp)
// 响应
.then( (resp)=>{
// 弹窗
alert(resp.data)
})
}
},
在查询页面点击添加:
修改页面
在查询视图内的methods
方法内加上修改方法
会话传参方法:
javascript
goUpdate(i){
//起个名字,数组数据用JSON格式格式化一下
sessionStorage.setItem('emp',JSON.stringify(this.items[i]))
// 跳转
this.$router.push('/update')
}
在修改视图内:
修改代码结构基本和增加一样,这里可以直接复制增加的代码,然后修改部分代码
修改的话需要指定编号,但是编号不能被修改(设置只读)
html
<input type="text" v-model="emp.empno" readonly> <br>
然后修改按钮的方法名
javascript
<button @click="update">修改</button>
修改的话要把之前会话的数据从钩子函数中取出来
javascript
mounted () {
// 按照名字取出数据
let s = sessionStorage.getItem('emp')
// 恢复成对象形式,再赋值给emp表
this.emp = JSON.parse(s)
}
methods
方法里面的修改方法名(update)和请求类型需要改(put)
javascript
methods: {
update(){
axios.put('/api/emp',this.emp)
.then( (resp)=>{
alert(resp.data)
})
}
},
最后修改视图的完整代码:
javascript
<template>
<div>
<input type="text" v-model="emp.empno" readonly> <br>
<input type="text" v-model="emp.ename"> <br>
<input type="text" v-model="emp.job"> <br>
<input type="date" v-model="emp.hiredate"> <br>
<input type="number" v-model="emp.sal"> <br>
<button @click="update">修改</button>
</div>
</template>
<script>
import axios from 'axios'
export default {
data () {
return {
emp:{
ename: '',
job: '',
hiredate: '',
sal: ''
}
}
},
methods: {
update(){
axios.put('/api/emp',this.emp)
.then( (resp)=>{
alert(resp.data)
})
}
},
components: {},
computed: {},
watch: {},
mounted () {
// 取出数据
let s = sessionStorage.getItem('emp')
this.emp = JSON.parse(s)
}
}
</script>
<style scoped>
</style>