SpringBoot 是提供一种快速整合的方式
文章目录
- 前期准备
- 新建数据库
- 新建项目
- config 配置包
- application.yml
- 后端业务开发
- po 类
- mapper 接口
- service 接口
- service 实现类
- controller 类
- 测试
- 增加数据测试
- 删除数据测试
- 修改数据测试
- 查新数据测试
- 前端页面开发
- 查询页面
- 删除功能
- 添加页面
- 修改页面
前期准备
新建数据库
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
组件扫描(默认扫描的是主启动类所在包及子包)
在主启动类中还需要在类的上面加两个注解
@MapperScan("com.ssm.mapper") //mapper包的限定名
@EnableTransactionManagement //开启事务管理
提示:以下是本篇文章正文内容,下面案例可供参考
config 配置包
MvcConfig 类
@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
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.neuedu.ssm: debug
# 配置mybatis实体类的别名包
mybatis:
type-aliases-package: com.neuedu.ssm.po
后端业务开发
po 类
@Data
:默认自动生成Getter、Setter、toString
@AllArgsConstructor
:默认生成有参构造方法(需要有参的时候两个都加上)
项目中默认就有无参的
@NoArgsConstructor
:默认生成无参构造方法
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
简单语句写注解里:
@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 接口
public interface EmpService {
String insert(Emp emp);
String delete(int empno);
String update(Emp emp);
List<Emp> queryAllEmps();
}
service 实现类
@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("主键")
表示获取请求路径中的主键参数,并将其绑定到方法的主键参数上。
@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 文件内配置路由
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
指令和插值语法
<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
data () {
return {
items:[]
}
},
接下来重点是方法,差所有数据,前后端要联系起来,导入 Ajax 的库axios
import axios from 'axios'
在methods
内配置查询方法:
query(){
axios.get('http://localhost:1234/ssm/emp')
},
因为删除、增加、修改都要发请求,地址都是http://localhost:1234/ssm/emp,有点麻烦
接下来配置一个代理服务器,简化路径
在项目最后一个文件vue.config.js
里面配置:
// 最后一行})前回车,前面代码后加逗号
devServer: {
proxy:{
'/api':{
//target: 'http://localhost',
//target: 'http://localhost:端口号/后端文件名/'
target: 'http://localhost:1234/ssm/',
ws: true,
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
以后再发请求这个路径就可以被/api
替代
路径后面跟上.then()
,里面加上箭头函数,里面写响应(resp),最后写赋值
所以最后查询视图的路径及代码:
query(){
axios.get('/api/emp')
.then((resp)=> {
this.items = resp.data
})
},
启动项目:点击查询
删除功能
在查询视图内
复制上面删除按钮中的方法,加在methods
方法内:
直接发请求
// i代表数组下标
del(i){
axios.delete(`/api/emp/${this.items[i].empno}`)
.then( (resp)=>{
alert(resp.data)
// 删完后查询一下
this.query()
})
},
添加页面
首先在首页视图中加上添加的方法,以便跳转
不需要传参,只需要跳转的路径
goAdd(){
this.$router.push('/add')
},
这时候可以跳转,但是大白屏
在添加视图内
<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
import axios from 'axios'
data
数据中:
data () {
return {
emp:{
ename: '',
job: '',
hiredate: '',
sal: ''
}
}
},
最后添加methods
方法
methods: {
add(){
// 增加post请求,方法里面两个参,一个地址一个数据
axios.post('/api/emp',this.emp)
// 响应
.then( (resp)=>{
// 弹窗
alert(resp.data)
})
}
},
在查询页面点击添加:
修改页面
在查询视图内的methods
方法内加上修改方法
会话传参方法:
goUpdate(i){
//起个名字,数组数据用JSON格式格式化一下
sessionStorage.setItem('emp',JSON.stringify(this.items[i]))
// 跳转
this.$router.push('/update')
}
在修改视图内:
修改代码结构基本和增加一样,这里可以直接复制增加的代码,然后修改部分代码
修改的话需要指定编号,但是编号不能被修改(设置只读)
<input type="text" v-model="emp.empno" readonly> <br>
然后修改按钮的方法名
<button @click="update">修改</button>
修改的话要把之前会话的数据从钩子函数中取出来
mounted () {
// 按照名字取出数据
let s = sessionStorage.getItem('emp')
// 恢复成对象形式,再赋值给emp表
this.emp = JSON.parse(s)
}
methods
方法里面的修改方法名(update)和请求类型需要改(put)
methods: {
update(){
axios.put('/api/emp',this.emp)
.then( (resp)=>{
alert(resp.data)
})
}
},
最后修改视图的完整代码:
<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>