目录
前言
实现用户的CRUD,实现后端全部是异步请求;前端是vue,之前在后端写得同步请求页面跳转,现在利用vue的路由进行实现.
后端我们使用的mybatis-plus和springboot进行
一、后端
依赖
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--监控sql的执行-->
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.9.1</version>
</dependency>
</dependencies>
1、实体类
package com.sofwin.pojo;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @author : wentao
* @version : 1.0
*/
//查看方法的快捷键 alt +7
@Data
//表名注解,标识实体类中对应的表 使用位置实体类
//value 表名
@TableName(value = "user")
public class User {
//标识id为表的主键
//value为id的名称 type为主键自增情况
//auto为数据库自增
//ASSIGN_UUID 通过uuid进行主键的自增
@TableId(value = "id",type = IdType.AUTO)
private Long id;
@TableField("name") //非主键的字段描述
private String name;
private Integer age;
private String email;
private String realName;
//insert的时候触发的时候自动填充
@TableField(fill = FieldFill.INSERT)
//@DateTimeFormat的作用是入参格式化,前端传string类型的时间字符串,此注解将字符串转换为Date类型。
@DateTimeFormat(pattern ="yyyy-MM-dd")
private Date createTime;
//update触发的时候自动填充
@TableField(fill = FieldFill.UPDATE)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date updateTime;
//乐观锁的 要设置默认为1
@Version
private Integer version;
@TableLogic
private Integer status;
}
2、实现统一结果的封装类
package com.sofwin.pojo;
import lombok.Data;
/**
* @author : wentao
* @version : 1.0
*/
@Data
public class ResponseEntity {
private Integer code;
private String msg;
private Object ret;
public static ResponseEntity success(Object ret){
ResponseEntity responseEntity=new ResponseEntity();
responseEntity.ret =ret;
responseEntity.msg ="操作成功";
responseEntity.code =200;
return responseEntity;
}
}
3、mapper
继承mybatisplus的接口 baseMapper
public interface UserMapper extends BaseMapper<User> {
}
4、service
继承 IService 泛型是实体类的类型 ----mybatis提供的
package com.sofwin.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sofwin.pojo.User;
/**
* @author : wentao
* @version : 1.0
*/
public interface UserService extends IService<User> {
Page<User> queryByPage(User user, Integer pageNumber, Integer pageSize);
}
这里需要注意的是 实现类一定要实现接口
package com.sofwin.service.impl;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sofwin.mapper.UserMapper;
import com.sofwin.pojo.User;
import com.sofwin.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
/**
* @author : wentao
* @version : 1.0
*/
@Service
//第一个泛型是mapper的 第一个是实体类的
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService{
@Autowired
private UserMapper mapper;
@Override
public Page<User> queryByPage(User user, Integer pageNumber, Integer pageSize) {
Page<User> page=new Page<>(pageNumber,pageSize);
LambdaQueryWrapper<User> wrapper=new LambdaQueryWrapper<>();
//如果字符串里面的值为null, "", " ",那么返回值为false;否则为true
if (StringUtils.hasText(user.getName())){
wrapper.like(User::getName,user.getName());
}
page = mapper.selectPage(page, wrapper);
return page;
}
}
5、 启动类
package com.sofwin;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author : wentao
* @version : 1.0
*/
@SpringBootApplication
//mapper的返现映射器
@MapperScan(basePackages = "com.sofwin.mapper")
public class App {
public static void main(String[]args){
SpringApplication.run(App.class,args);
}
}
6、配置文件
application.yml
spring:
datasource:
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://localhost:3306/dubbotest?serverTimezone=UTC
username: root
password: root
logging:
level:
root: info
com.sofwin: debug
mybatis-plus:
configuration:
#打印sql语句 org.apache.ibatis.logging.stdout.StdOutImpl
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
# global-config:
# db-config:
# table-prefix: 设置表的前缀名
#逻辑删除
global-config:
db-config:
logic-delete-field: status # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
server:
port: 80
spy.properties
用于mybatisplus 的扩展功能 sql语句检查 ---具体可以看mybatisplus的官网
#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2
7、config 配置类
跨域的配置类
package com.sofwin.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
//设置跨域的配置类
@Configuration
public class CrosConfiger {
@Bean
public CorsFilter corsFilter(){
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
return new CorsFilter(source);
}
}
分页和乐观锁的插件
package com.sofwin.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author : wentao
* @version : 1.0
*/
//mybatis plus的插件的拦截器
@Configuration
public class PageInteceptor {
@Bean
public MybatisPlusInterceptor getPageInteceptor(){
MybatisPlusInterceptor interceptor= new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
//乐观锁
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
8、controller控制层
package com.sofwin.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sofwin.pojo.ResponseEntity;
import com.sofwin.pojo.User;
import com.sofwin.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author : wentao
* @version : 1.0
*/
@RestController
@RequestMapping("/user")
public class UserServiceController {
@Autowired
private UserService userService;
/**
* 分页查询 还筛选
* @param user
* @param pageNumber
* @param pageSize
* @return
*/
@GetMapping()
public ResponseEntity queryByPage(User user,@RequestParam(required = true,defaultValue = "1")Integer pageNumber
,@RequestParam(required = true,defaultValue = "10")Integer pageSize){
Page<User> page= userService.queryByPage(user,pageNumber,pageSize);
return ResponseEntity.success(page);
}
/**
* 修改或者添加
* @param user
* @return
*/
@PostMapping()
public ResponseEntity saveOrUpdate(User user){
return ResponseEntity.success(userService.saveOrUpdate(user));
}
/**
* 修改的查询
* @param id
* @return
*/
@GetMapping("/{id}")
public ResponseEntity selectById(@PathVariable(name = "id") Long id){
return ResponseEntity.success(userService.getById(id));
}
/**
* 删除单个
* @param id
* @return
*/
@DeleteMapping()
public ResponseEntity removeById(Long id){
return ResponseEntity.success(userService.removeById(id));
}
/**
* 批量删除
* @param ids
* @return
*/
// @DeleteMapping ("/removeByIds/{ids}")
// public ResponseEntity removeById(@PathVariable Long[] ids){
// List<Long> list=new ArrayList();
// for (Long id : ids) {
// list.add(id);
// }
// boolean b = userService.removeByIds(list);
// return ResponseEntity.success(b);
// }
//第二种都可以 这个是普通的
@DeleteMapping ("/removeByIds")
public ResponseEntity removeById(@RequestBody Long[] ids){
List<Long> list=new ArrayList();
for (Long id : ids) {
list.add(id);
}
boolean b = userService.removeByIds(list);
return ResponseEntity.success(b);
}
}
二、数据库的sql
create database dubbotest;
use dubbotest;
create table user
(
id bigint auto_increment comment '主键ID'
primary key,
name varchar(30) null comment '姓名',
age int null comment '年龄',
email varchar(50) null comment '邮箱',
real_name varchar(20) null,
create_time date null,
update_time date null,
version int default 1 null,
status int default 0 null
);
后端整个代码gitee :vue的后端: vue的后端
三、vue的前端
前端代码gitee:vue+elementui前端: vue+elementui 前端